From e1f8cef70dfd457ff416af6f559c06da577fb2dc Mon Sep 17 00:00:00 2001 From: Scott Converse Date: Mon, 2 Nov 2026 18:07:46 -0700 Subject: [PATCH 1/7] Migrate Core distribution and imports to Townlight identities Codex implementation for the combined naming, Access and Notice candidate. Preserve historical ADRs and receipts; use fresh branded schema identities and advance to 1.3.0.dev2. Required release gate passed: 436 tests passed, 39 explicitly skipped, lint, source/wheel build and clean virtualenv installation/import smoke. Windows installed candidate acceptance remains pending. --- .github/ISSUE_TEMPLATE/bug_report.md | 4 +- .github/ISSUE_TEMPLATE/documentation.md | 2 +- .github/ISSUE_TEMPLATE/feature_request.md | 4 +- .github/PULL_REQUEST_TEMPLATE.md | 6 +- .github/workflows/ci.yml | 8 +- .github/workflows/cleanroom.yml | 12 +- .github/workflows/release.yml | 80 +- .gitignore | 2 +- .pipelines/module-release.yaml | 6 +- .pipelines/roles/local-rehearsal.md | 6 +- .pipelines/roles/preflight-auditor.md | 12 +- .pipelines/self-classification-rules.md | 12 +- AGENTS.md | 31 +- CONTRIBUTING.md | 14 +- README.md | 65 +- README.txt | 259 +-- SECURITY.md | 6 +- SUPPORT.md | 6 +- USER-MANUAL.docx | Bin 49842 -> 30184 bytes USER-MANUAL.md | 45 +- USER-MANUAL.pdf | Bin 398856 -> 361295 bytes USER-MANUAL.txt | 586 ++--- civiccore/db/__init__.py | 18 - civiccore/migrations/__init__.py | 1 - civiccore/migrations/alembic.ini | 3 - .../versions/civiccore_0005_job_leases.py | 26 - ...e.Dockerfile => townlight_core.Dockerfile} | 32 +- docs/SUPERVISOR.md | 18 +- docs/adr/index.md | 27 +- docs/beta-1/api/core.html | 4 +- .../docx/Townlight-Core-Manual-Beta-1.docx | Bin 49828 -> 30184 bytes docs/beta-1/index.html | 2 +- docs/beta-1/manuals/core.html | 1972 +++++++++-------- .../pdf/Townlight-Core-Manual-Beta-1.pdf | Bin 399139 -> 361295 bytes docs/beta-1/readmes/core.html | 18 +- docs/beta-1/reference/component-metadata.json | 62 +- .../reference/desktop-domain-openapi.json | 84 +- docs/beta-1/reference/native.html | 160 +- .../reference/runtime-payload-lock.json | 124 +- docs/beta-1/reference/source-inventory.json | 1504 ++++++------- docs/beta-1/versions.html | 230 +- docs/catalog-beta.md | 6 +- docs/department-authority.md | 22 +- docs/diagrams/civiccore-extraction-map.svg | 1 - docs/diagrams/migration-order.svg | 2 +- docs/diagrams/provider-abstraction.svg | 2 +- ....mmd => townlight_core-extraction-map.mmd} | 0 ....png => townlight_core-extraction-map.png} | Bin .../townlight_core-extraction-map.svg | 1 + docs/github-discussions-seed.md | 48 +- docs/index.html | 2 +- docs/job-artifacts.md | 4 +- docs/job-leases.md | 4 +- docs/module-inventory.md | 24 +- docs/ops/cleanroom-harness.md | 14 +- docs/ops/co-4-cross-module-retrofit-report.md | 6 +- docs/ops/co-7-freeze-readiness.md | 20 +- docs/ops/co-9-audit-full-release-gate.md | 66 +- ....md => co-9-townlight_core-v1-closeout.md} | 32 +- docs/ops/historical-provenance.md | 32 +- docs/ops/release-attestation.schema.json | 6 +- docs/ops/release-signing.md | 30 +- docs/ops/sigstore-release-workflow-draft.yml | 2 +- ...townlight_core-tier1-retrofit-ledger.json} | 156 +- ...> townlight_core-tier1-retrofit-ledger.md} | 8 +- docs/process/5-lens-self-audit.md | 24 +- ..._core-longmont-ingest-proof-2026-05-21.md} | 8 +- docs/release-recovery-status.md | 20 +- docs/rule-history.md | 14 +- docs/scaffold.md | 12 +- pyproject.toml | 18 +- scripts/build-release-attestation.py | 2 +- scripts/check-tier1-ledger.py | 8 +- ....sh => townlight_core-cleanroom-runner.sh} | 44 +- ...oom.sh => run-townlight_core-cleanroom.sh} | 22 +- scripts/verify-release-provenance.py | 2 +- scripts/verify-release.sh | 82 +- .../00_known_good_sigstore_attestation.json | 10 +- .../10_missing_attestation_schema.json | 10 +- .../20_wrong_workflow_identity.json | 10 +- .../30_mismatched_artifact_hash.json | 10 +- .../40_unexpected_oidc_issuer.json | 10 +- .../50_transparency_log_unavailable.json | 10 +- .../60_tag_target_mismatch.json | 10 +- .../70_workflow_rename_identity_drift.json | 10 +- .../80_trust_root_rotation.json | 10 +- tests/test_audit_primitives.py | 2 +- tests/test_auth_bearer.py | 56 +- tests/test_auth_suite_session.py | 16 +- tests/test_baseline_idempotency.py | 16 +- tests/test_city_profile.py | 6 +- tests/test_cleanroom_harness.py | 14 +- tests/test_connector_delta.py | 2 +- tests/test_connector_imports.py | 2 +- tests/test_connector_manifest.py | 24 +- tests/test_connector_sync.py | 2 +- tests/test_demo_town_contract.py | 6 +- tests/test_department_authority.py | 8 +- tests/test_department_authority_adr.py | 6 +- tests/test_exemption_evaluation.py | 2 +- tests/test_export_bundle.py | 6 +- tests/test_github_workflows.py | 14 +- tests/test_ingest_contracts.py | 2 +- tests/test_ingest_pipeline.py | 12 +- tests/test_job_artifacts.py | 10 +- tests/test_job_artifacts_adr.py | 10 +- tests/test_llm_context.py | 4 +- tests/test_llm_migration_0002.py | 18 +- tests/test_llm_ollama_think.py | 4 +- tests/test_llm_providers.py | 40 +- tests/test_llm_public_api.py | 30 +- tests/test_llm_registry_service.py | 12 +- tests/test_llm_structured.py | 8 +- tests/test_llm_templates.py | 166 +- tests/test_module_inventory.py | 10 +- tests/test_module_inventory_adr.py | 8 +- tests/test_module_resolution.py | 6 +- tests/test_notifications_notice.py | 2 +- tests/test_onboarding_profile.py | 2 +- tests/test_placeholder_adrs.py | 30 +- tests/test_platform_contracts.py | 64 +- tests/test_platform_task_queue.py | 16 +- tests/test_provenance_contracts.py | 2 +- tests/test_public_api_v03.py | 10 +- tests/test_release_provenance.py | 18 +- tests/test_rule_version_history.py | 6 +- tests/test_scaffold.py | 28 +- tests/test_scheduling_cron.py | 2 +- tests/test_search_helpers.py | 2 +- tests/test_security_at_rest.py | 2 +- tests/test_security_config_validation.py | 2 +- tests/test_security_host_validation.py | 2 +- tests/test_smoke.py | 66 +- tests/test_suite_session_negative_contract.py | 8 +- tests/test_testing_mock_city.py | 2 +- tests/test_tier1_retrofit_ledger.py | 8 +- tests/test_verification_browser_evidence.py | 2 +- {civiccore-ui => townlight_core-ui}/README.md | 6 +- .../components/components-reference.html | 2 +- .../components/components.css | 8 +- .../shell/shell.css | 6 +- .../tokens/tokens-reference.html | 4 +- .../tokens/tokens.css | 4 +- {civiccore => townlight_core}/__init__.py | 30 +- .../audit/__init__.py | 0 .../audit/primitives.py | 0 .../auth/__init__.py | 14 +- {civiccore => townlight_core}/auth/bearer.py | 0 .../auth/department_scope.py | 16 +- .../auth/staff_key.py | 2 +- .../auth/suite_session.py | 4 +- .../auth/trusted_headers.py | 4 +- .../catalog/__init__.py | 4 +- .../city_profile/__init__.py | 0 .../city_profile/models.py | 0 .../connectors/__init__.py | 8 +- .../connectors/delta.py | 0 .../connectors/imports.py | 0 .../connectors/manifest.py | 14 +- .../connectors/sync.py | 2 +- townlight_core/db/__init__.py | 18 + .../exemptions/__init__.py | 2 +- .../exemptions/history.py | 10 +- .../exemptions/patterns.py | 0 .../exports/__init__.py | 2 +- .../exports/bundle.py | 8 +- .../ingest/__init__.py | 6 +- .../ingest/chunker.py | 0 .../ingest/contracts.py | 0 .../ingest/embedder.py | 2 +- .../ingest/llm_extractor.py | 2 +- .../ingest/models.py | 4 +- .../ingest/parsers/__init__.py | 16 +- .../ingest/parsers/base.py | 0 .../ingest/parsers/csv_parser.py | 2 +- .../ingest/parsers/docx.py | 2 +- .../ingest/parsers/email.py | 2 +- .../ingest/parsers/html.py | 2 +- .../ingest/parsers/pdf.py | 2 +- .../ingest/parsers/text.py | 2 +- .../ingest/parsers/xlsx.py | 2 +- .../ingest/pipeline.py | 14 +- {civiccore => townlight_core}/llm/__init__.py | 20 +- {civiccore => townlight_core}/llm/context.py | 8 +- {civiccore => townlight_core}/llm/factory.py | 6 +- .../llm/providers/__init__.py | 14 +- .../llm/providers/anthropic.py | 14 +- .../llm/providers/base.py | 6 +- .../llm/providers/config.py | 2 +- .../llm/providers/ollama.py | 6 +- .../llm/providers/openai.py | 14 +- .../llm/providers/registry.py | 4 +- .../llm/registry/__init__.py | 10 +- .../llm/registry/models.py | 2 +- .../llm/registry/router.py | 6 +- .../llm/registry/schemas.py | 0 .../llm/registry/service.py | 10 +- .../llm/structured.py | 2 +- .../llm/templates/__init__.py | 20 +- .../llm/templates/engine.py | 6 +- .../llm/templates/exceptions.py | 4 +- .../llm/templates/models.py | 10 +- .../llm/templates/overrides.py | 12 +- .../llm/templates/resolver.py | 34 +- .../llm/templates/schemas.py | 2 +- townlight_core/migrations/__init__.py | 1 + townlight_core/migrations/alembic.ini | 3 + .../migrations/env.py | 4 +- .../migrations/guards.py | 10 +- .../migrations/runner.py | 24 +- .../migrations/versions/.gitkeep | 0 .../migrations/versions/__init__.py | 2 +- .../townlight_core_0001_baseline_v1.py | 20 +- .../versions/townlight_core_0002_llm.py | 38 +- .../townlight_core_0003_local_task_queue.py | 16 +- .../versions/townlight_core_0004_catalog.py | 6 +- .../townlight_core_0005_job_leases.py | 26 + .../townlight_core_0006_rule_history.py | 42 +- .../townlight_core_0007_module_inventory.py | 30 +- ...ownlight_core_0008_department_authority.py | 32 +- .../townlight_core_0009_job_artifacts.py | 26 +- .../models/__init__.py | 4 +- .../notifications/__init__.py | 2 +- .../notifications/notice.py | 0 .../onboarding/__init__.py | 2 +- .../onboarding/profile.py | 0 .../platform/__init__.py | 14 +- .../platform/backup.py | 8 +- .../platform/health.py | 4 +- .../platform/inventory.py | 34 +- .../platform/modules.py | 24 +- .../platform/runtime.py | 2 +- .../platform/task_queue.py | 6 +- .../platform/tasks.py | 2 +- .../provenance/__init__.py | 0 .../provenance/contracts.py | 0 .../release_provenance.py | 4 +- .../scaffold/__init__.py | 6 +- .../scaffold/__main__.py | 4 +- {civiccore => townlight_core}/scaffold/cli.py | 16 +- .../scaffold/project.py | 36 +- .../scaffold/spec.py | 12 +- .../scheduling/__init__.py | 2 +- .../scheduling/cron.py | 0 .../search/__init__.py | 0 .../security/__init__.py | 6 +- .../security/at_rest.py | 0 .../security/config_validation.py | 0 .../security/host_validation.py | 0 .../tasks/__init__.py | 4 +- .../tasks/artifacts.py | 12 +- {civiccore => townlight_core}/tasks/leased.py | 4 +- .../tasks/registry.py | 2 +- {civiccore => townlight_core}/tasks/worker.py | 10 +- .../testing/__init__.py | 2 +- .../testing/mock_city.py | 24 +- .../verification/__init__.py | 2 +- .../verification/browser_evidence.py | 0 258 files changed, 4077 insertions(+), 3970 deletions(-) delete mode 100644 civiccore/db/__init__.py delete mode 100644 civiccore/migrations/__init__.py delete mode 100644 civiccore/migrations/alembic.ini delete mode 100644 civiccore/migrations/versions/civiccore_0005_job_leases.py rename cleanroom/{civiccore.Dockerfile => townlight_core.Dockerfile} (57%) delete mode 100644 docs/diagrams/civiccore-extraction-map.svg rename docs/diagrams/{civiccore-extraction-map.mmd => townlight_core-extraction-map.mmd} (100%) rename docs/diagrams/{civiccore-extraction-map.png => townlight_core-extraction-map.png} (100%) create mode 100644 docs/diagrams/townlight_core-extraction-map.svg rename docs/ops/{co-9-civiccore-v1-closeout.md => co-9-townlight_core-v1-closeout.md} (59%) rename docs/ops/{civiccore-tier1-retrofit-ledger.json => townlight_core-tier1-retrofit-ledger.json} (79%) rename docs/ops/{civiccore-tier1-retrofit-ledger.md => townlight_core-tier1-retrofit-ledger.md} (95%) rename docs/qa/{civiccore-longmont-ingest-proof-2026-05-21.md => townlight_core-longmont-ingest-proof-2026-05-21.md} (74%) rename scripts/cleanroom/{civiccore-cleanroom-runner.sh => townlight_core-cleanroom-runner.sh} (85%) mode change 100755 => 100644 rename scripts/{run-civiccore-cleanroom.sh => run-townlight_core-cleanroom.sh} (88%) mode change 100755 => 100644 rename {civiccore-ui => townlight_core-ui}/README.md (91%) rename {civiccore-ui => townlight_core-ui}/components/components-reference.html (99%) rename {civiccore-ui => townlight_core-ui}/components/components.css (97%) rename {civiccore-ui => townlight_core-ui}/shell/shell.css (98%) rename {civiccore-ui => townlight_core-ui}/tokens/tokens-reference.html (97%) rename {civiccore-ui => townlight_core-ui}/tokens/tokens.css (98%) rename {civiccore => townlight_core}/__init__.py (93%) rename {civiccore => townlight_core}/audit/__init__.py (100%) rename {civiccore => townlight_core}/audit/primitives.py (100%) rename {civiccore => townlight_core}/auth/__init__.py (83%) rename {civiccore => townlight_core}/auth/bearer.py (100%) rename {civiccore => townlight_core}/auth/department_scope.py (97%) rename {civiccore => townlight_core}/auth/staff_key.py (97%) rename {civiccore => townlight_core}/auth/suite_session.py (98%) rename {civiccore => townlight_core}/auth/trusted_headers.py (98%) rename {civiccore => townlight_core}/catalog/__init__.py (96%) rename {civiccore => townlight_core}/city_profile/__init__.py (100%) rename {civiccore => townlight_core}/city_profile/models.py (100%) rename {civiccore => townlight_core}/connectors/__init__.py (88%) rename {civiccore => townlight_core}/connectors/delta.py (100%) rename {civiccore => townlight_core}/connectors/imports.py (100%) rename {civiccore => townlight_core}/connectors/manifest.py (94%) rename {civiccore => townlight_core}/connectors/sync.py (99%) create mode 100644 townlight_core/db/__init__.py rename {civiccore => townlight_core}/exemptions/__init__.py (98%) rename {civiccore => townlight_core}/exemptions/history.py (97%) rename {civiccore => townlight_core}/exemptions/patterns.py (100%) rename {civiccore => townlight_core}/exports/__init__.py (86%) rename {civiccore => townlight_core}/exports/bundle.py (96%) rename {civiccore => townlight_core}/ingest/__init__.py (89%) rename {civiccore => townlight_core}/ingest/chunker.py (100%) rename {civiccore => townlight_core}/ingest/contracts.py (100%) rename {civiccore => townlight_core}/ingest/embedder.py (96%) rename {civiccore => townlight_core}/ingest/llm_extractor.py (98%) rename {civiccore => townlight_core}/ingest/models.py (99%) rename {civiccore => townlight_core}/ingest/parsers/__init__.py (54%) rename {civiccore => townlight_core}/ingest/parsers/base.py (100%) rename {civiccore => townlight_core}/ingest/parsers/csv_parser.py (89%) rename {civiccore => townlight_core}/ingest/parsers/docx.py (97%) rename {civiccore => townlight_core}/ingest/parsers/email.py (93%) rename {civiccore => townlight_core}/ingest/parsers/html.py (89%) rename {civiccore => townlight_core}/ingest/parsers/pdf.py (90%) rename {civiccore => townlight_core}/ingest/parsers/text.py (85%) rename {civiccore => townlight_core}/ingest/parsers/xlsx.py (97%) rename {civiccore => townlight_core}/ingest/pipeline.py (96%) rename {civiccore => townlight_core}/llm/__init__.py (86%) rename {civiccore => townlight_core}/llm/context.py (97%) rename {civiccore => townlight_core}/llm/factory.py (93%) rename {civiccore => townlight_core}/llm/providers/__init__.py (62%) rename {civiccore => townlight_core}/llm/providers/anthropic.py (90%) rename {civiccore => townlight_core}/llm/providers/base.py (93%) rename {civiccore => townlight_core}/llm/providers/config.py (95%) rename {civiccore => townlight_core}/llm/providers/ollama.py (95%) rename {civiccore => townlight_core}/llm/providers/openai.py (89%) rename {civiccore => townlight_core}/llm/providers/registry.py (95%) rename {civiccore => townlight_core}/llm/registry/__init__.py (80%) rename {civiccore => townlight_core}/llm/registry/models.py (98%) rename {civiccore => townlight_core}/llm/registry/router.py (94%) rename {civiccore => townlight_core}/llm/registry/schemas.py (100%) rename {civiccore => townlight_core}/llm/registry/service.py (87%) rename {civiccore => townlight_core}/llm/structured.py (98%) rename {civiccore => townlight_core}/llm/templates/__init__.py (59%) rename {civiccore => townlight_core}/llm/templates/engine.py (92%) rename {civiccore => townlight_core}/llm/templates/exceptions.py (92%) rename {civiccore => townlight_core}/llm/templates/models.py (91%) rename {civiccore => townlight_core}/llm/templates/overrides.py (79%) rename {civiccore => townlight_core}/llm/templates/resolver.py (70%) rename {civiccore => townlight_core}/llm/templates/schemas.py (97%) create mode 100644 townlight_core/migrations/__init__.py create mode 100644 townlight_core/migrations/alembic.ini rename {civiccore => townlight_core}/migrations/env.py (91%) rename {civiccore => townlight_core}/migrations/guards.py (93%) rename {civiccore => townlight_core}/migrations/runner.py (71%) rename {civiccore => townlight_core}/migrations/versions/.gitkeep (100%) rename {civiccore => townlight_core}/migrations/versions/__init__.py (83%) rename civiccore/migrations/versions/civiccore_0001_baseline_v1.py => townlight_core/migrations/versions/townlight_core_0001_baseline_v1.py (97%) rename civiccore/migrations/versions/civiccore_0002_llm.py => townlight_core/migrations/versions/townlight_core_0002_llm.py (79%) rename civiccore/migrations/versions/civiccore_0003_local_task_queue.py => townlight_core/migrations/versions/townlight_core_0003_local_task_queue.py (68%) rename civiccore/migrations/versions/civiccore_0004_catalog.py => townlight_core/migrations/versions/townlight_core_0004_catalog.py (78%) create mode 100644 townlight_core/migrations/versions/townlight_core_0005_job_leases.py rename civiccore/migrations/versions/civiccore_0006_rule_history.py => townlight_core/migrations/versions/townlight_core_0006_rule_history.py (62%) rename civiccore/migrations/versions/civiccore_0007_module_inventory.py => townlight_core/migrations/versions/townlight_core_0007_module_inventory.py (68%) rename civiccore/migrations/versions/civiccore_0008_department_authority.py => townlight_core/migrations/versions/townlight_core_0008_department_authority.py (68%) rename civiccore/migrations/versions/civiccore_0009_job_artifacts.py => townlight_core/migrations/versions/townlight_core_0009_job_artifacts.py (73%) rename {civiccore => townlight_core}/models/__init__.py (53%) rename {civiccore => townlight_core}/notifications/__init__.py (89%) rename {civiccore => townlight_core}/notifications/notice.py (100%) rename {civiccore => townlight_core}/onboarding/__init__.py (90%) rename {civiccore => townlight_core}/onboarding/profile.py (100%) rename {civiccore => townlight_core}/platform/__init__.py (89%) rename {civiccore => townlight_core}/platform/backup.py (96%) rename {civiccore => townlight_core}/platform/health.py (95%) rename {civiccore => townlight_core}/platform/inventory.py (94%) rename {civiccore => townlight_core}/platform/modules.py (95%) rename {civiccore => townlight_core}/platform/runtime.py (96%) rename {civiccore => townlight_core}/platform/task_queue.py (98%) rename {civiccore => townlight_core}/platform/tasks.py (98%) rename {civiccore => townlight_core}/provenance/__init__.py (100%) rename {civiccore => townlight_core}/provenance/contracts.py (100%) rename {civiccore => townlight_core}/release_provenance.py (99%) rename {civiccore => townlight_core}/scaffold/__init__.py (90%) rename {civiccore => townlight_core}/scaffold/__main__.py (59%) rename {civiccore => townlight_core}/scaffold/cli.py (91%) rename {civiccore => townlight_core}/scaffold/project.py (94%) rename {civiccore => townlight_core}/scaffold/spec.py (95%) rename {civiccore => townlight_core}/scheduling/__init__.py (86%) rename {civiccore => townlight_core}/scheduling/cron.py (100%) rename {civiccore => townlight_core}/search/__init__.py (100%) rename {civiccore => townlight_core}/security/__init__.py (90%) rename {civiccore => townlight_core}/security/at_rest.py (100%) rename {civiccore => townlight_core}/security/config_validation.py (100%) rename {civiccore => townlight_core}/security/host_validation.py (100%) rename {civiccore => townlight_core}/tasks/__init__.py (84%) rename {civiccore => townlight_core}/tasks/artifacts.py (97%) rename {civiccore => townlight_core}/tasks/leased.py (96%) rename {civiccore => townlight_core}/tasks/registry.py (92%) rename {civiccore => townlight_core}/tasks/worker.py (88%) rename {civiccore => townlight_core}/testing/__init__.py (97%) rename {civiccore => townlight_core}/testing/mock_city.py (98%) rename {civiccore => townlight_core}/verification/__init__.py (86%) rename {civiccore => townlight_core}/verification/browser_evidence.py (100%) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 52f1254..82379a2 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,6 +1,6 @@ --- name: Bug report -about: Report a defect in civiccore +about: Report a defect in townlight_core title: "[bug] " labels: ["bug"] --- @@ -19,7 +19,7 @@ labels: ["bug"] **Environment** -- civiccore version (`python -c "import civiccore; print(civiccore.__version__)"`): +- townlight_core version (`python -c "import townlight_core; print(townlight_core.__version__)"`): - Python version: - Consuming application (records-ai, custom, evaluation): - Postgres version (if migration-related): diff --git a/.github/ISSUE_TEMPLATE/documentation.md b/.github/ISSUE_TEMPLATE/documentation.md index 0c5206e..dc303ea 100644 --- a/.github/ISSUE_TEMPLATE/documentation.md +++ b/.github/ISSUE_TEMPLATE/documentation.md @@ -16,4 +16,4 @@ labels: ["documentation"] **Audience this affects** - [ ] Module developer / IT integrator - [ ] Consuming application (records-ai, future modules) -- [ ] Evaluator (deciding whether to use civiccore) +- [ ] Evaluator (deciding whether to use townlight_core) diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index d416e40..144a8ac 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,6 +1,6 @@ --- name: Feature request -about: Suggest an enhancement to civiccore +about: Suggest an enhancement to townlight_core title: "[feat] " labels: ["enhancement"] --- @@ -14,6 +14,6 @@ labels: ["enhancement"] **Alternatives considered** **Scope check** - + **Additional context** diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index ff14729..5aa7e84 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -14,13 +14,13 @@ ## Test plan - [ ] `python -m pytest -q` passes -- [ ] `python -m ruff check civiccore tests` passes +- [ ] `python -m ruff check townlight_core tests` passes - [ ] If touching migrations: idempotency tests pass and Gate 1/2/3 logic still holds for downstream consumers -- [ ] If touching public API in `civiccore.llm`: smoke test verifies symbols still importable +- [ ] If touching public API in `townlight_core.llm`: smoke test verifies symbols still importable ## Checklist - [ ] CHANGELOG.md updated under `[Unreleased]` -- [ ] If version bumped: pyproject.toml, civiccore/__init__.py, scripts/verify-release.sh fresh-venv asserts all aligned +- [ ] If version bumped: pyproject.toml, townlight_core/__init__.py, scripts/verify-release.sh fresh-venv asserts all aligned - [ ] No secrets committed - [ ] Linked issue: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a5485ed..0f6e796 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,4 +1,4 @@ -name: civiccore CI +name: townlight_core CI on: pull_request: @@ -65,7 +65,7 @@ jobs: - name: Pre-pull pgvector image run: docker pull pgvector/pgvector:pg17 - - name: Install civiccore (editable, dev extras) + - name: Install townlight_core (editable, dev extras) run: | pip install --upgrade pip pip install -e .[dev] @@ -146,5 +146,5 @@ jobs: - name: Accessibility gate (no browser surface) run: | - echo "CivicCore exposes shared backend contracts and has no operator-facing browser surface in this repo." - echo "Per-PR axe gates run in CivicRecords AI, CivicClerk, CivicCode, and the CivicSuite launcher." + echo "TownlightCore exposes shared backend contracts and has no operator-facing browser surface in this repo." + echo "Per-PR axe gates run in TownlightRecords, TownlightMeetings, TownlightCode, and the Townlight launcher." diff --git a/.github/workflows/cleanroom.yml b/.github/workflows/cleanroom.yml index 7bfa077..df0bfdb 100644 --- a/.github/workflows/cleanroom.yml +++ b/.github/workflows/cleanroom.yml @@ -1,4 +1,4 @@ -name: civiccore cleanroom +name: townlight_core cleanroom on: pull_request: @@ -7,8 +7,8 @@ on: - ".github/workflows/cleanroom.yml" - "cleanroom/**" - "scripts/cleanroom/**" - - "scripts/run-civiccore-cleanroom.sh" - - "civiccore/release_provenance.py" + - "scripts/run-townlight_core-cleanroom.sh" + - "townlight_core/release_provenance.py" - "tests/fixtures/release_provenance/**" - "tests/test_cleanroom_harness.py" - "docs/ops/cleanroom-harness.md" @@ -36,10 +36,10 @@ jobs: fetch-depth: 0 - name: Verify Docker is available run: docker version - - name: Run CivicCore cleanroom harness - run: bash scripts/run-civiccore-cleanroom.sh "$TARGET_COMMIT" "docs/evidence/co6-ci-${TARGET_COMMIT}" + - name: Run TownlightCore cleanroom harness + run: bash scripts/run-townlight_core-cleanroom.sh "$TARGET_COMMIT" "docs/evidence/co6-ci-${TARGET_COMMIT}" - name: Upload cleanroom evidence uses: actions/upload-artifact@v7 with: - name: civiccore-co6-cleanroom-${{ env.TARGET_COMMIT }} + name: townlight_core-co6-cleanroom-${{ env.TARGET_COMMIT }} path: docs/evidence/co6-ci-${{ env.TARGET_COMMIT }}/ diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 941b3d0..218bab9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,7 +4,7 @@ on: push: tags: - "v*" - - "civiccore-*-freeze" + - "townlight_core-*-freeze" workflow_dispatch: inputs: release_tag: @@ -33,7 +33,7 @@ jobs: with: python-version: "3.13" - - name: Cleanroom cache strip (scoped, CivicSuite-only) + - name: Cleanroom cache strip (scoped, Townlight-only) shell: bash run: | python - <<'PY' @@ -44,10 +44,10 @@ jobs: for rel in (".npm", ".cache/pip"): shutil.rmtree(os.path.join(runner_temp, rel), ignore_errors=True) PY - docker builder prune --all --force --filter "label=civicsuite-cleanroom=1" || true - docker network ls --filter "label=civicsuite-cleanroom=1" -q \ + docker builder prune --all --force --filter "label=townlight-cleanroom=1" || true + docker network ls --filter "label=townlight-cleanroom=1" -q \ | xargs -r docker network rm || true - docker volume ls --filter "label=civicsuite-cleanroom=1" -q \ + docker volume ls --filter "label=townlight-cleanroom=1" -q \ | xargs -r docker volume rm || true - name: Install published wheel from release URL @@ -55,22 +55,22 @@ jobs: run: | TAG="${{ inputs.release_tag }}" VERSION="${TAG#v}" - WHEEL_URL="https://github.com/CivicSuite/civiccore/releases/download/${TAG}/civiccore-${VERSION}-py3-none-any.whl" + WHEEL_URL="https://github.com/Townlight/townlight_core/releases/download/${TAG}/townlight_core-${VERSION}-py3-none-any.whl" echo "Cleanroom wheel URL: ${WHEEL_URL}" python -m venv .cleanroom-venv . .cleanroom-venv/bin/activate python -m pip install --upgrade pip python -m pip install --no-cache-dir --force-reinstall "${WHEEL_URL}" TESTING=1 python - < release-notes.md < .env </ --workflow=release.yml --limit 5 gh run list -R / --workflow=ci.yml --limit 5 ``` -A workflow with 0s-duration failures in 5+ recent runs is a known-broken workflow. Audit finding TEST-022 from `audit-civicsuite-2026-05-09` documented exactly this pattern. If you see it, the workflow YAML is broken; combine with Check 1. +A workflow with 0s-duration failures in 5+ recent runs is a known-broken workflow. Audit finding TEST-022 from `audit-townlight-2026-05-09` documented exactly this pattern. If you see it, the workflow YAML is broken; combine with Check 1. ### Check 3 - Scripts referenced by workflows exist and execute @@ -60,11 +60,11 @@ rm -rf .venv-* node_modules/.cache 2>/dev/null bash scripts/verify-release.sh ``` -Local persisted state hides bugs. The civicrecords-ai email-validator bug only fired on fresh pgdata; local Docker volumes kept passing because the admin user existed from prior runs. **Always wipe before pre-flight.** +Local persisted state hides bugs. The townlight_records email-validator bug only fired on fresh pgdata; local Docker volumes kept passing because the admin user existed from prior runs. **Always wipe before pre-flight.** ### Check 5 - Cross-platform reality check -If the release workflow has a Windows job that runs Linux-only commands (or vice versa), flag it as Bug-Class-B (Windows/Linux mismatch) without trying to run it on the wrong platform. The fix pattern from civicrecords-ai PR #71 (split Linux verify + Windows installer) is the template. +If the release workflow has a Windows job that runs Linux-only commands (or vice versa), flag it as Bug-Class-B (Windows/Linux mismatch) without trying to run it on the wrong platform. The fix pattern from townlight_records PR #71 (split Linux verify + Windows installer) is the template. Common patterns to flag: - `runs-on: windows-latest` with `docker compose up` on Linux images @@ -77,11 +77,11 @@ Run a deliberate-failure scenario locally: stop a dependent service, then run th If the script doesn't dump container logs / env shape / dependency state on failure, that's a diagnostic gap. Add it as part of the Phase 0 bundled fix. -The civicrecords-ai diagnostic dump PR #72 is the template - when compose health-check fails, dump `docker compose logs api postgres redis ollama` + redacted .env + `docker compose ps` before declaring fail. +The townlight_records diagnostic dump PR #72 is the template - when compose health-check fails, dump `docker compose logs api postgres redis ollama` + redacted .env + `docker compose ps` before declaring fail. ### Check 7 - Audit punchlist correlation -Read `audit-civicsuite-2026-05-09/sprint-punchlist.md` (or equivalent audit doc for the current project). Cross-reference every finding tagged for this module's release infrastructure. If audit findings exist for this module that overlap with checks 1-6, name them in the Phase 0 report. The audit knew about these bugs - don't rediscover them. +Read `audit-townlight-2026-05-09/sprint-punchlist.md` (or equivalent audit doc for the current project). Cross-reference every finding tagged for this module's release infrastructure. If audit findings exist for this module that overlap with checks 1-6, name them in the Phase 0 report. The audit knew about these bugs - don't rediscover them. ## Bundled fix PR @@ -92,7 +92,7 @@ Every bug found by checks 1-6 goes into ONE pull request: - Each commit in the PR addresses ONE bug class with a focused message - CI on the PR must pass -DO NOT open multiple PRs for related infrastructure fixes. The civicrecords-ai sweep used 4 PRs for what should have been 1 - that's the anti-pattern this role exists to prevent. +DO NOT open multiple PRs for related infrastructure fixes. The townlight_records sweep used 4 PRs for what should have been 1 - that's the anti-pattern this role exists to prevent. ## When to skip a module entirely diff --git a/.pipelines/self-classification-rules.md b/.pipelines/self-classification-rules.md index 6c67880..7a17934 100644 --- a/.pipelines/self-classification-rules.md +++ b/.pipelines/self-classification-rules.md @@ -1,6 +1,6 @@ # Self-classification rules - pre-authorized for agents -These are the rules the executor role applies to every grep hit, every test failure, every workflow alert, and every "should I halt or fix forward?" judgment call. They're pre-authorized so the agent doesn't halt-and-ask on routine cases. The civicrecords-ai sweep wasted ~25% of its time on halt-and-ask cycles that should have been mechanical decisions. +These are the rules the executor role applies to every grep hit, every test failure, every workflow alert, and every "should I halt or fix forward?" judgment call. They're pre-authorized so the agent doesn't halt-and-ask on routine cases. The townlight_records sweep wasted ~25% of its time on halt-and-ask cycles that should have been mechanical decisions. ## Grep-hit classification (during edit phases) @@ -12,7 +12,7 @@ Every line returned by a release-sweep grep gets exactly ONE classification: - `.github/workflows/*.yml` lines that pip-install a versioned URL - `README.md`, `USER-MANUAL.md`, install-instruction snippets describing current state - Test files asserting current pin URL or current version constant -- Test fixture dicts like `{"civiccore": "1.0.0"}` (update value to new version) +- Test fixture dicts like `{"townlight_core": "1.0.0"}` (update value to new version) - Compatibility matrix entries describing current pin - Source files with `EXPECTED__VERSION = "X.Y.Z"` constants @@ -34,7 +34,7 @@ A grep hit is SHAPE-GUARD when ALL of these hold: - Updating X to the new version would pass trivially with no real coverage Examples: -- `assert "civiccore==1.0.0" not in dependencies` - asserts no `==` pinning, version-independent +- `assert "townlight_core==1.0.0" not in dependencies` - asserts no `==` pinning, version-independent - `assert "1.0.0.dev0" not in text` - asserts no stale dev marker, version-unrelated ### OWN-MODULE-VERSION - SKIP (do not edit during a dependency-bump sweep) @@ -72,7 +72,7 @@ The fix-forward bound is: changes must touch only `.github/workflows/`, `scripts ### CONTRACT-CHANGE - HALT AND REPORT - Any source code change required -- Any test asserting on dependency-removed behavior (e.g., civicclerk tests asserting on civiccore-removed `token_roles` field) - the auditor must approve the test update before the agent applies it +- Any test asserting on dependency-removed behavior (e.g., townlight_meetings tests asserting on townlight_core-removed `token_roles` field) - the auditor must approve the test update before the agent applies it - Any cross-module dependency conflict - Any failure whose root cause requires a design decision @@ -93,7 +93,7 @@ When fix-forward catches multiple MECHANICAL-CI-BUG issues in a single workflow - Bundle them into ONE commit on a single fix-forward branch - Branch name format: `fix/--` (e.g. `fix/release-yml-preflight-2026-05-11`) - One PR per fix-forward bundle, not one PR per bug -- The civicrecords-ai sweep opened 4 PRs (#70/#71/#72/#73) for what should have been 1 bundled PR. This is the explicit anti-pattern. +- The townlight_records sweep opened 4 PRs (#70/#71/#72/#73) for what should have been 1 bundled PR. This is the explicit anti-pattern. ## Tag-move budget @@ -104,7 +104,7 @@ A ` v` tag may be moved at most ONCE per release sprint, and only A second tag move is a signal that Phase 2 local rehearsal didn't catch what it should have. After the second move, halt and reassess Phase 2 instrumentation rather than continuing to chase remote bugs with more tag pushes. -CivicSuite v1.5.0 moved 4 times during recovery. The new pipeline targets ZERO moves per sprint; 1 move is acceptable for genuine environmental surprise. +Townlight v1.5.0 moved 4 times during recovery. The new pipeline targets ZERO moves per sprint; 1 move is acceptable for genuine environmental surprise. ## What this preserves vs. what changes diff --git a/AGENTS.md b/AGENTS.md index 254dded..855c84c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,14 +1,29 @@ # AGENTS.md -This project uses Agent Pipeline for Codex. +Scott's bounded completion contract governs this work. Legacy pipeline profiles +apply only when explicitly invoked; they do not authorize delegation, extra +features or repeated gates. Preserve repository-required CI and data safeguards. ## Project Orientation -- Purpose: TODO -- Primary users: TODO -- Stack: TODO -- Test command: TODO -- Lint/static command: TODO +- Purpose: Townlight's shared identity, provenance, ingestion, catalog, + exemption, scaffold, migration, task and recovery contracts. +- Primary users: owning Townlight products and platform administrators. +- Stack: Python 3.11+, FastAPI, SQLAlchemy, Alembic and PostgreSQL/pgvector. +- Distribution/import: `townlight-core` / `townlight_core`, version `1.3.0.dev2`. +- Test command: `python -m pytest tests/`; PostgreSQL tests require the declared + disposable Docker database. Report skips and installed acceptance separately. +- Lint/static command: `python -m ruff check .`; release command: + `bash scripts/verify-release.sh`. + +Catalog, exemption and scaffold contracts are implemented in this candidate. +The CO-7 placeholder ADRs describe their historical freeze, not current absence. +Keep original ADRs, signed releases and receipts unchanged. Fresh initialization +uses new identifiers; do not migrate an existing legacy database or profile. +The sole approved old active identifier is the Windows profile path +`%LOCALAPPDATA%\CivicSuite`. It does not authorize old package or product names. +No import shim is provided. Candidate source tests are not signed Windows +installed acceptance or authorization to publish. ## Order Of Operations @@ -47,4 +62,6 @@ This project uses Agent Pipeline for Codex. ## Custom Project Rules -TODO: add project-specific conventions, branch policy, documentation requirements, UI/QA gates, security constraints, and release rules. +Use one candidate and exact source/dependency pins. Preserve owning-product +authorization and data boundaries; shared contracts do not grant cross-product +authority. Reuse unaffected evidence with its original candidate identity. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 51df921..ceabd58 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ - + # Contributing to Townlight Core @@ -14,7 +14,7 @@ Townlight Core is at v0.1 (Phase 0 — package skeleton). Functional code lands in Phase 1 and beyond per the Townlight Core Extraction Spec section 12. If you want to contribute today, the most useful work is: -- Reviewing the Extraction Spec (in CivicSuite/civicsuite) and filing +- Reviewing the Extraction Spec (in Townlight/townlight) and filing issues against ambiguous wording. - Building a Phase 1 prototype against the auth + audit subsystem contracts in Appendix A of the spec. @@ -66,7 +66,7 @@ nowhere. Requirements: -- Python `>=3.11` (Townlight Core widens past civicrecords-ai's 3.12 floor +- Python `>=3.11` (Townlight Core widens past townlight_records's 3.12 floor because it is a shared library). - Git. - A POSIX-ish shell or PowerShell. The package itself is OS-agnostic. @@ -74,8 +74,8 @@ Requirements: Clone and install in editable mode with the dev extras: ```bash -git clone https://github.com/CivicSuite/civiccore.git -cd civiccore +git clone https://github.com/Townlight/townlight_core.git +cd townlight_core python -m venv .venv # macOS / Linux: source .venv/bin/activate @@ -103,7 +103,7 @@ python scripts/verify/verify_no_telemetry.py # planned ## Code standards - Match existing patterns. Where a pattern is missing, follow the - conventions in `civicrecords-ai/backend/app/` — Townlight Core is being + conventions in `townlight_records/backend/app/` — Townlight Core is being extracted from that codebase and consistency makes the migration reviewable. - Type hints on every public function. `mypy` strictness ratchets up @@ -137,7 +137,7 @@ listed in Appendix A is stable across the v0.x series: When you bump the version, update it in every location in the same commit (currently: `pyproject.toml` `[project].version` and -`civiccore/__init__.py` `__version__`). +`townlight_core/__init__.py` `__version__`). ## Security advisories diff --git a/README.md b/README.md index f542c70..2ad3dc2 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,14 @@ -> **Townlight Beta 1 public release:** [signed Windows installer, exact owned source, documentation and acceptance](https://github.com/townlight/townlight/releases/tag/townlight-beta-1). [Online manuals](https://townlight.github.io/manuals/core.html). The retained manual edition describes the accepted candidate before publication; publication changes distribution only. Component versions and signed bytes are unchanged. +> **Prepared naming, Access and Notice candidate — 2 November 2026.** Build, signing, installed acceptance and publication remain pending. Earlier signed releases and receipts apply only to their identified artifacts. # Townlight Core -**Townlight Beta 1** · Existing component versions retained · AGPL-3.0-only +**Townlight Beta 1** · Naming candidate; component versions advanced · AGPL-3.0-only Core provides the shared contracts, ingestion, identity helpers, task infrastructure and recovery foundation used by Townlight. Staff encounter these capabilities through Setup, Settings and System Health. Business decisions stay with their owning product. ## Start here -Staff should use the operating manual. Administrators should read first-run, configuration and recovery before changing a deployment. Developers should read the exact API/schema reference and matching source companion. This edition accompanies Townlight Beta 1; use the release link above for the signed candidate and exact source/documentation archives. +Staff should use the operating manual. Administrators should read first-run, configuration and recovery before changing a deployment. Developers should read the exact API/schema reference and matching source companion. This edition describes the prepared source candidate; obtain its installer only after signing and installed acceptance identify the exact artifact. - [Operating manual](docs/beta-1/manuals/core.html) · [Printable PDF](docs/beta-1/pdf/Townlight-Core-Manual-Beta-1.pdf) · [Editable Word manual](docs/beta-1/docx/Townlight-Core-Manual-Beta-1.docx) - [API and data dictionary](docs/beta-1/api/core.html) · [OpenAPI JSON](docs/beta-1/api/core-openapi.json) @@ -18,17 +18,15 @@ Staff should use the operating manual. Administrators should read first-run, con | Identity | Value | | --- | --- | -| Public documentation identity | Townlight Beta 1 | -| Installer version | 1.6.0.1 | -| Product component | civiccore 1.3.0.dev1 | -| Native desktop source version | 1.6.0-1 | -| Candidate MSI SHA256 | `98bcdef11ebdf5c767f620c904ff49f85115fde3b5c23f62703b111e645aaf86` | -| Corresponding-source SHA256 | `84a23e1297e42d17b16cfc9e51b2dd78bc46414c0de8ad7ebd2466c1a409d06b` | -| Current owned software license | AGPL-3.0-only | -| Supported acceptance profile | Windows x64 fresh install; inspections-preview; separate Station configuration | +| Documentation | Townlight Beta 1 naming, Access and Notice candidate | +| Intended installer version | 1.7.0.1; build and acceptance pending | +| Native desktop source version | 1.7.0-1 | +| Product component | townlight-core 1.3.0.dev2 | +| Principal import package | townlight_core | +| Candidate hashes | Pending build, signing and installed acceptance | +| License | AGPL-3.0-only | - -“Townlight Beta 1” identifies this coordinated beta delivery. It does not renumber the installer, native binary, Python packages or historical receipts. Component versions may differ. This documentation is a later companion to unchanged signed bytes, not a rebuilt installer. Historical release pages and manuals describe their own versions and are not the download instructions for this private candidate. +Use a fresh profile and empty database. Existing unmarked city data is refused before initialization; no in-place upgrade is supported. Preserve the existing `%LOCALAPPDATA%\CivicSuite` profile, data and recovery material. Historical releases retain their original identities. ## What staff can do @@ -67,7 +65,7 @@ Versioned saves use expected prior revision identifiers where defined. Reopen an ### Capacity and platform statements -This beta has synthetic single-profile workflow evidence. It does not have a published benchmark for concurrent staff capacity, minimum RAM/CPU, large-source limits or a field SLA. Do not turn a developer machine’s specification into a supported minimum. Installer size is 2,092,122,112 bytes before installation; allow additional disk for extracted runtime, database, originals, exports, media and backups. Select equipment/storage after sizing those actual workloads. +This beta has synthetic single-profile workflow evidence. It does not have a published benchmark for concurrent staff capacity, minimum RAM/CPU, large-source limits or a field SLA. Do not turn a developer machine’s specification into a supported minimum. The new installer size remains pending its build; allow additional disk for extracted runtime, database, originals, exports, media and backups. Select equipment/storage after sizing those actual workloads. The exact [runtime payload lock](docs/beta-1/reference/runtime-payload-lock.json) records pinned files, sizes and hashes. The [component metadata](docs/beta-1/reference/component-metadata.json) records shipped dependency declarations. These references are more precise than a manually copied dependency list. Third-party and historical license notices must accompany their matching payloads. @@ -77,14 +75,14 @@ The exact [runtime payload lock](docs/beta-1/reference/runtime-payload-lock.json | Input | Administrator setup choices, named staff accounts, source material submitted through the owning product, and protected backup storage. | | Retained records | Named local accounts; native sessions; source and department authority; task receipts; profile configuration; coherent backup manifests; catalog, exemption and scaffold contracts. | | Output | Ready local services, permission-aware shared contracts, task results, diagnostics and coherent backup or restore receipts. | -| Connections | All products use selected Core contracts. Core does not create unrestricted access between products. Notice and Access are supporting components, rather than additional products in this nine-product beta. | +| Connections | All products use selected Core contracts. Core does not create unrestricted access between products. Access and Notice provide the bounded staff workflows documented in their current manuals; installed acceptance remains pending. | ## Setup and operation 1. Obtain the identified signed private candidate and its corresponding-source companion from the beta coordinator. The landing pages in this documentation are not an installer download service. -2. On the intended fresh Windows test installation, verify the MSI hash and publisher signature before installing. Preserve unrelated profiles and recovery material. This candidate has fresh-install acceptance; historical in-place upgrades are unverified. -3. Launch Townlight under the intended named Windows account. Choose the storage folders. Select **Townlight Inspections candidate** (`inspections-preview`) for all eight desktop products. A narrower default selection will not expose all workspaces. +2. On the intended fresh Windows test installation, verify the MSI hash and publisher signature before installing. Preserve unrelated profiles and recovery material. Installed acceptance for this source candidate remains pending; no in-place legacy upgrade is supported. +3. Launch Townlight under the intended named Windows account. Choose the storage folders. Select **Townlight Inspections candidate** (`inspections-preview`) for the bounded desktop composition, including Access and Notice. A narrower default selection will not expose all workspaces. 4. Enter the city profile, time zone and contacts. Create the first named local administrator, sign in and choose protected backup storage. **Continue without local AI** is valid for the deterministic workflows. 5. Run Health Check and wait for readiness. Open Townlight. In System Health select **Finish Records Migration** to activate the canonical Python/PostgreSQL runtime. Do not fabricate migration receipts or seed accounts. 6. Create named staff through Settings. Import authorized sources using each product’s source library. All examples in this package are synthetic; they are not municipal authority. @@ -93,9 +91,9 @@ The exact [runtime payload lock](docs/beta-1/reference/runtime-payload-lock.json ## Configuration ### Native deployment configuration -Use Setup, Settings and System Health for supported staff operation. Administrators provision folders, backup storage, named accounts and the city profile. Select `inspections-preview` for the full eight-workspace desktop. Station remains a separate service boundary. Do not use a standalone product’s demo server as a substitute for the installed workspace. +Use Setup, Settings and System Health for supported staff operation. Administrators provision folders, backup storage, named accounts and the city profile. Select `inspections-preview` for the bounded desktop composition, including Access and Notice. Station remains a separate service boundary. Do not use a standalone product’s demo server as a substitute for the installed workspace. -Technical deployments use `TOWNLIGHT_PRODUCT_PROFILE`, `TOWNLIGHT_PROFILE_ROOT`, `DATABASE_URL`, `CIVICSUITE_RUNTIME_PORT`, `PORTAL_MODE` and the runtime-managed secret files. Treat database URLs and native session proofs as secrets. The installed native domain runtime explicitly refuses non-loopback binding. `PORTAL_MODE=private` is the accepted posture; changing it does not by itself commission an internet portal, authentication provider or reverse proxy. +Technical deployments use `TOWNLIGHT_PRODUCT_PROFILE`, `TOWNLIGHT_PROFILE_ROOT`, `DATABASE_URL`, `TOWNLIGHT_RUNTIME_PORT`, `PORTAL_MODE` and the runtime-managed secret files. Treat database URLs and native session proofs as secrets. The installed native domain runtime explicitly refuses non-loopback binding. `PORTAL_MODE=private` is the accepted posture; changing it does not by itself commission an internet portal, authentication provider or reverse proxy. The isolated documentation exporter sets a fictional profile and unusable synthetic database origin only to read schemas; those values are not deployment configuration. Keep deployment values in the intended process/account scope. An already-running process does not automatically inherit later environment edits. @@ -180,15 +178,34 @@ Shared catalog, exemption and module-generator code exists in this private candi ## Development and repository map +### Fresh source checkout and exact local wheel + +This renamed candidate is not yet published on a package index. From this +exact candidate checkout, build its wheel before installing consumers. Use a +separate empty development environment, never an existing municipal profile: + +```powershell +py -3.13 -m venv .venv +.\.venv\Scripts\python.exe -m pip install --upgrade pip build +.\.venv\Scripts\python.exe -m build --wheel --outdir ..\candidate-wheels +.\.venv\Scripts\python.exe -m pip install ..\candidate-wheels\townlight_core-1.3.0.dev2-py3-none-any.whl +.\.venv\Scripts\python.exe -c "import townlight_core; assert townlight_core.__version__ == '1.3.0.dev2'" +``` + +Consumers install this exact Core wheel first, then their matching local +candidate wheel. The corresponding-source manifest identifies the source +commit; a moving default branch is not a reproducible candidate pin. Package +installation does not initialize a database or establish installed acceptance. + Use the corresponding source for the candidate rather than assuming the public default branch matches it. The source companion contains `installed-owned-source`, product build inputs, desktop Rust/browser sources, locks and `BUILD.md`. It excludes credentials and third-party binary/model payloads. Use the recorded runtime lock when reproducing packaging. Relevant source contracts: -- `civiccore/auth` -- `civiccore/catalog` -- `civiccore/exemptions` -- `civiccore/scaffold` -- `civicsuite_runtime/services.py` +- `townlight_core/auth` +- `townlight_core/catalog` +- `townlight_core/exemptions` +- `townlight_core/scaffold` +- `townlight_runtime/services.py` - `desktop/src-tauri/src/supervisor.rs` The desktop package defines `npm run build`, `npm test`, `npm run test:browser` and its Tauri command. Python products retain their own `pyproject.toml`, tests and migrations; use the matching checkout’s declared dependencies and test configuration. Do not run a sample server against a production profile. This documentation build validates documentation only and reuses the separately identified installed acceptance; it does not claim a new complete application CI run. diff --git a/README.txt b/README.txt index f542c70..a46edae 100644 --- a/README.txt +++ b/README.txt @@ -1,212 +1,221 @@ -> **Townlight Beta 1 public release:** [signed Windows installer, exact owned source, documentation and acceptance](https://github.com/townlight/townlight/releases/tag/townlight-beta-1). [Online manuals](https://townlight.github.io/manuals/core.html). The retained manual edition describes the accepted candidate before publication; publication changes distribution only. Component versions and signed bytes are unchanged. + Prepared naming, Access and Notice candidate — 2 November 2026. Build, signing, installed acceptance and publication remain pending. Earlier signed releases and receipts apply only to their identified artifacts. -# Townlight Core +Townlight Core -**Townlight Beta 1** · Existing component versions retained · AGPL-3.0-only +Townlight Beta 1 · Naming candidate; component versions advanced · AGPL-3.0-only Core provides the shared contracts, ingestion, identity helpers, task infrastructure and recovery foundation used by Townlight. Staff encounter these capabilities through Setup, Settings and System Health. Business decisions stay with their owning product. -## Start here +Start here -Staff should use the operating manual. Administrators should read first-run, configuration and recovery before changing a deployment. Developers should read the exact API/schema reference and matching source companion. This edition accompanies Townlight Beta 1; use the release link above for the signed candidate and exact source/documentation archives. +Staff should use the operating manual. Administrators should read first-run, configuration and recovery before changing a deployment. Developers should read the exact API/schema reference and matching source companion. This edition describes the prepared source candidate; obtain its installer only after signing and installed acceptance identify the exact artifact. -- [Operating manual](docs/beta-1/manuals/core.html) · [Printable PDF](docs/beta-1/pdf/Townlight-Core-Manual-Beta-1.pdf) · [Editable Word manual](docs/beta-1/docx/Townlight-Core-Manual-Beta-1.docx) -- [API and data dictionary](docs/beta-1/api/core.html) · [OpenAPI JSON](docs/beta-1/api/core-openapi.json) -- [Product and suite directory](docs/beta-1/index.html) · [Terms and full license](docs/beta-1/terms.html) +- Operating manual · Printable PDF · Editable Word manual +- API and data dictionary · OpenAPI JSON +- Product and suite directory · Terms and full license -## Exact version and candidate +Exact version and candidate -| Identity | Value | -| --- | --- | -| Public documentation identity | Townlight Beta 1 | -| Installer version | 1.6.0.1 | -| Product component | civiccore 1.3.0.dev1 | -| Native desktop source version | 1.6.0-1 | -| Candidate MSI SHA256 | `98bcdef11ebdf5c767f620c904ff49f85115fde3b5c23f62703b111e645aaf86` | -| Corresponding-source SHA256 | `84a23e1297e42d17b16cfc9e51b2dd78bc46414c0de8ad7ebd2466c1a409d06b` | -| Current owned software license | AGPL-3.0-only | -| Supported acceptance profile | Windows x64 fresh install; inspections-preview; separate Station configuration | + Identity Value + ------------------------------- ------------------------------------------------------ + Documentation Townlight Beta 1 naming, Access and Notice candidate + Intended installer version 1.7.0.1; build and acceptance pending + Native desktop source version 1.7.0-1 + Product component townlight-core 1.3.0.dev2 + Principal import package townlight_core + Candidate hashes Pending build, signing and installed acceptance + License AGPL-3.0-only +Use a fresh profile and empty database. Existing unmarked city data is refused before initialization; no in-place upgrade is supported. Preserve the existing %LOCALAPPDATA%\CivicSuite profile, data and recovery material. Historical releases retain their original identities. -“Townlight Beta 1” identifies this coordinated beta delivery. It does not renumber the installer, native binary, Python packages or historical receipts. Component versions may differ. This documentation is a later companion to unchanged signed bytes, not a rebuilt installer. Historical release pages and manuals describe their own versions and are not the download instructions for this private candidate. +What staff can do -## What staff can do +- Complete setup: Choose folders and the full product composition. Create the city profile and the first named administrator. Choose a protected backup location. Defer optional local AI if it is not needed. +- Activate the runtime: Run the first-run health check, wait for readiness and open Townlight. In System Health select Finish Records Migration to activate the canonical Python and PostgreSQL services. A running process alone is not a ready database. +- Create staff access: Use Settings to create named staff. Sign out and confirm that staff can sign in with their own account. Keep administrator privileges with people responsible for setup; ordinary staff cannot administer users. +- Import through the right product: Use the source library of Code, Zoning, Planning or Permitting. Inspect provenance and permissions there. Core ingestion helpers do not bypass the owning product’s source review. +- Make a coherent backup: Save open work. Use Backup Now; it stops writers to preserve a consistent snapshot. Retain the backup receipt, then use Start to resume services. +- Restore and verify: Use Restore Latest Backup after preserving current recovery material. A result of Restore needs service start is an intermediate state: use Start, then Check. Reopen a known saved record to confirm recovery. +- Collect diagnostics: Record the time, selected composition, version, operation and exact error. Inspect System Health and create a redacted support bundle. Do not delete a profile as the first repair step. -- **Complete setup:** Choose folders and the full product composition. Create the city profile and the first named administrator. Choose a protected backup location. Defer optional local AI if it is not needed. -- **Activate the runtime:** Run the first-run health check, wait for readiness and open Townlight. In System Health select Finish Records Migration to activate the canonical Python and PostgreSQL services. A running process alone is not a ready database. -- **Create staff access:** Use Settings to create named staff. Sign out and confirm that staff can sign in with their own account. Keep administrator privileges with people responsible for setup; ordinary staff cannot administer users. -- **Import through the right product:** Use the source library of Code, Zoning, Planning or Permitting. Inspect provenance and permissions there. Core ingestion helpers do not bypass the owning product’s source review. -- **Make a coherent backup:** Save open work. Use Backup Now; it stops writers to preserve a consistent snapshot. Retain the backup receipt, then use Start to resume services. -- **Restore and verify:** Use Restore Latest Backup after preserving current recovery material. A result of Restore needs service start is an intermediate state: use Start, then Check. Reopen a known saved record to confirm recovery. -- **Collect diagnostics:** Record the time, selected composition, version, operation and exact error. Inspect System Health and create a redacted support bundle. Do not delete a profile as the first repair step. - -## Operating procedures and examples +Operating procedures and examples The operating manual now includes these existing procedures, with synthetic inputs, readback and limits. Follow the actual app boundary identified there; a standalone source capability is not automatically a desktop screen. -- [Shared catalog rules and scaffolding](docs/beta-1/manuals/core.html#shared-catalog-rules-and-scaffolding). -- [Catalog import and readback](docs/beta-1/manuals/core.html#catalog-import-and-readback). -- [Jurisdictional rule evaluation and review](docs/beta-1/manuals/core.html#jurisdictional-rule-evaluation-and-review). -- [Scaffold plan and generate](docs/beta-1/manuals/core.html#scaffold-plan-and-generate). +- Shared catalog rules and scaffolding. +- Catalog import and readback. +- Jurisdictional rule evaluation and review. +- Scaffold plan and generate. -## Architecture and data +Architecture and data -### Runtime and storage +Runtime and storage -The accepted package targets **Windows x64 fresh installation**. Its native shell uses **Rust 2021, Tauri 2 and Microsoft WebView2**; browser assets are JavaScript built with **Vite 8.1.6**. This describes the native desktop frontend; Station has a separate React operator, specified below or in its product manual. Canonical business workflows use bundled **CPython 3.13.5, FastAPI, Pydantic, SQLAlchemy and Alembic**, with **PostgreSQL 17 / PostGIS** and managed original files. The installed runtime tested here contains FastAPI 0.162.0. Package minimum Python requirements can differ from the bundled executable; the metadata reference preserves both. No stack rewrite is implied by the beta label. +The accepted package targets Windows x64 fresh installation. Its native shell uses Rust 2021, Tauri 2 and Microsoft WebView2; browser assets are JavaScript built with Vite 8.1.6. This describes the native desktop frontend; Station has a separate React operator, specified below or in its product manual. Canonical business workflows use bundled CPython 3.13.5, FastAPI, Pydantic, SQLAlchemy and Alembic, with PostgreSQL 17 / PostGIS and managed original files. The installed runtime tested here contains FastAPI 0.162.0. Package minimum Python requirements can differ from the bundled executable; the metadata reference preserves both. No stack rewrite is implied by the beta label. -The native transport is fixed to loopback `127.0.0.1:15480`; PostgreSQL uses the configured local runtime port (default `15432`). Optional local model service defaults to `127.0.0.1:15434`. Those are deployment defaults, not internet endpoints. The runtime has health, module and readiness endpoints; readiness is stronger than process existence. The task queue is the existing local Core task infrastructure, not an assertion that a separate Redis service is required for this desktop composition. +The native transport is fixed to loopback 127.0.0.1:15480; PostgreSQL uses the configured local runtime port (default 15432). Optional local model service defaults to 127.0.0.1:15434. Those are deployment defaults, not internet endpoints. The runtime has health, module and readiness endpoints; readiness is stronger than process existence. The task queue is the existing local Core task infrastructure, not an assertion that a separate Redis service is required for this desktop composition. -The default native profile is `%LOCALAPPDATA%\CivicSuite`; the historical directory name remains part of compatibility. Do not rename it to Townlight. A configured `TOWNLIGHT_PROFILE_ROOT` must be absolute. Local configuration and secrets live under that profile; protected managed files and database state must be backed up coherently. Source/runtime identity is distinct from a product’s display label. +The default native profile is %LOCALAPPDATA%\CivicSuite; the historical directory name remains part of compatibility. Do not rename it to Townlight. A configured TOWNLIGHT_PROFILE_ROOT must be absolute. Local configuration and secrets live under that profile; protected managed files and database state must be backed up coherently. Source/runtime identity is distinct from a product’s display label. -### Data and consistency +Data and consistency Named local accounts; native sessions; source and department authority; task receipts; profile configuration; coherent backup manifests; catalog, exemption and scaffold contracts. Versioned saves use expected prior revision identifiers where defined. Reopen and reconcile on conflict. Exact exports and handoffs use source IDs, current visibility, revision and SHA256. Review belongs to the saved revision and does not transfer silently to edited text. Database changes use the owning product’s migrations; a request or readiness check is not an authorization to mutate schema. -### Capacity and platform statements +Capacity and platform statements + +This beta has synthetic single-profile workflow evidence. It does not have a published benchmark for concurrent staff capacity, minimum RAM/CPU, large-source limits or a field SLA. Do not turn a developer machine’s specification into a supported minimum. The new installer size remains pending its build; allow additional disk for extracted runtime, database, originals, exports, media and backups. Select equipment/storage after sizing those actual workloads. -This beta has synthetic single-profile workflow evidence. It does not have a published benchmark for concurrent staff capacity, minimum RAM/CPU, large-source limits or a field SLA. Do not turn a developer machine’s specification into a supported minimum. Installer size is 2,092,122,112 bytes before installation; allow additional disk for extracted runtime, database, originals, exports, media and backups. Select equipment/storage after sizing those actual workloads. +The exact runtime payload lock records pinned files, sizes and hashes. The component metadata records shipped dependency declarations. These references are more precise than a manually copied dependency list. Third-party and historical license notices must accompany their matching payloads. -The exact [runtime payload lock](docs/beta-1/reference/runtime-payload-lock.json) records pinned files, sizes and hashes. The [component metadata](docs/beta-1/reference/component-metadata.json) records shipped dependency declarations. These references are more precise than a manually copied dependency list. Third-party and historical license notices must accompany their matching payloads. + --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Data contract Description + ----------------------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Input Administrator setup choices, named staff accounts, source material submitted through the owning product, and protected backup storage. + Retained records Named local accounts; native sessions; source and department authority; task receipts; profile configuration; coherent backup manifests; catalog, exemption and scaffold contracts. -| Data contract | Description | -| --- | --- | -| Input | Administrator setup choices, named staff accounts, source material submitted through the owning product, and protected backup storage. | -| Retained records | Named local accounts; native sessions; source and department authority; task receipts; profile configuration; coherent backup manifests; catalog, exemption and scaffold contracts. | -| Output | Ready local services, permission-aware shared contracts, task results, diagnostics and coherent backup or restore receipts. | -| Connections | All products use selected Core contracts. Core does not create unrestricted access between products. Notice and Access are supporting components, rather than additional products in this nine-product beta. | + Output Ready local services, permission-aware shared contracts, task results, diagnostics and coherent backup or restore receipts. + Connections All products use selected Core contracts. Core does not create unrestricted access between products. Access and Notice provide the bounded staff workflows documented in their current manuals; installed acceptance remains pending. + --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -## Setup and operation +Setup and operation -1. Obtain the identified signed private candidate and its corresponding-source companion from the beta coordinator. The landing pages in this documentation are not an installer download service. -2. On the intended fresh Windows test installation, verify the MSI hash and publisher signature before installing. Preserve unrelated profiles and recovery material. This candidate has fresh-install acceptance; historical in-place upgrades are unverified. -3. Launch Townlight under the intended named Windows account. Choose the storage folders. Select **Townlight Inspections candidate** (`inspections-preview`) for all eight desktop products. A narrower default selection will not expose all workspaces. -4. Enter the city profile, time zone and contacts. Create the first named local administrator, sign in and choose protected backup storage. **Continue without local AI** is valid for the deterministic workflows. -5. Run Health Check and wait for readiness. Open Townlight. In System Health select **Finish Records Migration** to activate the canonical Python/PostgreSQL runtime. Do not fabricate migration receipts or seed accounts. -6. Create named staff through Settings. Import authorized sources using each product’s source library. All examples in this package are synthetic; they are not municipal authority. -7. Provision Station separately if it is part of the beta exercise. Selecting the desktop composition does not start or configure Station. Configure vision explicitly only if automatic photo drafting is selected. +1. Obtain the identified signed private candidate and its corresponding-source companion from the beta coordinator. The landing pages in this documentation are not an installer download service. +2. On the intended fresh Windows test installation, verify the MSI hash and publisher signature before installing. Preserve unrelated profiles and recovery material. Installed acceptance for this source candidate remains pending; no in-place legacy upgrade is supported. +3. Launch Townlight under the intended named Windows account. Choose the storage folders. Select Townlight Inspections candidate (inspections-preview) for the bounded desktop composition, including Access and Notice. A narrower default selection will not expose all workspaces. +4. Enter the city profile, time zone and contacts. Create the first named local administrator, sign in and choose protected backup storage. Continue without local AI is valid for the deterministic workflows. +5. Run Health Check and wait for readiness. Open Townlight. In System Health select Finish Records Migration to activate the canonical Python/PostgreSQL runtime. Do not fabricate migration receipts or seed accounts. +6. Create named staff through Settings. Import authorized sources using each product’s source library. All examples in this package are synthetic; they are not municipal authority. +7. Provision Station separately if it is part of the beta exercise. Selecting the desktop composition does not start or configure Station. Configure vision explicitly only if automatic photo drafting is selected. -## Configuration -### Native deployment configuration +Configuration -Use Setup, Settings and System Health for supported staff operation. Administrators provision folders, backup storage, named accounts and the city profile. Select `inspections-preview` for the full eight-workspace desktop. Station remains a separate service boundary. Do not use a standalone product’s demo server as a substitute for the installed workspace. +Native deployment configuration -Technical deployments use `TOWNLIGHT_PRODUCT_PROFILE`, `TOWNLIGHT_PROFILE_ROOT`, `DATABASE_URL`, `CIVICSUITE_RUNTIME_PORT`, `PORTAL_MODE` and the runtime-managed secret files. Treat database URLs and native session proofs as secrets. The installed native domain runtime explicitly refuses non-loopback binding. `PORTAL_MODE=private` is the accepted posture; changing it does not by itself commission an internet portal, authentication provider or reverse proxy. +Use Setup, Settings and System Health for supported staff operation. Administrators provision folders, backup storage, named accounts and the city profile. Select inspections-preview for the bounded desktop composition, including Access and Notice. Station remains a separate service boundary. Do not use a standalone product’s demo server as a substitute for the installed workspace. + +Technical deployments use TOWNLIGHT_PRODUCT_PROFILE, TOWNLIGHT_PROFILE_ROOT, DATABASE_URL, TOWNLIGHT_RUNTIME_PORT, PORTAL_MODE and the runtime-managed secret files. Treat database URLs and native session proofs as secrets. The installed native domain runtime explicitly refuses non-loopback binding. PORTAL_MODE=private is the accepted posture; changing it does not by itself commission an internet portal, authentication provider or reverse proxy. The isolated documentation exporter sets a fictional profile and unusable synthetic database origin only to read schemas; those values are not deployment configuration. Keep deployment values in the intended process/account scope. An already-running process does not automatically inherit later environment edits. -## API usage -### Native command example +API usage + +Native command example -The following JavaScript belongs in the existing trusted Townlight frontend/development environment with `invoke` imported from `@tauri-apps/api/core`. It is not a command for an arbitrary web page or an instruction for nontechnical staff. IDs must come from records created in an isolated synthetic exercise. +The following JavaScript belongs in the existing trusted Townlight frontend/development environment with invoke imported from @tauri-apps/api/core. It is not a command for an arbitrary web page or an instruction for nontechnical staff. IDs must come from records created in an isolated synthetic exercise. -```javascript -import { invoke } from '@tauri-apps/api/core'; -const result = await invoke('get_app_state', {}); -console.log(result); -``` + import { invoke } from '@tauri-apps/api/core'; + const result = await invoke('get_app_state', {}); + console.log(result); -### Trusted local HTTP example +Trusted local HTTP example An administrator/developer can inspect an already-configured isolated runtime from a trusted local process. This PowerShell example reads the signed-in synthetic profile’s existing proof into memory; it does not create a user, seed a session, reveal the proof in output or bypass a permission check. Do not use real city data in development examples. A read response does not prove approval or publication. -```powershell -$profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite' -$sessionPath = Join-Path $profilePath 'config\local-session.json' -$session = Get-Content -LiteralPath $sessionPath -Raw | ConvertFrom-Json -$headers = @{ 'X-Townlight-Session' = $session.session_hash } -Invoke-RestMethod -Uri 'http://127.0.0.1:15480/desktop/v1/suite/state' -Headers $headers -Remove-Variable session, headers -``` + $profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite' + $sessionPath = Join-Path $profilePath 'config\local-session.json' + $session = Get-Content -LiteralPath $sessionPath -Raw | ConvertFrom-Json + $headers = @{ 'X-Townlight-Session' = $session.session_hash } + Invoke-RestMethod -Uri 'http://127.0.0.1:15480/desktop/v1/suite/state' -Headers $headers + Remove-Variable session, headers -### A synthetic write with subsequent readback +A synthetic write with subsequent readback This example demonstrates the existing Meetings HTTP contract in an isolated exercise. It is intentionally fictional. It does not start a service. Its authentication setup is included so it can be run independently under the signed-in synthetic account. If a write times out, inspect current records before repeating it. -```powershell -$profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite' -$sessionPath = Join-Path $profilePath 'config/local-session.json' -$session = Get-Content -LiteralPath $sessionPath -Raw | ConvertFrom-Json -$headers = @{ 'X-Townlight-Session' = $session.session_hash } -$body = @{ - title = 'Synthetic documentation exercise' - scheduled_start = '2026-11-05T18:00:00-07:00' - location = 'Synthetic room' - meeting_type = 'regular' -} | ConvertTo-Json -$meeting = Invoke-RestMethod -Method Post ` - -Uri 'http://127.0.0.1:15480/desktop/v1/meetings/meetings' ` - -Headers $headers -ContentType 'application/json' -Body $body -Invoke-RestMethod ` - -Uri ('http://127.0.0.1:15480/desktop/v1/meetings/meetings/' + $meeting.id) ` - -Headers $headers -Remove-Variable session, headers -``` + $profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite' + $sessionPath = Join-Path $profilePath 'config/local-session.json' + $session = Get-Content -LiteralPath $sessionPath -Raw | ConvertFrom-Json + $headers = @{ 'X-Townlight-Session' = $session.session_hash } + $body = @{ + title = 'Synthetic documentation exercise' + scheduled_start = '2026-11-05T18:00:00-07:00' + location = 'Synthetic room' + meeting_type = 'regular' + } | ConvertTo-Json + $meeting = Invoke-RestMethod -Method Post ` + -Uri 'http://127.0.0.1:15480/desktop/v1/meetings/meetings' ` + -Headers $headers -ContentType 'application/json' -Body $body + Invoke-RestMethod ` + -Uri ('http://127.0.0.1:15480/desktop/v1/meetings/meetings/' + $meeting.id) ` + -Headers $headers + Remove-Variable session, headers This write requires Meetings to be enabled and the signed-in staff role to permit it. It is a cross-suite integration example; for this product’s request models, use the complete technical reference below. -## MCP status +MCP status -No direct product MCP server is exposed by the accepted Townlight desktop or Station boundary. Do not configure an invented `townlight mcp` command or assume an AI client has staff permissions. The integration surfaces for this beta are native IPC, the documented HTTP APIs, source bundle imports, exact exports and the existing Station CLI. +No direct product MCP server is exposed by the accepted Townlight desktop or Station boundary. Do not configure an invented townlight mcp command or assume an AI client has staff permissions. The integration surfaces for this beta are native IPC, the documented HTTP APIs, source bundle imports, exact exports and the existing Station CLI. -The bundled transcription code includes a **TextFlowKit MCP adapter** as a separate source capability. It offers job-based `transcribe_media`, `get_transcript`, `list_jobs`, `get_job_status` and `export_transcript`, and additional tools declared in that adapter. It uses stdio first and optional Streamable HTTP, with the MCP SDK as an optional extra. It is not automatically launched, authenticated as Townlight staff or accepted as a Townlight product MCP deployment. This documentation does not add such a service. +The bundled transcription code includes a TextFlowKit MCP adapter as a separate source capability. It offers job-based transcribe_media, get_transcript, list_jobs, get_job_status and export_transcript, and additional tools declared in that adapter. It uses stdio first and optional Streamable HTTP, with the MCP SDK as an optional extra. It is not automatically launched, authenticated as Townlight staff or accepted as a Townlight product MCP deployment. This documentation does not add such a service. For a transcription client already provisioned separately, an illustrative tool call is: -```json -{"name":"get_job_status","arguments":{"job_id":"synthetic-existing-job-id"}} -``` + {"name":"get_job_status","arguments":{"job_id":"synthetic-existing-job-id"}} -Use a job ID returned by that transcription service. This example does not create a Townlight record or bypass its review/Records handoff. The exact optional adapter tool signatures are supplied in the [MCP source reference](docs/beta-1/reference/mcp.html). Station meeting capture does not become live speech recognition because this optional donor adapter exists. +Use a job ID returned by that transcription service. This example does not create a Townlight record or bypass its review/Records handoff. The exact optional adapter tool signatures are supplied in the MCP source reference. Station meeting capture does not become live speech recognition because this optional donor adapter exists. -## Verification and known limits +Verification and known limits -| Product | Recorded result | Precisely exercised | -| --- | --- | --- | -| Core | PASS | Normal empty-profile setup; canonical activation; UI-created staff and sign-in; staff denied user administration; coherent backup, mutation, restore, Start/Check and retained/absent record readback. | + -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Product Recorded result Precisely exercised + ----------------------- ----------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Core PASS Normal empty-profile setup; canonical activation; UI-created staff and sign-in; staff denied user administration; coherent backup, mutation, restore, Start/Check and retained/absent record readback. + -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- These results come from the identified signed candidate’s fresh normal-profile Sandbox exercise: real native IPC/HTTP/PostgreSQL and selected headless controls. All accounts, source bundles and media were synthetic. The guest install/uninstall and recovery passed, and the owned Sandbox stopped. No host installed application or standalone CivicCast was changed. This documentation task reuses those receipts; it does not claim a new software acceptance run. -The [workflow matrix](docs/beta-1/reference/workflow-matrix.json) identifies raw receipt filenames. The [evidence index](docs/beta-1/reference/sandbox-evidence-index.json) retains their original hashes; raw receipts remain in the private beta handoff rather than being silently republished with the documentation site. +The workflow matrix identifies raw receipt filenames. The evidence index retains their original hashes; raw receipts remain in the private beta handoff rather than being silently republished with the documentation site. The limits remain: actual city field acceptance and equipment/network commissioning; Station automatic provisioning/SCM commissioning; every UI/role combination; field recognition accuracy; and historical in-place upgrades are not certified. They are not five invented feature requirements. Fresh-install controlled beta handoff remains the accepted scope. This package makes no city-deployment, publication or general-availability claim. Shared catalog, exemption and module-generator code exists in this private candidate. It is not a centrally hosted federation service. A business product still owns its decisions, identity mapping and permission checks. Historical placeholder ADRs are retained as history, rather than descriptions of the current implementation. -## Development and repository map +Development and repository map + +Fresh source checkout and exact local wheel + +This renamed candidate is not yet published on a package index. From this exact candidate checkout, build its wheel before installing consumers. Use a separate empty development environment, never an existing municipal profile: + + py -3.13 -m venv .venv + .\.venv\Scripts\python.exe -m pip install --upgrade pip build + .\.venv\Scripts\python.exe -m build --wheel --outdir ..\candidate-wheels + .\.venv\Scripts\python.exe -m pip install ..\candidate-wheels\townlight_core-1.3.0.dev2-py3-none-any.whl + .\.venv\Scripts\python.exe -c "import townlight_core; assert townlight_core.__version__ == '1.3.0.dev2'" + +Consumers install this exact Core wheel first, then their matching local candidate wheel. The corresponding-source manifest identifies the source commit; a moving default branch is not a reproducible candidate pin. Package installation does not initialize a database or establish installed acceptance. -Use the corresponding source for the candidate rather than assuming the public default branch matches it. The source companion contains `installed-owned-source`, product build inputs, desktop Rust/browser sources, locks and `BUILD.md`. It excludes credentials and third-party binary/model payloads. Use the recorded runtime lock when reproducing packaging. +Use the corresponding source for the candidate rather than assuming the public default branch matches it. The source companion contains installed-owned-source, product build inputs, desktop Rust/browser sources, locks and BUILD.md. It excludes credentials and third-party binary/model payloads. Use the recorded runtime lock when reproducing packaging. Relevant source contracts: -- `civiccore/auth` -- `civiccore/catalog` -- `civiccore/exemptions` -- `civiccore/scaffold` -- `civicsuite_runtime/services.py` -- `desktop/src-tauri/src/supervisor.rs` +- townlight_core/auth +- townlight_core/catalog +- townlight_core/exemptions +- townlight_core/scaffold +- townlight_runtime/services.py +- desktop/src-tauri/src/supervisor.rs -The desktop package defines `npm run build`, `npm test`, `npm run test:browser` and its Tauri command. Python products retain their own `pyproject.toml`, tests and migrations; use the matching checkout’s declared dependencies and test configuration. Do not run a sample server against a production profile. This documentation build validates documentation only and reuses the separately identified installed acceptance; it does not claim a new complete application CI run. +The desktop package defines npm run build, npm test, npm run test:browser and its Tauri command. Python products retain their own pyproject.toml, tests and migrations; use the matching checkout’s declared dependencies and test configuration. Do not run a sample server against a production profile. This documentation build validates documentation only and reuses the separately identified installed acceptance; it does not claim a new complete application CI run. -## Recovery and support +Recovery and support -Save work and use Core’s canonical **Backup Now** before maintenance. That operation stops writers. Preserve the coherent profile/database/document backup and its receipt, then use **Start** to resume. A source export is not a full backup. +Save work and use Core’s canonical Backup Now before maintenance. That operation stops writers. Preserve the coherent profile/database/document backup and its receipt, then use Start to resume. A source export is not a full backup. -Use **Restore Latest Backup** through the supported controls. If the result says **Restore needs service start**, use **Start**, then **Check**, and reopen a known record. Do not repeat restore merely because services need to start. The fresh-profile acceptance verified that a fulfilled request survived restore and a post-backup marker did not. +Use Restore Latest Backup through the supported controls. If the result says Restore needs service start, use Start, then Check, and reopen a known record. Do not repeat restore merely because services need to start. The fresh-profile acceptance verified that a fulfilled request survived restore and a post-backup marker did not. Keep Station’s dedicated database and media evidence together in its own backup. Core’s native-profile backup must not be assumed to include an external Station data directory. Stop writers during a coordinated backup. Preserve failed media attempts and logs. On failure, record the time, selected composition, component/installer versions and exact message. Check System Health for stopped, starting, ready or failed dependencies. Use the existing Retry control after readiness; do not create duplicate business records to refresh a stale view. Share only a redacted diagnostic bundle. Preserve secrets, original evidence, recovery material and unrelated installations. -## License and responsible use +License and responsible use Current owned code is AGPL-3.0-only. Preserve full license, matching corresponding source, dependency notices and historical grants. Terms of use do not remove license rights. Source imports do not confer permission to publish third-party material. Review all automatic drafts and use the separate owning-product decision before official action. CivicCast remains independent. -## Earlier documentation +Earlier documentation -Previous editions are retained under `docs/history/pre-townlight-beta-1/`. They describe their original software and license grants. Use the current Townlight Beta 1 manual for this candidate. +Previous editions are retained under docs/history/pre-townlight-beta-1/. They describe their original software and license grants. Use the current Townlight Beta 1 manual for this candidate. diff --git a/SECURITY.md b/SECURITY.md index c4c52ac..c1060bf 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -21,13 +21,13 @@ Two preferred channels, in order: is the fastest path; it is private to maintainers until disclosure. 2. **Email** — if you cannot use the advisory flow, email the maintainer listed at https://github.com/townlight/core (the `Maintained by` - link in the README) with subject prefix `[civiccore-security]`. + link in the README) with subject prefix `[townlight_core-security]`. ### What to include - A description of the vulnerability and where it lives in the codebase. - A reproducer (minimal code or steps). -- The civiccore version affected. +- The townlight_core version affected. - Your assessment of impact (data exposure, privilege escalation, denial of service, etc.). - Whether you believe downstream consumers (records-ai, future modules) @@ -46,7 +46,7 @@ Two preferred channels, in order: In scope: -- Code in `civiccore/`. +- Code in `townlight_core/`. - Build / packaging configuration that ships in the release artifact. - The migration runner and any SQL it generates. - LLM provider abstraction (sanitization, prompt-injection defense, secret diff --git a/SUPPORT.md b/SUPPORT.md index 123f81e..a0a7c5d 100644 --- a/SUPPORT.md +++ b/SUPPORT.md @@ -1,6 +1,6 @@ # Support -civiccore is a shared platform library for the Townlight product family. Support is community-driven via GitHub. +townlight_core is a shared platform library for the Townlight product family. Support is community-driven via GitHub. ## Where to ask @@ -20,8 +20,8 @@ civiccore is a shared platform library for the Townlight product family. Support ## Audience-specific guidance -- **Module developers / IT integrators** consuming civiccore as a library: include the consuming application name, civiccore version, and Python/Postgres versions. -- **Evaluators** considering civiccore for a new module: a Discussions post under General is the right starting point. +- **Module developers / IT integrators** consuming townlight_core as a library: include the consuming application name, townlight_core version, and Python/Postgres versions. +- **Evaluators** considering townlight_core for a new module: a Discussions post under General is the right starting point. ## Response expectations diff --git a/USER-MANUAL.docx b/USER-MANUAL.docx index 0732d517a494118967ab5701f2ab74e6aafbbb06..529355c956570ac4ba0d5e0bb3c3e22a53154604 100644 GIT binary patch delta 26715 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 Ihreq72R6%`ssI20 delta 46492 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 diff --git a/USER-MANUAL.md b/USER-MANUAL.md index 918a922..d309578 100644 --- a/USER-MANUAL.md +++ b/USER-MANUAL.md @@ -1,6 +1,6 @@ # Townlight Core Manual -**Townlight Beta 1** · Documentation edition 30 October 2026 +**Townlight Beta 1** · Naming candidate documentation edition 2 November 2026 ## Contents @@ -34,23 +34,22 @@ Staff should begin with First run and Daily workflow. Administrators should also | Identity | Value | | --- | --- | -| Public documentation identity | Townlight Beta 1 | -| Installer version | 1.6.0.1 | -| Product component | civiccore 1.3.0.dev1 | -| Native desktop source version | 1.6.0-1 | -| Candidate MSI SHA256 | `98bcdef11ebdf5c767f620c904ff49f85115fde3b5c23f62703b111e645aaf86` | -| Corresponding-source SHA256 | `84a23e1297e42d17b16cfc9e51b2dd78bc46414c0de8ad7ebd2466c1a409d06b` | +| Documentation | Townlight Beta 1 naming, Access and Notice candidate | +| Intended installer version | 1.7.0.1; build and acceptance pending | +| Product component | townlight-core 1.3.0.dev2 | +| Principal import package | townlight_core | +| Native desktop source version | 1.7.0-1 | +| Candidate hashes | Pending candidate build, signing and installed acceptance | | Current owned software license | AGPL-3.0-only | -| Supported acceptance profile | Windows x64 fresh install; inspections-preview; separate Station configuration | +| Acceptance composition | Fresh Windows x64 profile; inspections-preview; Station configured separately | - -“Townlight Beta 1” identifies this coordinated beta delivery. It does not renumber the installer, native binary, Python packages or historical receipts. Component versions may differ. This documentation is a later companion to unchanged signed bytes, not a rebuilt installer. Historical release pages and manuals describe their own versions and are not the download instructions for this private candidate. +The naming change advances this package's version and requires a new signed installer and installed acceptance. Those steps and publication remain pending. Historical tags, receipts and archived manuals keep their original names and certify only their identified artifacts. Use an empty database and fresh profile; no in-place legacy upgrade is supported. The approved Windows profile path remains `%LOCALAPPDATA%\CivicSuite`. Preserve existing profiles, data and recovery material. ## First run 1. Obtain the identified signed private candidate and its corresponding-source companion from the beta coordinator. The landing pages in this documentation are not an installer download service. -2. On the intended fresh Windows test installation, verify the MSI hash and publisher signature before installing. Preserve unrelated profiles and recovery material. This candidate has fresh-install acceptance; historical in-place upgrades are unverified. -3. Launch Townlight under the intended named Windows account. Choose the storage folders. Select **Townlight Inspections candidate** (`inspections-preview`) for all eight desktop products. A narrower default selection will not expose all workspaces. +2. On the intended fresh Windows test installation, verify the MSI hash and publisher signature before installing. Preserve unrelated profiles and recovery material. Installed acceptance for this source candidate remains pending; no in-place legacy upgrade is supported. +3. Launch Townlight under the intended named Windows account. Choose the storage folders. Select **Townlight Inspections candidate** (`inspections-preview`) for the bounded desktop composition, including Access and Notice. A narrower default selection will not expose all workspaces. 4. Enter the city profile, time zone and contacts. Create the first named local administrator, sign in and choose protected backup storage. **Continue without local AI** is valid for the deterministic workflows. 5. Run Health Check and wait for readiness. Open Townlight. In System Health select **Finish Records Migration** to activate the canonical Python/PostgreSQL runtime. Do not fabricate migration receipts or seed accounts. 6. Create named staff through Settings. Import authorized sources using each product’s source library. All examples in this package are synthetic; they are not municipal authority. @@ -112,7 +111,7 @@ Drafting, review, approval, attachment, export, fulfillment and publication are ## Connected workflows -All products use selected Core contracts. Core does not create unrestricted access between products. Notice and Access are supporting components, rather than additional products in this nine-product beta. +All products use selected Core contracts. Core does not create unrestricted access between products. Access and Notice provide the bounded staff workflows documented in their current manuals; installed acceptance remains pending. | Direction | Material | @@ -138,14 +137,14 @@ These are existing Core developer and administrator contracts. They do not add a ### Catalog import and readback 1. Review the catalog's `catalog_version`, domain names and systems. Each system supplies vendor name, protocol, data shape, record types, redaction tier 1–3 and optional discovery hints. Hints are limited to `ports`, `db_patterns` and `service_accounts`; do not put credentials in them. -2. In an authorized application transaction, call `civiccore.catalog.import_catalog(session, bundle, actor_id=actual_actor_id)`. The actor is the authenticated application's identity. A changed or incomplete existing version is refused rather than overwritten. Use a newly reviewed version for changed catalog contents. +2. In an authorized application transaction, call `townlight_core.catalog.import_catalog(session, bundle, actor_id=actual_actor_id)`. The actor is the authenticated application's identity. A changed or incomplete existing version is refused rather than overwritten. Use a newly reviewed version for changed catalog contents. 3. Read `domains(session)`, `system_catalog(session, domain)` and `connectors_for(session, domain)` before committing. Commit only the intended import; roll back on refusal. Repeating an identical complete version is a no-op. 4. Treat returned systems and connector recommendations as catalog information. Import does not discover vendor endpoints, install a connector or establish access to a city's system. The following synthetic library example belongs inside an existing authorized async transaction. `session` and `actual_actor_id` are supplied by that application; this is not a command that seeds an administrator. ```python -from civiccore.catalog import import_catalog, system_catalog +from townlight_core.catalog import import_catalog, system_catalog bundle = { "catalog_version": "synthetic-1", @@ -168,7 +167,7 @@ Select the jurisdiction and active reviewed rule versions before evaluating docu ```python from uuid import UUID -from civiccore.exemptions import Rule, evaluate, RuleEvaluationError +from townlight_core.exemptions import Rule, evaluate, RuleEvaluationError rule = Rule( id=UUID("11111111-1111-4111-8111-111111111111"), @@ -188,16 +187,16 @@ This is fictional test text, not a Colorado exemption rule. Read each result's m Run the existing CLI from a developer environment containing the matching Core package. Choose an existing empty parent workspace directory, not an installed application's directory. The module's own directory will be created underneath it. The following creates only a fictional module project; it does not register, install, migrate or run it. ```powershell -& $control -m civiccore.scaffold plan civicnotes ` +& $control -m townlight_core.scaffold plan civicnotes ` --name 'Synthetic Notes' --description 'Synthetic scaffold exercise' -& $control -m civiccore.scaffold generate civicnotes ` +& $control -m townlight_core.scaffold generate civicnotes ` --name 'Synthetic Notes' --description 'Synthetic scaffold exercise' ` --target 'C:\TownlightSynthetic' --dry-run ``` -Here `$control` is the Python executable in that isolated developer environment. Inspect the plan and files, then remove `--dry-run` only when that exact target is approved for generation. Existing files are refused, not silently overwritten. Exit 0 indicates success; refusal exits 2. Options include `--version`, `--civiccore-min-version`, `--permission-key`, repeated `--staff-role` and `--route-path`; inspect `--help` for the exact invocation. Keep generated access requirements and migration stubs under the new module's own review. No automatic product deployment follows generation. +Here `$control` is the Python executable in that isolated developer environment. Inspect the plan and files, then remove `--dry-run` only when that exact target is approved for generation. Existing files are refused, not silently overwritten. Exit 0 indicates success; refusal exits 2. Options include `--version`, `--townlight_core-min-version`, `--permission-key`, repeated `--staff-role` and `--route-path`; inspect `--help` for the exact invocation. Keep generated access requirements and migration stubs under the new module's own review. No automatic product deployment follows generation. -Source contracts: `civiccore/catalog/__init__.py`, `civiccore/exemptions/__init__.py`, `civiccore/scaffold/cli.py`, `project.py`, and the Records catalog facade. +Source contracts: `townlight_core/catalog/__init__.py`, `townlight_core/exemptions/__init__.py`, `townlight_core/scaffold/cli.py`, `project.py`, and the Records catalog facade. ## Technical specifications @@ -217,16 +216,16 @@ Versioned saves use expected prior revision identifiers where defined. Reopen an ### Capacity and platform statements -This beta has synthetic single-profile workflow evidence. It does not have a published benchmark for concurrent staff capacity, minimum RAM/CPU, large-source limits or a field SLA. Do not turn a developer machine’s specification into a supported minimum. Installer size is 2,092,122,112 bytes before installation; allow additional disk for extracted runtime, database, originals, exports, media and backups. Select equipment/storage after sizing those actual workloads. +This beta has synthetic single-profile workflow evidence. It does not have a published benchmark for concurrent staff capacity, minimum RAM/CPU, large-source limits or a field SLA. Do not turn a developer machine’s specification into a supported minimum. The new installer size remains pending its build; allow additional disk for extracted runtime, database, originals, exports, media and backups. Select equipment/storage after sizing those actual workloads. The exact [runtime payload lock](docs/beta-1/reference/runtime-payload-lock.json) records pinned files, sizes and hashes. The [component metadata](docs/beta-1/reference/component-metadata.json) records shipped dependency declarations. These references are more precise than a manually copied dependency list. Third-party and historical license notices must accompany their matching payloads. ## Configuration and administration ### Native deployment configuration -Use Setup, Settings and System Health for supported staff operation. Administrators provision folders, backup storage, named accounts and the city profile. Select `inspections-preview` for the full eight-workspace desktop. Station remains a separate service boundary. Do not use a standalone product’s demo server as a substitute for the installed workspace. +Use Setup, Settings and System Health for supported staff operation. Administrators provision folders, backup storage, named accounts and the city profile. Select `inspections-preview` for the bounded desktop composition, including Access and Notice. Station remains a separate service boundary. Do not use a standalone product’s demo server as a substitute for the installed workspace. -Technical deployments use `TOWNLIGHT_PRODUCT_PROFILE`, `TOWNLIGHT_PROFILE_ROOT`, `DATABASE_URL`, `CIVICSUITE_RUNTIME_PORT`, `PORTAL_MODE` and the runtime-managed secret files. Treat database URLs and native session proofs as secrets. The installed native domain runtime explicitly refuses non-loopback binding. `PORTAL_MODE=private` is the accepted posture; changing it does not by itself commission an internet portal, authentication provider or reverse proxy. +Technical deployments use `TOWNLIGHT_PRODUCT_PROFILE`, `TOWNLIGHT_PROFILE_ROOT`, `DATABASE_URL`, `TOWNLIGHT_RUNTIME_PORT`, `PORTAL_MODE` and the runtime-managed secret files. Treat database URLs and native session proofs as secrets. The installed native domain runtime explicitly refuses non-loopback binding. `PORTAL_MODE=private` is the accepted posture; changing it does not by itself commission an internet portal, authentication provider or reverse proxy. The isolated documentation exporter sets a fictional profile and unusable synthetic database origin only to read schemas; those values are not deployment configuration. Keep deployment values in the intended process/account scope. An already-running process does not automatically inherit later environment edits. diff --git a/USER-MANUAL.pdf b/USER-MANUAL.pdf index 844d0892b0b281fd2f2d5626de8bc3597c54cf84..cb3ea25ad5a1902cb74156d5551c3ead4b05b459 100644 GIT binary patch literal 361295 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

R|gow@|gl!X!%NCWeZEHM*yt@yCx!7?SyN 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

xw&JL~vQwVB?G|fRbM7X(C zx^1o-3(f2f;asy>!8ek)?8~{r%F*!6$J?BP=rACX)Y+l#ba+SYbK)Nv4nXjS&TwbR z8x4kgBM>u@cjFX%MSr}V%yNG@Dg$Jn(fs8; zpN8ynW2Jc(@O5eVcv7N%IL7MaB}vn0`tYe#Z<29f0`O7KH`|IJ+0=UVp)?P(P8$jQ z0u5g7tL4mC9x!ql3xe!G8ay0tFv=SkKZ$rA_!BU#o5D~_i&Zvzh`9sSl~Z$P)O|&L zIP7bH>R=!sf|?)2k{92qU*kd#7I0I@{qZp(4JrR3tW@$pk`CH2t zk;&QV>BX6{W$UGtTC=8N4ccfeEp@@(bZx{?TxX@I)opa%HVbNnvOWp+0Z@c$(JcEC zb=9G?a|#08H|uXV4AxOii)AT&E^%6cH>gDTTRi7yH)c>q>TPFG7XseOgRXnBquXKT zrmoWMv55(@irC8ZEekus2mUrj8NKJx9P7DCHKMITpwvT_iZ}IE9{Q4;^Oltv@6pO|#yfmOYQW?BvnKK`Sre zZwq-0*qc?;_t67oqA_@m(ly2)G`rz#%cwR5a~zvh{D67PpB@=aboW4|{1Qc~Fxw9` z@SCU7U~!tGhrp>3GBrjz7Iom<#VzuZaMnllMzdKZn)Paz7^&MCWGKvOjP*Aj*U~=j z<}I_hZ8q8yw&WzIJw9?@l0ZKNL6X+0j+&!uFDuzQ?Xvj5OzS~ckUd#zmNybv5+1PY zryq|+bl88Ygk66<%N3H3)VcDG)PXwAMQj^D4!VqM0Y%JGU$U;3%Y*x3U&RXlJ((}N z%@o$CvJ5{_#bu_v%?3+|fbF@$ug_1IZMhZ4`$^R>G>VKAfr!j!6-`o7I5SdSDpraL zL>G5^)bt|DyD%)(zVv&8_0N{pQLqCUIQn_->5q= zsOhe=Mkvt;@JzE&lR=Ed8*^cFW)-)3p=+U|yd2Kkl)lt6M%=R z^X)Lm+GNwY2hjPMX36(g+D~*Zv~UJM!feu){BtKLVdHu0!P9vSF!=(!Gyd{gouOBi zO<)AykGl_v1mA@?e_#HCoW8MM_gTeM z8>Hpo$HqE9GEw3|M%*IW%)**X1Bva-Q2mf&33K1`3Hx+Amu$s&>VktlmLqT`hseG^ zSS=5j2DW@X+o=p4CvO#bgC@&r8!rzLo*!YG#=wI@7@Yq-J3&iiV}U!cjZXO0fM=ZG;Wz%1>TGX zg03yG0X?F2jVDw|6g7Bc{nQ^^#)eZqe9NB9{m@^VV@sTj`_LbyzH|UuKRsF!vGQX9 z+RLuzBI7a_$@3J<#1_QKW&oNj{jwYh*S1H-7)C`*)=eUV{%=S}Ot{S)^qLGizpY+< zB83x(t)NR5(z;_0B3V6`PhR$p%%QDdtW#k0I@}O8ned_ROhS>KByH!B?2Xh8%2=*V zsQZp~m)PvscSo_@7y`(L<7!+8fM_0tP>I%0Qk-a9invl%#$9y9t~(JM8stvMDhs&k z7dqCmaXVoLTZEU#ei93`h{)o5#Q<`zKjKkK64+*b-N)5NF1MI-@ve2_1Ekxml?+z; z@XB=!3|5V26TTIy)ugb5sygGoQFWU?P`O13?2GaIFM(mal0dL1R@lKWpe)Pl-6L67 zC04=6iD{zz_U(f?#^Hb=S#AvP6{p*dB|}wt3!v*@A8^!Kt`GR)jIvI>UTS360mdH( z_N-5Rvd_OyxyY0XQEKY1nmUs@LowJ#-HC2!#6#I&Nk5G@=$F3RmXYY_!qq0!m)Ra* z?!dLKLaS38#hfdX!N~=>Oh89*2$cL(+1`QE@z;}i4P{)wBvZ^!DfeTA;>?MuU5Q>z zqmmVY&@AmvvsZV4J_p(Z%Y=}r6^v=$XIxqwF20{|J8oIvNbqzUA97RF{wd@97TLu5 zJbC6|*e+3ApQ+RtdM}Fah4Kc`pd|OHtRSo~RqZENF_#`bJ~LHy%>D66y$OcMacp5H zkZFwLl3D!jflyPILPU_uCJdX~tJcBP4P~tLt!4{1-`36J5P7EzI>+}r?C^Tn^?^U?a(5!xY#@U~ zQ%F9%&+6DdI>PdQMl3onL^nJszR$#Kwlv4-Yj+OhXgpk`f1hy4*~-k4QFB_2Tuqcd z=6ZT8Q|O_>ZQIEaA8kBeYO$C}YA@q04m!~eo;&ZTa2k%!mES?N(EMv#%>Vq_6+RzA z0ZWP^N=n_rbM-u|@kDLW(4C>1g3{NW)(F$jsCmjyDi!%bcC%;TChFq zwhzoSr~u&BHM+ji){TlA%(B9~a_TjvKFiO<50K zkSDqUxAC|3rYgq9WH-#tI!giLoah6%aaz$W1^Ku65;2-2wF(#gDJ#Q(KD}0D{n-;5 z%rGH2B&yGZlEKUJb-h~VfitzZ2zHxF1SrnzMPM9+ACpX}@Ba8Vn^u>BVu)2^#qf$v zzkAg)q|u@ZdRX>dMA~SV6oY6_vBDQXYQu+(U$Sz-U524;n+Hso(&kj1y7R7Gc@P#V z_dnlk2v!e}(o)Tpc)JJT9ul5Q-N!r5IzT(}I*>Y;c-!IdBKa}qBD$D5?0JQnVRRW+ zaQ)2!6)c(s&*F$!w2PHx`eT%TRUCo_K8AXPXWl`v*3Dywl}W2QC9In^xUx{@t)quA zxr*&uKIlwA6q{k9p&^qastXtmCAP>Wvh^4DnLiU~h2t(w=7X!th_B{rmj^PISi^JI z?FHa0^9agkH?M8j9cv|x*fV4nuK8E(aP0L!3KA7PlrxBccYDbdPX?-RbNk6>Wr zT-ahp#5rVeS|l=^mOE0#5<(B3vP4lFzyDd0Q@kx&YVL>Z>8H2CWuhq=2=QxkxV~0P zD2+mboS$WOu)Z;&2Zc?y2M9;Zv@uP2EXUCUIa4ZXI$7D!U)e(nCund6rh?FtDi|rS z1ytyDbX2N4fhEaHyNBvG&e5fzL(N#@txPQ7%1%QW|AtYD9pg;Sx$V`@6R~~tL zQJgZPX;ry8Tryd4!f&gahCc2YHu39ta9VVq|8FtW6r){Zq!YsYQStiXx%>v;vdlv4 zW`5coC6hSXa^EV{GV6=Z2KD_hAyL}>#Y>dt?b<&({FgWjdz5VG?f36O*{GLJqjJUg zBLY~3g%4IMFd?HKbxVL{g<|7ZbX{3AYE`F-#2R`Z{EM)DpMzRBh`3=AFN#5vd9`?Y zy1>MWTjFwV(WoA^*&jhWm+9FKhTA_;G^MH( z6>CO+wv1;M6fPRdV_+K3ldIRs@E&T4COV0|W}uD>Q=cxE7lCLg4nDo;j5;<^K0msR zd=Oy_gy7Mu<;5HT>5qTDfX`#e*V7Z~HmLESu&J{FAf1TI$lu$z;dv}%j-xf!RPRTQ!ETg`x!xS57K3IX=_{TNBKkQBU} z>pe!x=t+rzl{||PQF^v^*p|5QxS}Om_t3wr@)e^k)jzu|H&SagsnwQmO0A3WtcaR- z>zzA2(TA1QsS(8R-I6K!=z=8s>@9#B#4QC?75rk9%GR8kklvt~d#n~B_m`|rhJxp3QN?+~y^@sepQglG@$2`l+z+!oC}<#? zc3?!9cayz_&@$|%*l+XsdZn9Y!^i55u+9EGHbq9=ZQ5W2Pj#pF3^q?oH+#o>%ZF;7 zYqHx9*dZDt-2bc+|5s`R0|OHS``3~$fCA=Iz5HeC|8>mGO{eH$V@M}zZRPNl=wN4R z<6v#~&s0X&(va@Qe`F>;LnAD7jqUOO8(e~sjUAtZo$>#3TH;Gy{a+>5|7U;%GYiB2 zOiNg;e$f)oFtoEG_*VoJz;M8kIG|ej@W;2H1|d%1bFuuRupb`I2aGgR0RcjG?A+LZ zn{m%pydV-UfWq&~Fiv=VyjRDTfQhm^K7f8<#Bq?7IMI_+(m%9>O(*SpEuQSGS;8kR zvEm5*`>y)DDDNY2k5BNTmp*g8w`!aq67UIk@6dT_D8{fv9KTWQyOiaxW@;i&&@op5C*|Ykv_=m*x)JBiO?8dO_ZIv1Q8&yb7 zXFz9Rr;s%BTN#?ob&y|9XTNITd%@Uj=fLNPYK-xm)N@NGZ!F~11X1)X3HK)Xca+%6 z8S|Oz?^^zI9`EPcK4PzwBCiP7&)REI;yc2`=kIsZ?e9bQwByc1QmM5-r#`nQGyC~9 z!C)HNC<#|AO`h=gi`KM%kO*iSt8MT9*zBKh!2j9PbPA4o4qpwfXy<77Pp1p&+8cg# z`+wis|CxsPBz%6E8aSBPtN(A{;0r$Z2SE528Sw=dd_f7H;}^~FHU2|BeAd3|U(mv5 z{T~?NYyP$7Yy5%`zQ%t){`cBfo&AfT_}^>(fg!%2g@5h&q9*^|3wYRTIBdFK zzZn@bxF0)pG1f|H(}6-t27{`y2qgA@0D>k1?UBOgFUJS=r4!x;b_Xkwzf>(P3HoV1 z%lYGWJMX*toSJzzs(OW82ujqT`kV>H9ndm|xffHM)HgS)i*~QIx6#Zu5A%wPhK{?} zdjw#?;LLiYL}4^q=!lK!>*%y^k0^pjWo*n1@1-xxP0+fLL}T^Ofvg)6i`%yT~(pU@5 z>Qq^z{vK$inI>z03M?;aXTtxCGIluLq$;aCc*lNoL^kCNX=~I|kvbm6%_WB05)an! z%X^FUfM0}lo;9~&JKIS^Yy9<8fO$>FA*;#ha3wWiu%dsjBt;Ou6SK(Hey{eI{?59u ztT0$xDeJZ3mAl>Y#xe;3{&X~@yvOl7%Y@#en$)__{3Y^^{<#5d4Oa7o{l>5GpA!ll z)tSE zkim)9Pkw@`a5$Z$c|_vWg`#9|ANCS~AwgK@A(s4v^e%K!{M(6uKikM?Z;|({K;NS7 za=;(?B`27~gUz$e#%PK$1t_-+sqQoZ6^4bf=ub;v@VUCX+?rZ!Psz}U-f2ys-2EGhAGbV=jw)&3oADZ=PMXiv|KK`Is|8+8+G{2!o zT|uNi?AmAjZe3D#^&4lM@f_8km8daghE>;;Wu_@MjpB@R##auHLg0{`bCNOL7$eb$ zU|zJZYVe+y5ot87W_|!sKazw4`6kK@E2^OXNOf*{LBEA6CL@|lH#thBRZ}fb@p3XZ41!pUh>9hlgdEDkr08Fp>RCzNz`m)Hn@9Z z9Y1@>j}cb!MSELXS%wI=n@?b&Eo#-fVt8|KhP6bshTj(I_ldY5f_W~JayKT(6v#<% ziZg)#Dt|h2*Jt#GuzP55*rq+{!rp;Oa^O}Fnip`Pz6WJbQS>LJMWEzN*Y~2;#?hvL zZ1@AQ$CzA`uKyX`!WP8KXPvPgCg<87Vd3PGgX*nZ#2KE~eCBRhWspqV8zw>@<&6g- z-5Kl|VzUqE5khB>Bv{M$zKXL`uj3SN&!go-g|F^1>=8}Yt2@yHIFL?`nQwme&No$kwoER7Om;DN80(IUS;L3v}Ul&&{LV zu)U)Ftewp5#r4H){*3N-$Jpy@LG;uVwo55BLj@VLPoR0I%3o+80*0!6}0WdxG zB`y?>4xWcW`9q8D@fsK2-`JX$bjq7(q0BZD_b|SSRW-uB+e& zf;L8w<8xQ5bSmgX^yzOJu2h01#@&!Wzg^O6~7(6FjAu8r*Cpk+iZs zn!`OL*HwQ^RDZhsie;u&Uw1~|Y^_;ydx#Bov$A`Q9Wdy@NlUXB@FhoEsp)D3sEZRf z8cM21Ykh;$bD?^V-CV#2`DG<8F#IhOtf?!J#$Xh61oDvO?rwIlw%q^IcUjcE#1E((wGtEYv4G0Eh@ug}2YoPs=3AAA4a zmGl&!6mvU?!RTHNHEOe(cxvc++`!l)epo5-@!eiH`I9|e+X5Ep@!`YVfmE}k4Lm9w zCax5$;zDx9IHwfF38_+(qz>~>V1cKjSKpQEoMR+TDI~j+W9qMiw0^8*Pa}?nwAf&V zxIR4xrCbKKN~^sjY5DlgdzC)~4mLF6W(yIa4DM8mnL)ANdD$Gb-~MAeNER*CS?)2Xc|8^D-*&`3jdcb0m4#g1BI=Z1Jl=#isKGD2g_rgf`e8c4Z8FwJozcC}};=GPDnqfA&K%;66{ zFq5qQ%5m@zTTcec8f)LYhUAnI)ixv-HT7UGTOMD0jtwO=_}(~T!S%&Y0?+0DLNXUPLMv_v2%2N^cOsedw@7N8;PD{6kp{K5N16@_idss83$Ornj=9 zFf9cRTrExzpRvC6y56i(bLK}{ei}(Yiul-{*^1a4%+g;Ssgc5tW-xZzJ|Yp5ahEz9 zTXtC|Ka%6)R2rl#GD3bTE6z?YwXq&a|4Egvdo)uHuL5x1W?N`oiMgj>`~q`)lKY0Jt_P; zLWh{{xb0dJq+x2H^%GlnjkYEkI~4k4aDD-sPCBp&Tw_)K>}NB)8@ZopVQ@M{kZ9lZ86uL+5z3>YUTu}EI4sPf;PYPzB2!b*fG$h%pl6RzlUN10JD47%7yolZv zhm>)&4?Cb3l_fWFnyIoE-!D^O2sZh}+#7q^2UjDgW?m157v?O8C6`KMIucpWEbuoA z9AK@w{3;kB&k*gc--qxzU|Y|+dt9{X=Z<+I_}+qwq!=M76;{pm!X_Ru0X9ND_|cJb-G0>R#nb%%i{`IIKax^Bgk z*r8P#h|HseC7TFO)m+E zvS&BYrk8&=CN1CZ;(IVg0AMQcgw%fXx<_wW;6gJOpC6L&esrd=-~XB^Q%Yux2KPHy zGG6+{09zf4*0&k~LnHq!O)~>4qQpfscmTa@5}^;l!zp+rXAGeY=h^fwAIJ49x?U&= zhx2U8DoB}&_!NJIVBTP42N}5_n-OM@g0R&C%`(L-u#<|lplbZcd@uBrDnLL6(M^dp z$ot^{O(|X$Dype;Bn;$9B1}gFp=R=jW6`?DgCE~($w4ERlU4iGz2@0vhe3SD>+AK# z=Vw7Wt;3hYgX^5)^yL~nLbU52Rev&)$DJxZxe4GIFuJ~KP)1YKL zQ<8|9s+Z-CR-pg}g7H9U3Pgs$GbP>TZwSWr1mht`-cr@*mZ)C+!g*t`N-Y{1TS3Q9 zd};2Z6=?-0jdW%zjrKve8PaL|gQNqBo(~f~kT?Ye2!*!de|dBg!^$TKBx~rMBPsT* z#GaB#P!D$ZOUJ0q>+CrzXfbDt>mhu;?c}1@@X8qGj35xSwuO$H+E&8MmW?F588?g>k>Z@8Cog4;qi27Q zAk4$hP0u6okUIv-3%JBRoU{-V1q<4<{&D=HfJa@3DZD8gKYMIg5_%U6<1-#d6gHdu zc{I#Btx{Z@WchdZx#Ix!X+? z6&?Sk;~8a6L%>k;x9WSkD`B*J-ks-y(T%V^E!L!29s`QGB_4c59svVpZeBMVW+pED z)pWHDvjJF0_MdN*OzaOMTc)FRsPXK}+o9F)zjJcA!SpdoMOh`Y*(=0Y0i&<)m$K$w z8p@nj=hB_d#Etu@SA6Fh5A9Qjq2png`*cf9<&;3jZk%g{vQEl)Ed_tisUJVIapcf|9%OjW9b`-$fbHia#mXGo36>${PQ+vO|AJGE zlg6Ntu+&p?tA&R$3lcFz{^MPh-IH8;`F@2&`G?DGGs5cVBB`KL-0Q;VbgjDOf#%%a zSR~-)I)(0~lY2aI_WEU};~;Vfl_i*uwEkHwe)=NJJVd658Pif(xsF&=Wm9#5P)%w& zxj*|8(BqLQ~W^n?n1Vfh~OCbaTx3VxLlkC?+ zY%sGNn;o*qfY1VEv&9E_}7SF;5{t9=6!t>Nk7%?z~3+ifMD_m-79o`65p*hoiqf^u?n1!v- z`r%A)3_cBOsCDVmEjb-*HmQT?7~3f2nnMMfIsWm1BuiZ^`n(-e`A1plfv@yu$K#ZQ zL;pD2I_S+W>RqJerO81hXc6g)65q}gtLM9?)1gD`^W>$QBeB!gCh4bs5 zn&~BWp%A{wVk-DVQGG3;sckt*7EE1Rsa~{EAITi-KYzak7U(8_3-qN|>CJ}g4WLhl z?=7KkLk;xPb*6_a>j9dkR}9JtpMloh?3tR$A~=N>Qb+Hjk5^#co(S4{qrVL#5Pw-h z3Ea172}6d@BH+RZ+|hj$N9UwicGOM&4xw!nE?xrM(i06O zfc`y1L-ejJ#1g4N z4-DEN>L2Dp3~EIBPY%T(W;$@+ij#pTm(PcQk=x!5J=95t+nz3y>RNHvxy)s5Vqe8& zftFpwUe}N3cb0!yy)62yMb0Fob$8gU!X>UQI!K$Gr~?o8QYdR>eMS?&ZuhWc8nrT* zdGLoL#bxd=lSYhJ(yNdEfh+UrWp=WanpAhhtS3sOO^vxV`W`>hQJx+!)#XIqByMDv zh}>uV>CQ&H%5MM?aZ5DHJv0F9r{xky!DZlf8ZGp#__W3G?KgpY-fgq%0<6*-n-8SJ zn$|v&*wLOCPQgtmm4ME|%pZ4TE0QSIpF)}6)KONjBfjt03L=*iV(QZr)!S&m@~E*F z2fV2*6$G%-Fq`M_!}_AK)41|UOqcXW3&BFu2shxH<@|ybr*W93tOCys@Kh6Nv8Y81 zjYeP-J)D-?B&c%LP~EDQvyRUTr7f<&sWqogVRVjpfzcOYVTd8LQ~O&qOy&~$S0k)H zEom|V8SOemC1<#7iozizSpZl~Ij1`9Y{7YKf<(`0!6IaEtg!O?A+^u_cM}>PVd!9z zsb3&b3Q)><$lFvtOe9m11cvnz5<1t=q5G2ASxy2bqj4ltA}Zdp3%mze=;-qJLh0@P@$%S?-)AgIo5YrZl;ql^5hila|I25T_MDi4>Uq4csfMa)q0TT zoY!Os{tN&M0N4}bs2juStzg2n3b)(}8g>~|v*|j?GsDl+0+`>JP{G~DF4%a8&mLz> z?ywS~1RT?D8+I)>8cbC!>KvM#Fx(%11EqOAxVRnlAK(;RE{xKlGG(F51F+G9JR?#w zA@PQJr!5wjc@PG`Tqp7!SI0#)X=$fp!@@L>^~G^X56yY1k!NiI?jj103b@YWpp!0} zR;e9DKYN2A2WD?^;y4Q+)o7hJ0l1F=keOFNM(+=9I%ox2l5uZp5*Zi3NYeL{Zkrnv zZ?=G2=S{gl&pJqD7aiMuo9rRb1-Q23 zw7L~u*UjkEsduT1afgbM^+^Q~(gZ31$p|cu&L!N_Bo+1{Y3cn2ZnG9fYh<`q74A`N z>D4lZ8hdyuGVa9e*wc}QBd3(qo<-#xs9nk;+8FFpJJKkYv1~l9H2>f=4YD+W+yf)@$o1ko%7#%oXLSU5h zR5UiYKLRU4ssvF*Z#N=bRF_##BS2Ix7SfS% z@OzW*B1|p{tKqo9x_isXz*vs_u>*-*des)MVNz6kv{M$^I$mIM!_ zmUTm%V1u5Fik&@K@aawsWsCl``OWtUBq11|L-6)BU7;pjAxJ%a7XsWJr4V#$LWJV) z6gMx}Q+wXZkUXN|DNW%4lbpYa-@Pq*rK36XXyB%fY#|Gp3S?cap0@&IAv*$Ts+FH( zZuKcTu|5-#4s@s96V?Q6a1NG=Ufg+$bN`2qvN2tLrAAtdKW` zf5*=6GNRH!(i1tV?NL?hj?jtj6MNy8YDM|39Q;!l#&ZT{(4;EZtU)jxqzV%@zrZek z8_C63zOEPJ4q;Vj3lVY+mo3$GLi$tj`{V^TjJZ0P(OZ}2 zJ!HvSR|EZZWVTRv%9YmsCt)jkKCh1V(Pcki9U@$MW zm}Yw=Z;~D6g+vSbx>BIG|4Dw?Mgg&kg`*>38yYYr%SkNXSa3yg-sBT}iLnTYN9a?x zts{at^FDr?mL-F_K~-wmwo1ivE*L63F%uk4aH>Uu5C_pv)ua59A@FMbvI(ZLM0mbo zqRCIGseDF=AsGPX*1ZzFb(sS$=Ar~wqQp$2k?CNBn+|pxOjN6cq~**3Xx6G6(xwkr zK~-Q6%@ZhwVrUVv>^C&2ZyPMC73HIbOb0gS+-0L%Jt8W>I;b`iMt+oRn6sr_dk_=w z2WywPSWeA3g@6n2t#qE(KGQYhtPbsjTCvpD@LReMK9e`a)%GaXpq|3C$4}hV zGs*M=C#A$mdnHrG;;{r-@N8v{A)d(7&c}mfxvzR5_r(Sh_LGznwA&sF`_6Q+22sRh z?o&2aj7&Xl`QP?nJ;#=9@phZ&V5jud#0AsM6iq5%%El{MbwqRbD?q4p`twe-u%xJ5$egg=x}Px}`8*%|4u;rlM=i zkY;=|W&Q2!sMSGse@X(b`gGp^Va9P+uHBdevX3f;;@HP8^$o3)aUT;dU3~Jyff8l1 z#z-K`d`!AeN|fkQ0=!7U7J|M{pF@X}u1ghI2HHl$8y6S>rdr!u6Qmw`ikiP2XdWaU zRu11AABe1rPg45{fN7v$A7A*3|A2x&2`J-#W2K5f^4^S}k(-wwxAM7EP^d6A1#?rN zZC;G;1igbIwZ3_GMEXH?21sjV5*(VjEx0mA+$Y99cfIN}HgJ~a`f>HBSpx@L=XwsOL!IG7 z)4O}-{)K0H??!o2U*@mh>1L@81`2i3?BsGwjG59 z@GyY{OtP-uyqT6+uX?N=o4#FeUtNcHtw3Hlo2(q;wEiy7ym#4n=40tGwI!w*q7 ze^Z=_TSgwsv@Ra@_GhPapx!D)Tex5$+>Gtd@$-V<0OUp4t>H2Bt8gL`ILl%8D)ZvAfBeUX~JQKM4q+k8oL5mIbQNSE_(ln3AibjMT4Vc&LF6U= zc6}T$2|W(<x8{`SYSV2eow7Rj;@0at7GgUE;X^baDjcy>OXlEszaqA^6Mr0;r9=N{BsdxN9e;fp=X60-&YaL5NQzf5@BxbD zeB?ET754dS(-jLy%bkL6jtlGBcgWi#CVcGIQxx{M+31mkQvh<%(^|1C_4(@^ydSXZ z7|u6WR)3%l-ft9GpL#D4PCakikTF86Poq23r4;O{9KJSLDKe(=pOLjcShg%k?ui3cw#+>2? zLnGuV{4Xht!tIg(ONV?#F>IX8d|V_|9^$(x5w75wg%VYK+JK((x;t{u2KLQW2b&wH zx0dZ-*tqF~7RdKJbx(El@yp7dko34t+()oHH#82CN_jJB*Nh%hRP6N8z3OVC0QrK& z{oUp@Jq3H51Ju7#KCOQ>&#as-?C>1$erMTbIhq?d1A`dK0YD~OCR^<(IsAtWUJy&E zv*#EEw-WUgn>uAYL-XJpIm6@8w`uK}Fc%1tZz0A8kvWS}W>w%Jl457g>Zj53Y7AaV za%@mc&e7ot_2zY)s#7Bw3=m8dj*Bp2GR(c-gwk2j!XExqn{&#Il< zZ&?)M^{QcR3VIV~e&XT=zU)?OJ;OM2;>JvU7h7pEE+KZPoJpNzqlfu zI2`U-nD~ln7cEkriAE?RMeQ+~l{2X=80pPRu(*N&h0V+z_{Yf{j{Ttss65H&@SlC7rM61PeLDT1RyB2N6 zbuKHMC3`mi_;J8P$K4i}q%5`fdmaz!ns|9(%DKbF);X&*XeDdSv&lFH`Yc_AjLB#;d6@As)aycl?c9mtPm?V6O}A#Pw&~ z=nnVorA_o_Ov~x^7T(mu8`EvVM-r%mW<*CgBp!gffKTSd;=spLLXkTa+wW;t#m%hC^zGPc;bd6#V) z7srpnB2qBNP$j+tTQo-yHmgjpp`2sFFDZ!5**P@`hnspgClnGC;K!Z5MKCNx1t0|Y z2T`=wuZy7J7Rc>NlkGv;6=z*v8w8SqTaV}7PHR=}_Ri-Lj098DE(K0z0$13f(jgCf zfZ_!~PH^`*yUHoyb)o!Xr+Zh*DZ;ZyuDzI@P5%6-AIilLdY^N#K|r3tnM?fco;4a# zQ@1*9#ysFG)my`Q>$;D1t!v3Uw=X2mt1%R`u?Kp)FC@#0Jr?x#R857K`y`hE*n5(T z259gqZhP?JP3-sDN;L7ojvs)|CIKp*qK6Xq{%Pq0_RrUd5O+S*kSHe(-XAh`deLT0QC+Tgr0~>yWNf6-syn z4JiE}%U{fY$VVb^sb1sI^^K$VtCIK>@jsu1rMXk`iaK!S&1_vd2l08@hTWocbmMzv z8ro=H_k?LJ?SWUIvFhy6X(gWoP-sE9c8la}-1OkmS={v4g;EwVU(6cu<=Et>%| z@|+lU(w#)SPho`{p!#&Dg%s4@l6w}=!^5g@!affeGjF^`26~#raOP(6^AY>D9yKu) z==Y@uoo96r?_Nh`F*?%u2X&M-KQ7RDS-N@%t$zwh+aqT_Ks4TYa{jZl?n~13B^Tvj zW%zgNZI=J1*4rZgKa!FDBU<|}GE$cR({!7OgZ_V#k;aZ&`O(99UvP^=uIBjWzt(>j zG&7B1KNUN<2SSz#VirU`^l8$zFixunJq*)NqwCXE%`)Sm-YUyjfu+vHb1>G;JZ}WI z4Oq0AyYI$jDTC*K)u;#-$`B@+tk?X9^uH0uD&}PU>G}xyao^Hb}Aj2WkfMF|m zg>!Hk^Du^S?V}-}SA zIpO2uuw;o(2(tejy5>R5xc~jghjwLyT#I93cal8h-l_tN2vZ{!FFjqL_rfA=SOMn|4Vc1|F%2-qY{+qKlx&RsVo1b{QOdVeyK0N=Ks{cY^y)df7wj`OZEAA z?jI%QSN)&gr)~9@>ho*gzm%I_^RM;)%swi&o z{?qvX^=9}_Hr6cvqm4B?J0tV|P1MO@?w~N3vhll0E73sm*TN`jV&xz7oe|N29&eW? z!qwVtu-#wEzI}<^=(8YB7Wk$=d}sK3Qm5FV$IC3X_p4215Q>@+>QC}bZC4CltbWMW zN~c!artLaRs+#=Gmv)n&zW6N`i|FDodA_X8wJ`R!&U7=*wlM~T540=v-8tCG3ZRU4 z>@@}ItspFIu`$a;o|p&;%${P>cm{bNqM6x90+ibM{p^>AAJ@a*g&Q2;E(aX%_tS|r z?ejP*w_|qx9F(q^#m>B<#m8edwm2)gW%UJF|JMrc9_~+DZOk= z2Jz2dQzHki?PD>(9j!nb1t76Oacpz~@TYz><6VD9+=!HxkKyXF@@oFjzK~_<;X}`A zdF|U+XRS0qwGZoBL8}Jd*a>WAdo*W;Y;Zjzea4#Anz3BWSPZ%|PDcH8dwDUc&9`Bx z`euBIk-QRxHSzKDO^cn~VRetp=$x%`?jukRG$I~Flg8y4hkPE$V&)x+{TZTJjl2jG zpIvlbrdktaQ41F5uY%kJUQlrdnDTT}$|LS3OFKJ^TCB4$RxU+CVdpFQ?KZ`nU3%oA zSv_`@_~e6xYHejZuEDo0(X+J@sK8s#S1XXqzpGvZXR|9TrGq)%rUiFnV8@E-;iitR zLYdPB6Li%oe6tN7lVP}x#fXK&M32nrV_iRRTS-9ecU#*rl7kGZ2|>;64C>|J*5S&D zpmc~%eJ!g&1G6FT5xMzUS1>wYpEuPY;EfLn6?^qm1REe05FNQ}AAaVSF%l~Ne4{qk zi)?50b?Wh4l77wkP;T*A$xu{U9~V9&v7(DRBQW6_2J|GQoXQ-Ml|qFDt4$23itLmV z7Kh|R1b3$0iWHMM2Y<%49NROXV;o$lmys6JFohZwY6?ub&TPn_^1ESUPf5vJ_y{a$ zDLu~0fdLeZ{uJx|TA3SI?tIe@6z2qV30;Dv2kcxzXk_UM<4Z8D%Ete_25A#i{9nx7 zQ;=lQzc%PD+qTUv+qP}nwr$(avTfTox~j`&SJl-2#GHwVnKSXt+|6Z1?5iCsckW#8 z`aN%p2vu)hP~zNgZ*202{50u)-g6ngCXoX{4iNs%s&vZBz+jd%`yrfm&}AK-Ujzj} zcH!yc=MW-Yf0|?*t;o-e4fNrkWM8@5Vc8sRknig!4}x;g^g@!?Mblmuc;e?~Jf6y9 zcEQ?|w&X6n0}Rxft@*y-j(@sx|h`qe2L-A^re;^Xhc-1vCJ_xQPg+-jv2aXzANfX)F62SDO3}F%(eUXXVT- zo9LPd?s+SFvg~GfuCQn3zVrw>y;;2_aLo3k@noJBH6K80R+E1nc`mqaIY1CTAIVXI z5|A69xCv9#2D4Hwsgvtv^ge|E_D0&n;`|6&BCMhGWgk`NB~w%t#9f(Jyeq6K%E+oD zh$Z$6!0Sl6gIM&+&^1*nT}4#;a3Jl=?3MrE5P6aK;xNB@4gQ6JT2^+dHooFq9yfQe z0@u$IbOcAx9X&IZ@nd`kdKvrcw70Z$TGlahWxL?{J z%~gCtoOQsj=wWUZdUM5!!S(Gsqn+yzXy#UUF7zmLALJzH4fHnK=21S!MJ1;u3ol1b zF()r4D<_Ygv`6sC_tJA3%s2JWd&;?&Ib#l=dw?QebRxNztn+vgS?63#vEa1m&g7Bg ze|#{~8=l?W3qe5nAj`}6`HTHGx96WgAEJ96yV2PCFrW6nu>2R^Ub!H3g_fEXPl|9# zJ2I{T=e#Pe!y6JgvBMjbb^Bd?VPzjYFJRZ)9(xTR&B5;EH@H2?^7vT1gS@``+dy_4 zTGu%1IJZ}}??H8x$Jfi@uX1>`=BlN+(;3D%Uiy8(b|chHy|? z9t8Sh_J1H=yf^5o3N7pMwKm#`aM zoFriIf@TX$R|hp|chZE>cY$5|$#N@3pm6bSED%7o$RC?*>7s}_RR@ZtEW0)*YqU{! z6v4RKY+_?c{8;^tUmYRSn<-bWev>I8+beoOC8!cg2DF%LLmj-{-uC{Y!GuKY&ewvx zL_ln?=8z5L|23NsHQu#?(Y7G@|Qn4gxDmRC)oMkw782fj~ z*ll-^<6YgF+gilf?K{nkr^23QWD`fj-fy`&?5?s_0BWnX8okwKlBy1lrXxj-p`|b- zZ+`h(^cr+vZ{)^#f^|z)9{2j86$V9$2hyTMizKX4yfdk2M#Wuyg^fjuQKYC1;wopw znv|^U%t_0|5m1Vn68U+!PC|*2jW;MsPFhNN$s&MuY&C$cMA3aTxMWU0UCr;HcyQt)tjDJbwP&jYd66Kkpdm%go79wR#K8$%pi=XAUyB zbs4xF-h9|{d6AnX zZ;>ug$HrvOkOapb+eM6y4-a2DkMT$yU$+~{J|0ban4KeSLWI_68$+vOBYk*B2=#GI z^bHTun`Th38k1=)5b>E&pg164+!WSAXA$&O*y($<(Q-~ zm**u|*lKSYlSGxd_|`2;;PbB*leQ_k_$umRPE?`#9N$TkunAVfjb>I$6l?8uNvkx& zOh}fb0t6h3t70^;lx`K@ohO9xXi;s9YDCObxMP)!i66Mm}ZPY=uWymPusNJY|+B(ncvE5t7GNi<08`fwZH)kxU2Em5l~x5{6U^Yk{|eT}A%)Q>r89CV_t zA^?Ws_|*CL_4^S`8h;~Nnx*M#w2f$(KqQ$}oU;~3MCqHV0K$}gomaEuL?`5Y zo5l!U%B4-g#BF{r{kFtZDQ7d+Oeu>nEO@Q9HzQq1w_`mU$!HdilKw0r7B@cMR(WA$ zFwYtA$Kg1MEd4*BVEo|{49K>KfEHKMy*~ah$PTcWqB&SIvh2-ELEX>mA zy4ywO{$8@(7}7eYtVV~%aObCE!=s5cs>7yi8~zYSc64nDOil~)t0-trOOw=+23g2N zD{dyK&M2vus#E^!YS}4QdO;6UP@egG#;wh<9$x(`$Wc7u5 z!npKT7RH&Z#n{R{7>@ZNZ1<2QILMznaN)fE)4NCyeEXw-i@4yL*+_H>InKKrlpDuG zA__O|#0cVIf6L8C25!fgJMi50jYz&xi6t}&zEKSj8Cf?YG?ZTyy)*5SVs%C-s!i4T z&6~V24ViakSh^F>iE4FS@B8`G z_I1T>Zr}9~_sPEN#}R2?7P3t6eS4?R=kp0MC)@MTgR$bTdSu36)i;+9&h10#9jg_s zYwga#8T`91b84{nwkkL;icIj#a5go3D?3+%68mYq-Q5_@PknCW@f>R{IKS%6Gi=(y^$5L`<^B(`gR?^EIa4OgP zDK~bb=MDPtezkp_iSlnoG&MCZlVm$C6QW}a$}Iun@5$VE+Mxx$%w(I8Vd0hu+r`d1 z@=bS2-0%AEgHaiy{Theijt>doOWb}>KohZX*PsN=P9T7!$`&@L7-sP=PFh;tU zV;}}^OpQk(&Xdt%bg-U`hvM_0CxaZ*s0KXm+V34_!xTqZGlB*9NiGuhIHrbXbgCHK z=Fnx|Qn6${kYwZfgDm@+?zgnU<#apSt8J&T!etEmcAy!bqM~Pj`wWl3Eajom)eaeR zDD`->s8t$Gd92wAemIYZ4*v3@wJ=8PDUgLHH1+OX6_h^9fhI~G(*YC;KHC8w%5#=O zAk-E4at5VJ#&88xhad{M3?^%#&7dR-H94+v#Y%|5pk-K+PVKt+sN{87XOiYPoOG2` zos8=~PGwQU?--Hg4hv3qvXkgvGb3d?kmL^i{1d(gY!{#dC&v$)NBzaAr+AG+=&{_i zW&^|`N9f@@q1YHR1EIzASphI8^f8?ZZU-eWXc%$7Ra^>JLiYzP#fTPkCIHOlX2`mn z!r?}3Pw6Sh8@M3~URYOLRM{x6G|60)>T2UoqNO$}=I)>%S#3-0KAtDrS$BxiqOa^M z_>{#LD8=yf9>N_Q$bBgtbwl zq5uV1PUGDT#<Z@8j5_q|&y<->odsph!tGwxeB_J^B{L=?Oir2$H!j*ab#c$USS3ScY*S@y zSYzTCRhidwk)2O0h|O{ouj_^vsDTbzgq9Y&d%mrr!0E#D&#uO0Q!j?Ff6b0pU>SO^ zC(#XNp5(wfQ@UOh^4S~u0e_o-0O>0x@zA|D5PO!<%Xc$V^KbK?AO0_~6ZtF@R_wg* zX9)Q;JEvWQcmRfYmQp#N!ar%p?0vahP3G3>-?g?-*KuR{_1i=q2sc}62b`rutX zlzjz+b(C`#G*oe;(*1G~(T!yrCzL-w&uSLY)-}d_Irj%82sM151gpqQ=R<-7+AG-(JQ*;&K^sqX^%5BVRT5%T)CiFCQZeFfxQdmxp%OdC1>83?wSzwLDe`q z@QvExx!S>Yu4uxVE(t`yso|B^w036Y+Mq%NsVIjNiH{ROop&<0qY~Olxe#=_itp6< z_f%P#cDbzcH79rVHD0!?ahbu_z-X^^__AchZA53iP%e2I)LfPWERghB>O|B9Fce92 z?f;Mzet6{*JA}PJQqX;zy^slH@Zp@O#q113j2;idD?mCy9D^b=% z8`R5O4egINM68|<_37b1T~z;a?P$Ag$1&LrToo>7??Hnq_ep&+KB=9bPGNj=JSpLs z$fbp!Ew=~*bg0grEZDenxB}l%+JS5Oo!tPe{Mc<;k7gvC3uk9$FN&R-CH9J$mzACL zBE{&9v&Jx&36p;=ehwOnUd-^KYG{7Ouk1;L+IJ(_dIJ0#vizx9){b(Z%$-late*OO ziKJd8A!DZn*@KSm(}+c+8wLy=Q#_&r;zEh_k<9-@M@_S3Gh?@D&TOu>Z*aP2oaQ|! zG6Z3)iETvcpNK9*t1-x#BYfIC>PgaYdJg4wp>OoN&btQxs{;oE?7R_KRpsCNJd^)v2D!Y>uy{ zZip6e-S!yeICRxm(|^)Pbe!$!HE_K3dRXN1G}=zf(8sw~;tbxW~Nn@J499(SC2&dIt!YMbyI$y!9r6=mW zAMg24t{g19YL8pn-gDM< z_+}_cQ7^vQ1iWsapL<%wVVqsxgw##!7)-5M+}n84x3$h|N-Q~Ou{`G3N1tlv{^6ON zi2MEQmO0I5YE|x}$KH>;v`r&1(QCJex)9qDpRsKMlPQw@c3h&xx}dbEq@LU%9J@jM z6c*QF+;;gz9cCxCi-AW@bXbK8Bah}wXLBR?N%Fq&2+0DWLYTwKW}6I zx8A|Z!o>8SEB=$f{NNp||8MaQq5nUnF8>4G!TNv4JD52CmsO{Uvi3izOW4gD8mC)$ zlz=opX~^;dvEzF9=rai6Z`~54q6GZcm*^wAWH*UN4nKXG*5oQqcCnA+71>6xISAX7 zV9!oYsP1q88|_T{;^JPh$5cZTE!3`CCT~nER#}n3g!cH%E}f67k}?7Ut*0Y&4x4)K zd&MSV8@qL%0q9YOf$0PqY~if3d43mC(wP=JbxDi<>cBmPhd%8s?I@M6s2sG}mZU>& z2QW5wxOf%HMLw}P@Z0Zuw_u$_a$&w?cJbbXKQTH>-q;*yC3D8XFLL#&+aq(39o?K5 zqZkf)M@&8Vy?V$`e z5&vj7%W9jL8Z3Ycxlo0Cy6Ik&s_!(OizXsY2?{;(rt5ircJBTT7Y>nF_g@vgSgW=A zjrXkn zYiab~k2iV~?j}~R>$I|MZ#mZ#YF9@*omhp--U7cNrCWDXv$fx8ZbhT-kr$6>03N#} zJl~`b6D>)+B;^`J3`|LqcKBmo-`D>HtoO*=o*U=*1@UoFEQR+L_xCUJhg?3Ru88>b zr_PT`aYJPM_I+*9D*p)qg<~<)w}$U0-b2vmxI}0E40rkSmHq}%gX4g?8ginW7xWN% z4S(a{t5WD{$}Iuw3^2#Un{wtEa=IermcL>)96ihwAy1S@=+mwYZ|8&Nmqqfp8sAb=2Ome6i>4KBb@I@0Ppa?q%XX zO8;zo-9xB`YzFg7Q_p+(?Ct}52*QBKhlz#S!BHBN7grPG``K6VOVH2Ek3$=29m6l? z23(bZMRT>p!JN2y1uvMiYS_97x^R%CZyi0ofp`uma3IgbqoJb5V)L5W+_fj&m71bV z9-*b8P{`JHT1+lmE&)!kSedOa&dph;^O)Ut!Q$_~U*c<{6c!Eg$O-QINR`)hOMnbV zVD)f`NhY_fw*!}%occs*E|RDO5kJJHy#_~0Q&PERJ8lM^{eQ#;2CGFS;9c9SVs$Dsh`A7XWA0>iEGGMWgxj2{~vdbvE<43RVB>`UEo^vVv$8h zA`_6i=~=W$&AUZ4I#XDD)e9Mugi;SSr9E~u_cO?ZV! zOjv}*<~`F6c&6%EU>evAK2q2Dh0KgRQJyy$4>OMYf_@?7wm>g1NJnaSWU*gpeKZ3LYO&O_YjZn2gjWpD;HAif12PRlC7lcvNkZ_k zqDCaikFwzo_oHlh2JZ^mjoyrS{0PXIey^71-vTkg{$r{;GJg_oh)wk~myXapf>;mU zSd%DzdO^$U7j24r1AB5j6Ai(i4NmY&vc1Qt`&*d1*0J^)g}<*5x*n10OQgfR{T)IN54OKM_^vvl`7`zP`@sA||H2&IXW`#S zlYYIae!wRT>C9Zn9CCgspY><;19R@g7nR2Np1{8fd#Bgo<|FAZj;kTEV~*NOkBz(G zyXT|7NBk2mb?hHKrT_$FzWS4^Ky9&gu! zvv-vyTsyInlc~wUDYIB8?xQ#|9{LPn5pEnazy{bQxEuQiHh`U0Dr6Am?p*qj0+Z9Q zd3g&X1S5ss00H)S!unLqv6-{RdGoZs>0&Gd$4nM}%RJOPb(V|eVz`>Y>~EI&0LrWS zx6P;ZQ?(9%S+ia(g6PEqHn8-z;~Fy3rF2NUFBFK!ykld@GM|O{<+Is`8n-pYN{FR9 z2m(ZbvH#KG;b8~FV{r7JGPuYS%XVhnc8$+840`E{Ynf!SsWkR0h*v$Qk6PUlat?Og z-gc^7X!6rC?Rr8$s2eThz^9#3@^*JeO@?1VJLZ)3Z8oYsmDv8|40Z}^OY-4Ny(jZV zccxpA5t<+X#18{t3#sq{^sLvBS)p%b+^{Nn)x*h*dsXeb5aeFU^P_E;EG3POM5B|V zPxpE3ZgV!_n60d>%vNU-smtfHxlW3zCR4~(=P0Og^_py-DT;=IHT<(!r-=;OF=Ne+ z0q==B{b>hvOk^oJU$ik4sn$mWMAukRVqsK1)Yj2qsbc`-OGyC4mfen`4PoHWQ8iNH zN{KE=yJ{x^%9dEa*K&iYtTXNr$srSexQ+J+4bo3HTUw`IX>>M&_qCfEOi5ocX$)ni zwGnF78j)fR5V@&bTN1jRUs+Gw=Sm#n>-KCjF*7>W)L7!r+0z;<##FpqtDOX5@(@}E zVr#n1`9$D=cMToOovJh!BSU3fTS9Evw3zJN))6a9luXHRnG3VBCztVY)AQwt+3_#O z9`0*C!i1GdBWdYs(-ksVOEbw_b6TDkbhm9nvIhs9_b{cL;;K#ep8pmp6m#fP z;u8Qd$bY5b>{vhrcTmztn|Z)?U}gX>PHe??-BW-Z(2!)Ozh1IJV&b~bNt}*Ou_Pm9 z`*)_bJ*|T7Y9p=ix)L+*YI{VMdr{}$GED>Trz2GL@AHa;ZaM%01!b|d4rE~+J{+@> zT2^Tra@NXi$~2KhKO{S($BCP8r$W~avf1cEtIHR?9|AQpPC^wnTyd;2dZm=ff35oE z@E6kdS(s5QB6i}7bpv7DWRAwpSEJHp19d2bn-wne&3 zTQdu@tdccT&tj=-N*%E)w^GX{>T-h-Otv2J-9YarT4Mi$qmp1!3w5J6xss;hPFz`< z>t6@z`5>P*`bE@;vJ=ug2d33#w#uZRn$V2iUu1ElrKzK39nr?l81&XzIhhfw1@L2N ztGUcF)l>y=!JrvzsMy4^G6Ay0MF9a4yy!-(%6Hr~3@rO(`(erzQthnDB(jKvnl?FN zUNR+iwzlB%HSw4!>Jye`!fq_NS|g5TY@kIy3^oOiuD(uSHfbBfZY_h^toZ6t>CPyCmVPZ2k&~TVI~m7oS#ch4KY#R`2)4G_Mj4plqraXRtdBqE7F`xMAsV?yauM52yI%@hyykE{`rLn z&1_;Qu!?KIl2O205y2-R_U$|aBxjx2w2nIni(Q>NcxKM8*e1hv*C@y~i9R|B`Wy`H z1y95PLL^2wr`-=7__=P41V#|>{3-TBT{M$~RnOeck`2Y{HCF%igwdJ;dXGh@QskGQ z-+l5}uTVQDrlT(0PSNQjNma>=ZNIa)MOZ}4jvGVGjzd|{T>QDGS z)ER4IJS}_DqR|47s*#TnmPDt9pQ7o=utx{ZZe{$~#RWC>d4})Z`}=E17&xvmv==o( zk^W!Oy~L>;uiPPv=D#-dkrZwVyE!b3#MaH4HZzjtyN87I6=}MNj)M6xT)Oo}Bcrl3 z>Ivr_-5R8h_J8oz^W);xzblN z9r3-WtG&;0v}4Ti;8s+_I>dj_%!REa$PMk6Uy41uA`^xlQ+H^wprSh=MURX%SVSCW z-(!&X&?`<$lU^BVn9x>JA_q^@oFYs1M7JYL5;w;O{ZS;02d3SRVNX0aIxJP+R#e^W zb^^P`s8lMCV}3cF?%uvqqTq#QSFFx}Us2FhM4f6Au680mv)xZRJVBut=t9_Q5>?E} ze)i|=dKl1c`qNB1oBxkAVav{bSGTJy$M-Ys2Hxf+wR#(LHawhX|k?& zdH>f%thkxd5>>2_W(=KPs&SCjQ3E?X(vdPEm>a&6!v`-s*^vV|Tz|Nb2L5Ht&=r>u zDSVS7MUjUJUI%ye#T?1|a2_3k6CSM@YfEnAKm*t7D51>QCR$jUhdCsS#AE?}?7#pw zFH#snw2K&C`4Dk}&$#h9V3woga6ZE~OvF2{g!g5%5RZTXk7SNx>A$#L{iz7 z8}JX^bOkXLWT^Q)SdGQGIuuv`y|7aG`n`4}S{o~!m6vNw;-EkK0nQfo8jB^%O#}`=Owe%rSorA>W2tFgq`CfH4oq0K zElEX~1d#7!M={u~Oo@-E7}>7^iZRBr)l|e{Wu!?+g0%9aBi(t}XVrl{tn+#xwyg6? zAhE0p+8}7G3JM@fa1N~V>LB7)1#RGn9nr-0IFZ$cN!T2!AQV*h1Bv5wr?Hx;(VMBF zlfG>3_=EE#rco%BKw<^)S9OUGE1LLaO)^VluJdFqs{&Qvla%*SNKQp>LP3YPmQJ+- zSb-Ue3{`TK_lMU@M||owuuTJ$zL1BCq`(v4*vc~42&u_T+XtD)3tgI|F%?zz+Z7H4 zKE$fRT-A*ieqV=0?^dmb#O(yzO(*=ldmn%>m6d;E1pY@SgRQrB>$920=jK%2V`{t0 zU&R!v;Ou+|pc=d&d1+N$p6Sx?CmXJcVaKuUCUvz5 zFr3M>*`CM^r-#)m9Cq6+x7@1IKgHyE@jj>IRGwAi**o1^N3828lF@<=($&q36P=M5 zWm9^T4?@E*K^X5n4(l+vdKNFhgZWQFO&CmF|J_H>s*%#`{x!a3QHnA5y7L;(8HPjSld$PbhvE zo2-J1^b83c%y(~~a*(09Ld1VXup)pH&K7LuVfZflJh(Bg%>3{3cTz+72zJ zlf*M^*m{ypdG%(EMpLn#%(_G(+8HIctbIa>?VD zDMqOQMAuPWMw@Y6HoqQ}e{_!S*7ujbd?mMq!*w>xrPArVBt`LfHh7y{MUv^;FvmWW z_Pr+w9Qu^Wu47ZaUtN3qja@-R1OvIxp}rPbZ$9YZL%9-MpfG)mmW~Ke%Q~9bkU&ra zkD#fYrbH1T0+53KYPazA-p|QH_PdMKMGGu&rc4-7J}U~&ieE~R)Wn^?-YB#bLART0 z(&e_b)t-k+$9BC=S=(hi4L-r!Uyxt>8;%M?hIlx6zLfX-zN9qUAn|>xF5bdbHkID? zIduR~FJGo_YR901D951M#FmJdRDmHO!|^%ur=g%HV6jN=lnjrH4+3##1u_fgp{S;C zHB%`Rl$3&k!a5>i&ui^#rlw<{vBw0p+eu)5Q;q5ed-qAKC< zi;CO^*qZPi3;C16?rc=V44$57!Jt)c;9>H0OcLuRPTaB?$?!NRf&DB}4^ycw-xM|0 zCc*5Ngx@8802XSls<28_3T|++FBh@oi!=R*^TG<~pEG>o8$0HEUT<&ZX8O+Frq+(t ze@1Eu@W18e4oqMkw(|)1pC8;?{a(*mEodr`Qna$R+2doJ6?~wnrzQzJCLn{yo1pZ3;mGi3{l!K}t>1WJ$p5$kQ z*Bfk|yx%`)?`3bG?!C`P;577h3N!+eP~l&&%d{I%jh2W!Q~}l-4!d91W^X{;_cMIe zT$hvRYVDLEHDB3Vm)O;4%Cw@L+(7h8Ac)J$0NE7jGkEhVFvuDc_uaLUGP;UoP}Zaj z>xxjg9sy}y0R`$a$xq)ESGaJ}dZ?u2yh@tP3LKh5KSX3<3++xhq&u1#zuTeT~JM48&jFfXN{7c^tdGU1o zEQC)8FP$`?_**{qUG1V03b*O+i*k_3zNkToSYrhXzKDAzVwe+T#X5-Sk(1R(5mb@U z(P&x{s36uv)Jv~us5J{G)-Iw;@C~@E?a5c9s>vuoce1KhmP>rB5(SS53&0Qa!Qf8x z#68ttzfw?q(lF=!S>;*wZ6Vq3{Bic7)R^SgTTWMgL~ zGzlaeKon_m-jlstBVPxk1kxj#pgB@W)Gt5>N<6{{FB6w?X_zx=xm7NcMO%d$rrm=F zY9Xw&up}0W3IoSF`|ihyzmMaT_{)yBye#demeUOaEdSZ&cVpxGI}L+v&&2`W{M)s7 zLJ;T8kf?5h{IwHkN_^^9X&)}f-8zi!OBzjhiZRRA?^mjCO8!`n34G3zW)D~N+_{_m z$Q3(VIVQK&GbyrIxmko2IzNj?;Ti(!e+v5$69~M1XZJ&T{5B85+UWGJKn?P5g>wkg zhWsU;^MAwD_(}gc=nWH2eQ-jXg36l{YanApqpCz{iAEgaJGfUE(w^j-r}|TVUz&CA z)R(>3(j~b*52t_X`hmSHllVvhvFk|hDf z_h%`3HeNqB%yXeD858|RCpJFVXqe|gM~?}mWhnkPF|GQ9f(@8lFovj{5W+7S?2UDj(Q|m}`&tS7=s$r#Bg*P|VHHYU> zSNfLcaggL+gy5%8DYk#rU&%t~wI}P`r(4^FJGorD7>m#3Iu5D3oPFKrIii~w=LUKi zk;qHY_H3G{5RT44%sWAmTy-6Wg_xN)4x?wjWF2B-Zq6(mfdw;5nC{P10N-co-aZ@JqcSI zPNWPhZL5!Gf*%r!9=CUoWys%qWY3&HpPo1ui=#nTniP^uYkNpjTb>R~-*>P5b!DgM z(V_lpnp^v)WNCpDn@ddi!@>d&u5y7eKCE})7Btj=Rgfrg;pe#8qml$xP11tH0?{UI zOqd@RXdy2`e3%?p+N!g~$Pf+Qzy_8g@1Su1B4;5_)xRh~k(tvHFja{A%~cTvkn?$Y zcS)V*1mC9ve{Pq{iSX54rwaeE;yE7Q)vX`7N0ilX&X(by(AyZHBKC&8osH_N+eptv zYvA75^_xbtIsd%tOfS!A-_F}RgR2A?UuoVaxNS4ft3>P@R}Z@V_!vk3BD2Qg(g$hcL6ZW`Jxj079lYaQV zJJG8rWFCy5I^;Fn09#Z~Tv*RJm752tD}?YoN|3MSKUpFTydcpHMomS? zZOwm$o{urO-?%=uY{`9P>%vVN*?78Na@YSsa#W-{^Rbu0n@~2h@p?jQRdGI1MGaW= zoyHS&5P`idDEWNk0z7`+e!nAkUalGlm2~p}ycMO$1gk`||6)Y);FDQ=k>~9UjQu$M z^(X z#o-gUycyIXZ2Hds2}UPy;5&O6kR-q@bO0^$nLi8GBEWqf5F~(g-AKC%s%b=+^g+A} z6cMlB5)Gfft>3)>A-@W?DS6Zewi;4ok(GgKqQgJ*q~)fqTH!!)vUO3ymA+k$3|z}U zGvlv|Y{usV=N?)r3(YhI(KpwpqpI^Y!0~8Pw)8}9# z^H6s3P!97{6S7i(`BGDHL?Bd|b`J9qxV#svh^sc5@tBm##ED82{Z@_RAPj;KC<^_} zrCuxTss2`S+DYK|xfW<|z+A2DSMpC|;zo?~9`%**dpZ_;Ts-*+tW;c*=7Ym_)?*WP zQ?jmTI$?b8Bq6d*y8GCP89ccqutAHgD{`$k3hBu$d&9@z7Uzx4hOtS2!@U^CYDZxo zd;l&7N3P=sNXfNZzX-FnvnZ}HMJQTv;f|D9)k_oB3k0>A{U>2sG;<H6TW*saui#V_fjfC|j?t2}RH$ zaMp_POsATk5JCy4jQJNS;(!zJJkA-+Ss7HIO8^qEDWn7#Jj6Q)SJ23+0K}j-QUQBC z5Ni#6M^WG|gI>`N4d6_7mLYF`-et9I!pAL}TU-W~b zq~#&bZktc7B0s{30Af2~4)maWa6KKQt)K;zkRu~V-=PU&9O!`oqE}FTx{<-db`Ia1 z!mHD!c+qWJqXRDBH)M!;BkAgN;wvZ3@Piv?bpn!HcAX?UzP=;409@to#=pN46#gE2BdjP= z_fu6ga`}GJ2X2kBC}JzP*Ur7Z#ek;+ahy3nJUXgKt6kui-(G=0OuBJV)eB?q_d#6R z&Pf^l5q|k`4{wly8zMRF!_|iBT*q5*%yHztle}{0Bcd#GE=H`wns@+ZJ+%*35IPh#Sw(7rP!KQ_DHI3PSJ$iRw`91EP2Az5R7Do)SxSL$kQ`= zvtpVC#kZ|Y7lN-V0Ef%Jf%;E21ZRC9ZeLit0F{+(c5~RO&fu+-?2ac8ZI#(x>s#e# zR3(+jbAK<`Vj&S+va~n^tda)fw?CvYu2MkF+hnzUsP9q-4pfh6Lj0ffG@%leqpVrg zUu@q?STFM)-liiSx+k|dxGQ(C2co%4xy(kP3@kgJ>&>ifHhrcu&0odxy<8-%*I!!% z8LdC?WQ}#1@2>j^L0Z2lLkinvZ>ix)OwwI)x}EOAn^D94S}mt~sTpl9Tdm9F{gx6x zzgEe;B+=yKnxelnqblFE!E{WZYX{wMfQ%6%W}>48i-!h;Fs2FG&(r$S?yR`estu=A zNmNzV6>YHY%zcQcYS>MgtTiC4s9rF*eCHO_c2l6svWh|G=>TeTQ|`bNmB}=LPyC`a zn~k=>_7gR4mamu-AOK}M80huan1wY;nP!IX2$<9bK2f*d43DVQ2{a8oa&~begh|zL z{t{iWrF2xd!AfT!rT8uoEiiMtxFvADt}fdF73u=$uWm+B_gn3*&z~rPQfjcGNglSD z-pFU=6q|I6Fa>Z99=+tT6oLm1QgLD`uRWB#lO=AHg1y%Im zUd+cuFKTcnxehKi+G=OujJt#Oea;4dsnARX19CUcNxbO_i7PzrO%nt?AaJwG+6`X& zudkZe3m4reAG)QVO%%F^5KszCH!HE}T)y-9;q^?!K4u1t3M0HGtNR z;yIePWZkx$PWOa~`^G0s{((-1g+%KN}|IEtUg z41&DEI55A8@+)B|K~cY16r1LdcdXm07oT*OZK>}ds?j*-2aH$$>E`0;h!1O9IzcNw zF)+#!5Sd z8RHcHQ4M<2Y`|=2pz0C+jO6NqVW=BTvsU2f{xN8>5_D*U`7{|9?kG3O1Q&KZ82_Z4RyGdIw zYdv`2{8sTM^!~l&;jjex#YNE_RJ$9!1LFTz?I8b_kPLm{Tn>cHe5)ZWLMA(5~J3szI0DbfxIQ$F3x(GR41$`>%MPh;ye02{}Le? zYnz169y|JF)KX9RQUkww(^RE5FH+nxV72NgTD-BI)BGE}n%Qji$N-KD#0vCR`s~7K z_>kY(j93(a+0ZC!n-adRlOy{;BlRNE3>|xB#*rlmn|!tEax&v^vV=2gErJ9DL(Pf$10{8ruvTiuMLFVS5K(*<3I$KFh1!0z|&v$F%G$LdU1 zHW)Wpy^Nwf_o{VA?M}y z8t`ThEpAtFry=o9bkN%qz6!yG0K~5+r&Q42?CNkr=Xp-r>n3VmF)+M}Ua(ysqIbRlL zg_n1<;NvD`{htAci!cT|07F#(>h!Snh)SvbUWn95!ad9h$jST}Px}VHV^Kb1us!v| zK7AGxCaHfa0R?(=#lxG>!GTJDflTnDTUS<`Awmw+ko-_R9qb=QozT?2P(wS+vXDX! zSRiO$QdsUG2V=~%r84L!=NLEdut6kqDRaz>=Ntz=QVKKv6vgCO!TRu~O&akewtQ)s zA<(o2?m1~{9)3VVnVKb0TjXOY+_oq)l=SFC8N_vNZ#xSj-H*V6F&yp$E8q7yT8G!y zO?{KrwW0U^^&K}5zwhOQ>b^jeZRy8q?PJ1uLAoLgwHn$1wYmnFSg}faB16H(CLg}I zSjnL}kzJSCB>~2w@OHIe%a|z&KEapXTrW?%unEUYa3YjMYJPJ@A$8R8Eqzb2RdKtm zk>AdSM_XN0n}i|Xep+0Qrf8EwGMCBIaFryF_NJJO`sJzCyLs#uEtVgTlxdK+kS(q{d46Sc5gwA*Rk% z__i>^X|K;TrouWSB0{MvMnC3bpP0z0g=dEh63F_Oz-g;gk#O^QyMsu-tP~jt5Q+Jt z=}|!uI%FzGIAY)sl0|F)?gXi{<-=S{u2@N=GQ?GmgbAmwb^$fdQGzX)d=IO`W2Bwg zpN%hX`%s!|MLp%~UrWCHzGmMK2#gP?^ZXvi)n(e;h0`d(9?~%X{91+?rbHsv0DZXO6ZZs| zyo>q2(6hl-Ago!6-$p^WR(xMa?gc2d`w#ks>B5%!+ z;v#Ngkn~Uu^C8z1nn!6jZ$vmKg|0b-AzO%3qJJSFks?Jz(04*o{56PJCl(TI4g8By zC?7IJ{1`P)9YiaXS@DeGv~P*TWoaEmoMWECdYWZBGbHpbM88=7SIm-StP~Nj+$4HV zn|~bBlnG*1%L^J-Ot)mtG3yhMqmfKB(t#$i~gokLgR(|(;D$Dc6$cEfy}Yxg0pO_iIl zNIS|R$aLSUF#fIscRP;>xINe4^QYGN`UfO-o})1F?fRu$AgiC#BG^@Fl!JoUQ`bct zk%f#c*qy67ZY~epjlVC3mRsbO20+h45CqXpb}n_Ov4{))JXo3=lc)IZ&cV`Sj`6W4 z+2XPV9by${=xbKGP{pfIw`gPDldBAwk~u)7^uW~FKsCkZ*-osBz^qfu)tbDR`-I~^ z;LL0D>hy?V##X=LC zgi=L-Z>m{1u8uyMIkS&R308hjwyjwBM)w4u{;pUY!+X7Cuf*t9pg(ctns4gImhDbA zhK)JMI<`}FIv^-cmKBhhHxH6SDUk_Sxm-FbrD?1)X8tISR5q81>2!!M>Z>v=N8s_L zVRqm5jO%ZXo`clEfagNEHdm6Nk{S*_p;;I^4(Lt^QJ?gn+!s6yJUT!{pz!1v6h=VM z<*_*`j1B+a*n118Dz-LmTx_wuc49Y&)1ZV3qKFvSf+$jglz@tft=Nj##kIx6x?TfY zRIDqg*xd;hSpOZfk2CwsYzBqz`__NG?^?e1FlWv)Pw!{%{oBv|&wa^R2iXDav2S{Ac4YnYAKwTT`VvmOm;b*lAU%V*V#Y#K5ywQS1{j!&vC3>dY1 zU8{Btb}T;M%5Q3$VQtq1)TvXVVVzD>|EXI1($sM-Q5l!xJ1-mD!SVIVAJ@OPe3N!) z)WcY}8%=MXIvH>^B6-3p>xj=YZil88Pi$QHXVW+BPj|cd=D%tcs|wU{|{ES9-x42DBh|v7k zr&j+Nn&7%K9=SI4%eSIr?f6IKc4tNxKwZ1{kAxE-$f-c0ZLXQ+HvbM&K zRFmlHGhJ^?ii|03wK}|>>vfawr6SLp)F`j$_&)5oZQX~qR&N#u99f=mZdrKBvD1By zhux@SZgVW*+w7(7wkLbd*;#A#p0ahWo!M1?+1*Xo)Vc=M%TA20H*LaQ?>4vB`-ZDW zdaP=nZlYOnqi(A@U1F!TYPfan#@4CJnzyTCuUr_|N}+GIUwOvny^dT^yRlL zcG@$Y*A|P~QYO{?K+*BXKL7mozLxEmjE0F(i_%K&vFPm7^w8Ot9hN@tK6d@Lvgwy6 zE;9+x-5T6+U%LI{K9Bt$JN1t9t>^AwVA2AkYu&I=dmIQ74KXMzg_cM z`u4e63*Tc;&-Qt|wXV9V;%lX5-yVebes})ytdFM` zlzv}K`(={Dr()0kx<2hZc$azDg};`^UTNL0_vMXe%UHUXTN9ra8TCDRcC{bh=e)f3 zv+I&;mJb_s&tJSnBg>w5BTw4JeqR-}&HAg0uIYW>7jxX3UvsNhY;>cJ{~TO>a!CiB zo38iba>aL?sMEW0-H@H3EV5MnTpwxxs9m1Y12o3B%JEr#Fv5s$?KNWvmuw$e6 zDH*ONe-G6BefatGzgx~bU*sR_X6HN~kG04bvvKo~l_T^Go8DWnw1P#b`xnO%)qAO& zzT1tw9=!JFhDSY51)5kauCd%%rEbt*Udpmp18P@{h>IS)ulVk}r^;2TKCJbPLJi$7 z-Jj62QoV$Cn+`nRI!8DBQkdP=PyYpssyNCdNL9kE;?o`ftoJ?JZvA1u&t@LQmcDbW zZQAv<_HMl?Ep0~}DsS%NQQflmh0Si?-n;fM=Jule8%vw}uP%@Kus+>%+o!&pe2s>)@fBIKl`oT0ea=IzZQ3Fv8rR{ z;W-Ion!I#au_o4W?ebDBU2j|ry4bZ{z}Zb6dkX&jz~RdmMXfR4-^YKBD_nK>!$+sz z#=Jf3n>pMyxm$sY{mz(fKm7h>>Fy^Vmb|_1=lZSP4kg={Zam8)_IPZ~!!yDnP5Lxh zRL<|jgKkR>?nv6zvUK~JmD3J>o2Is_)yLNETzcE2^tNRhS3R1(xl*I*C!)bY(Np2o zd-Ql*X+ge&|K@vLq~Sx)@@Kcqw6+|Ue(`O5`s%_@n$C&U-_{JB=QsHImUy?2rj6{U zzO#BVWI@R>WhS&(P|DTBp4Wnf~(5^IqE@1#}$$pY!J-mzKZ(vg&wD`n-@w zwGOy6I572om8%1uem9vjqio9X(vJJaKi*eTEL=y zKKFcC1wvK%Y)m5ShSDvwW#b#QOw|wSTxx8=Q5&OP)%MRES-f_s6&GHHr`787rrd6eoAZ`C?22oqZhmr$ znf~Of0iEvL$ZQ-?wwA?&(nZ0$AU?D%;&P)yrdjJE)o#Q-$rv~*t@G>)wPs%^nVB{) zxL|1Ke(tmKExhK}?{&v|J7!zW{jR8VDeJrG$|r#{$N8?QW>b6R{oYR=*ZZnYHJwnx zr(IL4n@eJ5wt9UxHPEJIbcn-XwQ1wb{>v}S9JZ_BoC?v4YsI+Fsb4?( zcU#}MX8QVt3n}Lge7CQ1^%+OwDzEjrRAJ&F<@JgaA1gP`YHe2dNoDu34GK5(3awYz zMmcCkYv&T{FX_w+Zy5NlXNi?@x6636E@Bf?*VQfM z^0fJll260DI(1gp=(X&$`oqb$m%2~)Dl>b$P2uE16D=!^ZuzPsC&+W8* zanDLcKD*gv_xeHe53Zjz-SlE1i+|g_b)Gui_iE3iVvpzFSA9KGLlK+2>edU>4m+#- z)ljj$7HIY~wz1o}iro@xcc_@;HFS{sVw=AkJzkQL?iD#{Z?gZBf6Dz+Ve5i2I(RQwRnb1UsGrX+e@Pno*yeq{Q7-=DWK9-KQlag{2d;y;rPj$Gk=`S~sLn7XmM zZywW~TKnV4i8BvhER87<@6)}6k4uUF$|Ubf+Y-Gs&Foxs^#P4fF3&1dGBt2@vC>l$ zmP~T<_izYrkm>oX%SESQmEXS^YWej{>pkI5PFLG(-t%sejSJh>x4v~gw6uBF<#n%% z2ei46wR5=N*xm0lZbt2?9}%$O^v}&B`)UW39J=Q9z51Ciwuk2TEjO=TjmsxZ*S4?s zsMMbN(Qct@T0a^VzkT&3+k`1w*Y&)b)OTw@!qq4B;ujSkSH4w$lZc9~Hs{;XqWtho z#n{O)nVs7&e{nf(XzM8(-iB`WE}D5m5m9LU6T3T^UpA&^>h1mscWf5+cD<(a^>A1V$ zr%Qj`F}qgwP)+~a!P>t;j7QCH0u3f_1Zqnbn^eA0%C$t%hm(KWj(It(T;t+y zQ`i4%+2ecCu+!g%JX`eYruE*2iE9^)edZfgt5*2SE4vau*$)i7@$q%JRUZ-$X}isz zynn;fG4J<146SnQWxcO8@7!LLx#V!*zwck!)la*&KO@}E{mPo|5!KsN}}uf#MS2Z zQI{jLDkb?p>womT!_NwqS#OVg7``;-M}-$!^xsl@DrfcDc>7Y~tqITj*SYiG-TMc? z3+WH-`Jjkc{-aP>U-0Eg$0(nymS1{j^?C>1Q{TI;^UpSk&QV45&OgHntWP|7qfeGw z3V5}crs4PEA6h>P+38sBds)SYN-0e**Sb6ZdQ?iI50z?cNSwUkQvWUoE+t<2_My^; z*7rifCyuQDrq=l?U$?)%Tu2ZGYb^${^C^WWNO&5I_ zzbiiJ*+jQ_T^G&x+U{Xm)c84TqT&vE9lTPYTIU9{&EG7v>(%Cl?Gr2aA|p+n+l;HW zy4JV5Ed#1HO#bg~Nar3kriuqt4m+hvhL7lZU_JjlunL^@B^^#tS5xXdFuX?21(VOH z+o^>GIu8s#!{2k)P`6XqX_fp2o+C!zfljIL%rQB441R+;t)jn;yQreyz;nmsH{@J0 zyMk>rdCY3)^qU5SD$XBxfD&=`}1Jpoy9FbFAu+H^Ym7D)aP4$3g*vOv9d|UW6fXx zNVwns_0~dWQI7tB-=BOL(5LOZ5=SCdCm;TC_VvIy`}`Z`>oqlD)#p+kdo%z2@|P~( zuKcSxZw-aD**#I|->*d4-R=LqO1_&@TO`(~ zUirq#gD>unuKsnx?9#zEEuP&AzGw1bP`6!`p50i!wq%QY6))v4(DU8#b(W(F?JA+M zJe$9s-N5fMt6CWMTY!OnY=%UJtR*kr~-EZdkjf;lQ294GF7adi!_M*A{9u?d* zA?@_?ft_}`ysG)>bJae(`iC!dJ8!e)ako$7&ZPZ}SyuS!(2Uqs<5u_DVD~aQs^iy~ zmPPJZXB21Kq|)n7{BbiTAHFYMlM+1N-wWn45o3|C4u$9GbZzw8Zh9%crP! zER9H3U;I1v^`1s$?>Bj~*I`=02#@scC6ac9d@r;st7xyb!%b8veKw8ot+!`^U+{go0=UdCz8A9KCFa=ms( znKu4Q3+NZD^>6N)FMf5ct49l8FFa)V<v)4lSC60EJi5`= z`faN8^_UcNW>Md=eraVd?%Y)_Xv^uH%_Hk zdbwr~{p^&HDYYiW_qcs-b?J3=lH2*u`**#od$-1}A2({pJzN%gxagktA;2Y? zsN>K_tK6E}Z*E?r?Zg%b9L^_IOzE36YkcvlWxiXN2<>rebNId$V+w{1uJRV3-qv-^9O zROt1i-{@-(YUKN8>X^{_x0ZkEmT_{Kdo`~~FGCv~id*XQM$SLB;eO_^hW9(%kFwiVesm5==~N z&8D1rG-Q8zff(%vlcV2TM8CA{Gg37=?9tk=`Bzpsq=j^S-|N2n{gQ!+Cq9j|Y<%#W zYwSB$=XLLnFRb$+_}C8B^nyP#)@EhiT;;d2?ZucAVQcTqUXl5=NX#+y;28zS&adoK zV8n~dCy&Lh`)~YVJ0gEWo3EAcmmXfLrse3jp6BmG-Wa=B6$S-E$ddK~VjT^r@Id6kg z%`?aTZanwZn%8aHe2hujGq>6P=*(07V)I8`d)IH~{R^S7?}i2rA5ihrt-ked+4ih= zOV_jhk;?m9Rj#}5@0exV73G5eIqX__|JaKklVf{zHw`V6X1lvpW!H=c^KB-!J$7W_ zKu_oI`Hu#rM?5K*&~m8B-flCF+Pd62v1!WO@ZBxVl44Gbs2Al?)XTQ2!hGGKz}dxJ z8(nQ){B}xB(@)!mTrAeFufjC`K!?fOvg#aldbOgIyLRe<4Xuw`H{FpMSiI$tI~Q!v zz4#Ecb!=RPhKV(PSSG(~-eyMP0L@Dw{LJisa~4;@?{VA zTh^PL_iCF?c^5GGm8|MWA*ytSH)HPspR+oT? zK_m0uIMk-b$=M}Z@9a=|U5VAsVOQVWs2$*_ZM)tt{@VlVDk42~doI_KXzd35x~xxKr17I$!KWL{`p>$$UBlTF2)x{vMIFgj*!ymrEe z-Yd#ih`rKeOk9V-raewgn0al6I%VUa-2=N6>zAglI@5Ee_c8A+u>tzZW9nOYYHItp z>99mmveVqmrqeoDWK2BQ@ZIo9lm9&#Tlk?3I9FP3OGf0OuKk_X%&(og$-Ybc((b$W zOz)&^{OQUi&wZ9%!$yC&>eO`0j0(#}tzG$LUD?UA9^UGzvurVP*TAMdr>||XZqVsb zY5$~`>=50(QupbbQlIRtVt3xJU%AOmcXW90tl_wG^E$0+(W_i%=iP;_b{;q1v|Ie# zz0(%it}OFpWQ3+(blm0ZgGQ^Y5;~RJ`rorjY1S<&pNO!xoY0^_Oy@VB8pXM-nXbLs zZehDC&ZX}c3){VIcB781+rOHzrr^)b^+P6~9=z;wv7c)^kL(^0W^vp@;d1U0p@Cz&*`4S7)8ctj(ubtv4~r*_x_PT+l^&Wxvus?;s1LW? zHgk)8M88gY$Al(TR*gLP-^SYw%rn~c=vQ`4z^mt#Dr_qgGijG^=T^5aHD1#*_RJSe z>WWXRC$?GE&%Hrhm4Jqg3VA(GZ2C3f^0;YWGp&3< z4H?xv)S<_g2#2LN*FCwqt$o`Tb5rtZH#9D~($8^vq^ob4anldCQaDyFU9D}~rlu## zlyh~df4D-w@imuK_-k8-#-W3ooGkkO$Zp+~xbo3QOAht7IlIbh!J5#`L5ugUU)Su$ zrl5C`Ywn~xZ0Z@>yJO2!RYopNnex1Lvu>8F+l{`e+gNAmxj@sA$~r-F|8`xqG3kEM ze$`y&EPWiIN?E?)^X7-ugL@`exZFE=-+xMjZpA8$@@?2_Q?JY_d+#5-f9kpCknRfY zzB#TBU2m8Tcr?qjOVM)`baVO^e>Q&Mj!)BjTL1TAe9aYeeMT<+y0BYaSFej3Q)+JN zzGvr3_m^p{$E3wA(F{-d(qYH$)Q;`Fd%c|0aoC>WZD;o}Inl4iyt*Yk1H81CqeoYt zQT?y?|8-ecBG$FGkHgt6&Ou4fdW^ZKtTMo%M(W1=vHk6wTE#x!;8XBwXI0}R+Q%Ea z46XO@?dOj%OH-ybG^kE z9<(Q|@(PcOs+m`O3V#O&XLgJ{bo6Z1>%CKs+^9U@-!%iKz8F}oU_$D?=5t@a^*GRA zz^)jdz4;P8*nM;BUUg%GQvT+h>rGu0d$#zDV$0Tbo0&Ma{=2ug!-6LJdbVA$^W}ya z9#)?24=#_sGGc=J+{pKnz9&0gEcfkb!5(M2y(*nn>1h6%jppq-vi{s&pQlgu&%D3! z+|r{{)>K*Y`SCn$|_&EaYcaN{uyNIt=oN`ewGX){)^4ju%+Gs_mI> z?lxbGdLKU@)?k&>kwBHI>ebaxEem*Ecy!Au*xD>%SHy^kS6q&`c!VcD{jqDA&6@_n zStSRTol$j5@UeSI)qBQT?h31xT=>*Rlc^pT_c(mCF21Bozx7Z4Te)Xuc`wz0Yvs51 z*)_DOdDFptTCBL@^tj%__OA}6kDFM~+Pks&U;ggPXCI1tvh+ko+|*GYSB;+4%>T~& z2MLAJvixqn?&SM0MSs19)!|J|8npNr6!viMlL_TkC_{T$`8>Py>@ zis5H_4Y|E^Q`b)k)$hXhjequSw(8%8H&0KR;=g5C*~-4bB_ejXSG1ZnCDrrYmOHCc zcRM^!th>*l%A#=%Q(D=o$|T=y7JB`^BktY%wwick!{4Q*Tw)-Ok^)&mB`g!Tmvuvdmun>2~=WFI-r9e(#fqj~vctz2HdO zu&#&e?>ccdKog#>${1bzP}{9tU0ZbwY(4(kL*1k`!SS&xA8)K1{$$!fOOuhUF5Yc0 zb912oey`fjbE3~J=`*)=%Jo;7mE9}GhZWu0%-Y5I+?lxPZass~m^bTv@A(MtehUg# zYw%)f;^9@HUz@HP{KMmDHM=?1hmzl%3%R||tMjn_S2{ci+uHTq8<$&${r~xU-REaE zQ={L8F8n@YX@Bc(nx}_e_MH;4?m(Kuyr~D46yF*)Z<&|PO7~_v_UksNk9#kTS+?k9 zg3oS;Aair)RjCzI-BQ;UNN%OrqpMcz`o;BqZJL#jS{(Sv`d0HLr|LCscQ1O8+wr?| zmbdkI{@}^`>Eqvasov2hVRO`giXWb2HrdwCW~h4B{-z_Q_t}uyZlCO*ety*VkFz)3b)P;Y*m>oXtg@%WSKE6$`V`r*@Wf{W`m|1YfBUk@m8R?W zb!@hH+EMTS{Eq|;oe_NX*uS?UzwJEOa{Y0K6tiJhxAjrKEV^#`+@g(Fd++>j{^V)p zOFsO2o?>eQlb-ROD?2Rj^zBQ9u-6R}Bd_fXn_O;`_4^Bl8m_$g$+zF}vzy~i^snyF zakS&M%syuCm%ShOGdw!#>vsK}O>XI74^9>uJM&PDA+WTV8;fZGk?N*nX zv8jH*{aNNK3v6q?Iqqc2APfB<%>b7c&s@4ZQFOYW|M;rblc!HfXtqKVGR$V6N7Hjn z8=IG~b5HEr+}=Dcv+~!!e_Xj=!=~HUXJtnRz0`iFxcQXZ#%f+?@+%5H{uVgv)Dxwr zcX)kWwaZDq|G0-go9vyObZO6n*bkc>_O3is{q>G!H|<{D+7x?v)BT8mZD)6_@4UQk zDc^0)_O^_xcjsE*tG73L#SDLb(cC5?@>Pc0u(4h*-0ZS;1dMn#rE*5vwuiG%-QV8x zyjy73(+^9JT@*Pd*yYuO(t%qCT_5It$m-{jnkT1w9>2YPQAT))@Ev1Kt_KxfX4ZFW z#a@;HI|IV@><{W1x2NjF@4Yjr$Lk{}<`tNF=I^PMk`JAInB`k;SV;9Wmy3U$ zf7@eme|^N63QPL#7}R{F`x=|-x6j`_{&T$D@xkL77GA0EJ7V9xPaC?NO-S3?RhMzt zJw3p@%9(WyU!E(w>_;8T?Fmj9DVhUYG@(H+=k%)8J-Gg>ppT!Me~NXB|LS%3b>^I# zZ})G_oZs+mt%k?GEKff1^kM40`k(4Q|2ebXrDfl0d@VS(Y~<>$<{kUTzSy&A_@l?Z z563Jy@8){VXZ^^2|3-Y<@-lt-&9K6&3N^O2%)h%!?1nY{I)E4M-Ce%9WBK*bcSqf* zb$qGMiyD_=mfzX(bdcx3!|5k)TOEF?3r@Rru7A>`ouh4r*7$os+w{^^OU1|k^`y&am@oRXa>3cU3k$H|LA~wv7^%iZLOAf z-kfpfYDVzhlsZXPg(?+KQ&qUNY4ybd=bEi;*4%HztkL^cri@wcn0&!zc)9C|d%Fkp zP5AU|DgX2P%=aeL?U``9!3x4izauq{ZQf~b9ld*riyvm z7vF8anlCxrp?bMPw$CcGpHb^jR^)_UXG+(Md^-0>?Tl}=sviuUygO-LFOLdKV}{px z=rFK?pND4qldXTvuC#Z5R_U70@_nh++(A1}d`Lj|y)!Zq< zGtl45RN)xt=@)LMw*a3)f+O0r35j%Tt_2Iw&D9oaGo{K>XJ%!o?5DuDw+{9T^nqWQ zDq4qo`2rClK`EoR zKX5C#!prI1-gBDcm#&X(X1eg;4rz*c{!xjMgR*ELhl3^g6?xBZA|?G7F(L(d#} z5oI&N?A*Fut5%eDt+KYwtGzz=G+{mKhSYg#mA>%ss(HgtR0wk%-Rc5p-`DwIJKIak zEq_+Fs*p5i-o9#&rfV9fM;~nYNWIfxTXa`Nq32!e`u{BP)cJu1G> zM@D@=k(_$|YndU|0m&7+X)BI>`^ItVwlAX#cy3q}FY0Le95#c^&aXuGfRt9ep0HZ5 z{{r_s$X*TFYXN&I@EZJw{w6(PaW7bO9qf-7_JH7C3A|5qdjy6Ey*(n*A6C!n59_Fe z&IwiFs&Isks)2iA;4=&c9rsxSK5MzpT6hn4zYcs>ao6?m9`3p&_>9yGm~pfMf2g^e zz$Oy-1Kni`I?euyZavxBwzfub2?;*Wj>Ulh18{{<)Y90@qvH3h`csV~8JXYKm zU=%Xgf(uF>4{8lPl>S-Ni1VQ3@t{Uh^Zh|%lzsDp2RJyBsL;kS3En9M>gc3|+FhNT~*^*EO zg(dz94atx)9w|Z9V?`)iWs|p*{1L`VL;I7`0?CmV4uz(HkZBze0~ea$3Qq9w0}(?{ z6r?8#(h~*gv4W)ikw1O`dC=2%4hbqro-^2o3aM9RG{bt>VK$RWIQ1k@DhUy zEqJOP>H_Kr>I>)z>H=~B^#!lP@8LC_eEp~`wB|rzd<|hvyM*}+gPdYR629pH6x;wW zG57{ZU!*a_C$Jgf56VDk67df;Y9*>srCMtaSdr!vY1E)!x)K3=!b>bZb({_XgHVse z|DfL?A8Tvi3(sYUhkx6h47MqFZc!>9E3P^k|4yHP#8rTs6`kFP@^D% z^x(fx!zijq)U*NLLFr(Gp@=g`f-@+Q1c=I#1nHDWg0r!}gZZTjP6)y{0!u>{D&V=0 zKSN9bPX&&Qd4nF#c?FUIdOLRwT0n0h!M9FlWe%9*`v%gpfmgbq0jp&2l0fSeuYdsq zuTa07M<6eSx&+q*yh6TV6aqdG@8JKi*Kqei`@pEwO30wK)S82QY%Bv8hny>LacERt z0Eyt3!IB8(2A=jwJ~fhrND8Hfl7fFwBIISzBJdxy2E6ZA_7i%N2KuVBEI30GSqK;IGa$ceq8P*ZE z4AwN#76eunb5k&q8eai}Q5b|#|H|{=Uckr2}gYJd*aIr|}8Ga9+32EtxF7TqZtHIVPdIrhq zf>>KnL132_Y9^Zs0(m^c8xhA)V(6WmBw|vb(F$sb%d1G!L?ec9r=(Nqt?0}{iDz6C zB99ihFE7CH?2lWm!0TRAfJ380HlfHc&>_3f2t)QMZD2;erwcEzm#wFZvB}H~6<< zxqxC^rBj*1tzcuuNd#e^A^8%GFG4YlY7U|94fztf3)C}Y8L|oVOXlGua>!VMT#Jh+ zBnmeMpr`?MLs3V>G(-`g%h?pVEuwFzMDQk%!Q}uUmdql?GO9cbl@;Ivc%Lg-#lwFI z!^%+C!f+yC0)#XS_(TR6KAbs4%?S5Oj!`!3q6L@iahN}Nvu>+ zt7CZENhp=knumr|NNT*{XRtI<5M^l~FA&i}17s1kAZIm0fI=?-H}dsFWJSLR#PnRn z1$AT47rZXz-6|~zYL;bD1~pjLXdZ#({9VfuYe7rGf6!;4Cjg7HC6ch3N(C7F<)xe_ z8n`za0wKVQJsQBw16V=P2e>uZf^Y~k5A-)E3FMv|^fbT@a6KOV12&c?4c^_A$~;6G zoNbANk(fgzxX?SZsaN1M1M-D30^ir54?&*+{F6Z%-ADWn+)MO8u9GYc3jqU7Km%5( zXt06w!1K_^3aP}HHEgnh{a)e zvSb1=2FDk`KH}df-Z%>(>q36Hm_&a=58-5hvdfzvV>p1pqv5);z-nYyj987oj;Y3I zDxuY~DTGiB4*d&i7W@}!n)6p?1wrnG62tr9@4-Lh|HN{J97;*0)`OiC;7-314=on7 z%dg?ls4!9^xERZDf{@@ue;8lgN0oy82R)OQ8ODv9IsYaX#azjct$UWc?T7kWVge4QT7L**)B+d!7 zV{k@{B{77U7A%|rVWfRgFrZ^FqEJ$!qQ=Tl)L_UWDQYmJPgvBTO=zMAz%R5Gk_lQ1 z=mhBjc^3E%{DHg`%Enz|%Fo?{JQjT>sgu%y5(Ff~JxD468<;q#3S}Lk60+I*G0gR$ z1Hx6NmucD`Hb^ML*4+KLz9V_3*|nj1x^#ld{UBWz?PK2$!N(0B?yM}3MI>~1c7#ewu9Wj ztPK7(NXI!H%95OO@dqnW>7XV!dl9W54e@A0&5+D1)B@%O#jKP@jIu1P5md4mycvy( zLXBioz`(FW`5tl%Gc1=;P}vBiLmWf zKrM6H`L!}cNvH(d9)dB4mQYatU%#UWq~A^}_TD^#_Z!Hh~Dp26^_K@5ie5*iHEs8B4ZSQ0?s^B)Bc3@#uV zG$5i0|Ney&1qMW88JQ)5EjN%XCChLzk+Z3Zj9?RRd?Jwq32D=>h#jOSh$4R`wa4LKQhdx+sIDcy+#i9vhuED zXKQL5*&;G1GzdJ!EHWrCIJ`xqO&w2gDAuP1_zW*A>e!l^S%-Q1ws3WDn z5fR!#p%^}VxcP9kc}SR_0-UC>Qdp=IDphlENAvIz!4aO3&4a`1LK2t;JlY!O9~$8w z5^M%(dJYU38evnX4o5hYM>sg#95G_<6%wQXUnrF3YQzj61^#RSPVRXR_3{a`?dU%+ z%%`)jufLa%nM!AFX|4o%Zq(aS*I%b;Yz=?<>t4VI_iG2oo<3pWfDc=xxt_c0*EPtm z0y4;BSgsI2p9bv+goyME1wvR5A;5ht?1AYbLc+R-gaq353iFTf3A0wv*AdT#i#`sX z5k9uy43Mt5QrX->)m^D?p|xtE)it-!x3I9_{T$zE__a%jx4-WQIlt!J`Rmu5AIkbY z|6U1AV(kK#0xqa9_#jmA|3CisKSBOqv*Z6P@;{5@kp}+fT6v_{-zNJ%i~P3g^5}>E zvq&B(_P5FY&mzCAx;*;f|16S6iv4Y}|Fg(%t1gdz_&U=!Mb63~f$=4}N9{4*>eRnSm}aodMcm1X%D= zbP4qI@(BX%loV|OL%arqc1vLC&Zmu!Z%CMr8CaRu!NdFtXV5-M(2j~;927hl9ZRmO zvH(4sJpIBvLkImiA4*G(4<+dOB;bU%izuQ3&}`#RRbY6uTKHf-cEG3v^L>x!b z)M!Tum>P*s(d6&>iqPatE#ixoLR0g1ytJ$f8W#iDLhl- zT}1waa?R9uN0nBiyqLxw%xBBl4eNxW#|Iu53o04acvIiZ42w_EM9mzfqY;~$w4?cz z3!U9St`Hl|czFhebu}u(5dleld6BKjyU0eO z(vgjxC&`#0vehE0#7d!!{di|JW3np_aYlN;0DGPi)_?kTbf7C z*dp!-%05A4Yh}%^wIY!X3P-Uq8{KJSY(zkkUtVNu^DeTHsI;-s^CTHFL^kdqB8(fX z6x!Io7umRDx|takpQ4Fcu1oWXjjcr~RmdTjF9?k-Ys}V)L^hboh#4Ch%h=d*BOCO= zrv{8%i)^jfn2nw%tw<8tVyeVSp$+qUk&RpE17nLtHtNAI%_C=QvB;(hG^3Zni>7g% zSY(SAXy|;Lk+Bg0Nq%{e&AsRScb8gOODgz%(3Ek|^CTHFM7CB$l~^ehJ#?cqJ*jFO zzf-{syj%d4Ji>rPFIJGIiH*&@*_x*~uo6HOXhv^E5jVD2WQ!JP+#3w&Y8)+}O7hD$ zcHTuc*ZG%HBz&GEV+Lc3sghd~rs(}%WaAfQ0Aq_qwo$8lp^Z3Wi?}0LL=mKMe#c>v z6(4S%jk_OH1A=IQ#=WW)lX5MMbDf(h`C%wYGWN^ZBC6zCLJR4k z7Shu6q#~PZIBmxDn-Lky6}-5!fteZCO`qbCxpBZ!9E;( z3T1ilP;5Cf4n<;yw`aljDfd0z)B&3=+~0U97%bItf8zxtu)xFpji;SpTFCv4i&Zo5 zvO%C6ASCzR9#ig>JZ3ngfXj2=3-W~$y^2s$rR{SA(?wuyVDo}{HnTFyOJp0^mjP-9 zi{fBCoZ^XDWWZNN0wYg3YUI53veHVc0G*CbIr{E1=fj)|EULoK}wtYz8(4b)W z6?oqh*qanbv>_y(JQW%(p61A#@RFv43aOcdk_}PJ4Ha4fKy1!ch&T5rd-Gep8IPsi z;btDNH!3=W_7=A`#@=GzQvQM?iWQ9j;>j9t1Ob5RYx&Qou)j>}X(@%UVUpb)kV1^n zeNyg}jr;4=Tp(g?7>)95u%$ppMg^=COQQH_UP{mz=CdyL;BCGDZ%sy5g^RtDgP8?A z&jIgmV_EXgbtd$8p3cOIVI?w-WLEe?m&P+a_{ut55D2p;DnBG2%{LbY9AcLy0Kyy_ z4EwopR;PzKHjb0C4Mg*A-PH3%Cinj318a%E90BX}Dj%bWh#mAP?1NdT3?bb}^=vRoO1 zMe``#(3J)ogv;58kHO6~S0=M!N=>q}GKMndk(%g9BO3>s8)}ktWznq61~vbwD-*af zc>SkXRz~X>@?1GDv$CElni1|+k}YDRyvWLAVMpl7Y!oOzD`TK$9=S5L60KyTd~-uh zQm!nDLj`?7^D-+FFg6z3XljF&;v{`WU?Vhh%_AF8Yy3(!fSR)rA3yzPSy`vjkQpFZ zo1|P>c2>qP)I3rXn9GAT7>YHRq9iSt8>$kxGhbDrnVAhr|I^G&;O0sK_ob8}yI#gn z=De~KJ*i=1#EFseA~lmWcA=iwFkXJxW29|f>4~0LuyNYCp(lYeF!6u*}7^;Sw!2yl>IFyNBiO>&$V&!gdH zD>;UUYdCm?9ACnj175+_r8Z=h2yZWG2++ZGpl5`C5ZH*bALJPZwW8!7GavzljyMaI zjBb-8EWNu&Nakqy)3Cn>7Gl97IiLZ~%YcI}SUey-Sl$AQj}(W@G1_Rm@6Q+m%WA@> zv+?&FqD9FE-xCImQRGUrQ7x%#eul=7`#;G%(ycJSvJO~~1DoxXr0kwq3lQX7l23k^@^SQp zV6NEv3h_VwUbI>8j7nGvsB5=(j%`dP9f7(bpxG{#+!N0Q+^eKk+N&wG$a@q8 z3-~p~qg;r6G$1=@>!0xgN@|)Lrte8ld;fqBU=z?y6RO`-i2(fnrz}Aaf$Xytd20!+ zna+&fheR-JNoC}?bggJ^0;?G-m#bX!<7>Xt4vITFYLB;Fl`+Is}fuBL> zP<%0q4SWJi#XDNSV<}IMv8lv61*5~Nl1?sA{p_p~=)BUI5`d80;$}t*`RzChD7I8?2Cdi@G~Vxm)y`5&!PFc;&!7bch1u!O?qo{ zil#P@aq^c|g)s~)TfY%aJYeBkfXc`T5KLvRQ-TBXZQ6uHx`7RLl}2k0b_TQnZlKod z%ymea;6OY#>_V6mTyq40s}emhqGBI8$fX$;=_Wv9VN~pM7N&;Y1Y@B#5*YUtC z!U#ZJq9vV>KLYXq{lDjk;?0u9Fzr2^(|C3rzpu(xNJH+UR~ z)L&>WnbyLUB^XnvXEFy}ryx&1ABfKM42|#)3FiKTIS{FsK&l{EZ|W(`)p68|0}}nU zc`s8ax>%)hp@q2~7@ZG^g@218Vl^u8TapL?aMm1v5MUxys;tbdv`8A53CXb;&H!}I z&jxoawbZI2eZ<-O;beCdzReA^y`e10hN~MT8hMYT6l~ZfrSl9ztV@PVcDeV@c)`m` z^t2pdvn4q)8jJpn1+dC2ba*!InZsD9cvxqH3&8#}6fv}IFDZ%$j8Mfxrt%5Xi;`@R za1IF5S%uwXJO_kntFn>E@(F{bKB2*o#w2yjA1Ha9!40})$1N2^G<2W;wm(pW89*8u zfG>wfEmQ_TF+e{POfdwYlm20NekqhEo3`Wx`6A(hoC6u9H|Ai0K}jlJ_kM$ZK;|T! z_f@3(nUG&usAv_&t>6KdL@dn8v@w~`dr>dpt#$DT1LYgJHgk~XI|}X~E@U=mj>34; z6j(}7k-l*l6>n4zv%9hzaA{IX6>X@FZZ)uI!Wc5B!mwSTRzaU* zI-U`pNs>=77r^*sBf@mfWaEN!K$spv*&VHOK$!MeHVU2Zu{`v-A#`)iW5J@OilEHE zF##2U_kx*#iXeP3lw6n@*jV>pZY=H?DgsNVh%&)5Y&Ry2-BqHPbQMAzOL`s|`gxt% z4XQToKB{835Et0)7jE7_FxPA+j_Frr1Hm>7GUCEw;f$66*;x5(OoP%mSf3y*G=)~r z=0z_c_W4r~G7bCVmD})#U%}LK)B*RWf)+_~**VlF%rhb+ zEE{doPLDc!OA?jEC%q`eZmKSeBppF)+%$Oi3+O$Zjo|doI2#`=i%U9w*r;bYT!IOe zFeKT1!{u-ZW=0fA=6pmJNjiSmAY)mA)A7T`3CrS=iXSx_`zwn}DtgpxM6WC^spwI& zA-S@+q@qX7?#3>QODcNQZ0xKoE~)5Iv*E9DxCF(lz}4006(4_;+(6k%kz_`X9Kk^W zOp#MUR>dAC<)=9X)JJs4On&=wV|zWs#(#huzs(mf&>suv=Km;*yRYcK=&h zT+-3Q2B^y663m)}e#r)+%Ha|ez7$Dj^vL3pjvh8fR2G+X^ss@Rvbdz9hmF{jMUsvl zHtVo{&+O)BpfsmQGS`viI1wn#g(TSsD_Odvqlb;Ulf@++J#2uXERuBe zu%T|UNYc^6ZnZ0mBpp5M{;%>Trtl>-l+l?1B!^M>z8i`rGlJ|xf+NC00v!WGhO;M= z@bx?tVP+i3W0npiHfT+*TIpC~!;R!|N(U1gL?n+U9ZhTqkX-5MfMWL!mB%R^Q3&23 zIe6s2spz;ufEP)^vY4g!*wt)olblov-}EAMes&{7d3;gMa%}ntU1NaIr44@APL`T*N?p%2{4U({%-gRT(DXj*};V9KUy@>&fwD!kEG9E?^6An!oDC@6wzbU`Q>B{O#S+iW/Ot@ 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 literal 398856 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%0D(nBjH7tJv^y^x&>WYTaNFc_7Z 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≥B+8#$^1MN;)MO50xe_3QnfTNa0MUT>u%u_psEr1 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

tD4 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%0D{0rtPn2{In9wDzzNSgracQ7D7%aSkOj58 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

doABUCs-daJPqRsBZu-cMs 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 Ze|x + Current owned software license AGPL-3.0-only -### 1. Complete setup + Acceptance composition Fresh Windows x64 profile; inspections-preview; Station configured separately + ------------------------------------------------------------------------------------------------------------------- -Choose folders and the full product composition. Create the city profile and the first named administrator. Choose a protected backup location. Defer optional local AI if it is not needed. +The naming change advances this package’s version and requires a new signed installer and installed acceptance. Those steps and publication remain pending. Historical tags, receipts and archived manuals keep their original names and certify only their identified artifacts. Use an empty database and fresh profile; no in-place legacy upgrade is supported. The approved Windows profile path remains %LOCALAPPDATA%\CivicSuite. Preserve existing profiles, data and recovery material. - +First run -### 2. Activate the runtime +1. Obtain the identified signed private candidate and its corresponding-source companion from the beta coordinator. The landing pages in this documentation are not an installer download service. +2. On the intended fresh Windows test installation, verify the MSI hash and publisher signature before installing. Preserve unrelated profiles and recovery material. Installed acceptance for this source candidate remains pending; no in-place legacy upgrade is supported. +3. Launch Townlight under the intended named Windows account. Choose the storage folders. Select Townlight Inspections candidate (inspections-preview) for the bounded desktop composition, including Access and Notice. A narrower default selection will not expose all workspaces. +4. Enter the city profile, time zone and contacts. Create the first named local administrator, sign in and choose protected backup storage. Continue without local AI is valid for the deterministic workflows. +5. Run Health Check and wait for readiness. Open Townlight. In System Health select Finish Records Migration to activate the canonical Python/PostgreSQL runtime. Do not fabricate migration receipts or seed accounts. +6. Create named staff through Settings. Import authorized sources using each product’s source library. All examples in this package are synthetic; they are not municipal authority. +7. Provision Station separately if it is part of the beta exercise. Selecting the desktop composition does not start or configure Station. Configure vision explicitly only if automatic photo drafting is selected. -Run the first-run health check, wait for readiness and open Townlight. In System Health select Finish Records Migration to activate the canonical Python and PostgreSQL services. A running process alone is not a ready database. +Daily workflow - +1. Complete setup -### 3. Create staff access +Choose folders and the full product composition. Create the city profile and the first named administrator. Choose a protected backup location. Defer optional local AI if it is not needed. -Use Settings to create named staff. Sign out and confirm that staff can sign in with their own account. Keep administrator privileges with people responsible for setup; ordinary staff cannot administer users. +2. Activate the runtime - +Run the first-run health check, wait for readiness and open Townlight. In System Health select Finish Records Migration to activate the canonical Python and PostgreSQL services. A running process alone is not a ready database. -### 4. Import through the right product +3. Create staff access -Use the source library of Code, Zoning, Planning or Permitting. Inspect provenance and permissions there. Core ingestion helpers do not bypass the owning product’s source review. +Use Settings to create named staff. Sign out and confirm that staff can sign in with their own account. Keep administrator privileges with people responsible for setup; ordinary staff cannot administer users. - +4. Import through the right product -### 5. Make a coherent backup +Use the source library of Code, Zoning, Planning or Permitting. Inspect provenance and permissions there. Core ingestion helpers do not bypass the owning product’s source review. -Save open work. Use Backup Now; it stops writers to preserve a consistent snapshot. Retain the backup receipt, then use Start to resume services. +5. Make a coherent backup - +Save open work. Use Backup Now; it stops writers to preserve a consistent snapshot. Retain the backup receipt, then use Start to resume services. -### 6. Restore and verify +6. Restore and verify Use Restore Latest Backup after preserving current recovery material. A result of Restore needs service start is an intermediate state: use Start, then Check. Reopen a known saved record to confirm recovery. - - -### 7. Collect diagnostics +7. Collect diagnostics Record the time, selected composition, version, operation and exact error. Inspect System Health and create a redacted support bundle. Do not delete a profile as the first repair step. -### Working safely +Working safely Use your own named account and save before leaving a screen. A saved draft is durable; unsaved form text may not be. If a write has an unknown result, reopen its record before repeating it. @@ -110,196 +104,184 @@ Keep originals and derivatives separate. Review the intended audience before exp Drafting, review, approval, attachment, export, fulfillment and publication are separate operations. A Townlight workpaper does not itself adopt law, issue a permit, impose a fine or release a records response. The responsible staff member records the applicable decision. -## Connected workflows - -All products use selected Core contracts. Core does not create unrestricted access between products. Notice and Access are supporting components, rather than additional products in this nine-product beta. +Connected workflows +All products use selected Core contracts. Core does not create unrestricted access between products. Access and Notice provide the bounded staff workflows documented in their current manuals; installed acceptance remains pending. -| Direction | Material | -| --- | --- | -| Input | Administrator setup choices, named staff accounts, source material submitted through the owning product, and protected backup storage. | -| Output | Ready local services, permission-aware shared contracts, task results, diagnostics and coherent backup or restore receipts. | + ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Direction Material + ----------------------------------- ---------------------------------------------------------------------------------------------------------------------------------------- + Input Administrator setup choices, named staff accounts, source material submitted through the owning product, and protected backup storage. + Output Ready local services, permission-aware shared contracts, task results, diagnostics and coherent backup or restore receipts. + ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -### Product boundary +Product boundary Shared catalog, exemption and module-generator code exists in this private candidate. It is not a centrally hosted federation service. A business product still owns its decisions, identity mapping and permission checks. Historical placeholder ADRs are retained as history, rather than descriptions of the current implementation. -## Architecture +Architecture -![Townlight Core architecture and evidence flow](docs/beta-1/assets/core-architecture.svg) +[Townlight Core architecture and evidence flow] The drawing shows the principal staff/evidence path. Native commands carry trusted identity to Python business services; PostgreSQL and retained original files hold durable state. A downstream copy does not silently transfer decision authority. Station has its own configured authority/media boundary, database and mutable files. The connected-workflow text supplies the drawing’s reading order and accessibility alternative. -## Shared catalog rules and scaffolding +Shared catalog rules and scaffolding -These are existing Core developer and administrator contracts. They do not add a new Core administration screen. Staff use the owning product's normal controls; developers call the library only inside an authenticated application or an isolated synthetic test. The caller owns authorization and database commit or rollback. +These are existing Core developer and administrator contracts. They do not add a new Core administration screen. Staff use the owning product’s normal controls; developers call the library only inside an authenticated application or an isolated synthetic test. The caller owns authorization and database commit or rollback. -### Catalog import and readback +Catalog import and readback -1. Review the catalog's `catalog_version`, domain names and systems. Each system supplies vendor name, protocol, data shape, record types, redaction tier 1–3 and optional discovery hints. Hints are limited to `ports`, `db_patterns` and `service_accounts`; do not put credentials in them. -2. In an authorized application transaction, call `civiccore.catalog.import_catalog(session, bundle, actor_id=actual_actor_id)`. The actor is the authenticated application's identity. A changed or incomplete existing version is refused rather than overwritten. Use a newly reviewed version for changed catalog contents. -3. Read `domains(session)`, `system_catalog(session, domain)` and `connectors_for(session, domain)` before committing. Commit only the intended import; roll back on refusal. Repeating an identical complete version is a no-op. -4. Treat returned systems and connector recommendations as catalog information. Import does not discover vendor endpoints, install a connector or establish access to a city's system. +1. Review the catalog’s catalog_version, domain names and systems. Each system supplies vendor name, protocol, data shape, record types, redaction tier 1–3 and optional discovery hints. Hints are limited to ports, db_patterns and service_accounts; do not put credentials in them. +2. In an authorized application transaction, call townlight_core.catalog.import_catalog(session, bundle, actor_id=actual_actor_id). The actor is the authenticated application’s identity. A changed or incomplete existing version is refused rather than overwritten. Use a newly reviewed version for changed catalog contents. +3. Read domains(session), system_catalog(session, domain) and connectors_for(session, domain) before committing. Commit only the intended import; roll back on refusal. Repeating an identical complete version is a no-op. +4. Treat returned systems and connector recommendations as catalog information. Import does not discover vendor endpoints, install a connector or establish access to a city’s system. -The following synthetic library example belongs inside an existing authorized async transaction. `session` and `actual_actor_id` are supplied by that application; this is not a command that seeds an administrator. +The following synthetic library example belongs inside an existing authorized async transaction. session and actual_actor_id are supplied by that application; this is not a command that seeds an administrator. -```python -from civiccore.catalog import import_catalog, system_catalog + from townlight_core.catalog import import_catalog, system_catalog -bundle = { - "catalog_version": "synthetic-1", - "domains": [{"domain": "synthetic-records", "systems": [{ - "vendor_name": "Synthetic file source", - "access_protocol": "file", "data_shape": "json", - "common_record_types": ["synthetic minutes"], - "redaction_tier": 2, "discovery_hints": {} - }]}] -} -loaded = await import_catalog(session, bundle, actor_id=actual_actor_id) -rows = await system_catalog(session, "synthetic-records") -``` + bundle = { + "catalog_version": "synthetic-1", + "domains": [{"domain": "synthetic-records", "systems": [{ + "vendor_name": "Synthetic file source", + "access_protocol": "file", "data_shape": "json", + "common_record_types": ["synthetic minutes"], + "redaction_tier": 2, "discovery_hints": {} + }]}] + } + loaded = await import_catalog(session, bundle, actor_id=actual_actor_id) + rows = await system_catalog(session, "synthetic-records") -The Records compatibility facade reads its bundled `app/data/systems_catalog.json` through Core. Its existing administrator `POST /catalog/load` takes no replacement bundle body; `GET /catalog/domains`, `/catalog/systems?domain=...` and `/catalog/connectors?domain=...` expose readback. These non-desktop routes use the application's actual authenticated staff/admin dependencies. Do not substitute an invented role header. The shared SDK example above is the route for a developer-supplied bundle. +The Records compatibility facade reads its bundled app/data/systems_catalog.json through Core. Its existing administrator POST /catalog/load takes no replacement bundle body; GET /catalog/domains, /catalog/systems?domain=... and /catalog/connectors?domain=... expose readback. These non-desktop routes use the application’s actual authenticated staff/admin dependencies. Do not substitute an invented role header. The shared SDK example above is the route for a developer-supplied bundle. -### Jurisdictional rule evaluation and review +Jurisdictional rule evaluation and review -Select the jurisdiction and active reviewed rule versions before evaluating document text. Core's `Rule` carries `id`, `state_code`, `category`, `rule_type`, `definition` and integer `version`. Supported supplied rule types are `keyword` and `regex`; an unsupported rule or incomplete/timed-out scan raises `RuleEvaluationError`. An error must remain an incomplete scan, never “no exemptions found.” Core does not assume a jurisdiction or claim complete legal coverage. +Select the jurisdiction and active reviewed rule versions before evaluating document text. Core’s Rule carries id, state_code, category, rule_type, definition and integer version. Supported supplied rule types are keyword and regex; an unsupported rule or incomplete/timed-out scan raises RuleEvaluationError. An error must remain an incomplete scan, never “no exemptions found.” Core does not assume a jurisdiction or claim complete legal coverage. -```python -from uuid import UUID -from civiccore.exemptions import Rule, evaluate, RuleEvaluationError + from uuid import UUID + from townlight_core.exemptions import Rule, evaluate, RuleEvaluationError -rule = Rule( - id=UUID("11111111-1111-4111-8111-111111111111"), - state_code="CO", category="Synthetic review flag", - rule_type="keyword", definition="synthetic protected text", version=1 -) -try: - flags = evaluate("Contains synthetic protected text", "CO", rules=[rule]) -except RuleEvaluationError: - raise # The owning application records an incomplete scan. -``` + rule = Rule( + id=UUID("11111111-1111-4111-8111-111111111111"), + state_code="CO", category="Synthetic review flag", + rule_type="keyword", definition="synthetic protected text", version=1 + ) + try: + flags = evaluate("Contains synthetic protected text", "CO", rules=[rule]) + except RuleEvaluationError: + raise # The owning application records an incomplete scan. -This is fictional test text, not a Colorado exemption rule. Read each result's matched text, rule identity/version and confidence, then use Records' explicit reviewer decision and legal/source basis. A flag is not an authorized withholding or redaction. Records' existing exemption rule/history/test and flag-review endpoints are listed in its technical reference; record changes through those controls, preserving history. +This is fictional test text, not a Colorado exemption rule. Read each result’s matched text, rule identity/version and confidence, then use Records’ explicit reviewer decision and legal/source basis. A flag is not an authorized withholding or redaction. Records’ existing exemption rule/history/test and flag-review endpoints are listed in its technical reference; record changes through those controls, preserving history. -### Scaffold plan and generate +Scaffold plan and generate -Run the existing CLI from a developer environment containing the matching Core package. Choose an existing empty parent workspace directory, not an installed application's directory. The module's own directory will be created underneath it. The following creates only a fictional module project; it does not register, install, migrate or run it. +Run the existing CLI from a developer environment containing the matching Core package. Choose an existing empty parent workspace directory, not an installed application’s directory. The module’s own directory will be created underneath it. The following creates only a fictional module project; it does not register, install, migrate or run it. -```powershell -& $control -m civiccore.scaffold plan civicnotes ` - --name 'Synthetic Notes' --description 'Synthetic scaffold exercise' -& $control -m civiccore.scaffold generate civicnotes ` - --name 'Synthetic Notes' --description 'Synthetic scaffold exercise' ` - --target 'C:\TownlightSynthetic' --dry-run -``` + & $control -m townlight_core.scaffold plan civicnotes ` + --name 'Synthetic Notes' --description 'Synthetic scaffold exercise' + & $control -m townlight_core.scaffold generate civicnotes ` + --name 'Synthetic Notes' --description 'Synthetic scaffold exercise' ` + --target 'C:\TownlightSynthetic' --dry-run -Here `$control` is the Python executable in that isolated developer environment. Inspect the plan and files, then remove `--dry-run` only when that exact target is approved for generation. Existing files are refused, not silently overwritten. Exit 0 indicates success; refusal exits 2. Options include `--version`, `--civiccore-min-version`, `--permission-key`, repeated `--staff-role` and `--route-path`; inspect `--help` for the exact invocation. Keep generated access requirements and migration stubs under the new module's own review. No automatic product deployment follows generation. +Here $control is the Python executable in that isolated developer environment. Inspect the plan and files, then remove --dry-run only when that exact target is approved for generation. Existing files are refused, not silently overwritten. Exit 0 indicates success; refusal exits 2. Options include --version, --townlight_core-min-version, --permission-key, repeated --staff-role and --route-path; inspect --help for the exact invocation. Keep generated access requirements and migration stubs under the new module’s own review. No automatic product deployment follows generation. -Source contracts: `civiccore/catalog/__init__.py`, `civiccore/exemptions/__init__.py`, `civiccore/scaffold/cli.py`, `project.py`, and the Records catalog facade. +Source contracts: townlight_core/catalog/__init__.py, townlight_core/exemptions/__init__.py, townlight_core/scaffold/cli.py, project.py, and the Records catalog facade. +Technical specifications -## Technical specifications -### Runtime and storage +Runtime and storage -The accepted package targets **Windows x64 fresh installation**. Its native shell uses **Rust 2021, Tauri 2 and Microsoft WebView2**; browser assets are JavaScript built with **Vite 8.1.6**. This describes the native desktop frontend; Station has a separate React operator, specified below or in its product manual. Canonical business workflows use bundled **CPython 3.13.5, FastAPI, Pydantic, SQLAlchemy and Alembic**, with **PostgreSQL 17 / PostGIS** and managed original files. The installed runtime tested here contains FastAPI 0.162.0. Package minimum Python requirements can differ from the bundled executable; the metadata reference preserves both. No stack rewrite is implied by the beta label. +The accepted package targets Windows x64 fresh installation. Its native shell uses Rust 2021, Tauri 2 and Microsoft WebView2; browser assets are JavaScript built with Vite 8.1.6. This describes the native desktop frontend; Station has a separate React operator, specified below or in its product manual. Canonical business workflows use bundled CPython 3.13.5, FastAPI, Pydantic, SQLAlchemy and Alembic, with PostgreSQL 17 / PostGIS and managed original files. The installed runtime tested here contains FastAPI 0.162.0. Package minimum Python requirements can differ from the bundled executable; the metadata reference preserves both. No stack rewrite is implied by the beta label. -The native transport is fixed to loopback `127.0.0.1:15480`; PostgreSQL uses the configured local runtime port (default `15432`). Optional local model service defaults to `127.0.0.1:15434`. Those are deployment defaults, not internet endpoints. The runtime has health, module and readiness endpoints; readiness is stronger than process existence. The task queue is the existing local Core task infrastructure, not an assertion that a separate Redis service is required for this desktop composition. +The native transport is fixed to loopback 127.0.0.1:15480; PostgreSQL uses the configured local runtime port (default 15432). Optional local model service defaults to 127.0.0.1:15434. Those are deployment defaults, not internet endpoints. The runtime has health, module and readiness endpoints; readiness is stronger than process existence. The task queue is the existing local Core task infrastructure, not an assertion that a separate Redis service is required for this desktop composition. -The default native profile is `%LOCALAPPDATA%\CivicSuite`; the historical directory name remains part of compatibility. Do not rename it to Townlight. A configured `TOWNLIGHT_PROFILE_ROOT` must be absolute. Local configuration and secrets live under that profile; protected managed files and database state must be backed up coherently. Source/runtime identity is distinct from a product’s display label. +The default native profile is %LOCALAPPDATA%\CivicSuite; the historical directory name remains part of compatibility. Do not rename it to Townlight. A configured TOWNLIGHT_PROFILE_ROOT must be absolute. Local configuration and secrets live under that profile; protected managed files and database state must be backed up coherently. Source/runtime identity is distinct from a product’s display label. -### Data and consistency +Data and consistency Named local accounts; native sessions; source and department authority; task receipts; profile configuration; coherent backup manifests; catalog, exemption and scaffold contracts. Versioned saves use expected prior revision identifiers where defined. Reopen and reconcile on conflict. Exact exports and handoffs use source IDs, current visibility, revision and SHA256. Review belongs to the saved revision and does not transfer silently to edited text. Database changes use the owning product’s migrations; a request or readiness check is not an authorization to mutate schema. -### Capacity and platform statements +Capacity and platform statements + +This beta has synthetic single-profile workflow evidence. It does not have a published benchmark for concurrent staff capacity, minimum RAM/CPU, large-source limits or a field SLA. Do not turn a developer machine’s specification into a supported minimum. The new installer size remains pending its build; allow additional disk for extracted runtime, database, originals, exports, media and backups. Select equipment/storage after sizing those actual workloads. -This beta has synthetic single-profile workflow evidence. It does not have a published benchmark for concurrent staff capacity, minimum RAM/CPU, large-source limits or a field SLA. Do not turn a developer machine’s specification into a supported minimum. Installer size is 2,092,122,112 bytes before installation; allow additional disk for extracted runtime, database, originals, exports, media and backups. Select equipment/storage after sizing those actual workloads. +The exact runtime payload lock records pinned files, sizes and hashes. The component metadata records shipped dependency declarations. These references are more precise than a manually copied dependency list. Third-party and historical license notices must accompany their matching payloads. -The exact [runtime payload lock](docs/beta-1/reference/runtime-payload-lock.json) records pinned files, sizes and hashes. The [component metadata](docs/beta-1/reference/component-metadata.json) records shipped dependency declarations. These references are more precise than a manually copied dependency list. Third-party and historical license notices must accompany their matching payloads. +Configuration and administration -## Configuration and administration -### Native deployment configuration +Native deployment configuration -Use Setup, Settings and System Health for supported staff operation. Administrators provision folders, backup storage, named accounts and the city profile. Select `inspections-preview` for the full eight-workspace desktop. Station remains a separate service boundary. Do not use a standalone product’s demo server as a substitute for the installed workspace. +Use Setup, Settings and System Health for supported staff operation. Administrators provision folders, backup storage, named accounts and the city profile. Select inspections-preview for the bounded desktop composition, including Access and Notice. Station remains a separate service boundary. Do not use a standalone product’s demo server as a substitute for the installed workspace. -Technical deployments use `TOWNLIGHT_PRODUCT_PROFILE`, `TOWNLIGHT_PROFILE_ROOT`, `DATABASE_URL`, `CIVICSUITE_RUNTIME_PORT`, `PORTAL_MODE` and the runtime-managed secret files. Treat database URLs and native session proofs as secrets. The installed native domain runtime explicitly refuses non-loopback binding. `PORTAL_MODE=private` is the accepted posture; changing it does not by itself commission an internet portal, authentication provider or reverse proxy. +Technical deployments use TOWNLIGHT_PRODUCT_PROFILE, TOWNLIGHT_PROFILE_ROOT, DATABASE_URL, TOWNLIGHT_RUNTIME_PORT, PORTAL_MODE and the runtime-managed secret files. Treat database URLs and native session proofs as secrets. The installed native domain runtime explicitly refuses non-loopback binding. PORTAL_MODE=private is the accepted posture; changing it does not by itself commission an internet portal, authentication provider or reverse proxy. The isolated documentation exporter sets a fictional profile and unusable synthetic database origin only to read schemas; those values are not deployment configuration. Keep deployment values in the intended process/account scope. An already-running process does not automatically inherit later environment edits. -## API and integration examples -### Native command example +API and integration examples -The following JavaScript belongs in the existing trusted Townlight frontend/development environment with `invoke` imported from `@tauri-apps/api/core`. It is not a command for an arbitrary web page or an instruction for nontechnical staff. IDs must come from records created in an isolated synthetic exercise. +Native command example -```javascript -import { invoke } from '@tauri-apps/api/core'; -const result = await invoke('get_app_state', {}); -console.log(result); -``` +The following JavaScript belongs in the existing trusted Townlight frontend/development environment with invoke imported from @tauri-apps/api/core. It is not a command for an arbitrary web page or an instruction for nontechnical staff. IDs must come from records created in an isolated synthetic exercise. -### Trusted local HTTP example + import { invoke } from '@tauri-apps/api/core'; + const result = await invoke('get_app_state', {}); + console.log(result); + +Trusted local HTTP example An administrator/developer can inspect an already-configured isolated runtime from a trusted local process. This PowerShell example reads the signed-in synthetic profile’s existing proof into memory; it does not create a user, seed a session, reveal the proof in output or bypass a permission check. Do not use real city data in development examples. A read response does not prove approval or publication. -```powershell -$profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite' -$sessionPath = Join-Path $profilePath 'config\local-session.json' -$session = Get-Content -LiteralPath $sessionPath -Raw | ConvertFrom-Json -$headers = @{ 'X-Townlight-Session' = $session.session_hash } -Invoke-RestMethod -Uri 'http://127.0.0.1:15480/desktop/v1/suite/state' -Headers $headers -Remove-Variable session, headers -``` + $profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite' + $sessionPath = Join-Path $profilePath 'config\local-session.json' + $session = Get-Content -LiteralPath $sessionPath -Raw | ConvertFrom-Json + $headers = @{ 'X-Townlight-Session' = $session.session_hash } + Invoke-RestMethod -Uri 'http://127.0.0.1:15480/desktop/v1/suite/state' -Headers $headers + Remove-Variable session, headers -### A synthetic write with subsequent readback +A synthetic write with subsequent readback This example demonstrates the existing Meetings HTTP contract in an isolated exercise. It is intentionally fictional. It does not start a service. Its authentication setup is included so it can be run independently under the signed-in synthetic account. If a write times out, inspect current records before repeating it. -```powershell -$profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite' -$sessionPath = Join-Path $profilePath 'config/local-session.json' -$session = Get-Content -LiteralPath $sessionPath -Raw | ConvertFrom-Json -$headers = @{ 'X-Townlight-Session' = $session.session_hash } -$body = @{ - title = 'Synthetic documentation exercise' - scheduled_start = '2026-11-05T18:00:00-07:00' - location = 'Synthetic room' - meeting_type = 'regular' -} | ConvertTo-Json -$meeting = Invoke-RestMethod -Method Post ` - -Uri 'http://127.0.0.1:15480/desktop/v1/meetings/meetings' ` - -Headers $headers -ContentType 'application/json' -Body $body -Invoke-RestMethod ` - -Uri ('http://127.0.0.1:15480/desktop/v1/meetings/meetings/' + $meeting.id) ` - -Headers $headers -Remove-Variable session, headers -``` + $profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite' + $sessionPath = Join-Path $profilePath 'config/local-session.json' + $session = Get-Content -LiteralPath $sessionPath -Raw | ConvertFrom-Json + $headers = @{ 'X-Townlight-Session' = $session.session_hash } + $body = @{ + title = 'Synthetic documentation exercise' + scheduled_start = '2026-11-05T18:00:00-07:00' + location = 'Synthetic room' + meeting_type = 'regular' + } | ConvertTo-Json + $meeting = Invoke-RestMethod -Method Post ` + -Uri 'http://127.0.0.1:15480/desktop/v1/meetings/meetings' ` + -Headers $headers -ContentType 'application/json' -Body $body + Invoke-RestMethod ` + -Uri ('http://127.0.0.1:15480/desktop/v1/meetings/meetings/' + $meeting.id) ` + -Headers $headers + Remove-Variable session, headers This write requires Meetings to be enabled and the signed-in staff role to permit it. It is a cross-suite integration example; for this product’s request models, use the complete technical reference below. -### Complete technical contract +Complete technical contract -Read the [Core API reference](docs/beta-1/api/core.html) for every documented operation, request field, constraint, response declaration and source supplement. Download the [OpenAPI JSON](docs/beta-1/api/core-openapi.json) for tools. For Station this is the suite-side schema only; its separate service contract is documented in the API supplement. The [reference directory](docs/beta-1/reference/index.html) includes configuration/source inventories, dependency declarations, native command contracts, MCP signatures and candidate evidence. +Read the Core API reference for every documented operation, request field, constraint, response declaration and source supplement. Download the OpenAPI JSON for tools. For Station this is the suite-side schema only; its separate service contract is documented in the API supplement. The reference directory includes configuration/source inventories, dependency declarations, native command contracts, MCP signatures and candidate evidence. -## MCP and automation boundary +MCP and automation boundary -No direct product MCP server is exposed by the accepted Townlight desktop or Station boundary. Do not configure an invented `townlight mcp` command or assume an AI client has staff permissions. The integration surfaces for this beta are native IPC, the documented HTTP APIs, source bundle imports, exact exports and the existing Station CLI. +No direct product MCP server is exposed by the accepted Townlight desktop or Station boundary. Do not configure an invented townlight mcp command or assume an AI client has staff permissions. The integration surfaces for this beta are native IPC, the documented HTTP APIs, source bundle imports, exact exports and the existing Station CLI. -The bundled transcription code includes a **TextFlowKit MCP adapter** as a separate source capability. It offers job-based `transcribe_media`, `get_transcript`, `list_jobs`, `get_job_status` and `export_transcript`, and additional tools declared in that adapter. It uses stdio first and optional Streamable HTTP, with the MCP SDK as an optional extra. It is not automatically launched, authenticated as Townlight staff or accepted as a Townlight product MCP deployment. This documentation does not add such a service. +The bundled transcription code includes a TextFlowKit MCP adapter as a separate source capability. It offers job-based transcribe_media, get_transcript, list_jobs, get_job_status and export_transcript, and additional tools declared in that adapter. It uses stdio first and optional Streamable HTTP, with the MCP SDK as an optional extra. It is not automatically launched, authenticated as Townlight staff or accepted as a Townlight product MCP deployment. This documentation does not add such a service. For a transcription client already provisioned separately, an illustrative tool call is: -```json -{"name":"get_job_status","arguments":{"job_id":"synthetic-existing-job-id"}} -``` - -Use a job ID returned by that transcription service. This example does not create a Townlight record or bypass its review/Records handoff. The exact optional adapter tool signatures are supplied in the [MCP source reference](docs/beta-1/reference/mcp.html). Station meeting capture does not become live speech recognition because this optional donor adapter exists. + {"name":"get_job_status","arguments":{"job_id":"synthetic-existing-job-id"}} -## Security and permissions +Use a job ID returned by that transcription service. This example does not create a Townlight record or bypass its review/Records handoff. The exact optional adapter tool signatures are supplied in the MCP source reference. Station meeting capture does not become live speech recognition because this optional donor adapter exists. +Security and permissions Use your own named account and save before leaving a screen. A saved draft is durable; unsaved form text may not be. If a write has an unknown result, reopen its record before repeating it. @@ -313,147 +295,181 @@ The native session is validated and mapped to a persisted SQL identity. An edita Use protected local folders, account permissions and credential storage. Never include the native session file, database passwords, provider keys or unredacted support bundles in a public issue or generated public documentation. A local public view is not automatically a secured internet deployment. Keep network exposure and real equipment acceptance specific to the chosen beta site. -## Backup recovery and maintenance +Backup recovery and maintenance -Save work and use Core’s canonical **Backup Now** before maintenance. That operation stops writers. Preserve the coherent profile/database/document backup and its receipt, then use **Start** to resume. A source export is not a full backup. +Save work and use Core’s canonical Backup Now before maintenance. That operation stops writers. Preserve the coherent profile/database/document backup and its receipt, then use Start to resume. A source export is not a full backup. -Use **Restore Latest Backup** through the supported controls. If the result says **Restore needs service start**, use **Start**, then **Check**, and reopen a known record. Do not repeat restore merely because services need to start. The fresh-profile acceptance verified that a fulfilled request survived restore and a post-backup marker did not. +Use Restore Latest Backup through the supported controls. If the result says Restore needs service start, use Start, then Check, and reopen a known record. Do not repeat restore merely because services need to start. The fresh-profile acceptance verified that a fulfilled request survived restore and a post-backup marker did not. Keep Station’s dedicated database and media evidence together in its own backup. Core’s native-profile backup must not be assumed to include an external Station data directory. Stop writers during a coordinated backup. Preserve failed media attempts and logs. On failure, record the time, selected composition, component/installer versions and exact message. Check System Health for stopped, starting, ready or failed dependencies. Use the existing Retry control after readiness; do not create duplicate business records to refresh a stale view. Share only a redacted diagnostic bundle. Preserve secrets, original evidence, recovery material and unrelated installations. -## Troubleshooting +Troubleshooting + + --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Symptom Likely meaning Next action + ----------------------------- ------------------------------------------------------------------------ -------------------------------------------------------------------------------------------------- + Workspace absent Wrong product composition or unavailable canonical runtime. Check selected composition; activate through Finish Records Migration; wait for readiness. + + Cannot sign in / 401 Missing or expired named account session. Sign in normally; reopen a Station launch ticket if applicable. + + Permission denied / 403 Account, module, source or browser-origin permission. Ask the authorized administrator to inspect the intended permission; do not invent role headers. + + Save conflict / 409 The saved revision, expected source hash or lifecycle changed. Keep edits, reopen current state and reconcile deliberately. + + Invalid input / 422 Required field, format, geometry, source envelope or state is invalid. Read the field detail and correct the input/source; preserve originals. -| Symptom | Likely meaning | Next action | -| --- | --- | --- | -| Workspace absent | Wrong product composition or unavailable canonical runtime. | Check selected composition; activate through Finish Records Migration; wait for readiness. | -| Cannot sign in / 401 | Missing or expired named account session. | Sign in normally; reopen a Station launch ticket if applicable. | -| Permission denied / 403 | Account, module, source or browser-origin permission. | Ask the authorized administrator to inspect the intended permission; do not invent role headers. | -| Save conflict / 409 | The saved revision, expected source hash or lifecycle changed. | Keep edits, reopen current state and reconcile deliberately. | -| Invalid input / 422 | Required field, format, geometry, source envelope or state is invalid. | Read the field detail and correct the input/source; preserve originals. | -| Service unavailable / 503 | Database, schema, connected source or configuration unavailable. | Inspect System Health and the named dependency. Preserve work; retry only after readiness. | -| Export refused | Missing exact review, approval, audience or source authorization. | Read the refusal and complete the owning product’s explicit decision. | -| Restore needs service start | The snapshot was restored but services have not resumed. | Use Start, then Check and verify a saved record; do not blindly repeat restore. | + Service unavailable / 503 Database, schema, connected source or configuration unavailable. Inspect System Health and the named dependency. Preserve work; retry only after readiness. + Export refused Missing exact review, approval, audience or source authorization. Read the refusal and complete the owning product’s explicit decision. -## Verified workflows and limits + Restore needs service start The snapshot was restored but services have not resumed. Use Start, then Check and verify a saved record; do not blindly repeat restore. + --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -| Product | Recorded result | Precisely exercised | -| --- | --- | --- | -| Core | PASS | Normal empty-profile setup; canonical activation; UI-created staff and sign-in; staff denied user administration; coherent backup, mutation, restore, Start/Check and retained/absent record readback. | +Verified workflows and limits + -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Product Recorded result Precisely exercised + ----------------------- ----------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Core PASS Normal empty-profile setup; canonical activation; UI-created staff and sign-in; staff denied user administration; coherent backup, mutation, restore, Start/Check and retained/absent record readback. + + -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- These results come from the identified signed candidate’s fresh normal-profile Sandbox exercise: real native IPC/HTTP/PostgreSQL and selected headless controls. All accounts, source bundles and media were synthetic. The guest install/uninstall and recovery passed, and the owned Sandbox stopped. No host installed application or standalone CivicCast was changed. This documentation task reuses those receipts; it does not claim a new software acceptance run. -The [workflow matrix](docs/beta-1/reference/workflow-matrix.json) identifies raw receipt filenames. The [evidence index](docs/beta-1/reference/sandbox-evidence-index.json) retains their original hashes; raw receipts remain in the private beta handoff rather than being silently republished with the documentation site. +The workflow matrix identifies raw receipt filenames. The evidence index retains their original hashes; raw receipts remain in the private beta handoff rather than being silently republished with the documentation site. The limits remain: actual city field acceptance and equipment/network commissioning; Station automatic provisioning/SCM commissioning; every UI/role combination; field recognition accuracy; and historical in-place upgrades are not certified. They are not five invented feature requirements. Fresh-install controlled beta handoff remains the accepted scope. This package makes no city-deployment, publication or general-availability claim. -## Terms of service and license +Terms of service and license -### Scope and status +Scope and status These terms describe the Townlight Beta 1 software and this documentation package. This is a locally prepared private beta, not a hosted-service subscription, a city deployment agreement or a public release. No uptime commitment, support response time, indemnity, data-processing agreement or paid service is created by these documents. A separate signed agreement, if any, governs services it actually provides. -### Software license and rights +Software license and rights -Current Townlight-owned distributions identified in this candidate use **AGPL-3.0-only**. The full license is supplied with this documentation and with the source companion. The license governs rights to run, copy, modify and convey the covered software; these operational terms do not add restrictions to those rights. Historical grants and dependency licenses retain their own terms. CivicCast remains a separate product and is not relicensed by this documentation work. +Current Townlight-owned distributions identified in this candidate use AGPL-3.0-only. The full license is supplied with this documentation and with the source companion. The license governs rights to run, copy, modify and convey the covered software; these operational terms do not add restrictions to those rights. Historical grants and dependency licenses retain their own terms. CivicCast remains a separate product and is not relicensed by this documentation work. -When conveying covered software, retain applicable notices and provide the corresponding source and installation/build information required by the license. For a modified version supporting remote network interaction, follow section 13’s source-offer requirement. The companion archive identifies the source for this candidate; a link to a different public branch is not a substitute for the matching source. Read the supplied license for the complete conditions. See the [GNU license reference](https://www.gnu.org/licenses/agpl-3.0.html) and [GNU licensing FAQ](https://www.gnu.org/licenses/gpl-faq.en.html). +When conveying covered software, retain applicable notices and provide the corresponding source and installation/build information required by the license. For a modified version supporting remote network interaction, follow section 13’s source-offer requirement. The companion archive identifies the source for this candidate; a link to a different public branch is not a substitute for the matching source. Read the supplied license for the complete conditions. See the GNU license reference and GNU licensing FAQ. -### Data ownership and access +Data ownership and access Importing a document does not transfer its ownership or grant permission to publish it. The operating organization controls its accounts, access decisions, lawful source use, retention and review/release policy. Keep resident information, credentials, private notes and restricted evidence in their authorized locations. Documentation examples contain fictional data. No real city account, credential or record is required to exercise these examples in an isolated test environment. -### Local operation and external processors +Local operation and external processors The accepted beta workflow is local and uses named staff accounts. Station has separate storage and credentials. Configure backup destinations and optional model/network providers deliberately. A configured external provider may receive submitted prompts, images or audio according to that configuration and provider’s terms; this documentation does not promise that every optional configuration is offline. An email outbox or local public view does not establish external delivery or an internet deployment. This static documentation site has no analytics, account collection or remote font dependency. -### Staff decisions and source applicability +Staff decisions and source applicability Staff verify the jurisdiction, source currency, permissions, citations and proposed audience. Model output and generated guidance require review. No draft is automatically an official legal interpretation, zoning determination, permit approval, fee assessment, enforcement notice or records-release decision. Official permit fee authority remains with the adopted source and responsible organization; imported amounts do not become a new authoritative calculation. -### Beta operation and recovery +Beta operation and recovery Use the identified candidate in its supported fresh-install scope. Preserve backups and original evidence. Test physical equipment and chosen network/service configuration before relying on them. The supplied acceptance describes selected synthetic workflows, not every screen, vendor, field condition or upgrade. Operators decide whether a particular deployment meets their own operational obligations. -### Warranty and liability +Warranty and liability The covered software’s warranty and liability conditions are those in sections 15–17 of the supplied AGPL and any applicable separate written undertaking. This documentation creates no additional warranty or limitation beyond those terms. Third-party software is subject to its retained license notices. Nothing here removes rights that applicable law makes nonwaivable. -### Support and incident reporting +Support and incident reporting Use the project’s existing SUPPORT and SECURITY guidance for its matching repository. Report reproducible behavior with the version, operation and redacted logs. Do not put credentials, resident records or unredacted evidence in a public issue. Coordinate sensitive reports through the channel designated in SECURITY. No new support address or service commitment is invented here. -### Ending a beta exercise and document changes +Ending a beta exercise and document changes When an organization ends testing, it controls retention/export and removes access according to its policy. Uninstall may retain data; back up and inspect the selected removal options. Ending an exercise does not revoke rights already granted by AGPL. Later software/documentation versions must identify their changed candidate and scope; historical receipts retain their original identities. These terms do not claim that a city has accepted a contract merely by reading a manual. -## Glossary - -| Term | Meaning | -| --- | --- | -| Approval | An explicit authorized decision on the saved text/artifact. It is separate from saving or attachment. | -| Canonical record | The owning product’s retained identity and saved version, rather than an editable copied label. | -| Composition | The selected set of desktop modules; inspections-preview exposes the eight staff products. | -| Corresponding source | The source/build material matching the delivered covered program, subject to its license. | -| Derivative / Records copy | A separately prepared document with its own intended audience and hash. | -| Hash / SHA256 | A fingerprint of exact bytes. It detects change; it does not establish legal authority. | -| Idempotency | Repeating the same identified request has the same intended effect; changing its payload can be refused. | -| IPC | The native desktop command boundary between its browser interface and Rust host. | -| MCP | Model Context Protocol; no direct Townlight product server is enabled by this beta. | -| Original | Retained source bytes. A reviewed derivative does not replace them. | -| Provenance | Source, version, date, actor and relationship information retained with evidence. | -| Revision | An immutable saved version. Later edits do not inherit an earlier review automatically. | -| Snapshot | A fixed audience-specific copy tied to a source/reviewed revision. | -| Station | Townlight’s separate media boundary using a pinned CivicCast-derived engine; standalone CivicCast remains separate. | - - -## Alphabetical subject index - -- **Accounts and authentication** — [Security and permissions](#security-and-permissions). -- **AGPL and source** — [Terms of service and license](#terms-of-service-and-license). -- **API contracts** — [API and integration examples](#api-and-integration-examples). -- **Architecture** — [Architecture](#architecture). -- **Backup** — [Backup recovery and maintenance](#backup-recovery-and-maintenance). -- **Beta version** — [Beta identity](#beta-identity). -- **Configuration** — [Configuration and administration](#configuration-and-administration). -- **Evidence and acceptance** — [Verified workflows and limits](#verified-workflows-and-limits). -- **Fees and official decisions** — [Terms of service and license](#terms-of-service-and-license). -- **First run** — [First run](#first-run). -- **Handoffs and audience** — [Connected workflows](#connected-workflows). -- **MCP** — [MCP and automation boundary](#mcp-and-automation-boundary). -- **Originals and provenance** — [Security and permissions](#security-and-permissions). -- **Recovery** — [Backup recovery and maintenance](#backup-recovery-and-maintenance). -- **Staff procedures** — [Daily workflow](#daily-workflow). -- **Station configuration** — [Configuration and administration](#configuration-and-administration). -- **Technical stack** — [Technical specifications](#technical-specifications). -- **Troubleshooting** — [Troubleshooting](#troubleshooting). - -### Operating subject links - -- **Catalog import and readback** — [Catalog import and readback](#catalog-import-and-readback). -- **Jurisdictional rule evaluation and review** — [Jurisdictional rule evaluation and review](#jurisdictional-rule-evaluation-and-review). -- **Scaffold plan and generate** — [Scaffold plan and generate](#scaffold-plan-and-generate). -- **Shared catalog rules and scaffolding** — [Shared catalog rules and scaffolding](#shared-catalog-rules-and-scaffolding). - -## Source and document control +Glossary + + --------------------------------------------------------------------------------------------------------------------------------------------------------- + Term Meaning + ----------------------------------- --------------------------------------------------------------------------------------------------------------------- + Approval An explicit authorized decision on the saved text/artifact. It is separate from saving or attachment. + + Canonical record The owning product’s retained identity and saved version, rather than an editable copied label. + + Composition The selected set of desktop modules; inspections-preview exposes the eight staff products. + + Corresponding source The source/build material matching the delivered covered program, subject to its license. + + Derivative / Records copy A separately prepared document with its own intended audience and hash. + + Hash / SHA256 A fingerprint of exact bytes. It detects change; it does not establish legal authority. + + Idempotency Repeating the same identified request has the same intended effect; changing its payload can be refused. + + IPC The native desktop command boundary between its browser interface and Rust host. + + MCP Model Context Protocol; no direct Townlight product server is enabled by this beta. + + Original Retained source bytes. A reviewed derivative does not replace them. + + Provenance Source, version, date, actor and relationship information retained with evidence. + + Revision An immutable saved version. Later edits do not inherit an earlier review automatically. + + Snapshot A fixed audience-specific copy tied to a source/reviewed revision. + + Station Townlight’s separate media boundary using a pinned CivicCast-derived engine; standalone CivicCast remains separate. + --------------------------------------------------------------------------------------------------------------------------------------------------------- + +Alphabetical subject index + +- Accounts and authentication — Security and permissions. +- AGPL and source — Terms of service and license. +- API contracts — API and integration examples. +- Architecture — Architecture. +- Backup — Backup recovery and maintenance. +- Beta version — Beta identity. +- Configuration — Configuration and administration. +- Evidence and acceptance — Verified workflows and limits. +- Fees and official decisions — Terms of service and license. +- First run — First run. +- Handoffs and audience — Connected workflows. +- MCP — MCP and automation boundary. +- Originals and provenance — Security and permissions. +- Recovery — Backup recovery and maintenance. +- Staff procedures — Daily workflow. +- Station configuration — Configuration and administration. +- Technical stack — Technical specifications. +- Troubleshooting — Troubleshooting. + +Operating subject links + +- Catalog import and readback — Catalog import and readback. +- Jurisdictional rule evaluation and review — Jurisdictional rule evaluation and review. +- Scaffold plan and generate — Scaffold plan and generate. +- Shared catalog rules and scaffolding — Shared catalog rules and scaffolding. + +Source and document control This edition is authored from the immutable corresponding-source companion, the generated installed-domain schema and the retained workflow receipts. The current software versions and signed artifacts are unchanged. Public historical pages are not synchronized or published by this local documentation task. -### Workflow subject index - -- **Activate the runtime** — [Daily workflow, step 2](#workflow-2). -- **Collect diagnostics** — [Daily workflow, step 7](#workflow-7). -- **Complete setup** — [Daily workflow, step 1](#workflow-1). -- **Create staff access** — [Daily workflow, step 3](#workflow-3). -- **Import through the right product** — [Daily workflow, step 4](#workflow-4). -- **Make a coherent backup** — [Daily workflow, step 5](#workflow-5). -- **Restore and verify** — [Daily workflow, step 6](#workflow-6). - -- [Source inventory and file hashes](docs/beta-1/reference/source-inventory.json) -- [All component metadata](docs/beta-1/reference/component-metadata.json) -- [Installed domain OpenAPI](docs/beta-1/reference/desktop-domain-openapi.json) -- [Workflow matrix](docs/beta-1/reference/workflow-matrix.json) -- [Full AGPL text](docs/beta-1/reference/AGPL-3.0.txt) +Workflow subject index + +- Activate the runtime — Daily workflow, step 2. + +- Collect diagnostics — Daily workflow, step 7. + +- Complete setup — Daily workflow, step 1. + +- Create staff access — Daily workflow, step 3. + +- Import through the right product — Daily workflow, step 4. + +- Make a coherent backup — Daily workflow, step 5. + +- Restore and verify — Daily workflow, step 6. + +- Source inventory and file hashes + +- All component metadata + +- Installed domain OpenAPI + +- Workflow matrix + +- Full AGPL text diff --git a/civiccore/db/__init__.py b/civiccore/db/__init__.py deleted file mode 100644 index e1a14c7..0000000 --- a/civiccore/db/__init__.py +++ /dev/null @@ -1,18 +0,0 @@ -""" -Shared SQLAlchemy declarative base for all civiccore ORM models. - -All ORM models in civiccore (and downstream consumers such as civicrecords-ai) -should inherit from this ``Base`` class so that metadata is shared across the -same declarative registry. In Phase 2 Step 5, civicrecords-ai will migrate its -own models to import and inherit from this Base rather than maintaining a -separate one. -""" - -from sqlalchemy.orm import DeclarativeBase - - -class Base(DeclarativeBase): - """Shared declarative base for all civiccore ORM models.""" - - -__all__ = ["Base"] diff --git a/civiccore/migrations/__init__.py b/civiccore/migrations/__init__.py deleted file mode 100644 index 73fc7aa..0000000 --- a/civiccore/migrations/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""CivicCore: Alembic migrations for shared tables. Run by every consuming module's migration runner BEFORE that module's own migrations. See env.py for the migration-ordering contract from CivicCore Extraction Spec section 14.""" diff --git a/civiccore/migrations/alembic.ini b/civiccore/migrations/alembic.ini deleted file mode 100644 index 0656e11..0000000 --- a/civiccore/migrations/alembic.ini +++ /dev/null @@ -1,3 +0,0 @@ -[alembic] -script_location = %(here)s -version_table = alembic_version_civiccore diff --git a/civiccore/migrations/versions/civiccore_0005_job_leases.py b/civiccore/migrations/versions/civiccore_0005_job_leases.py deleted file mode 100644 index 02b43c7..0000000 --- a/civiccore/migrations/versions/civiccore_0005_job_leases.py +++ /dev/null @@ -1,26 +0,0 @@ -# SPDX-License-Identifier: AGPL-3.0-only -"""Fenced worker leases on the existing shared queue; no second job store.""" - -from alembic import op - -revision = "civiccore_0005_job_leases" -down_revision = "civiccore_0004_catalog" -branch_labels = None -depends_on = None - - -def upgrade(): - op.execute("ALTER TABLE civiccore_local_tasks ADD COLUMN IF NOT EXISTS claim_token varchar(64)") - op.execute( - "ALTER TABLE civiccore_local_tasks ADD COLUMN IF NOT EXISTS lease_expires_at timestamptz" - ) - op.execute( - "ALTER TABLE civiccore_local_tasks ADD COLUMN IF NOT EXISTS cancelled_by varchar(128)" - ) - op.execute( - "CREATE INDEX IF NOT EXISTS ix_civiccore_local_tasks_lease ON civiccore_local_tasks (status,lease_expires_at)" - ) - - -def downgrade(): - pass # Preserve jobs and cancellation history; restore a coherent backup. diff --git a/cleanroom/civiccore.Dockerfile b/cleanroom/townlight_core.Dockerfile similarity index 57% rename from cleanroom/civiccore.Dockerfile rename to cleanroom/townlight_core.Dockerfile index 43f9048..eb40e30 100644 --- a/cleanroom/civiccore.Dockerfile +++ b/cleanroom/townlight_core.Dockerfile @@ -2,17 +2,17 @@ FROM --platform=linux/amd64 python:3.13-slim-bookworm@sha256:bb73517d48bd32016e15eade0c009b2724ec3a025a9975b5cd9b251d0dcadb33 -ARG CIVICCORE_REPO_URL=https://github.com/CivicSuite/civiccore.git -ARG CIVICCORE_COMMIT +ARG TOWNLIGHT_CORE_REPO_URL=https://github.com/townlight/core.git +ARG TOWNLIGHT_CORE_COMMIT ARG COSIGN_VERSION=v3.0.6 ARG COSIGN_SHA256=c956e5dfcac53d52bcf058360d579472f0c1d2d9b69f55209e256fe7783f4c74 -LABEL org.opencontainers.image.title="CivicCore CO-6 cleanroom harness" -LABEL org.opencontainers.image.description="Pinned cleanroom image for CivicCore release and provenance verification." +LABEL org.opencontainers.image.title="Townlight Core CO-6 cleanroom harness" +LABEL org.opencontainers.image.description="Pinned cleanroom image for Townlight Core release and provenance verification." SHELL ["/bin/bash", "-o", "pipefail", "-c"] -RUN test -n "${CIVICCORE_COMMIT}" +RUN test -n "${TOWNLIGHT_CORE_COMMIT}" RUN apt-get update \ && apt-get install -y --no-install-recommends \ @@ -33,26 +33,26 @@ RUN curl -fsSL \ && chmod 0755 /usr/local/bin/cosign \ && cosign version -RUN git clone --filter=blob:none "${CIVICCORE_REPO_URL}" /workspace/civiccore \ - && cd /workspace/civiccore \ - && git fetch --depth 1 origin "${CIVICCORE_COMMIT}" \ - && git checkout --detach "${CIVICCORE_COMMIT}" \ - && test "$(git rev-parse HEAD)" = "${CIVICCORE_COMMIT}" +RUN git clone --filter=blob:none "${TOWNLIGHT_CORE_REPO_URL}" /workspace/townlight_core \ + && cd /workspace/townlight_core \ + && git fetch --depth 1 origin "${TOWNLIGHT_CORE_COMMIT}" \ + && git checkout --detach "${TOWNLIGHT_CORE_COMMIT}" \ + && test "$(git rev-parse HEAD)" = "${TOWNLIGHT_CORE_COMMIT}" -WORKDIR /workspace/civiccore +WORKDIR /workspace/townlight_core RUN python -m pip install --upgrade pip \ && python -m pip install -e .[dev] -COPY scripts/cleanroom/civiccore-cleanroom-runner.sh /usr/local/bin/civiccore-cleanroom-runner -RUN chmod 0755 /usr/local/bin/civiccore-cleanroom-runner +COPY scripts/cleanroom/townlight_core-cleanroom-runner.sh /usr/local/bin/townlight_core-cleanroom-runner +RUN chmod 0755 /usr/local/bin/townlight_core-cleanroom-runner -ENV CIVICCORE_REPO_URL="${CIVICCORE_REPO_URL}" -ENV CIVICCORE_COMMIT="${CIVICCORE_COMMIT}" +ENV TOWNLIGHT_CORE_REPO_URL="${TOWNLIGHT_CORE_REPO_URL}" +ENV TOWNLIGHT_CORE_COMMIT="${TOWNLIGHT_CORE_COMMIT}" ENV CLEANROOM_BASE_IMAGE="python:3.13-slim-bookworm" ENV CLEANROOM_BASE_IMAGE_DIGEST="sha256:bb73517d48bd32016e15eade0c009b2724ec3a025a9975b5cd9b251d0dcadb33" ENV CLEANROOM_COSIGN_VERSION="${COSIGN_VERSION}" ENV CLEANROOM_COSIGN_SHA256="${COSIGN_SHA256}" -ENTRYPOINT ["civiccore-cleanroom-runner"] +ENTRYPOINT ["townlight_core-cleanroom-runner"] CMD ["online"] diff --git a/docs/SUPERVISOR.md b/docs/SUPERVISOR.md index f0be06b..74d6212 100644 --- a/docs/SUPERVISOR.md +++ b/docs/SUPERVISOR.md @@ -1,14 +1,14 @@ -# CivicCore Supervisor Card +# Townlight Core Supervisor Card One-page operating card for Scott. Keep this open when you supervise a session. Everything here is grounded in what actually exists in this repo today. Current state at the time this card was written: - Branch: `docs/phase2-closeout-standardization` (Phase 1 complete, Phase 2 closeout / standardization in flight) -- Version: `civiccore 0.2.0` (pyproject.toml + civiccore/__init__.py agree) +- Version: `townlight_core 0.2.0` (pyproject.toml + townlight_core/__init__.py agree) - Rule 11 hook wired locally in `.claude/hooks/` (untracked in git after 6fb2c6f) -- civiccore is the validation project for Hard Rule 11 (Commit-Size Acknowledgment Gate) +- townlight_core is the validation project for Hard Rule 11 (Commit-Size Acknowledgment Gate) --- @@ -16,7 +16,7 @@ Current state at the time this card was written: Skim in this order, top-down: -1. `README.md` — Status section tells you what phase CivicCore is in today. +1. `README.md` — Status section tells you what phase Townlight Core is in today. 2. `CHANGELOG.md` — look at `## [Unreleased]` to see what's accumulated since last tag. 3. `git log --oneline -10` — last 10 commits, note the current branch. 4. `docs/` — this card plus `index.html` (landing page); nothing else should live here yet. @@ -32,7 +32,7 @@ Five things, in order of how often you'll need them: 1. **Run the tests** — from repo root: `pytest` (configured in pyproject.toml `[tool.pytest.ini_options]`, `testpaths = ["tests"]`, asyncio mode auto). Current suite: `tests/test_smoke.py`, `tests/test_baseline_idempotency.py`. Any logic change must either update these or add a new test. 2. **Lint + type check** — `ruff check .` (configured, `target-version = py311`, `line-length = 100`). No mypy in pyproject today; don't let the agent pretend there is. -3. **Verify before push** — there's no `verify-release.sh` yet; `scripts/verify/` exists as a directory placeholder. When the agent says "ran verify", ask which command. Until the script is written, manual pre-push is: tests green + ruff clean + CHANGELOG updated + version consistent (pyproject.toml line 7, civiccore/__init__.py line 13). +3. **Verify before push** — there's no `verify-release.sh` yet; `scripts/verify/` exists as a directory placeholder. When the agent says "ran verify", ask which command. Until the script is written, manual pre-push is: tests green + ruff clean + CHANGELOG updated + version consistent (pyproject.toml line 7, townlight_core/__init__.py line 13). 4. **Watch Rule 11 behavior** — this project's job is to validate the gate. Every time the agent runs a `git commit` via Bash, the PreToolUse hook (`.claude/hooks/commit-size-gate.sh` → `.py`, THRESHOLD=800) fires. Expected behavior: - <800 staged lines → silent pass - ≥800 staged lines with a literal bracketed tag (`[MVP]`, `[LARGE-CHANGE]`, `[REFACTOR]`, `[INITIAL]`, `[MERGE]`, `[REVERT]`, `[SCOPE-EXPANSION: reason]`) → pass @@ -40,7 +40,7 @@ Five things, in order of how often you'll need them: - `--amend`, `-F`, editor commits → fail-open (bypass). This is intentional. - You say the literal phrase `override rule 11` → 60-second one-shot bypass. If you see a false positive (small commit blocked, or tag-present commit blocked), that's the bug you're hunting. Save the stderr output. -5. **Keep civiccore and civiccore-ui aligned** — if a schema, token, or shell component changes in `civiccore/` (models, auth, catalog) or `civiccore-ui/` (components, shell, tokens), make sure the agent touches both sides in the same commit. Extraction-in-sync was the Phase 1 contract and still applies through Phase 2 closeout. +5. **Keep townlight_core and townlight_core-ui aligned** — if a schema, token, or shell component changes in `townlight_core/` (models, auth, catalog) or `townlight_core-ui/` (components, shell, tokens), make sure the agent touches both sides in the same commit. Extraction-in-sync was the Phase 1 contract and still applies through Phase 2 closeout. --- @@ -71,13 +71,13 @@ See `coder-ui-qa-test` skill. ## 5. Good session ending — project-specific checklist -A session on civiccore is done when all of these are true: +A session on townlight_core is done when all of these are true: - `pytest` green from repo root (no skips, no xfails added). - `ruff check .` clean. -- Version matches across `pyproject.toml` (line 7) and `civiccore/__init__.py` (line 13). Bump both together or neither. +- Version matches across `pyproject.toml` (line 7) and `townlight_core/__init__.py` (line 13). Bump both together or neither. - `CHANGELOG.md` `## [Unreleased]` has an entry for every user-visible change made this session. - No false-positive Rule 11 blocks during the session. If the gate blocked a commit, one of three things is true and you can say which: (a) the commit genuinely was ≥800 lines and deserved a tag, (b) it was a known bypass surface, (c) it's a bug and you've captured stderr + the staged diff size for the post-mortem. -- If the session touched anything in both `civiccore/` and `civiccore-ui/`, the two sides agree — shared schemas, tokens, or interfaces are in sync. Extraction-in-sync remains the contract through Phase 2 closeout; drift between core and UI is a regression. +- If the session touched anything in both `townlight_core/` and `townlight_core-ui/`, the two sides agree — shared schemas, tokens, or interfaces are in sync. Extraction-in-sync remains the contract through Phase 2 closeout; drift between core and UI is a regression. - Branch is still `docs/phase2-closeout-standardization` (or a child of it) unless we explicitly cut a new one. No surprise branch moves. - No files created outside scope: no `tasks.md`, no `lessons-learned.md`, no `handoff.md`, no `tests/uat/`, no `private/`, no new hook scripts. If the agent wrote any of those, delete them before closing. diff --git a/docs/adr/index.md b/docs/adr/index.md index 9ca5c81..f5b1ed5 100644 --- a/docs/adr/index.md +++ b/docs/adr/index.md @@ -1,20 +1,27 @@ -# CivicCore Architecture Decision Records +# Townlight Core Architecture Decision Records -CivicCore ADRs record module-scoped platform decisions. Cross-module decisions -that bind more than one repository remain in the umbrella `CivicSuite` +Townlight Core ADRs record module-scoped platform decisions. Cross-module decisions +that bind more than one repository remain in the umbrella `Townlight` architecture ADR index. ## Placeholder Namespace Deferrals -These CO-7 ADRs define the placeholder namespace boundary for the freeze line: +These historical CO-7 ADRs define the placeholder namespace boundary for their +original freeze line. They retain their original text and identities. Current +catalog, exemption and scaffold implementations are described by ADR-0004 +through ADR-0010 and their owning source/tests; this index is not a current +blanket deferral. -- [ADR-0001: Defer `civiccore.catalog`](ADR-0001-defer-civiccore-catalog.md) -- [ADR-0002: Defer `civiccore.exemptions`](ADR-0002-defer-civiccore-exemptions.md) -- [ADR-0003: Defer `civiccore.scaffold`](ADR-0003-defer-civiccore-scaffold.md) +The current principal namespaces are `townlight_core.catalog`, +`townlight_core.exemptions` and `townlight_core.scaffold`. + +- [ADR-0001: Historical catalog deferral](ADR-0001-defer-civiccore-catalog.md) +- [ADR-0002: Historical exemptions deferral](ADR-0002-defer-civiccore-exemptions.md) +- [ADR-0003: Historical scaffold deferral](ADR-0003-defer-civiccore-scaffold.md) Rule: no downstream module may import, foreign-key to, document as required, or otherwise depend on a placeholder namespace until that namespace ships in a -versioned CivicCore release artifact and the downstream compatibility matrix is +versioned Townlight Core release artifact and the downstream compatibility matrix is updated to name that release. - [ADR-0004: Beta shared catalog extraction](ADR-0004-beta-shared-catalog.md) partially supersedes ADR-0001 in the private candidate; broader inventory remains open. @@ -27,6 +34,6 @@ updated to name that release. - [ADR-0008: Beta installed-module inventory and recommendations](ADR-0008-beta-module-inventory.md) partially supersedes ADR-0001/ADR-0004 for the tested persisted, scoped module inventory and its deterministic recommendations. It reuses the shipped `build_module_registry` rather than adding a resolver, records only caller-declared installs, and keeps the municipal systems catalog distinct. Per-city module commissioning, installer/umbrella registration, artifact proof and consumer wiring remain open. -- [ADR-0009: Department-scoped shared authority](ADR-0009-department-scoped-authority.md) adds the deny-by-default department/tenant authorization contract around the shipped auth, search, export and model-context helpers: a department claim is admissible only from the persisted `civiccore_department_grant_events` ledger, roles are intersected rather than unioned, revocation is an appended event, and no credential verifier, route or second permission engine is added. A Core HTTP/CLI surface, per-city department commissioning, role-to-job-function mapping and consumer wiring remain open. +- [ADR-0009: Department-scoped shared authority](ADR-0009-department-scoped-authority.md) adds the deny-by-default department/tenant authorization contract around the shipped auth, search, export and model-context helpers: a department claim is admissible only from the persisted `townlight_core_department_grant_events` ledger, roles are intersected rather than unioned, revocation is an appended event, and no credential verifier, route or second permission engine is added. A Core HTTP/CLI surface, per-city department commissioning, role-to-job-function mapping and consumer wiring remain open. -- [ADR-0010: Claim-bound acceptance of ingest and media artifacts](ADR-0010-claim-bound-artifacts.md) adds one adapter (`civiccore.tasks.artifacts`, migration `civiccore_0009_job_artifacts`) that binds a derived artifact to the producing job identity and its still-active claim, publishes it only inside a configured store root with a re-verified sha256, and records an attributed, append-only receipt. It adds no transcription, OCR, transcoding, embedding, provider call or second job engine; consumer wiring, large-original storage and retention/redaction workflows remain open. +- [ADR-0010: Claim-bound acceptance of ingest and media artifacts](ADR-0010-claim-bound-artifacts.md) adds one adapter (`townlight_core.tasks.artifacts`, migration `townlight_core_0009_job_artifacts`) that binds a derived artifact to the producing job identity and its still-active claim, publishes it only inside a configured store root with a re-verified sha256, and records an attributed, append-only receipt. It adds no transcription, OCR, transcoding, embedding, provider call or second job engine; consumer wiring, large-original storage and retention/redaction workflows remain open. diff --git a/docs/beta-1/api/core.html b/docs/beta-1/api/core.html index c05e38e..a2d38aa 100644 --- a/docs/beta-1/api/core.html +++ b/docs/beta-1/api/core.html @@ -1937,7 +1937,7 @@

Source route and href="../reference/source-inventory.json">source inventory.

router.py

Candidate source: -installed-owned-source/civiccore/llm/registry/router.py.

+installed-owned-source/townlight_core/llm/registry/router.py.

GET /admin/models — handler list_models, line 46. Declared router prefix included.

router.py

HTTPException(status_code=404, detail=f'Model {model_id} not found').

services.py

Candidate source: -installed-owned-source/civicsuite_runtime/services.py.

+installed-owned-source/townlight_runtime/services.py.

GET /health — handler runtime_health, line 439. Declared router prefix included.

diff --git a/docs/beta-1/docx/Townlight-Core-Manual-Beta-1.docx b/docs/beta-1/docx/Townlight-Core-Manual-Beta-1.docx index 1d8bb2a2bc3ed017fe69a9e85ef5e3ee716af35a..529355c956570ac4ba0d5e0bb3c3e22a53154604 100644 GIT binary patch delta 26779 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

qen;_D4C{^BGb`@)p^jEjiI5ZPCXr?c!Dn$yK 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 SVTJzo8GQflU3bere*Hg2_5xl2 diff --git a/docs/beta-1/index.html b/docs/beta-1/index.html index 9f44791..ee41f73 100644 --- a/docs/beta-1/index.html +++ b/docs/beta-1/index.html @@ -1 +1 @@ -Townlight Core | Townlight Beta 1

townlightTownlight Beta 1
Townlight Core · Townlight Beta 1

A shared foundation for accountable municipal work.

Core provides the shared contracts, ingestion, identity helpers, task infrastructure and recovery foundation used by Townlight. Staff encounter these capabilities through Setup, Settings and System Health. Business decisions stay with their owning product.

civiccore 1.3.0.dev1AGPL-3.0-onlyPrivate beta · Windows fresh-install scope
For IT administrators and platform maintainers

What the workflow delivers

  1. Complete setup. Choose folders and the full product composition. Create the city profile and the first named administrator. Choose a protected backup location. Defer optional local AI if it is not needed.
  2. Activate the runtime. Run the first-run health check, wait for readiness and open Townlight. In System Health select Finish Records Migration to activate the canonical Python and PostgreSQL services. A running process alone is not a ready database.
  3. Create staff access. Use Settings to create named staff. Sign out and confirm that staff can sign in with their own account. Keep administrator privileges with people responsible for setup; ordinary staff cannot administer users.
  4. Import through the right product. Use the source library of Code, Zoning, Planning or Permitting. Inspect provenance and permissions there. Core ingestion helpers do not bypass the owning product’s source review.

Connected evidence

All products use selected Core contracts. Core does not create unrestricted access between products. Notice and Access are supporting components, rather than additional products in this nine-product beta.

Know the beta boundary

Shared catalog, exemption and module-generator code exists in this private candidate. It is not a centrally hosted federation service. A business product still owns its decisions, identity mapping and permission checks. Historical placeholder ADRs are retained as history, rather than descriptions of the current implementation.

Architecture

Where the evidence goes

Townlight Core architecture and evidence flow

All products use selected Core contracts. Core does not create unrestricted access between products. Notice and Access are supporting components, rather than additional products in this nine-product beta.

Evidence rather than promises

Selected staff workflows passed.

The signed private candidate passed normal first-run and selected synthetic workflows in a fresh Windows Sandbox profile. This is not a claim that every screen, vendor, upgrade or city equipment configuration has been certified.

Read the exact acceptance and limits →

Ready to evaluate?

Begin with the manual and the identified private candidate from the beta coordinator. Configure the chosen test site and have its staff review source applicability and run the existing workflows.

\ No newline at end of file +Townlight Core | Townlight Beta 1
townlightTownlight Beta 1
Townlight Core · Townlight Beta 1

A shared foundation for accountable municipal work.

Core provides the shared contracts, ingestion, identity helpers, task infrastructure and recovery foundation used by Townlight. Staff encounter these capabilities through Setup, Settings and System Health. Business decisions stay with their owning product.

townlight-core 1.3.0.dev2AGPL-3.0-onlyPrivate beta · Windows fresh-install scope
For IT administrators and platform maintainers

What the workflow delivers

  1. Complete setup. Choose folders and the full product composition. Create the city profile and the first named administrator. Choose a protected backup location. Defer optional local AI if it is not needed.
  2. Activate the runtime. Run the first-run health check, wait for readiness and open Townlight. In System Health select Finish Records Migration to activate the canonical Python and PostgreSQL services. A running process alone is not a ready database.
  3. Create staff access. Use Settings to create named staff. Sign out and confirm that staff can sign in with their own account. Keep administrator privileges with people responsible for setup; ordinary staff cannot administer users.
  4. Import through the right product. Use the source library of Code, Zoning, Planning or Permitting. Inspect provenance and permissions there. Core ingestion helpers do not bypass the owning product’s source review.

Connected evidence

All products use selected Core contracts. Core does not create unrestricted access between products. Access and Notice provide the bounded staff workflows described in their current manuals; installed acceptance remains pending.

Know the beta boundary

Shared catalog, exemption and module-generator code exists in this private candidate. It is not a centrally hosted federation service. A business product still owns its decisions, identity mapping and permission checks. Historical placeholder ADRs are retained as history, rather than descriptions of the current implementation.

Architecture

Where the evidence goes

Townlight Core architecture and evidence flow

All products use selected Core contracts. Core does not create unrestricted access between products. Access and Notice provide the bounded staff workflows described in their current manuals; installed acceptance remains pending.

Evidence rather than promises

Candidate installed acceptance remains pending.

Earlier releases have their own first-run and synthetic Windows Sandbox evidence. This changed source candidate requires a new signed installer and installed acceptance. This is not a claim that every screen, vendor, upgrade or city equipment configuration has been certified.

Read the exact acceptance and limits →

Ready to evaluate?

Begin with the current manual; obtain this candidate only after its exact installer and acceptance are identified. Configure the chosen test site and have its staff review source applicability and run the existing workflows.

\ No newline at end of file diff --git a/docs/beta-1/manuals/core.html b/docs/beta-1/manuals/core.html index 9c9bde7..750bc48 100644 --- a/docs/beta-1/manuals/core.html +++ b/docs/beta-1/manuals/core.html @@ -1,5 +1,6 @@ -Townlight -Core Manual | Townlight Beta 1
townlightTownlight Beta 1
-
Townlight Beta 1

Townlight -Core -Manual

Staff guide and technical reference

Documentation edition 30 October 2026
Existing component versions retained
Signed suite installer 1.6.0.1
Private beta documentation companion

Using -this manual

-

Townlight Core helps IT administrators and platform maintainers. Core -provides the shared contracts, ingestion, identity helpers, task -infrastructure and recovery foundation used by Townlight. Staff -encounter these capabilities through Setup, Settings and System Health. -Business decisions stay with their owning product.

-

Staff should begin with First run and Daily workflow. Administrators -should also read Architecture, Technical specifications, Configuration, -Security and Recovery. Developers should use the exact API/data -dictionary and examples. The table of contents and alphabetical subject -index link to the relevant sections in the HTML edition; the PDF -preserves headings and searchable text. An editable Word edition is -included with the same documentation companion.

-

Beta identity

- ---- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IdentityValue
Public documentation identityTownlight Beta 1
Installer version1.6.0.1
Product componentciviccore 1.3.0.dev1
Native desktop source version1.6.0-1
Candidate MSI SHA25698bcdef11ebdf5c767f620c904ff49f85115fde3b5c23f62703b111e645aaf86
Corresponding-source SHA25684a23e1297e42d17b16cfc9e51b2dd78bc46414c0de8ad7ebd2466c1a409d06b
Current owned software licenseAGPL-3.0-only
Supported acceptance profileWindows x64 fresh install; inspections-preview; separate Station -configuration
-

“Townlight Beta 1” identifies this coordinated beta delivery. It does -not renumber the installer, native binary, Python packages or historical -receipts. Component versions may differ. This documentation is a later -companion to unchanged signed bytes, not a rebuilt installer. Historical -release pages and manuals describe their own versions and are not the -download instructions for this private candidate.

-

First run

-
    -
  1. Obtain the identified signed private candidate and its -corresponding-source companion from the beta coordinator. The landing -pages in this documentation are not an installer download service.
  2. -
  3. On the intended fresh Windows test installation, verify the MSI hash -and publisher signature before installing. Preserve unrelated profiles -and recovery material. This candidate has fresh-install acceptance; -historical in-place upgrades are unverified.
  4. -
  5. Launch Townlight under the intended named Windows account. Choose -the storage folders. Select Townlight Inspections -candidate (inspections-preview) for all eight -desktop products. A narrower default selection will not expose all -workspaces.
  6. -
  7. Enter the city profile, time zone and contacts. Create the first -named local administrator, sign in and choose protected backup storage. -Continue without local AI is valid for the -deterministic workflows.
  8. -
  9. Run Health Check and wait for readiness. Open Townlight. In System -Health select Finish Records Migration to activate the -canonical Python/PostgreSQL runtime. Do not fabricate migration receipts -or seed accounts.
  10. -
  11. Create named staff through Settings. Import authorized sources using -each product’s source library. All examples in this package are -synthetic; they are not municipal authority.
  12. -
  13. Provision Station separately if it is part of the beta exercise. -Selecting the desktop composition does not start or configure Station. -Configure vision explicitly only if automatic photo drafting is -selected.
  14. -
-

Daily workflow

-

1. Complete setup

-

Choose folders and the full product composition. Create the city -profile and the first named administrator. Choose a protected backup -location. Defer optional local AI if it is not needed.

-

2. Activate the runtime

-

Run the first-run health check, wait for readiness and open -Townlight. In System Health select Finish Records Migration to activate -the canonical Python and PostgreSQL services. A running process alone is -not a ready database.

-

3. Create staff access

-

Use Settings to create named staff. Sign out and confirm that staff -can sign in with their own account. Keep administrator privileges with -people responsible for setup; ordinary staff cannot administer -users.

-

4. Import through the right product

-

Use the source library of Code, Zoning, Planning or Permitting. -Inspect provenance and permissions there. Core ingestion helpers do not -bypass the owning product’s source review.

-

5. Make a coherent backup

-

Save open work. Use Backup Now; it stops writers to preserve a -consistent snapshot. Retain the backup receipt, then use Start to resume -services.

-

6. Restore and verify

-

Use Restore Latest Backup after preserving current recovery material. -A result of Restore needs service start is an intermediate state: use -Start, then Check. Reopen a known saved record to confirm recovery.

-

7. Collect diagnostics

-

Record the time, selected composition, version, operation and exact -error. Inspect System Health and create a redacted support bundle. Do -not delete a profile as the first repair step.

-

Working safely

-

Use your own named account and save before leaving a screen. A saved -draft is durable; unsaved form text may not be. If a write has an -unknown result, reopen its record before repeating it.

-

Read source jurisdiction, dates, citation, version and visibility. A -copied source hash identifies exact bytes, not their legal -applicability. If a source changes or permission is removed, resolve the -source problem rather than substituting stale cached content.

-

Keep originals and derivatives separate. Review the intended audience -before export. A public summary excludes private fields only through the -applicable copy contract and your review. A renamed private packet is -still private content.

-

Drafting, review, approval, attachment, export, fulfillment and -publication are separate operations. A Townlight workpaper does not -itself adopt law, issue a permit, impose a fine or release a records -response. The responsible staff member records the applicable -decision.

-

Connected workflows

-

All products use selected Core contracts. Core does not create -unrestricted access between products. Notice and Access are supporting -components, rather than additional products in this nine-product -beta.

- ---- - - - - - - - - - - - - - - - - -
DirectionMaterial
InputAdministrator setup choices, named staff accounts, source material -submitted through the owning product, and protected backup storage.
OutputReady local services, permission-aware shared contracts, task -results, diagnostics and coherent backup or restore receipts.
-

Product boundary

-

Shared catalog, exemption and module-generator code exists in this -private candidate. It is not a centrally hosted federation service. A -business product still owns its decisions, identity mapping and -permission checks. Historical placeholder ADRs are retained as history, -rather than descriptions of the current implementation.

-

Architecture

-

Townlight Core architecture and evidence flow

-

The drawing shows the principal staff/evidence path. Native commands -carry trusted identity to Python business services; PostgreSQL and -retained original files hold durable state. A downstream copy does not -silently transfer decision authority. Station has its own configured -authority/media boundary, database and mutable files. The -connected-workflow text supplies the drawing’s reading order and -accessibility alternative.

-

Shared catalog rules and -scaffolding

-

These are existing Core developer and administrator contracts. They -do not add a new Core administration screen. Staff use the owning -product’s normal controls; developers call the library only inside an -authenticated application or an isolated synthetic test. The caller owns -authorization and database commit or rollback.

-

Catalog import and readback

-
    -
  1. Review the catalog’s catalog_version, domain names and -systems. Each system supplies vendor name, protocol, data shape, record -types, redaction tier 1–3 and optional discovery hints. Hints are -limited to ports, db_patterns and -service_accounts; do not put credentials in them.
  2. -
  3. In an authorized application transaction, call -civiccore.catalog.import_catalog(session, bundle, actor_id=actual_actor_id). -The actor is the authenticated application’s identity. A changed or -incomplete existing version is refused rather than overwritten. Use a -newly reviewed version for changed catalog contents.
  4. -
  5. Read domains(session), -system_catalog(session, domain) and -connectors_for(session, domain) before committing. Commit -only the intended import; roll back on refusal. Repeating an identical -complete version is a no-op.
  6. -
  7. Treat returned systems and connector recommendations as catalog -information. Import does not discover vendor endpoints, install a -connector or establish access to a city’s system.
  8. -
-

The following synthetic library example belongs inside an existing -authorized async transaction. session and -actual_actor_id are supplied by that application; this is -not a command that seeds an administrator.

-
from civiccore.catalog import import_catalog, system_catalog
-
-bundle = {
-    "catalog_version": "synthetic-1",
-    "domains": [{"domain": "synthetic-records", "systems": [{
-        "vendor_name": "Synthetic file source",
-        "access_protocol": "file", "data_shape": "json",
-        "common_record_types": ["synthetic minutes"],
-        "redaction_tier": 2, "discovery_hints": {}
-    }]}]
-}
-loaded = await import_catalog(session, bundle, actor_id=actual_actor_id)
-rows = await system_catalog(session, "synthetic-records")
-

The Records compatibility facade reads its bundled -app/data/systems_catalog.json through Core. Its existing -administrator POST /catalog/load takes no replacement -bundle body; GET /catalog/domains, -/catalog/systems?domain=... and -/catalog/connectors?domain=... expose readback. These -non-desktop routes use the application’s actual authenticated -staff/admin dependencies. Do not substitute an invented role header. The -shared SDK example above is the route for a developer-supplied -bundle.

-

Jurisdictional rule -evaluation and review

-

Select the jurisdiction and active reviewed rule versions before -evaluating document text. Core’s Rule carries -id, state_code, category, -rule_type, definition and integer -version. Supported supplied rule types are -keyword and regex; an unsupported rule or -incomplete/timed-out scan raises RuleEvaluationError. An -error must remain an incomplete scan, never “no exemptions found.” Core -does not assume a jurisdiction or claim complete legal coverage.

-
from uuid import UUID
-from civiccore.exemptions import Rule, evaluate, RuleEvaluationError
-
-rule = Rule(
-    id=UUID("11111111-1111-4111-8111-111111111111"),
-    state_code="CO", category="Synthetic review flag",
-    rule_type="keyword", definition="synthetic protected text", version=1
-)
-try:
-    flags = evaluate("Contains synthetic protected text", "CO", rules=[rule])
-except RuleEvaluationError:
-    raise  # The owning application records an incomplete scan.
-

This is fictional test text, not a Colorado exemption rule. Read each -result’s matched text, rule identity/version and confidence, then use -Records’ explicit reviewer decision and legal/source basis. A flag is -not an authorized withholding or redaction. Records’ existing exemption -rule/history/test and flag-review endpoints are listed in its technical -reference; record changes through those controls, preserving -history.

-

Scaffold plan and generate

-

Run the existing CLI from a developer environment containing the -matching Core package. Choose an existing empty parent workspace -directory, not an installed application’s directory. The module’s own -directory will be created underneath it. The following creates only a -fictional module project; it does not register, install, migrate or run -it.

-
& $control -m civiccore.scaffold plan civicnotes `
-  --name 'Synthetic Notes' --description 'Synthetic scaffold exercise'
-& $control -m civiccore.scaffold generate civicnotes `
-  --name 'Synthetic Notes' --description 'Synthetic scaffold exercise' `
-  --target 'C:\TownlightSynthetic' --dry-run
-

Here $control is the Python executable in that isolated -developer environment. Inspect the plan and files, then remove ---dry-run only when that exact target is approved for -generation. Existing files are refused, not silently overwritten. Exit 0 -indicates success; refusal exits 2. Options include ---version, --civiccore-min-version, ---permission-key, repeated --staff-role and ---route-path; inspect --help for the exact -invocation. Keep generated access requirements and migration stubs under -the new module’s own review. No automatic product deployment follows -generation.

-

Source contracts: civiccore/catalog/__init__.py, -civiccore/exemptions/__init__.py, -civiccore/scaffold/cli.py, project.py, and the -Records catalog facade.

-

Technical specifications

-

Runtime and storage

-

The accepted package targets Windows x64 fresh -installation. Its native shell uses Rust 2021, Tauri 2 -and Microsoft WebView2; browser assets are JavaScript built -with Vite 8.1.6. This describes the native desktop -frontend; Station has a separate React operator, specified below or in -its product manual. Canonical business workflows use bundled -CPython 3.13.5, FastAPI, Pydantic, SQLAlchemy and -Alembic, with PostgreSQL 17 / PostGIS and -managed original files. The installed runtime tested here contains -FastAPI 0.162.0. Package minimum Python requirements can differ from the -bundled executable; the metadata reference preserves both. No stack -rewrite is implied by the beta label.

-

The native transport is fixed to loopback -127.0.0.1:15480; PostgreSQL uses the configured local -runtime port (default 15432). Optional local model service -defaults to 127.0.0.1:15434. Those are deployment defaults, -not internet endpoints. The runtime has health, module and readiness -endpoints; readiness is stronger than process existence. The task queue -is the existing local Core task infrastructure, not an assertion that a -separate Redis service is required for this desktop composition.

-

The default native profile is %LOCALAPPDATA%\CivicSuite; -the historical directory name remains part of compatibility. Do not -rename it to Townlight. A configured TOWNLIGHT_PROFILE_ROOT -must be absolute. Local configuration and secrets live under that -profile; protected managed files and database state must be backed up -coherently. Source/runtime identity is distinct from a product’s display -label.

-

Data and consistency

-

Named local accounts; native sessions; source and department -authority; task receipts; profile configuration; coherent backup -manifests; catalog, exemption and scaffold contracts.

-

Versioned saves use expected prior revision identifiers where -defined. Reopen and reconcile on conflict. Exact exports and handoffs -use source IDs, current visibility, revision and SHA256. Review belongs -to the saved revision and does not transfer silently to edited text. -Database changes use the owning product’s migrations; a request or -readiness check is not an authorization to mutate schema.

-

Capacity and platform -statements

-

This beta has synthetic single-profile workflow evidence. It does not -have a published benchmark for concurrent staff capacity, minimum -RAM/CPU, large-source limits or a field SLA. Do not turn a developer -machine’s specification into a supported minimum. Installer size is -2,092,122,112 bytes before installation; allow additional disk for -extracted runtime, database, originals, exports, media and backups. -Select equipment/storage after sizing those actual workloads.

-

The exact runtime -payload lock records pinned files, sizes and hashes. The component metadata -records shipped dependency declarations. These references are more -precise than a manually copied dependency list. Third-party and -historical license notices must accompany their matching payloads.

-

Configuration and -administration

-

Native deployment -configuration

-

Use Setup, Settings and System Health for supported staff operation. -Administrators provision folders, backup storage, named accounts and the -city profile. Select inspections-preview for the full -eight-workspace desktop. Station remains a separate service boundary. Do -not use a standalone product’s demo server as a substitute for the -installed workspace.

-

Technical deployments use TOWNLIGHT_PRODUCT_PROFILE, -TOWNLIGHT_PROFILE_ROOT, DATABASE_URL, -CIVICSUITE_RUNTIME_PORT, PORTAL_MODE and the -runtime-managed secret files. Treat database URLs and native session -proofs as secrets. The installed native domain runtime explicitly -refuses non-loopback binding. PORTAL_MODE=private is the -accepted posture; changing it does not by itself commission an internet -portal, authentication provider or reverse proxy.

-

The isolated documentation exporter sets a fictional profile and -unusable synthetic database origin only to read schemas; those values -are not deployment configuration. Keep deployment values in the intended -process/account scope. An already-running process does not automatically -inherit later environment edits.

-

API and integration examples

-

Native command example

-

The following JavaScript belongs in the existing trusted Townlight -frontend/development environment with invoke imported from -@tauri-apps/api/core. It is not a command for an arbitrary -web page or an instruction for nontechnical staff. IDs must come from -records created in an isolated synthetic exercise.

-
import { invoke } from '@tauri-apps/api/core';
-const result = await invoke('get_app_state', {});
-console.log(result);
-

Trusted local HTTP example

-

An administrator/developer can inspect an already-configured isolated -runtime from a trusted local process. This PowerShell example reads the -signed-in synthetic profile’s existing proof into memory; it does not -create a user, seed a session, reveal the proof in output or bypass a -permission check. Do not use real city data in development examples. A -read response does not prove approval or publication.

-
$profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite'
-$sessionPath = Join-Path $profilePath 'config\local-session.json'
-$session = Get-Content -LiteralPath $sessionPath -Raw | ConvertFrom-Json
-$headers = @{ 'X-Townlight-Session' = $session.session_hash }
-Invoke-RestMethod -Uri 'http://127.0.0.1:15480/desktop/v1/suite/state' -Headers $headers
-Remove-Variable session, headers
-

A synthetic write -with subsequent readback

-

This example demonstrates the existing Meetings HTTP contract in an -isolated exercise. It is intentionally fictional. It does not start a -service. Its authentication setup is included so it can be run -independently under the signed-in synthetic account. If a write times -out, inspect current records before repeating it.

-
$profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite'
-$sessionPath = Join-Path $profilePath 'config/local-session.json'
-$session = Get-Content -LiteralPath $sessionPath -Raw | ConvertFrom-Json
-$headers = @{ 'X-Townlight-Session' = $session.session_hash }
-$body = @{
-  title = 'Synthetic documentation exercise'
-  scheduled_start = '2026-11-05T18:00:00-07:00'
-  location = 'Synthetic room'
-  meeting_type = 'regular'
-} | ConvertTo-Json
-$meeting = Invoke-RestMethod -Method Post `
-  -Uri 'http://127.0.0.1:15480/desktop/v1/meetings/meetings' `
-  -Headers $headers -ContentType 'application/json' -Body $body
-Invoke-RestMethod `
-  -Uri ('http://127.0.0.1:15480/desktop/v1/meetings/meetings/' + $meeting.id) `
-  -Headers $headers
-Remove-Variable session, headers
-

This write requires Meetings to be enabled and the signed-in staff -role to permit it. It is a cross-suite integration example; for this -product’s request models, use the complete technical reference -below.

-

Complete technical contract

-

Read the Core API reference for every -documented operation, request field, constraint, response declaration -and source supplement. Download the OpenAPI JSON for tools. For Station -this is the suite-side schema only; its separate service contract is -documented in the API supplement. The reference directory includes -configuration/source inventories, dependency declarations, native -command contracts, MCP signatures and candidate evidence.

-

MCP and automation boundary

-

No direct product MCP server is exposed by the accepted Townlight -desktop or Station boundary. Do not configure an invented -townlight mcp command or assume an AI client has staff -permissions. The integration surfaces for this beta are native IPC, the -documented HTTP APIs, source bundle imports, exact exports and the -existing Station CLI.

-

The bundled transcription code includes a TextFlowKit MCP -adapter as a separate source capability. It offers job-based -transcribe_media, get_transcript, -list_jobs, get_job_status and -export_transcript, and additional tools declared in that -adapter. It uses stdio first and optional Streamable HTTP, with the MCP -SDK as an optional extra. It is not automatically launched, -authenticated as Townlight staff or accepted as a Townlight product MCP -deployment. This documentation does not add such a service.

-

For a transcription client already provisioned separately, an -illustrative tool call is:

-
{"name":"get_job_status","arguments":{"job_id":"synthetic-existing-job-id"}}
-

Use a job ID returned by that transcription service. This example -does not create a Townlight record or bypass its review/Records handoff. -The exact optional adapter tool signatures are supplied in the MCP source reference. Station meeting -capture does not become live speech recognition because this optional -donor adapter exists.

-

Security and permissions

-

Use your own named account and save before leaving a screen. A saved -draft is durable; unsaved form text may not be. If a write has an -unknown result, reopen its record before repeating it.

-

Read source jurisdiction, dates, citation, version and visibility. A -copied source hash identifies exact bytes, not their legal -applicability. If a source changes or permission is removed, resolve the -source problem rather than substituting stale cached content.

-

Keep originals and derivatives separate. Review the intended audience -before export. A public summary excludes private fields only through the -applicable copy contract and your review. A renamed private packet is -still private content.

-

Drafting, review, approval, attachment, export, fulfillment and -publication are separate operations. A Townlight workpaper does not -itself adopt law, issue a permit, impose a fine or release a records -response. The responsible staff member records the applicable -decision.

-

The native session is validated and mapped to a persisted SQL -identity. An editable actor/reviewer label is not authentication. -Product/module permissions and source visibility apply at the server -boundary. Revoked/unavailable authority fails closed for new Station -operations; a previous permission result is not a perpetual -authorization.

-

Use protected local folders, account permissions and credential -storage. Never include the native session file, database passwords, -provider keys or unredacted support bundles in a public issue or -generated public documentation. A local public view is not automatically -a secured internet deployment. Keep network exposure and real equipment -acceptance specific to the chosen beta site.

-

Backup recovery and -maintenance

-

Save work and use Core’s canonical Backup Now before -maintenance. That operation stops writers. Preserve the coherent -profile/database/document backup and its receipt, then use -Start to resume. A source export is not a full -backup.

-

Use Restore Latest Backup through the supported -controls. If the result says Restore needs service -start, use Start, then Check, -and reopen a known record. Do not repeat restore merely because services -need to start. The fresh-profile acceptance verified that a fulfilled -request survived restore and a post-backup marker did not.

-

Keep Station’s dedicated database and media evidence together in its -own backup. Core’s native-profile backup must not be assumed to include -an external Station data directory. Stop writers during a coordinated -backup. Preserve failed media attempts and logs.

-

On failure, record the time, selected composition, -component/installer versions and exact message. Check System Health for -stopped, starting, ready or failed dependencies. Use the existing Retry -control after readiness; do not create duplicate business records to -refresh a stale view. Share only a redacted diagnostic bundle. Preserve -secrets, original evidence, recovery material and unrelated -installations.

-

Troubleshooting

- ----- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SymptomLikely meaningNext action
Workspace absentWrong product composition or unavailable canonical runtime.Check selected composition; activate through Finish Records -Migration; wait for readiness.
Cannot sign in / 401Missing or expired named account session.Sign in normally; reopen a Station launch ticket if applicable.
Permission denied / 403Account, module, source or browser-origin permission.Ask the authorized administrator to inspect the intended permission; -do not invent role headers.
Save conflict / 409The saved revision, expected source hash or lifecycle changed.Keep edits, reopen current state and reconcile deliberately.
Invalid input / 422Required field, format, geometry, source envelope or state is -invalid.Read the field detail and correct the input/source; preserve -originals.
Service unavailable / 503Database, schema, connected source or configuration -unavailable.Inspect System Health and the named dependency. Preserve work; retry -only after readiness.
Export refusedMissing exact review, approval, audience or source -authorization.Read the refusal and complete the owning product’s explicit -decision.
Restore needs service startThe snapshot was restored but services have not resumed.Use Start, then Check and verify a saved record; do not blindly -repeat restore.
-

Verified workflows and -limits

- ----- - - - - - - - - - - - - - - -
ProductRecorded resultPrecisely exercised
CorePASSNormal empty-profile setup; canonical activation; UI-created staff -and sign-in; staff denied user administration; coherent backup, -mutation, restore, Start/Check and retained/absent record readback.
-

These results come from the identified signed candidate’s fresh -normal-profile Sandbox exercise: real native IPC/HTTP/PostgreSQL and -selected headless controls. All accounts, source bundles and media were -synthetic. The guest install/uninstall and recovery passed, and the -owned Sandbox stopped. No host installed application or standalone -CivicCast was changed. This documentation task reuses those receipts; it -does not claim a new software acceptance run.

-

The workflow matrix -identifies raw receipt filenames. The evidence index -retains their original hashes; raw receipts remain in the private beta -handoff rather than being silently republished with the documentation -site.

-

The limits remain: actual city field acceptance and equipment/network -commissioning; Station automatic provisioning/SCM commissioning; every -UI/role combination; field recognition accuracy; and historical in-place -upgrades are not certified. They are not five invented feature -requirements. Fresh-install controlled beta handoff remains the accepted -scope. This package makes no city-deployment, publication or -general-availability claim.

-

Terms of service and license

-

Scope and status

-

These terms describe the Townlight Beta 1 software and this -documentation package. This is a locally prepared private beta, not a -hosted-service subscription, a city deployment agreement or a public -release. No uptime commitment, support response time, indemnity, -data-processing agreement or paid service is created by these documents. -A separate signed agreement, if any, governs services it actually -provides.

-

Software license and rights

-

Current Townlight-owned distributions identified in this candidate -use AGPL-3.0-only. The full license is supplied with -this documentation and with the source companion. The license governs -rights to run, copy, modify and convey the covered software; these -operational terms do not add restrictions to those rights. Historical -grants and dependency licenses retain their own terms. CivicCast remains -a separate product and is not relicensed by this documentation work.

-

When conveying covered software, retain applicable notices and -provide the corresponding source and installation/build information -required by the license. For a modified version supporting remote -network interaction, follow section 13’s source-offer requirement. The -companion archive identifies the source for this candidate; a link to a -different public branch is not a substitute for the matching source. -Read the supplied license for the complete conditions. See the GNU license -reference and GNU licensing -FAQ.

-

Data ownership and access

-

Importing a document does not transfer its ownership or grant -permission to publish it. The operating organization controls its -accounts, access decisions, lawful source use, retention and -review/release policy. Keep resident information, credentials, private -notes and restricted evidence in their authorized locations. -Documentation examples contain fictional data. No real city account, -credential or record is required to exercise these examples in an -isolated test environment.

-

Local operation and -external processors

-

The accepted beta workflow is local and uses named staff accounts. -Station has separate storage and credentials. Configure backup -destinations and optional model/network providers deliberately. A -configured external provider may receive submitted prompts, images or -audio according to that configuration and provider’s terms; this -documentation does not promise that every optional configuration is -offline. An email outbox or local public view does not establish -external delivery or an internet deployment. This static documentation -site has no analytics, account collection or remote font dependency.

-

Staff decisions and -source applicability

-

Staff verify the jurisdiction, source currency, permissions, -citations and proposed audience. Model output and generated guidance -require review. No draft is automatically an official legal -interpretation, zoning determination, permit approval, fee assessment, -enforcement notice or records-release decision. Official permit fee -authority remains with the adopted source and responsible organization; -imported amounts do not become a new authoritative calculation.

-

Beta operation and recovery

-

Use the identified candidate in its supported fresh-install scope. -Preserve backups and original evidence. Test physical equipment and -chosen network/service configuration before relying on them. The -supplied acceptance describes selected synthetic workflows, not every -screen, vendor, field condition or upgrade. Operators decide whether a -particular deployment meets their own operational obligations.

-

Warranty and liability

-

The covered software’s warranty and liability conditions are those in -sections 15–17 of the supplied AGPL and any applicable separate written -undertaking. This documentation creates no additional warranty or -limitation beyond those terms. Third-party software is subject to its -retained license notices. Nothing here removes rights that applicable -law makes nonwaivable.

-

Support and incident -reporting

-

Use the project’s existing SUPPORT and SECURITY guidance for its -matching repository. Report reproducible behavior with the version, -operation and redacted logs. Do not put credentials, resident records or -unredacted evidence in a public issue. Coordinate sensitive reports -through the channel designated in SECURITY. No new support address or -service commitment is invented here.

-

Ending a beta -exercise and document changes

-

When an organization ends testing, it controls retention/export and -removes access according to its policy. Uninstall may retain data; back -up and inspect the selected removal options. Ending an exercise does not -revoke rights already granted by AGPL. Later software/documentation -versions must identify their changed candidate and scope; historical -receipts retain their original identities. These terms do not claim that -a city has accepted a contract merely by reading a manual.

-

Glossary

- ---- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TermMeaning
ApprovalAn explicit authorized decision on the saved text/artifact. It is -separate from saving or attachment.
Canonical recordThe owning product’s retained identity and saved version, rather -than an editable copied label.
CompositionThe selected set of desktop modules; inspections-preview exposes the -eight staff products.
Corresponding sourceThe source/build material matching the delivered covered program, -subject to its license.
Derivative / Records copyA separately prepared document with its own intended audience and -hash.
Hash / SHA256A fingerprint of exact bytes. It detects change; it does not -establish legal authority.
IdempotencyRepeating the same identified request has the same intended effect; -changing its payload can be refused.
IPCThe native desktop command boundary between its browser interface -and Rust host.
MCPModel Context Protocol; no direct Townlight product server is -enabled by this beta.
OriginalRetained source bytes. A reviewed derivative does not replace -them.
ProvenanceSource, version, date, actor and relationship information retained -with evidence.
RevisionAn immutable saved version. Later edits do not inherit an earlier -review automatically.
SnapshotA fixed audience-specific copy tied to a source/reviewed -revision.
StationTownlight’s separate media boundary using a pinned CivicCast-derived -engine; standalone CivicCast remains separate.
-

Alphabetical subject index

- - - -

Source and document control

-

This edition is authored from the immutable corresponding-source -companion, the generated installed-domain schema and the retained -workflow receipts. The current software versions and signed artifacts -are unchanged. Public historical pages are not synchronized or published -by this local documentation task.

-

Workflow subject index

-
- \ No newline at end of file + + +
Townlight +
+

Naming, Access and Notice source candidate · 2 November 2026

+

Prepared documentation. Build, signing, installed acceptance and publication remain pending.

+ + +

Townlight Core Manual

+

Townlight Beta 1 · Naming candidate documentation +edition 2 November 2026

+

Contents

+ +

Using this manual

+

Townlight Core helps IT administrators and platform maintainers. Core +provides the shared contracts, ingestion, identity helpers, task +infrastructure and recovery foundation used by Townlight. Staff +encounter these capabilities through Setup, Settings and System Health. +Business decisions stay with their owning product.

+

Staff should begin with First run and Daily workflow. Administrators +should also read Architecture, Technical specifications, Configuration, +Security and Recovery. Developers should use the exact API/data +dictionary and examples. The table of contents and alphabetical subject +index link to the relevant sections in the HTML edition; the PDF +preserves headings and searchable text. An editable Word edition is +included with the same documentation companion.

+

Beta identity

+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IdentityValue
DocumentationTownlight Beta 1 naming, Access and Notice candidate
Intended installer version1.7.0.1; build and acceptance pending
Product componenttownlight-core 1.3.0.dev2
Principal import packagetownlight_core
Native desktop source version1.7.0-1
Candidate hashesPending candidate build, signing and installed acceptance
Current owned software licenseAGPL-3.0-only
Acceptance compositionFresh Windows x64 profile; inspections-preview; Station configured +separately
+

The naming change advances this package’s version and requires a new +signed installer and installed acceptance. Those steps and publication +remain pending. Historical tags, receipts and archived manuals keep +their original names and certify only their identified artifacts. Use an +empty database and fresh profile; no in-place legacy upgrade is +supported. The approved Windows profile path remains +%LOCALAPPDATA%\CivicSuite. Preserve existing profiles, data +and recovery material.

+

First run

+
    +
  1. Obtain the identified signed private candidate and its +corresponding-source companion from the beta coordinator. The landing +pages in this documentation are not an installer download service.
  2. +
  3. On the intended fresh Windows test installation, verify the MSI hash +and publisher signature before installing. Preserve unrelated profiles +and recovery material. Installed acceptance for this source candidate +remains pending; no in-place legacy upgrade is supported.
  4. +
  5. Launch Townlight under the intended named Windows account. Choose +the storage folders. Select Townlight Inspections +candidate (inspections-preview) for the bounded +desktop composition, including Access and Notice. A narrower default +selection will not expose all workspaces.
  6. +
  7. Enter the city profile, time zone and contacts. Create the first +named local administrator, sign in and choose protected backup storage. +Continue without local AI is valid for the +deterministic workflows.
  8. +
  9. Run Health Check and wait for readiness. Open Townlight. In System +Health select Finish Records Migration to activate the +canonical Python/PostgreSQL runtime. Do not fabricate migration receipts +or seed accounts.
  10. +
  11. Create named staff through Settings. Import authorized sources using +each product’s source library. All examples in this package are +synthetic; they are not municipal authority.
  12. +
  13. Provision Station separately if it is part of the beta exercise. +Selecting the desktop composition does not start or configure Station. +Configure vision explicitly only if automatic photo drafting is +selected.
  14. +
+

Daily workflow

+

+

1. Complete setup

+

Choose folders and the full product composition. Create the city +profile and the first named administrator. Choose a protected backup +location. Defer optional local AI if it is not needed.

+

+

2. Activate the runtime

+

Run the first-run health check, wait for readiness and open +Townlight. In System Health select Finish Records Migration to activate +the canonical Python and PostgreSQL services. A running process alone is +not a ready database.

+

+

3. Create staff access

+

Use Settings to create named staff. Sign out and confirm that staff +can sign in with their own account. Keep administrator privileges with +people responsible for setup; ordinary staff cannot administer +users.

+

+

4. Import through the right +product

+

Use the source library of Code, Zoning, Planning or Permitting. +Inspect provenance and permissions there. Core ingestion helpers do not +bypass the owning product’s source review.

+

+

5. Make a coherent backup

+

Save open work. Use Backup Now; it stops writers to preserve a +consistent snapshot. Retain the backup receipt, then use Start to resume +services.

+

+

6. Restore and verify

+

Use Restore Latest Backup after preserving current recovery material. +A result of Restore needs service start is an intermediate state: use +Start, then Check. Reopen a known saved record to confirm recovery.

+

+

7. Collect diagnostics

+

Record the time, selected composition, version, operation and exact +error. Inspect System Health and create a redacted support bundle. Do +not delete a profile as the first repair step.

+

Working safely

+

Use your own named account and save before leaving a screen. A saved +draft is durable; unsaved form text may not be. If a write has an +unknown result, reopen its record before repeating it.

+

Read source jurisdiction, dates, citation, version and visibility. A +copied source hash identifies exact bytes, not their legal +applicability. If a source changes or permission is removed, resolve the +source problem rather than substituting stale cached content.

+

Keep originals and derivatives separate. Review the intended audience +before export. A public summary excludes private fields only through the +applicable copy contract and your review. A renamed private packet is +still private content.

+

Drafting, review, approval, attachment, export, fulfillment and +publication are separate operations. A Townlight workpaper does not +itself adopt law, issue a permit, impose a fine or release a records +response. The responsible staff member records the applicable +decision.

+

Connected workflows

+

All products use selected Core contracts. Core does not create +unrestricted access between products. Access and Notice provide the +bounded staff workflows documented in their current manuals; installed +acceptance remains pending.

+ ++++ + + + + + + + + + + + + + + + + +
DirectionMaterial
InputAdministrator setup choices, named staff accounts, source material +submitted through the owning product, and protected backup storage.
OutputReady local services, permission-aware shared contracts, task +results, diagnostics and coherent backup or restore receipts.
+

Product boundary

+

Shared catalog, exemption and module-generator code exists in this +private candidate. It is not a centrally hosted federation service. A +business product still owns its decisions, identity mapping and +permission checks. Historical placeholder ADRs are retained as history, +rather than descriptions of the current implementation.

+

Architecture

+
+ + +
+

The drawing shows the principal staff/evidence path. Native commands +carry trusted identity to Python business services; PostgreSQL and +retained original files hold durable state. A downstream copy does not +silently transfer decision authority. Station has its own configured +authority/media boundary, database and mutable files. The +connected-workflow text supplies the drawing’s reading order and +accessibility alternative.

+

Shared catalog rules and +scaffolding

+

These are existing Core developer and administrator contracts. They +do not add a new Core administration screen. Staff use the owning +product’s normal controls; developers call the library only inside an +authenticated application or an isolated synthetic test. The caller owns +authorization and database commit or rollback.

+

Catalog import and readback

+
    +
  1. Review the catalog’s catalog_version, domain names and +systems. Each system supplies vendor name, protocol, data shape, record +types, redaction tier 1–3 and optional discovery hints. Hints are +limited to ports, db_patterns and +service_accounts; do not put credentials in them.
  2. +
  3. In an authorized application transaction, call +townlight_core.catalog.import_catalog(session, bundle, actor_id=actual_actor_id). +The actor is the authenticated application’s identity. A changed or +incomplete existing version is refused rather than overwritten. Use a +newly reviewed version for changed catalog contents.
  4. +
  5. Read domains(session), +system_catalog(session, domain) and +connectors_for(session, domain) before committing. Commit +only the intended import; roll back on refusal. Repeating an identical +complete version is a no-op.
  6. +
  7. Treat returned systems and connector recommendations as catalog +information. Import does not discover vendor endpoints, install a +connector or establish access to a city’s system.
  8. +
+

The following synthetic library example belongs inside an existing +authorized async transaction. session and +actual_actor_id are supplied by that application; this is +not a command that seeds an administrator.

+
from townlight_core.catalog import import_catalog, system_catalog
+
+bundle = {
+    "catalog_version": "synthetic-1",
+    "domains": [{"domain": "synthetic-records", "systems": [{
+        "vendor_name": "Synthetic file source",
+        "access_protocol": "file", "data_shape": "json",
+        "common_record_types": ["synthetic minutes"],
+        "redaction_tier": 2, "discovery_hints": {}
+    }]}]
+}
+loaded = await import_catalog(session, bundle, actor_id=actual_actor_id)
+rows = await system_catalog(session, "synthetic-records")
+

The Records compatibility facade reads its bundled +app/data/systems_catalog.json through Core. Its existing +administrator POST /catalog/load takes no replacement +bundle body; GET /catalog/domains, +/catalog/systems?domain=... and +/catalog/connectors?domain=... expose readback. These +non-desktop routes use the application’s actual authenticated +staff/admin dependencies. Do not substitute an invented role header. The +shared SDK example above is the route for a developer-supplied +bundle.

+

Jurisdictional rule +evaluation and review

+

Select the jurisdiction and active reviewed rule versions before +evaluating document text. Core’s Rule carries +id, state_code, category, +rule_type, definition and integer +version. Supported supplied rule types are +keyword and regex; an unsupported rule or +incomplete/timed-out scan raises RuleEvaluationError. An +error must remain an incomplete scan, never “no exemptions found.” Core +does not assume a jurisdiction or claim complete legal coverage.

+
from uuid import UUID
+from townlight_core.exemptions import Rule, evaluate, RuleEvaluationError
+
+rule = Rule(
+    id=UUID("11111111-1111-4111-8111-111111111111"),
+    state_code="CO", category="Synthetic review flag",
+    rule_type="keyword", definition="synthetic protected text", version=1
+)
+try:
+    flags = evaluate("Contains synthetic protected text", "CO", rules=[rule])
+except RuleEvaluationError:
+    raise  # The owning application records an incomplete scan.
+

This is fictional test text, not a Colorado exemption rule. Read each +result’s matched text, rule identity/version and confidence, then use +Records’ explicit reviewer decision and legal/source basis. A flag is +not an authorized withholding or redaction. Records’ existing exemption +rule/history/test and flag-review endpoints are listed in its technical +reference; record changes through those controls, preserving +history.

+

Scaffold plan and generate

+

Run the existing CLI from a developer environment containing the +matching Core package. Choose an existing empty parent workspace +directory, not an installed application’s directory. The module’s own +directory will be created underneath it. The following creates only a +fictional module project; it does not register, install, migrate or run +it.

+
& $control -m townlight_core.scaffold plan civicnotes `
+  --name 'Synthetic Notes' --description 'Synthetic scaffold exercise'
+& $control -m townlight_core.scaffold generate civicnotes `
+  --name 'Synthetic Notes' --description 'Synthetic scaffold exercise' `
+  --target 'C:\TownlightSynthetic' --dry-run
+

Here $control is the Python executable in that isolated +developer environment. Inspect the plan and files, then remove +--dry-run only when that exact target is approved for +generation. Existing files are refused, not silently overwritten. Exit 0 +indicates success; refusal exits 2. Options include +--version, --townlight_core-min-version, +--permission-key, repeated --staff-role and +--route-path; inspect --help for the exact +invocation. Keep generated access requirements and migration stubs under +the new module’s own review. No automatic product deployment follows +generation.

+

Source contracts: townlight_core/catalog/__init__.py, +townlight_core/exemptions/__init__.py, +townlight_core/scaffold/cli.py, project.py, +and the Records catalog facade.

+

Technical specifications

+

Runtime and storage

+

The accepted package targets Windows x64 fresh +installation. Its native shell uses Rust 2021, Tauri 2 +and Microsoft WebView2; browser assets are JavaScript built +with Vite 8.1.6. This describes the native desktop +frontend; Station has a separate React operator, specified below or in +its product manual. Canonical business workflows use bundled +CPython 3.13.5, FastAPI, Pydantic, SQLAlchemy and +Alembic, with PostgreSQL 17 / PostGIS and +managed original files. The installed runtime tested here contains +FastAPI 0.162.0. Package minimum Python requirements can differ from the +bundled executable; the metadata reference preserves both. No stack +rewrite is implied by the beta label.

+

The native transport is fixed to loopback +127.0.0.1:15480; PostgreSQL uses the configured local +runtime port (default 15432). Optional local model service +defaults to 127.0.0.1:15434. Those are deployment defaults, +not internet endpoints. The runtime has health, module and readiness +endpoints; readiness is stronger than process existence. The task queue +is the existing local Core task infrastructure, not an assertion that a +separate Redis service is required for this desktop composition.

+

The default native profile is %LOCALAPPDATA%\CivicSuite; +the historical directory name remains part of compatibility. Do not +rename it to Townlight. A configured TOWNLIGHT_PROFILE_ROOT +must be absolute. Local configuration and secrets live under that +profile; protected managed files and database state must be backed up +coherently. Source/runtime identity is distinct from a product’s display +label.

+

Data and consistency

+

Named local accounts; native sessions; source and department +authority; task receipts; profile configuration; coherent backup +manifests; catalog, exemption and scaffold contracts.

+

Versioned saves use expected prior revision identifiers where +defined. Reopen and reconcile on conflict. Exact exports and handoffs +use source IDs, current visibility, revision and SHA256. Review belongs +to the saved revision and does not transfer silently to edited text. +Database changes use the owning product’s migrations; a request or +readiness check is not an authorization to mutate schema.

+

Capacity and platform +statements

+

This beta has synthetic single-profile workflow evidence. It does not +have a published benchmark for concurrent staff capacity, minimum +RAM/CPU, large-source limits or a field SLA. Do not turn a developer +machine’s specification into a supported minimum. The new installer size +remains pending its build; allow additional disk for extracted runtime, +database, originals, exports, media and backups. Select +equipment/storage after sizing those actual workloads.

+

The exact runtime payload +lock records pinned files, sizes and hashes. The component +metadata records shipped dependency declarations. These references +are more precise than a manually copied dependency list. Third-party and +historical license notices must accompany their matching payloads.

+

Configuration and +administration

+

Native deployment +configuration

+

Use Setup, Settings and System Health for supported staff operation. +Administrators provision folders, backup storage, named accounts and the +city profile. Select inspections-preview for the bounded +desktop composition, including Access and Notice. Station remains a +separate service boundary. Do not use a standalone product’s demo server +as a substitute for the installed workspace.

+

Technical deployments use TOWNLIGHT_PRODUCT_PROFILE, +TOWNLIGHT_PROFILE_ROOT, DATABASE_URL, +TOWNLIGHT_RUNTIME_PORT, PORTAL_MODE and the +runtime-managed secret files. Treat database URLs and native session +proofs as secrets. The installed native domain runtime explicitly +refuses non-loopback binding. PORTAL_MODE=private is the +accepted posture; changing it does not by itself commission an internet +portal, authentication provider or reverse proxy.

+

The isolated documentation exporter sets a fictional profile and +unusable synthetic database origin only to read schemas; those values +are not deployment configuration. Keep deployment values in the intended +process/account scope. An already-running process does not automatically +inherit later environment edits.

+

API and integration examples

+

Native command example

+

The following JavaScript belongs in the existing trusted Townlight +frontend/development environment with invoke imported from +@tauri-apps/api/core. It is not a command for an arbitrary +web page or an instruction for nontechnical staff. IDs must come from +records created in an isolated synthetic exercise.

+
import { invoke } from '@tauri-apps/api/core';
+const result = await invoke('get_app_state', {});
+console.log(result);
+

Trusted local HTTP example

+

An administrator/developer can inspect an already-configured isolated +runtime from a trusted local process. This PowerShell example reads the +signed-in synthetic profile’s existing proof into memory; it does not +create a user, seed a session, reveal the proof in output or bypass a +permission check. Do not use real city data in development examples. A +read response does not prove approval or publication.

+
$profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite'
+$sessionPath = Join-Path $profilePath 'config\local-session.json'
+$session = Get-Content -LiteralPath $sessionPath -Raw | ConvertFrom-Json
+$headers = @{ 'X-Townlight-Session' = $session.session_hash }
+Invoke-RestMethod -Uri 'http://127.0.0.1:15480/desktop/v1/suite/state' -Headers $headers
+Remove-Variable session, headers
+

A synthetic write +with subsequent readback

+

This example demonstrates the existing Meetings HTTP contract in an +isolated exercise. It is intentionally fictional. It does not start a +service. Its authentication setup is included so it can be run +independently under the signed-in synthetic account. If a write times +out, inspect current records before repeating it.

+
$profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite'
+$sessionPath = Join-Path $profilePath 'config/local-session.json'
+$session = Get-Content -LiteralPath $sessionPath -Raw | ConvertFrom-Json
+$headers = @{ 'X-Townlight-Session' = $session.session_hash }
+$body = @{
+  title = 'Synthetic documentation exercise'
+  scheduled_start = '2026-11-05T18:00:00-07:00'
+  location = 'Synthetic room'
+  meeting_type = 'regular'
+} | ConvertTo-Json
+$meeting = Invoke-RestMethod -Method Post `
+  -Uri 'http://127.0.0.1:15480/desktop/v1/meetings/meetings' `
+  -Headers $headers -ContentType 'application/json' -Body $body
+Invoke-RestMethod `
+  -Uri ('http://127.0.0.1:15480/desktop/v1/meetings/meetings/' + $meeting.id) `
+  -Headers $headers
+Remove-Variable session, headers
+

This write requires Meetings to be enabled and the signed-in staff +role to permit it. It is a cross-suite integration example; for this +product’s request models, use the complete technical reference +below.

+

Complete technical contract

+

Read the Core API reference +for every documented operation, request field, constraint, response +declaration and source supplement. Download the OpenAPI JSON for tools. For +Station this is the suite-side schema only; its separate service +contract is documented in the API supplement. The reference directory includes +configuration/source inventories, dependency declarations, native +command contracts, MCP signatures and candidate evidence.

+

MCP and automation boundary

+

No direct product MCP server is exposed by the accepted Townlight +desktop or Station boundary. Do not configure an invented +townlight mcp command or assume an AI client has staff +permissions. The integration surfaces for this beta are native IPC, the +documented HTTP APIs, source bundle imports, exact exports and the +existing Station CLI.

+

The bundled transcription code includes a TextFlowKit MCP +adapter as a separate source capability. It offers job-based +transcribe_media, get_transcript, +list_jobs, get_job_status and +export_transcript, and additional tools declared in that +adapter. It uses stdio first and optional Streamable HTTP, with the MCP +SDK as an optional extra. It is not automatically launched, +authenticated as Townlight staff or accepted as a Townlight product MCP +deployment. This documentation does not add such a service.

+

For a transcription client already provisioned separately, an +illustrative tool call is:

+
{"name":"get_job_status","arguments":{"job_id":"synthetic-existing-job-id"}}
+

Use a job ID returned by that transcription service. This example +does not create a Townlight record or bypass its review/Records handoff. +The exact optional adapter tool signatures are supplied in the MCP source reference. Station +meeting capture does not become live speech recognition because this +optional donor adapter exists.

+

Security and permissions

+

Use your own named account and save before leaving a screen. A saved +draft is durable; unsaved form text may not be. If a write has an +unknown result, reopen its record before repeating it.

+

Read source jurisdiction, dates, citation, version and visibility. A +copied source hash identifies exact bytes, not their legal +applicability. If a source changes or permission is removed, resolve the +source problem rather than substituting stale cached content.

+

Keep originals and derivatives separate. Review the intended audience +before export. A public summary excludes private fields only through the +applicable copy contract and your review. A renamed private packet is +still private content.

+

Drafting, review, approval, attachment, export, fulfillment and +publication are separate operations. A Townlight workpaper does not +itself adopt law, issue a permit, impose a fine or release a records +response. The responsible staff member records the applicable +decision.

+

The native session is validated and mapped to a persisted SQL +identity. An editable actor/reviewer label is not authentication. +Product/module permissions and source visibility apply at the server +boundary. Revoked/unavailable authority fails closed for new Station +operations; a previous permission result is not a perpetual +authorization.

+

Use protected local folders, account permissions and credential +storage. Never include the native session file, database passwords, +provider keys or unredacted support bundles in a public issue or +generated public documentation. A local public view is not automatically +a secured internet deployment. Keep network exposure and real equipment +acceptance specific to the chosen beta site.

+

Backup recovery and +maintenance

+

Save work and use Core’s canonical Backup Now before +maintenance. That operation stops writers. Preserve the coherent +profile/database/document backup and its receipt, then use +Start to resume. A source export is not a full +backup.

+

Use Restore Latest Backup through the supported +controls. If the result says Restore needs service +start, use Start, then Check, +and reopen a known record. Do not repeat restore merely because services +need to start. The fresh-profile acceptance verified that a fulfilled +request survived restore and a post-backup marker did not.

+

Keep Station’s dedicated database and media evidence together in its +own backup. Core’s native-profile backup must not be assumed to include +an external Station data directory. Stop writers during a coordinated +backup. Preserve failed media attempts and logs.

+

On failure, record the time, selected composition, +component/installer versions and exact message. Check System Health for +stopped, starting, ready or failed dependencies. Use the existing Retry +control after readiness; do not create duplicate business records to +refresh a stale view. Share only a redacted diagnostic bundle. Preserve +secrets, original evidence, recovery material and unrelated +installations.

+

Troubleshooting

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SymptomLikely meaningNext action
Workspace absentWrong product composition or unavailable canonical runtime.Check selected composition; activate through Finish Records +Migration; wait for readiness.
Cannot sign in / 401Missing or expired named account session.Sign in normally; reopen a Station launch ticket if applicable.
Permission denied / 403Account, module, source or browser-origin permission.Ask the authorized administrator to inspect the intended permission; +do not invent role headers.
Save conflict / 409The saved revision, expected source hash or lifecycle changed.Keep edits, reopen current state and reconcile deliberately.
Invalid input / 422Required field, format, geometry, source envelope or state is +invalid.Read the field detail and correct the input/source; preserve +originals.
Service unavailable / 503Database, schema, connected source or configuration +unavailable.Inspect System Health and the named dependency. Preserve work; retry +only after readiness.
Export refusedMissing exact review, approval, audience or source +authorization.Read the refusal and complete the owning product’s explicit +decision.
Restore needs service startThe snapshot was restored but services have not resumed.Use Start, then Check and verify a saved record; do not blindly +repeat restore.
+

Verified workflows and +limits

+ +++++ + + + + + + + + + + + + + + +
ProductRecorded resultPrecisely exercised
CorePASSNormal empty-profile setup; canonical activation; UI-created staff +and sign-in; staff denied user administration; coherent backup, +mutation, restore, Start/Check and retained/absent record readback.
+

These results come from the identified signed candidate’s fresh +normal-profile Sandbox exercise: real native IPC/HTTP/PostgreSQL and +selected headless controls. All accounts, source bundles and media were +synthetic. The guest install/uninstall and recovery passed, and the +owned Sandbox stopped. No host installed application or standalone +CivicCast was changed. This documentation task reuses those receipts; it +does not claim a new software acceptance run.

+

The workflow +matrix identifies raw receipt filenames. The evidence +index retains their original hashes; raw receipts remain in the +private beta handoff rather than being silently republished with the +documentation site.

+

The limits remain: actual city field acceptance and equipment/network +commissioning; Station automatic provisioning/SCM commissioning; every +UI/role combination; field recognition accuracy; and historical in-place +upgrades are not certified. They are not five invented feature +requirements. Fresh-install controlled beta handoff remains the accepted +scope. This package makes no city-deployment, publication or +general-availability claim.

+

Terms of service and license

+

Scope and status

+

These terms describe the Townlight Beta 1 software and this +documentation package. This is a locally prepared private beta, not a +hosted-service subscription, a city deployment agreement or a public +release. No uptime commitment, support response time, indemnity, +data-processing agreement or paid service is created by these documents. +A separate signed agreement, if any, governs services it actually +provides.

+

Software license and rights

+

Current Townlight-owned distributions identified in this candidate +use AGPL-3.0-only. The full license is supplied with +this documentation and with the source companion. The license governs +rights to run, copy, modify and convey the covered software; these +operational terms do not add restrictions to those rights. Historical +grants and dependency licenses retain their own terms. CivicCast remains +a separate product and is not relicensed by this documentation work.

+

When conveying covered software, retain applicable notices and +provide the corresponding source and installation/build information +required by the license. For a modified version supporting remote +network interaction, follow section 13’s source-offer requirement. The +companion archive identifies the source for this candidate; a link to a +different public branch is not a substitute for the matching source. +Read the supplied license for the complete conditions. See the GNU license +reference and GNU licensing +FAQ.

+

Data ownership and access

+

Importing a document does not transfer its ownership or grant +permission to publish it. The operating organization controls its +accounts, access decisions, lawful source use, retention and +review/release policy. Keep resident information, credentials, private +notes and restricted evidence in their authorized locations. +Documentation examples contain fictional data. No real city account, +credential or record is required to exercise these examples in an +isolated test environment.

+

Local operation and +external processors

+

The accepted beta workflow is local and uses named staff accounts. +Station has separate storage and credentials. Configure backup +destinations and optional model/network providers deliberately. A +configured external provider may receive submitted prompts, images or +audio according to that configuration and provider’s terms; this +documentation does not promise that every optional configuration is +offline. An email outbox or local public view does not establish +external delivery or an internet deployment. This static documentation +site has no analytics, account collection or remote font dependency.

+

Staff decisions and +source applicability

+

Staff verify the jurisdiction, source currency, permissions, +citations and proposed audience. Model output and generated guidance +require review. No draft is automatically an official legal +interpretation, zoning determination, permit approval, fee assessment, +enforcement notice or records-release decision. Official permit fee +authority remains with the adopted source and responsible organization; +imported amounts do not become a new authoritative calculation.

+

Beta operation and recovery

+

Use the identified candidate in its supported fresh-install scope. +Preserve backups and original evidence. Test physical equipment and +chosen network/service configuration before relying on them. The +supplied acceptance describes selected synthetic workflows, not every +screen, vendor, field condition or upgrade. Operators decide whether a +particular deployment meets their own operational obligations.

+

Warranty and liability

+

The covered software’s warranty and liability conditions are those in +sections 15–17 of the supplied AGPL and any applicable separate written +undertaking. This documentation creates no additional warranty or +limitation beyond those terms. Third-party software is subject to its +retained license notices. Nothing here removes rights that applicable +law makes nonwaivable.

+

Support and incident +reporting

+

Use the project’s existing SUPPORT and SECURITY guidance for its +matching repository. Report reproducible behavior with the version, +operation and redacted logs. Do not put credentials, resident records or +unredacted evidence in a public issue. Coordinate sensitive reports +through the channel designated in SECURITY. No new support address or +service commitment is invented here.

+

Ending a beta +exercise and document changes

+

When an organization ends testing, it controls retention/export and +removes access according to its policy. Uninstall may retain data; back +up and inspect the selected removal options. Ending an exercise does not +revoke rights already granted by AGPL. Later software/documentation +versions must identify their changed candidate and scope; historical +receipts retain their original identities. These terms do not claim that +a city has accepted a contract merely by reading a manual.

+

Glossary

+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TermMeaning
ApprovalAn explicit authorized decision on the saved text/artifact. It is +separate from saving or attachment.
Canonical recordThe owning product’s retained identity and saved version, rather +than an editable copied label.
CompositionThe selected set of desktop modules; inspections-preview exposes the +eight staff products.
Corresponding sourceThe source/build material matching the delivered covered program, +subject to its license.
Derivative / Records copyA separately prepared document with its own intended audience and +hash.
Hash / SHA256A fingerprint of exact bytes. It detects change; it does not +establish legal authority.
IdempotencyRepeating the same identified request has the same intended effect; +changing its payload can be refused.
IPCThe native desktop command boundary between its browser interface +and Rust host.
MCPModel Context Protocol; no direct Townlight product server is +enabled by this beta.
OriginalRetained source bytes. A reviewed derivative does not replace +them.
ProvenanceSource, version, date, actor and relationship information retained +with evidence.
RevisionAn immutable saved version. Later edits do not inherit an earlier +review automatically.
SnapshotA fixed audience-specific copy tied to a source/reviewed +revision.
StationTownlight’s separate media boundary using a pinned CivicCast-derived +engine; standalone CivicCast remains separate.
+

Alphabetical subject index

+ + + +

Source and document control

+

This edition is authored from the immutable corresponding-source +companion, the generated installed-domain schema and the retained +workflow receipts. The current software versions and signed artifacts +are unchanged. Public historical pages are not synchronized or published +by this local documentation task.

+

Workflow subject index

+ +
Townlight · AGPL-3.0-only · Candidate evidence applies only to its identified artifacts.
\ No newline at end of file diff --git a/docs/beta-1/pdf/Townlight-Core-Manual-Beta-1.pdf b/docs/beta-1/pdf/Townlight-Core-Manual-Beta-1.pdf index a0c6709f0a8d114124134374ebcd76b32831f8ac..cb3ea25ad5a1902cb74156d5551c3ead4b05b459 100644 GIT binary patch literal 361295 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

R|gow@|gl!X!%NCWeZEHM*yt@yCx!7?SyN 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

xw&JL~vQwVB?G|fRbM7X(C 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/Ot@ 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 literal 399139 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 z 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¬ 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

t=b!pVBrwRxBDbW)&<7kZ0a013!QBn&|CE z?#Sx!>Ew5>znmWEjK2Oju-*S-3(|O*d1ll7D)*zmHDBnN_qmYi=At)29rvN|;i>T5 z=3Q{z!$Eh<-a3y@@`lSGfjl$mEWtjk4yH!c!B)mL8-9Wu?2=h^);BV^JnLxwFEV1E zM#wj5#$*&p`h?ybRY;cIc#awmT1{2Rt>C*fZ9VnB+*^J_NkU1?+!sO_)2#{Mz(%U- zhc%37)Le=%c02&xQSk|0=j!Bo=bmpRuRi`UE&y9j$o07`q6vY8p7;h3y~f(<;L)w0 zsl{WH)rokBQE+OGL4K>{YqDOFox6e6Z+zOg*0|QSVIuuH8dJ_Bw)H_OsVsIRDR;{A z&mFDJXpT~&9K9JjWZQJRRLEL%#mZU?{b)k&si`%)TtO)+W$gJMllf!aO$8CkLOYIG#;yYQGr!w*Cw^%RKd@#dq;1ij-P ze&{g{iJPR2wH`8L`gO;PbH)Qkyf3 zPWHWPx&)b(;!;ku-Bf-O#-}7enV41UoZbwQ6&IQMvjK|*o1G15ve63E>~d4Me^PA+ z!MX-RzSeY1cO{x;-x?Zwk)7T^iO)fsF4&BnH_#75A%juGqI+>6RkK)r&p!L>Mp0!V zG!p#gsSzidp}|P&k9X8Ko@(PLn^J0KWtS=>uY+8t2ypHeJrxgk^bwu2Zq4!?J$pS* z^$GEQ?z|05So41E64~~%a`(9-{mh(Tllidshv!%gwU(z=g3h)Ron>cw<;8UK`1Xi^ z`N7TOM{N2r5QZp-cAJd~(L2X+`vQ4`PZjvu5!w-_wF!E~M5C{)k@X8sUD6kbGDrf$ z19M1dsikqHU);o5dAhL!^0!b!@irgsmYX%alGXgIvNnfrh;yYdt)6;1-7?!|Q#g5> z7n}MmBkGN;e1)sKzivj$7h?ZR<2U@16bG^65yFg3sZyN`<>=s|R#S0)w&ec#H@=6< zgD*A6+m4Y9-Vp~>x-3o4PdgQ;q{&jdjtJ%n6pU1B0R){Zqd`Pa63eq2R4s~iCTQeURSJV zwkFO9+s_S(j+m@n{+RkXWkYYNz#W#>oVb%nj3PAD>uc;iEJLepel0z{$w2M!yfDxW zA7AnKTEc?AHdnw}yVB|IJGz2px^5f=R_oKySn-Xj#&ywRm8}V3do%P)pVkI9i2fjt zRD2h+GV;=%Vb*D97QqPJ=6Z+!8@h$*j^Ntj{_jB@8j%D5iuRgw{yv&0})Oj(SBCiX3u7Dq-_1MwNz}j`UD540VYa^0)2>Tik9PG~cNV zPOj^V+8$7!MDT`^zRXs`XtZIQ)6?2bdhKcJJfw8i<1$3$*gon^MXT z!>W`fL{kUG&JKHx$E)M5v!oRWCD*xL&0)P}9jSQh(=}v0JBpXDHr3@-@ET)&>eevB zXN%)_%Bd}nxj96VIq%8m(oMq)ll}9a(r+)r2$uZb;CCP9UZ081o8+D*@&8DAe?BMrXp;!hNTDNAshH|5t5Y#LI+?suD_^Pu z9UpdSQ}%llVGA>;Sm)7qoY&q#r)*-mgebT&M#%Ht^1DPG%?#4X~+N7^o*pbg7RA0;j+4X29W`*Ofg!MFvXWL$EY4u|4lb~YsDqSrUs*k^ToFoyrrmzisWXsg)uMbEH_!bonQ=dOXX;O5!t z+Gj_DbOvL!y1@@$Da0gLUC!IyVV*aUNpl-IEY+3S`4fGn_5C^N=ys=Rh_S0C!i(Gp zB_4=$A2-~Q4K^O-uXtKLu$Jw7ZlcMKQm^NxXrpaDSjg7=XmVJCpUuS3697C>9oOA4aDIhqqi?AhSf+&qu zm81>^C3*}tl)0LIo}y0{v`RVH&RI!)2W2jgDMO_i5%lq0hjUKK&YM+_#RgueKM}&K zcuMkk>Pz$m&O);LQb1xl%S-@!dSzeOdP+2|j>pfmc9lc>Cf3F5ZF?*E6mFaJH*Tvz z%o-*-oTdf5RXd`ZCfN=R03DmsHk3^lt@!c-2YXQ8lJJjMe<#RMQTuMx-rf(fFZ(yQ zI;-bD7S3QVJ?#&7m4-puy;2&x&VJvbdcE4QWJoW|<$9}s9{001;D{|to&Q|!KMXv- zM$H4_3S%OSOfX1*Fu#zARY3II9;MnZ^X{~FsDMX5(>#G_m+xwlOA?N0v5IeluKM$} z)mYd;eySiuFuKCa_x1$Sr@}0!i3#CG`_4w4ejEWDann(9U0Velm`EaI=pUTQ`OK&= zJIBG8S+XMr7vCb4B2d_!`r@>#9+0bkaep*dVb`=xG-I5Un*@AAjy%<5*SzwQMrFla z$hg(_?$zT>!~ME)p+g7Pk#Ppac2SPtpD!1SqQ)kr?Dd7boS1*61<+ESOfIl-4}>ar zg)kVFK3;POVoJEWM7$-uqrbybnK=@u?6Ssr2R;8uR=VnMriDhHS(L$Th=me>~I1~LB$?4CKG=m28Q1Vv62q2DtU|F^$LDi3Lz|(P)#RNSP=`B73lL|R`m@zmlBC4B>$YWNQ)C0xsWff z$|Xg!O8bGTdpzCP2FH3KXV%bzuXUCcQ~NDqM6?FIU0>R04!__o^sT?N{k(MUve1~r z;=9`I4Kj@%e!<1cr)(P?is@ekJd&5hVzyCsjdyUm%MXAE-Yvq{!FUxnU-9%jFCSk& zaIgEMj!tB%9>9Ludi3h($z7z2K5m+Z2;r+aj-~zuSYYa#gww-SJmHsju(8;=PloL7 zIJbO3fWwk=&g(}f{AWE*I_r3gM8#jGhfIiP=A>TC6>oZ{yK!wtwJ0v z^hMMdl~=gaMjbDU#ms=bQfClCG(u;JTd+0++rm@HvV!zMGlwL{S824V)!Qcj6rHBC zLCcUC)Jq?kWm#3KS=A#SSDfp2JI`!7kzL|X8E?`~RYs@}3RGSubW}fCVq63+&2Qhh ztRNp9iNB zN1)5yDI;Wj^x>25(CY#liCU6q(#Ubg5n4#TlF`c{YTOYT6LvCgDlmRqlr=GU`Pw7+ zO8m-p1NS=4BTkSWt8hsvPvKhpgWyM=K=4oXtDii{jgL5)(~YwZyxZm9xem#`l^38S zoNb~Y;w&$gIT) z1(yt0zXXE1liR1wJ{uLC2*Uy6iLAQK`r^H_>6Bb~JtqH+DQ)*1>#}o=6fv#j9ThdO zR(95_$0aTU4mSyBXfC=;PJW!wzzWr&`t&coF%e4Fmg#GNz=ZM))pf_dL>CNhh)?3O zXqQZ|Y@erEnTpY*rSlJE`TZwT*Rv@jC2cjwWj*jZrDZo);i)6I`PO}6vm$#hr>j3I zsOI_l0MVk!)~vxm!NH;NlxXmbIksf3N=4>m^N-`tO(kqFUtx-H7^2V+N*s*bi7G0J zqh3I9d-=%?H6zdJ2Zz)j{c*H0xF8U{6wGrDAx$Cu)7`f^WKO2bzN>+{?`50tZz7Lr z@{Sh{p8kwJJ>%<OM-X+}NQ`~YKt1ejaFbWh=gP2W zSkDf`o_H@#i#@u%x;pV~#TiB6;^=tbf9vb>@><}?6}LTdWI~?XHd)TsQp;3}k@{=c z8JB;v$Ys)%Ax^d3^Z^Gl2W zEG98+vs(D<@B29XFU+Yx3a)dZ>cH)Wj^VXco7`A?Fxv_?Ur-E1f3 zC%qpE0VXLd0OBy?+Rz`&N&+L9Q~KnRiJDsPbvq8Vq4;ITpWADhtL{2C*~By|Sj4Fp z8NQ=j#fiRqAH%fvW}vA*JE}(E45f1LC|iH*%;UT^{#uwAJV_d zYYcy}TY9qOhlL?*rakUd#_}eoURv@q?iY&^Jz@YvGHwjy6Oq?hy~#;EmrpgO`o2-d z-`HQHD+}Con9mzMi$&mdHAhPr41 zkuU|%oAiB+xPeJ`CMn*Xb36YZB4u*fKH7(qNoS9IXV3L-W`2;Y*FK?VtxlO4NQm*T zm-6hw7b^Ms%!AgsyoI;fXub-*X76}Ux5=6NP0}~IojXXG${<~yZoY6@z^p`{faTHH zV``j1rn0K4s@KYsbIENF9jDugZ|wZcCtfa37YBC8Wxt%Js!YFLaax^U>CFxr>RPD8?QwWdKhI|8WGFxIJ+1^zUPuUg`2rH5UWY^-UB~}3yn`DH2LkS24QJE zOrW%zUZtO9t+h`nh1JUH6j$%$Sc!ghnwD8~QtL&sJP+V8p#d`z4U!ax9>2&}G84qp zp30h0(l7uI?#u37Rdew)Rr5j$sf9U4ws@Glb;xikdb2tNAvs#^4JlptG6hiaQ&em1 z2%QpvMbL)4a%Xlnp0|_S@C(lt%#s<;>HSpdGXJ83yxk0+Tv~HVM51~WeUOvTbET0E z^m^}2Ppq^-h_=jg;*bXzG5)4vlo5m>F@w?1&xMd^Ft8t5bm0!%b`koR z^BFnZ4#pXdvz3l%5_Thzi;0bxue2`W$=|oe#;4-7u$f&xalt_*BwpBaFQS%^) zk)Hq9k?j|&w!$e=VaP%pi>w04WW1Z)kYU|)CTuVaD7~3qb<_S_#Nzt|{-M?PE|PAR zQl74j4(SryZIBY323qo-v}_dN;GhI0sRIq-UO3^{j{F8S7qNTk9I(^i=1%>g%BfEu^m3 z&g_IS)<&gjWk!UiHO5nmyu2CcKTD_IH`eo&Zta$IYqB(O1Pt<5UHfUT-QA3u0U1UG zm=A`#^GmYz(}uIJ7;ok>^ThV|fVcrA0T0-F6>tI9j;km?_|2wDSSRjVMBf3HSyMq~TXNK^M4_d)@7xM=wuFxeh*Wmoi}Q3t$s_>=Q9$ z@d~%<%JLvpU-+kD@41y%?)Rp&<#lH`-Sg&=37t#(RW_cui~v&$`nf!y1~>! z^(YJwP=QyXQyh;0iy+4uED4EM^L9N+{@r@#iJWbFYd*|wQ#zsJ%=mMDc#3qeBf050tCW1k<;|p-h?LSp+&7J@)5?n@_4#(4_A$4kzh_OOrCZ?w z=y9Wt!ruXkjq_|dMAr|^7WBfBi%h7pNwS2=wEXP{kYGbF1#rjtUYU3}z%&u|Ie;)+ zl~;QkRDL=Y`dEQY!hqeXjDXqs z-`ER{?-p%p@(LOf6e8J&z?ppe?aMtt5W#F5|9JN0a3{U3&@ANrgwO?5r`I;s5q3~^ zPCq()|WUD?>;ju69~(iSoB_~gmc=SY|iPnb@rh6cJ{oQ10D_>tyLLy zv;?Jj7-`ZNRlh62`~2hXp*mTDJW*DlAoW9s$NW)IqN*6A9;mqERE5_RS1+d}HG(Wj zWm_%6aLb4uOckhM+~GX%41LUMg>XD0Cu14z`-E~rMYzc4P+;*$wunfydt+{UV_*K>8 zi=UK#dUOJ@^UBg4{{ zCfwdNc`Vdjl3^okme2}4Hex

H>IM#u4f3RVwT!jgf40JNQT~Hf@wBYStIlf~G<){LrRN!hhQl&X&4vO| zvc&cyz@0HluAx-tuaz}*<14Hed&Bib4~(HYRy2GP2lj7t7ZCd2Ab&U~de!o{gLOpe zD3ZDzo#cuC%CpTec9jA@X~DzJ@UHY*G&YxKiByN~X)AEk3n0`})4tFw#L!Ro#K2Jg z?7n7-N71%Nw9;p05)X6e5(mbGiidO{hBL)%sRKmNH6xc#8|kmstxO)3Vm(7U12U;! zd2kmNu4_v-=r$11ekfqEj8e9bEq@|EC+uboddM|lN<3S;tt~@P+^!y7L#C1?+4^QC zJhPvWpGBQ5hfb!|%9*4iS~S3$q*nAjpV9G)h$=)&-x(PE10!vm=g2uM2>{&(fe>}* zyr-Tm^ojGe1uuyzz={oOvqGsn#A5nk6-qqfE5>~2_;6ZoYNkk?4RJe+Z1Z7-x7Ubc zhJROD(I9d5O#N54Z_jutu1%k7Abozj~Bjg$K?2k(FT|Nf7L zzx@A|En$>2>J$#f?Ku?wMCpw~0c#K;OU5!F!1+tbJ5MuZe|8q1}rY@^TT^yrpC&I1p~tjICTU1e-=H~kWn<52Pi8q3F4 zl5KbUqWaS#i$cpCSrruPB|FSYibNtwkeZ|#+zf`xV`IrT&Csa&&=GuPC`lttKcJ!R|M>359-YOrj8;_v#S<&0Oe3Z>gSw~k58Y+@g_BfbI^QkC6z$Huo|!v98c)C- zlet15@4O1wb-8;ab~)8hMUAl^`{}=l?k}JCe@FM1c{%tGC;DHOgSF&}ohg&WG zvW=E>{$)-MH@yDkC(rTAxLMuO{Fi$^4<8#Zn2(p64Q`vx3Ab>D8#}`jewkQXy2B0i zJ>B7k=Byqzw(hKsW=@`F4!^vm|KlbP=K9_5`Ilw=Kc$G9>s}ED=dTqX+)w;BQO_+s z%vf#z)Wz{p0_XVqs?M;LGam>}GG};OzYuJ-ok1=9lCDKc$DC<6aNX zy)0gVdnm#mrN`Xa$q8P}EG_=ji2v7(u~b%6R$i zmHindGdFV^TMxJ{Pd7ML;=dH<`*!HxdG>eS!2iA+?)%K*;^4m*1P|43#o65kPGPWM zH8+F1u{&GCOOk`7JFA(K1*^NcnUxhBr2wyjf6;kwkN$6+e>a!^-`B|@cwg<{(fbuR zu3tg?Gj8yZ*}&lpaK3}Pi>0}(6@1gf*4gQ=St|H@mi}%5|9{v>@dyZlIR$?y;^nxH z=AXjg#mvgq+SBb`&VA&}EF5i}e&HGJll~Gs&fl&1@2MOA=QV*F-aPQ}-Up9|hYPNe z4_+&Ni=CN^?Y%HtIGV%yUqUT?%pBoth`+{ve4 z(cI;asCjxgJN^;G=gyvRLWi60UqknMdw-88`G-QsDFB9p0e%%aKCb&H{+YS%mgb&r zzsMoKYJ`iWo1?9}`+rmFIDc>W@2M&Oj51!q`zp)B$9pf1L-0TK;klW)y{8MS8ys8a zW$E^ZKu5D*IqYQSWd7Hth4c6R;GXC54+(_R8Q@{#{-bl^6%hE3Ko2)(&*$(0X5;Ma z@%J`_^Y;$no-FeZ34(J>;Khua|5s__<+~5xpScMS6uja1y+gRqR|i{1TaUk0gx@=d zd*;nQB#@i$z9Mi7fO&cNf3FB|7M-IztFslWyQQ0#t-0mDw84oR?tjb9-@A%?63;&* z4o>HQ$Bmo!kKUB)S1kXGp0$IsyZe7rD}V0}?r}i>j20e2cs{~8AirAN`;h%9#LU6P z#tc3T`=dATd~OHtO<8T7EG&Kg+F<+k)*JuB(o+Wx1>3MZG~{dMrp?F!9~8E-OB-cb8#ATdo?@(y@Sj$xJIKIH+(&cqf`BnAV#LS^dPx*D6&20Qx32Qc zxKdPkMw))1bm}mfMwwGkN80dbaaD9{CaS;|A(r(!3R523O-P|ep=sAyv!Z9{487dQ z*ZB4U9os{liJ#f)?pLR6w-U8e)553-$-MSJ2O{=e(@>$rDmG#d5Sz8VH##e`)e}@N zrb6?;d@l#1m%jX~#F&Y>s1+|Qj5ZiR!c;C8^(ZOm+YpixJCbQ7zLI)tMO5vmx7Xoo zGSzN4SdX%u9-)3|YF-l1EDk_mz{jCL=*LEeKa2^VJ?UVP=*edjs7J9M3mL<~g z`n#(px$02+7cK8IhGNg_hYwiK8%E1xdlwd74pQK_^>BabYO7~0_CXC978ZAaO01z8 zl`wo?@P5nDLZ@N#dRP1{C{-r@>0WhT&dI@mIH3fAMIm&dpN%_a4S8*8*+W-KkbX?g zAYS`GDEO_KMM4&@8Y&5adxG@~duo;fhCS+U&+rIIu=|*LUHs#(M~dH$cNXWGy_b9Y z)t_q#f3w7a;b$;t3jSqVt0r|MmB$g{0OF-yGWPe}p{Wdc+ooM%@fwta3D|+CTRTJp zy*V>!Z?-q$4ZuipAkTH01v397cE6y_5RM?}&kO&=#865c`r?Uu?k zB0A=@N$?90_$|MMSq-_ay&qyb1u2dk9CS;sc$~MOG-ch$e$8L+4V2TGN_f<8#foIa zaQQK1P-*ih5j9Q67X#frXTqpI#pEH`*83L;ul03s4|FExFTeV`>aL0~*+&~UeKQtK zwcl?fWZLhuD#}%{ZJWMbTRG78k1p`6C=A1OZCjWZ{ZfD6jDe2EoY zO_1SpTy^;SkN=M9$1V$>lJnd%_I{1F;eY-I!k-kp`+#>N?(pHlA3yo~oY5W3^}j&W zyT8@HyO%#ELchpa@ZR#@Q`=vO|Anac2Q8Wzesgzc2Q&EK=zo=_2Or@7VhzGO>;KU7 zc<+&czfCOePx|i!{e`B-`>!behxGS1U4K5p{{xa9d@chY@$$mwGXfkua9G)|5sD6+ zWd_gCe@&0?AK>o~`iq+O2QcsthS?wNwZA>vAKW!KKqDr{D3yIcL9d*ZAP`FHQk&UP1K#iMz%FfAPi1B_PNN=dN+U-+}S) z!KWO2aL(T!Tbvwl$Qu_o2Yk2!f7JiL*LeSmaJ*0W_hbJFU*qBufGhtWhc|FE+<$!= zyY~?zKttw=|8}T(Ey(dRz4DjWg)~f#`k(ne;yNi*6Qb8E8#pwdy+Ro?O#-052+=i* zk94r}IIK;D=Ug_+m?^HQ zpF1a#B8UStS(t`_p@}Le&Dwgr_ z5Dbe~rchTF6u%KFeawShDK|KV!h)Ouu^*5}1S7nAP6890j2 zFfscu?6&SfC>DSNT};jO1zX(6hhoob8W7bOGENuU1+GFOg>nS;R``AmsxjpKG9~^S z3!Zg`kKckP6Zf zvLDw&0;6LW;^Y(rfbrZ+wIvtCuV6BKeO`4cwY^)NHcw2tD(@&hWuXUUU^wE2@6v#1 zbb&KnEE!ntU<3?Pyagat4KNL!VTjCTL<=DPuBS~{PEnpN3=Ye5zV3TFcDfk5rXn{0 zzD^?-{spA-PW>jTCuSlJA@Q||Ca^^pc50H%aWwA}rVo)tb3hzeR}I;Nh~8z_CLF$w zpGOG7Ae@e_qdwIO;tM+J)7}+>+mhq=oqV&{?V(gP1YR8)H56yvomG*-SfeoGt;oun zFq}Cg>dvS!RJA5don;Dv1X}sXZ;5El<32n@%3*vNqhdvR9H>s=MPt~5&@lF1J6)vQ zfJN=&QB&T#p`%lpB0~)C?$ZN2;?0_zR3 zn{D_g)=UoBT;>qQVTUo}LZps_@0h|rfRlG`$rHOHy+yZP!4E(wS*ExEUMSblh+B!13LC@XliMK zoBICbM19z6mBYgJH|=JaL-ZTmUM%yUylRp1dGkf`gI}C}LZuzLGp}ar_qDD34rS4p zrZb_t``B5zrERFa!Q7IH^j21@`mIi-mRQwolvSuzgLcIt-udC`-P*;&1B~45;A>vF z^TwdUpep!(@kcRHcd$V`le6TR;p6rdli;U`$JMHxLU%zw-}?qSk5R}{5R(s92h!~X zo%r=@_P0OaG~!!wzU3-o+aB$IyXLK7cjw$Lz{#)?6KTA!gi8)&9Rgmyk3;L!rU$*t z0JB(x9?=to7bxMzWP+D3MmZz|NMrAa2*N4pLHyhjN6Q|yM~k&h6Xw1gO1O0y;OUb) z(c6{>O1Mul!43)i)Ps(;70N@=5$1E%T_*|0WVJ2}+Ks&@KHOf56fKeS@wsS{f&}5U zcT=7>=f`)WNV_GZw>k^gECk_-O1L6DKs5$5saJVDQdM__*Pa{_ljrR(qqs7`&m(jB zxg;#e(nhiAK@4}?1K$r%ys&&3eqrOZz%E8?6*)$Awv-Ob)h<;e)}H3=X#6 z3iN^~CuSVbP^+W2A8`gsaVGU}VfR>C>JK=i9gVAJ(}h}1^31ZVv?w~pryY^KR#_KZ zT~#67~^5U!S7#A4Xy5Tv80VXIBQlQ#I&fzGk6LTM|lU(tc?q(TXl zP|vy}`-lPjTJ_OjkB0_W?c02$t-qc-*wAP~RokvnpW>2(ape>}_G#yHQT9QAq1CL- z_DDeUZq*AE{j8jr5Y{o_avCLmek)6_aZ4kk-7bA=fkkcdXC}w|=Gs`ovye zp1$K^{wc*TZZ=(2tM{QTio>ohSMcX*;)d>vzN*Uy9G|o({glimSzJJ|ik%M)#mb4& zEzP@8S@klfkFv5*+?*i9?l>2QBRw2b;nl4yhSAl%I@2JX$XEPx6}p<1%C+s5r|~Pi ztZ5ZP9IMNBduBbxR?P3hZRIo+cLU;v9gP}4tDh|FkaxDJE9%Y8P?p>4c{i31X-_W@ z$|_?VnU~svS{!0K{R}vxRrMxJJGgXJ=V1)dbQrseonw>aibP(iso&i620mmxRX}t# zZp@05T7GcRDm421>t>{|P4_y8A%zEiJ3SpKFzH6t5TvGv$;Ot$psTHi!_KLmx1RSo z(;Uyr_t9bP0G=Lo&a*oE=NL(@!=JpOiy&MR@w)nEJx)wG++GI9O*OMsXt8}vX*S0K zibz~xxU4z1zAPwKVgpgNQMUdH$ZgWAg>*z#_64bwcgYVk%`KnroAuYU@|d03W%dQ$ zT8_&*7(zW1^$fOa0Jn@9eA+NwCoz*}=wh+6@m&>0p`Y|<4DKvffEH=f_^>Hid0W222BMc zsip;6;_iVwm9^2RXUtX2!U|28X%CLZ&uaQO%Y0Y2np!KADA;Uubf6SALQV@CPTd5J z7Ut$n19LVQ?*$yS4NoeDoX{96JeBG6GD{bXzax$x5wwtB;BC{z|YUU4o_y+$8^q3Y$8!6@YIF6;c<1X?@rgN$@ zV^TD43(J~n{efRpCtUgf%d1jMlrc!h(a3qrIX74$Dd7puqH9RHT_%}5h2<{B8A`u#brq7G)SuIB77FJUY3^D0V`UBi`W2AiHFs8LaFLgNohhW$GH(59ep%8S&l!%|%GNVctBq|U(?V%XBArO38#%PI z>%IcwcczFa&8d;j(Tiu)DR0T9$m6BWeTnIEGvLHN|K`GuMzZ2kTPYBSuc}>)T)t98 zZ=k4crR(5~!2R%JLXV#QLnI_mtm%Rc?)d4NK2c_tx=|aDVs3mIhkYKU)gHld3lmG7 z3TCyfW6wJL|A)!ZcF3FjLYjtYNlHA&5K(ldXJ*S1RWoZmQqm!UyF;NrJl$hOq0(g! z-#E(ZaVa2JsyCB(v=qi`R$3E}7E4L1G7WKFv)hY#w|=rCZ-Fzox63KNpWLN7FD^M` z#>DpQk+1x7nT&?_UpgQ9+b2iVCw)P&ceqH*RFF4NmdbFgKX%R(^ulv#uxT-5!cdfp z_#~h*v|dm{{CxjgkF2`StwSJ-q^{je`1)DRBX&db!HhNZ2gTa zmKEmRc55CnPek@gE!@HaKrqyJqZyQN>nHEH=w>1xUoKa%MW1XEByQ5FVbf5{&lwyG z;1%yRbsX;xt4E@$%&$4wWhKjXo6lGn=z*2yj#~tAixqFMv=yOvy>$_9vSuvrxbVq| z(Qp<5HjJ`rJIP{l@yxs;Hh*4t+>Y4_2JuIbT{Aw{3MWIIZory8`my0sIxa|vtl0h8 za(uRD_6Rl4=OO&0x$;Fxi@Zs@RiWW5ZAGcrxi6$vlqfISj*c%y8fSAm`JV)* z6b<9c!t}Vttg*Pm4vjA=u+d7GP%{}0c36&2-(Xwl zelzai$P@Jm{xz+sd-kwhF4&sD?^JDLrQh$;4%MXQd5is`r1^ozFilUeP5scK@2 zEh%3S%&0^(rL3ID&f#Nzki^njnmx?N90W=}(p#OaP{LQU>%~(bffea(?Y(AgG{IWA z`;tpr7d|?Lj}k1^r2nGxoI%OSEt08gi{rv|Jt-LOJ5XX1;H#cYw|B~~J1o#Zr!>Xe z-Q87^7oMDj3`w#`G2;=7?7q@@PvuzpK$LG7ok9D`I;*Rc69d{O`4hdabYB(6*bWu! zlXzKx^!P%Xi|pw22AGCvuPg+Qe1Br7D;jv=#_y zWk@s!T!x8%CF&Cb2tH0+!dP>Jw9+N=BcBLCT4@p=0ep?X9|69~;A-?WB1kJsVmk07 zU)&hC?-U@&lDG+UlLzBLgqah=0D|DepMW`r#0L-$3|f}NkATZc@z;2L6M#9^#3j%g z6GWIP(Foux2^K=GlLEKn_jy4a2>RHO>tw(Q7;Bsm;m3)?0AFb^4#pY{M3^xV73kJ3 z&WE-p3Rz%I^ar}V7yke}!GJj6_W3~;m=d2s7HASZ0eZ}dQ-Ee=a5>PeTwEL7qFLMt zuWuNjN1sRs*v9R94yngjlZCJl%FBcKL2G^x7Tmr7$Pj_ND%cT#1}fA7vjS|1<&(uX z&@EnyTVYtFiCdu;s)4Zp&CkFS$m;BgPaqe_>W>obAev|vS>na$7IotEXoZI0PXH$T z7b;+5NE}I@F2o1Or4Nn(FyYF#iJt(!5zAMJy8&OZ;--ts?spZICVn6QXfjM9spf{1 zdg4M4Li{d}JW<6u7ZLX-scO9E@Bhz6-}Q!`lc^FNe)si zN7c~LC^y4uAU||2)(%V1$BHeT64xmA1IYZq+i85Ak9dF!?^qicU}dpfWdbHzg>+>VshMMa&=2 zH%=%Rp6{HQ8c2y;_dW2uA8B>7_GOufu`}x~r4f}n58IVFk2t>d=Jm}kZEkkoX(nSI zh7u271fcMWl(&5~NZ6^f+x^(EwXRT$&mB`(?)H0AjdJ^2>QZ zHr$KXFmDkn5)z3!@DVHI6gYx+5ed@+Sc7utk9Z;N1Q#)|bl@|*i%^&XAo!6>D9prP zsh}CO^XNzrG71WKx=a8Fra7_(1V23Dgoxo^ynwj^sPQjCVAmqi=FK3#1Q;hE7<|MA z@di=S9r**C34CH<*}x#VWh{UksP!2%9cB+SraMB1q@%S;FUtVfaeZFH%mAZ!0@C2m z<}BYHZs`F~(I~++c`#9c2=D`1INBavO%%)-O;~E#7SMur6A9A*zNW2-g%JR~@Gp2F zRKOq^Qz3{Wuo3@)4#En2z;HwgkwbH!KLSCb(1fLzB>*_MO?fbSz&T!1I!pw3K<`2V zi3fi0!z5@1T_HoTfYSs`$>IzUAyCC57a>Rka2i)vd6^GT4qA9>N(UhVrV%tnz=nZo zc)Cwb(ID7>ShNLcQ#^D7)^69 zz!!O=ekvUuH|n=H3#gC9&f5k?KbD-h_i6?m;J|mQ;JXDU?s8f|2j}qJM)+>giMuoW zZm5 zoGdZUDd0;=U4*|n{IGhXiwgWu?f~(@%mA@dR9(b%YF)&9mBUISlR;A@JUJbn91B0& zaIRCP6sryTc|fGtX7hnoy?Zv%{=%aeuLCm~q4UK2Tz}Q^5fP}(=7A3U5aIqpApDTA zjF5LiYix_b*H4Rdhu?VU>-*|^q*TN7Fn7J$$uz5{aj5>3*OozniPMr4QDIDD@~R2dX@qlLz0$WbAkQ@4;iiRo2s6V_sM>n60fU z$(cqE$b9C~->#?+l9Y`r+IdvlW!qK9d@c7=koj2Xr}HB-=B$jKFkMI}jb&eV$HU9R zBZDI8o%!~wmoMp-Zw`Z@cRPTaVE2%TIlKZYDk{Y^4-bJ{_=?4o&DD#A?8Dj~Oy|-Z zP1K+>?^_?$v$`8i9`SKpC?iM}1RxYgz!FE0p$WO731O2$FbYMuLIi9*1dfTp_r(zc zaS*>#!FRwRZ4n4ha1cGP0b3Lx=sR3-YjDUjDTF{Q#P8l9Xf^zJIKmTT#P7(!F$EB` zT>>FD1mTJqs7ehS+r$;mlRyYWNBoWk95Vrj++rerX8=JHXhLp5h~M#mW3C`54o!$? z2!bCqU`qr9HOCbXhVPI7wx~eR0$lO-CCgMf3mx7y*diS%6~_ASe>9_%%()nFPWQ zaRg5(gb4VyB*IT(z!n(@T0#@zC57-41+c{gf-=B&BoIUp5$g#6HmJZc_yaadAvlI1 zT+so?h(XX^nve(Z8xsO-xPfDjaK&-p_W~k*2Ls38w>XEN8H(@$2e4%fg8G9)4k8hD z;BkeA1_cEDfh+DUiQp-Tun7NgY=F%^G(ZPu;Ji`dvI>4p11PwPGUez*0&R(laU~m- zuGK;HgCa`NJSXGgr!aL#>Xe=MFm)pV#;Gx=rZZ{E&JXw=2jkRbn0hWhjNsnAWkL_KPqUEx@-hpECKYK4k+z)o?GWcR${d$*l%^BHpUt z7(26ik|UC~p2w@zT0tc+Dc4{HE6=REXlmZb`PWT8-NXNELrZ@g%SggFM$=mHGI74d zjB(v6-pb-z0sZ(RkEAd768+b5TsQ^zM`yub?q0sXo8WeRFhjO>Re0!=w{e44**kT9 zg&HV0XJyhV+bmc(9>+r`O3pQ&FDL1d*vahm~4`?LQt5&^Hz}yPuxQs__}L3GqirHlrO22zwHy=J7+GYwFNXVEx4O3@h?6 zMkc^zZDThdz!EjM3YD98%g6J7`Pno&b`|q+D#Uy^{aM|{pp4SsdgWxg-VYgDgX)UG zw=UU82U)&9Otkd=}YQ?>0SqeGT8O3KuN04QCprY`L{4_Y^dj zPoJOVlWtgK`&$s^*#^8QF3Qhav$}Eha((cAFf%)M!lq$d`%C1)lPoK%k5As+o$5uY zj(Wcny#&(9snl#Rx94M@r>{7NJ0nBc>#W8k(F>(OGvz|#uB7`wyzV!-s3{LKm4JBl z6D8}?WCPuzEk+i?G;D4;xTzuMap~!esJ1VI$4Wk(A5P>1Q(+iX*E5_&?0F^4`aGm% z!xwxOF5T+!vDHvSw?@}RyK*XjDz=-6XIN2dcO+MQ8>laCl2dQ6Sh! zrYF6}wZk^)^>HP^L=M^1|3}?91?Lt-3pzQmZQJ@|+qP}nIo=3Sq|=6Qmd`@Wg`8jPFN*(UlDWc^f6VJ3r;h=Luy1*FtS(^f(% zR5e#f6n^H%ENh}{Fc$aZ3RfGT!d?A_(yEHLZyfG+f<(T1Y11OTv3>{JAH&?{cID}9 zoZnPf~e@^oU0f< zb?&MU(kektic7m)=dEG*mm&;G+DAP1J9nq_OSrzg9q#+%<9D?KAc5?_CydtMoGdqV zlBE4)vm{VPKvW_W#YzLY`H?0Rvx`GPEW`Y#G4}&&F>=&gNQqKNgSn83q7rU^Qq-4k+YJL32mTV!lE4C9i_`bF!^TXy`dUvw1O1EKDb5hCtKkg%cae8-f#THDxcf< z#c%1Zv!P*cdB&5!^F4NGKk>4_PU{lw^}T3FamBa=AdnZ%leC!k_?J&{B~Ot|HuOXM zD@g(uAaDoAdMQ%&jsvvQ+0^oT5T*zs_N7VZ2mSH;MuE!KF@8bF9VLb04oZ&oh9ydk z-gE9PKo6p7sY8c&D;F$f+AmgE2ukjOOXTG|tW3OeuML|)v^JjunCDq%uV;53GMtZ1 zwq9pRSegBN8!8RgNzH6Bo$uZ-xa~Y|W1YlkQ3@^*9w1z(yfim|Fw!4Z`QB`4k>0A_ zGGQZzTnw&IL3n;usD``Nzg0(~NXslT(a`G2eiL+HEYC)@V$3Eg7gW|q zlm5UcteNTj&g`mH&r2De9=_Yl!Wy0x;6CN+kG|smxCq?90)67@heGRwf=E!ClNLg* z9VU&7-X+Z;qsu9X?(im^^Cm^<9P?i+`UG~?%abLJ$%ht`(So%N?wV(uAG%UD91Uw} z^`QCU`sS&LZvSMZdqg#5j{6bxXKlA&A>rYDq!~;m5fPLn2}DjL^H}6+C1!FW84`^J zX%_S&ji^Cko<dWeM19{eQ%BT+9)_#1G)9O@j2y~= zBK{DQFFnT}y(sn&svsGKdSRU!*j1-|wdp(m#vadPsQm@X2_(b!{drsVlE9!@9xrhK zaLrCF1&+{Y)+#f{Dq4|vE#`AI*@^2BX--CFZW5_Nj5u)ADk+p8Pa*+z;`ucMPRq`3 zg2hvGySp?*H0_bLZhJBLxbtu3PXrPz8OnR@J@Xf-Fgq5oC6jH@yv16n^Eqq?7kg6g zFe$-=#~bWNw@vZPCYhi(&0#2bd#@y{ZzUPz!cT?C*1m)RlJ zv0gJjh~;K?ju*kJ$An7bc3h0yuY|tEcQh5A$`51q{cNCC=*(#8$uyh}uk@KJA)GR- zE%29(YDE1PL8&07`sF4AZQJF|nB!Mxp1#BSuJ$lNgRHiv?&h6kERwRiOs%%!VLm=Q z!rvrT=DgSAeQ!h_P3H4c72vQ|o{qQ(u9qxU6DyKmsnR;Kf`u_OXYw03nHhLTf zW+S0sB%{mWaoTQ9%5NUqW~GO^nRs7f^AI0SY4Ey!^bHZm*x8|xX)*F^vOfLQ zd?U>QdmVs3bNg$!0K+vR)ctNE2^RZfgPa4`d!lNBLbJpwYjCM*)<748dOxh_ZTz`@ zUGaI3inap&g7AYLpT--LEq+Jd&=5`LN>LKc83mBWmAtNqQf)>3X zR_x*v70JtP*e!|e@^n5|qCwc^@qJZUUnxzoR%467>%N%5K3}LPUn-AN-H|UafP>BhW5U@_ zV%*3BQSzusXks%_h>Egozc?kFkGzt!87Yw($%Vc+Z0wAj{3c7bH)WYseJ`p!IZk&? zQ)fEANw0I*q4kYm4FV>Q?}4(Q7zj$d&Jq(&=%T!;Ew=Z14al`$1>jB%eX5>hY#B~d z>z^;(>DCkK|15_w`cE$Jk(=xX52P3j=}yyc_zz+h*JH@rb2+vy?fz;Fb}hr-E$Fwc4*QF+ zLOj}RMnX3v%7kU4n;vvr*0M%aF2&6Nl^ss@ERmFNV2g~yPutvDEc>vTQ*cPoQm!^ZVAQ(I`Pd7tvQ{bRp;()Tgr z_k~3KV&h|uX_a|#97rRAsE>yjfsq9iK?he z@0w=ha1M8LvEvn?S*!YJeZ0;>3^^{EWF#~m=bLH%t*};1{}uHzir$NWQ*mk5g1h9D zU);7pP5kl1<(uJm;8Z~41C0wR?M@)K$LqkbG*T~gRa2?xj5c30i}tOzNq|anrd7kj zfH>k|(pfWqdId8Bqn}ZWk?rr}h5?7m%XRB2lL|8c zLojBqL5J7tD2@Gg8B~yBzqUD%-X zd7eex(uBomj;Fu&zb*O5qiE?^oKqautJ~9aYidB*6v6k%JX{PrhfS{v=H3CxXY10V zyr6w%gES!Vem*9t;)Y?|mf$6}XTU8G9+yd4Z3<7!TkzNKr&ks)$;?363w3pAYvt{< zI=`Ea=^N_2yicoe=mlyGS0jH&aUUcIUX_yVKOuR(6voOs6t54QYzSXea$VUOPiucrwk$HwN;Owbjwtl~)>oI2$nP&ev+O778VLP9tTPo3Q*j9+87`Q7R&$+x5CwGZs9cTb|une%=uT zL5t2aJXoD{3CgQsh|Yjy!x-jGdh`Ohc04asAu@{1VEJ)}tx5OHt364h>W7K0Ma)kx znOrsGK_#+Rzwu1el1ZuQw=+3qxiC0ZsK55dLa^Z$1OkYYBrO?;l=wnjmZv(_VVH)@y-~kKlgXB$mVSUQE8; zB!zE%tf@&`5mD$UV+;p6K$Rw$AQTn*HYDCm0$-RdLBeM79@f8{ap! z@U46LV#MY~U5ot6TI+pdGWS;6Jq-QA;u$xejx4}vI(rT_)oINc1>ak!NO-$pKd*}u4)G#NcW$8V~rG{=_q2zM{Y9yvQ3i*P$V)0vp-@e z+1ss!uwfP9tzfWGa7E3|D`LVZ=R@(48@EEc3UbMaZcZQl=1H2uk``BJmG|5X&pw}X zuIZ$w$Z5fbFWMHSiWati$6Yduq1Vz=yzXgDq|u zOU`?CZbVgHIJTP^&v>zzH`!f49?%7H1PvcL?e3m^Bya?Y&zJ4S1iQ$#(_>dqroC*# zCtOHw84vj(Vk@gMo?j{mx+XqrP+D>+R_Rf+gS7`KpOcqL3r$#_NuWgRJwk!Ah4h?> z(oy1y!sHbzYwRcRnN@PmT~KRbWT77nt6*#<40s;dcT9N~iJE7!z)MoAPrJlver;r; z$#17?bIl$wQV*G*B<>&PdS+o?l#rvIl@W9mJ(V^j|Lr;Vg8BUhGYA?*u zNKV{ujwR@qLIGsUWscY2Pp%Hhj{oH_x?rioXa$+EugftYWm9a`igoS!1$6mXo=FHeaUps`dc)+b{lJpN&&#%si)%e5ACAv;-ATo{Ud`v=Rl@JT!JfVBpjz!F#t zVRA+wGLQ1Ir|A$v+i@-U2XPi|#rY1Ze8$fPi-uB@Mcl-7JIp|1 z(W7@oH7=5bjz1)pQ)Pzrv6yCv?#6%0BLl>bZH5*LSdfXE|ypJ*JbT zl;hObeRlD=fFhU+W*VrqF$hQodmRd3^o;ilimO|m8f-P{L>Unz=E>+DH|N&}s}lx0;Y_XZH6qInRJfo zm{ur4e=KyZ~GvGA_;#^{e4odhX9MdJ{tf>>D z&DEj}$}3z^MvOF&IZng}jeq5UYf}v=x(u((u}*+t{#N;s5of} zv~zmnr>S4reb$%f`gXrxT_zt)ZEq^lDvOxcyYsPLQ-r=rn+ygg+$0h*!&6@|o*ga2 zbogSI%gI}kA9t+C zqftz+scw<2sv3u%FGJXzd04`6-^kYB@b&qY(({MQEXA}(uWRw8rC)i=vfn=UPxdX69I8nRR#i z#4?aDZWb-@)GVLc(l>H4^KM$)CA06C@8P|q`Xx>N0%5tGo1?6Ml8TQQL=Mt2Lbd)X zkEg2KX%O^Jh|RdZD(WKt1Y&R;q+Rob*eC67S}GYAM9Xjmi~@@Sd@ry~T@az>rrcPmy<5j(ktxqj{VARHSwZ(&}I5 z0x>^jKbemQnwL2LRTcD*FXHV>oe>cDLM@u|mbfxqsU-;Z=*w6faN}D4rW78>Bm<&p zYw004`p>&`gg7b7&p3**vb2Nz{I=TrNndSaN`x4l{cS@hZTS+5H_M}J1n@emvjrv8 zufXDm_4hoMN@7bp$YxNS{s6=8S;=Mf`egp|-umK3bw! zVPp`Hp+ld-C{ejM11nm-h%JlzCwT>>WDieq1?rL0O~^1Td75yUazP7=M2&h-Nis!3 zN4Ox9qi148d8l?2L4RAKtD`4?SEb8dL*sZR5o1NxeT{t1xgjp6eZjdKGRo<)Ci`F@zpIcc_#JlS{gBw#sXbe)(qcHZ4W8vdzy9j0_aHW{jS1Pm@dMz7Q7A!$+xopo%5_P@4ev$B z_}S9x$?9qQ6e)P5E&EoV(|)Qv_&jv-Ens!OGm{EFh|fM+xVq4Fg!e>kh1$g#r6ESg zu-#s+K;pcp6)&7e8$=`(1_z5M`j8F!cd*RB^X;Vcn* zHPw4Mby-~+JrLY=aIrR8l4|ju@W*>%`QenN^>c6J%n`LY#Vn~SAfheLW>tFvmj`fNyV&r>MzUCzOe(X;M_S{-c_Yt)o*4xTN|h4k-^2AT zBLWb<*%ibTlcG_@r|>yF!IEQO2E#fs6|TC8Z>!j$t#{#h{XrPldp!96{GGobGkT3$ z>8|jwyJ$*V)%*R4jncLJ6W!<1qY8?(%FmT3Q~B8-Bjin1;EcAAg6J+Q^otoMcM&Hr z{SLvG*bY!A^xwv1# z6(OZaKHJMaPCaaFA^Wl}CfNz>c0?xZGw+F;W#%aJs98OC>_4ib$KIo}Y-=(f9<8D% zw>5Z6(WtQ;#a8Gsw%nDTOVQ0@r14_;a`*nrS_{5nI*?75;Z@MI$7VGY`FAnPW<0eL z(KQ{yCu?iS9RLnK7OdLb%{wA4J|n7+`-uEWFFR|kR^&a)CPGpQ-IX`RhL;ng<6A0! z!^|U4E64}lN;zLvTJ-X7<-$(Hb`{0Q=t%2{}d{s4mP_>d@No77owk_@v^GZQpxNt+$3hv zwh`@+G)~`dC$&f=a6TjKIvXb?!! zg@SOu0iC8R@Zw$nmSb#(CvxMXTiyIheUh17eNso0S@{;(;P*LLmRPL1=u)za*M{N% zyPc9Voe#JbAm6olh4P7pGbpDIfcvvXh;(lC(-A4S!}S9c z%Q}fU^UFQ{Jcy4+@HlIUZ^`^PiBg#OZ4*(lxWC*>hznpnbeb(U&&~8n(lRUD!{R4T za*t9wVEmq!%2TYvwUw8}NdKT9T-bg&>N+W^<6@=MB3s*PN|Dhhe)34taLVq^L)H6R zEvsQXI|*GLr+rXyVWwec?C=GN)6BVrj&Cc~mhCutryB(iQXuCIRt>5jdPMHM;@hl3wTuu?u0+Yxh5AGd_7w7vU zBn{G!z~79tGLx-3>ujT)8GE3Jax8kPP=E-+H3~~FcCRd6u$E% z@6&Z!R9Sx?!6rx^!X^j;kR_PoD|Rq?VNu5N_4>@y+W4&MMZJaZ_j3Wmx8rGxXKj9t zetvJhHgLg^MLfNE-Y=%vSYD&h$b9;|WYg^;;lk&e{vB>xf>rn8{MBb67f6xokQWM+ z^V+_tmb*XjIT83mC`E#fx4Qhe!}4RuaC2jZ?)e&ypqEdQSVz2y;eH6Z-VjLldJ?EY z58gy9AMh*sN%kcvig?sf_+sXT|2jpm+<^n}W(m7feW7s~gO+*AsgRofmBl%eQm=4C z?WOC$mp&s4!xzw-oR?KTk3e)YZU5OKR>y@IJ&d>TVo1jPHM}?mclmZ;4ku)tCvbR= zy@VHs_w3~;)TMUqHg8SQd*>sxI{_$jo~z>d9LdN+m%)EOd?)Z@V#DS^6olhczE5Jq zb}l{0Dc9y-_Eq0j-*&wHoZX}V{x@n7@Aqki_mqWeBSoDW#3nbTbuf$ytrO-o?2U-6 z7e>;3?9ECraF!oW07HdZ4FBkZC&XV91plt*@eEGi8X0-48`Z}5y4EEm?&p^~>6TdA zN2?RE>iL$ye5KFmxl#Vi&%+t(dnRzOpa56MErB)@eXRtmE|*K%*y8fW-DBSop$o-Q zh}n@^AsRC?@;*>!AA6lQ4G(s&S9_5ywiLSY;NJQ6*~!<}jY5cR5;zMZAWYrM99w#F z{aPx-atJKqPhd?@zw{53fqw|J=-<0T){n_sx$~vL1k(5YJcwno4zd#}?oN)gCy0dL z8jbV_#I~qhcXXPxK1Y$_4e?w%5`G?-kANwf;w@EB|JHA&)&~F-k&L#S$P=RT>gxpI zSQp={KC&UTZtmW@!#+m%flAjA3JfyCDDbJHz4kMmhQ>@IDdn;`>2ML=p|O z`BZi=wGNWXapR~>Bl)yQ(#fgv7Hu`9X<08Td98!YY5E*f#F>Mbu98u!DVN84oX509 z1YTw(XOQ~dv;`dgLElvLer0T%bMwbk;JsMS2p@Nz;b}6vFj~n)`l)?LFfH@Ku7a3u zB3V7R$*#IZtVfPe&y-H}dO7Qjt_Ugi8cq8N ztU;Y{vBHG6Nczi4AwhM#(pd3J@ditOxMd}_v^s;$!XS(IN_qujCLLGP>Q8AmPUqcg z^YiCVa&EPvo506i{9*9K`t;Nq58eew>lQMS|M_jGd~#Zh;ll6eoi3?Dx=gOi+j-Zv zGK~#=K(ajtT35_-KRbgY^UP$_6H7pt`^#VRLcIQaPPe(qy7k3I@}?HCOQq+< z0^GMUhfGjWg=Q-kDbHgTzao&ML_i+$mDD}X<35uWdFGU>#Z=p z!o7Y=DeWrvyb!Og$9^@Y=EbRIj;YnvQFVWZW%qun8p&Tvi61CbM;Tt&;4tmGGpju@ zeBBr|jd}WdHwic;;VBY33;0C=#GJ|+gvId!J$^`-lw4(O@oCruvGSanwu2(Ob;8{>h+?Sa*!&{pzkj)?7j)*RMac4X6q#}sh z_oowh7K#p#S{8QLY*UqwFIk$l9XY=y*3vzFq8;B=_v`ub2Dq>UEL;O|Nxo_(ReKjq zJh3HDwarYQRNJT+-LA76iz$n6mbKx^JwpW{Q zTNH4X#Gw11R*P7c& zj@$CVb3I_tbKsMtDl`+5=`lW}zO6V6UneHnakN5a+Ng9$sWl4AggGRWGcn+XBAmFr zkNn-M^UvUm6=P9zA=;=Ly@z5DBFQM!X-FAfBGho(Tl_aZ!5-D|($(AC<0SPhvBg<- zAB%Tmivjqz_DzJZ*E=m9V*bC^U{k-w7n{3|5lF32n$bUsNcq4TtdhSCNb~JWXpu~= zz?JAP9{2)T$7hM+T9t~_zeq$114A%S2BZeKog^Y=Kr>JL5;$V2co9DhN~U#RS?`vo z2#VOzWC+wd|IM?!rm!w=a&I#?n3-;3SskLQT=teU|I6{!tv9|~iM4dT)4H;((rNS( zo}|)=%lQd~<5p-Xe~U}-D$RWImC!8jU>iEL!;)A~iOi7eH>hc)Tl)xWw=MsM4UHCh ze??ky#;Q)dE{=3=yG*d}zu{)PDP=&|CTkYfMi18}UpDX|DW)4Z6(}LvnygjLPz`FjwyMytWs{B89H@`hJ&hYq5`vI5C4K&dPSBt?I#i+#yt*BvvBcI$ zP@?)wO^^n%s4otI|E>N)joyM9Uy0E=wvq0Q!JomApaeB%FWf(m8HQ}g{aYsS1|9ui zsROA2z?t{>U|-xo?~865=QV>fg8d1rNl=niYf}XOC=UwC`}14fHJLRGnG$S}Gks?a z0O_z!;rac1C33l$4s29Zi#}T`#8LSJpH7SMv>~=j!=rPsNcmh;yEc?RFD>{804*bq zndZVyYOFdg{qB0-7V->RRnZgx4V8yZSA-8cNhisA_IiW;fiqU-hUcp;iSCW>)}xuMp@ z7ZpvxAGyt1!ofkHh?+ZJ4cT!F(P#MiV?^D_0rA>wn#mXs3V`fAaXvQqMZ~e=zMu`A z?KsBJ3u$?xnA0mp&%_A4_hoI;yHAM%b@MLEvq1MJSvv%V?^Wr1sVkkQ2@ve_$g{BW z{loffa2MP@7;BkQB1u9%#qc;mCoQaPZln7nNWIR(hvw<6tZa6;KiTn(Ien^Py1%l< zU)C{FC)3(n`uYhhx&xp8(t+jo8ch-sb4TTsPzAHU8cnw3*%s7sx!k{}dh=@edCh>( z_IMDA)a+^UXf}(pZIRune(P`L^L(P5kWJi;pJyC?oVYM=)ef268Y@F}3E7+^oaoI6 zP09WmZkRaq;u#PGVyb@7c12R-$UC(Vk^WhU0w%h14^R@^AO8vy+0=QGnL*!JICsM}*+VF;%DNsaUS zuL(df&|&ZHqpk49+*4G-g1}!}hMAG*=ryO#B{XiV+c)Pp;@h6fnWmmFEn72BCm&sl z(!-$SWxbterJ|KeUCxnq9ZXXkhJLQ6HgQbVE^>xn*$oMQ3f*k`|6H7olW#Sc8_l+O zZkaYh=PX8zW7rd<>F|AeRW#proX*cj4oAyPU7z@G=;>*3^=YXnF##%R*VE%w!BM~L zQ6AL4jjK9f?_h_1ij8b+j9~MNqFx?U-5KSa5Yd@u{rk&Yqs0~CWp~?L0Po^0s2cuD z$cYC8dQ5@U=*dU({z?55Cxm}oX(5V*wRSyXT>v=m!?-P|9@9(630oN}8u=kL?VM+Y zf?@~0rsQ5S6AZ>JAMY*ntqqRy)hG~ApNYW-mZM^FhvQ1fX=-gB%#Gphi}B5}4oZ*D zZV77l66PH}-`ndkM9eZu6hncDo?`wI4_!(aVP6!{)D>4)Q!P+a)IP}hEP3Vqf5!;# zzEPwR&rQJ1z#YL|!L7mVL-iCaIGmU*7>Afw7~6hEOs2Y@QG$_@afo~5h6%vL$h>L~ zaNjP*Dej6;_DXVqbY@g0G$s^gY}>c_ej3w8G+Tg}Yzq*(%qMY&hdz4Ba++{;-DE#J z0e7UfAKOJmPu)rmDkj+IZ&^m?D1;-=Uxk!zgzC9ijD_l@m7d9KBAa0Tl2vh*Z*G)z zQ4N_*!lN~HJp>~poriTbIVDwJ9F29b1Or}L(qF8q{?_9-f;g-6Joe-`fH*DpJbV=k zmN;Fl3>@Wu#=RE^d_|PJ<{==J1Q!cM1lLwLPY=lY2i0(u;Rvy>H3NhUgTMg6y{u0z zh7Rt#-{>DhsC(ZS?`cC1?}lE}%P9jNO$&?swi9vQD8Wr4us)&@{FPGssy?;S9$KGt zd)5m(gvE?m_B9Tka#0G^IR*#r~e!~)xE-i`@4IMDvP?)!g*Uj0wf(*FkU{CA`smj8t; z{ZEddZqlS(B_m?UvmZ3Wx@d^49|=)0XyicQvs&5{Frd(pKDtE`s&V*pHAEhbylA}A?s3;uWR|UDEw``!*4F6DosiyCHsW5@Xb`?8x|uG zDUH_^MU(&iecpTX+pKF-Juy_Xf3i)+MK>&A!(f_JswBC>WVOXs8>(U6-!ZA+!ULNh zeE8InOu8hxLZsZK3&J!%lS-I&lSnNn9*aN#Vg^5$>mJq%oK*(vVK0?R9tkFy=}>_( zK0~NLLf}N{U<9`Q*8o$J07JDPT{xOdMSfZk%gAq7@`ePm#p8Zt9uZlIdne%P~x#)7tO< z$1MM!aOnSTmj43`^&d2<|D5JU9ql;UW+cCD{n_b+8^@IEIi$I%Y`kz(VnMYrXTsm8 zz(^Da-{NlXO1AE;`n2b9ar}JU??QC^U*}Zt4L^NIcCRm=^9b_#{GV?NG2(Sf z68o2dTi8UZzgM1X{Wbh{F}^1-L3fuALm+OVZk9SkJ<4QBO?_5Iyq?MEueW>O&)$X+ zqICGaKkjzlNHK1f7}$1x(Nr_&>$39}Jc-O?KA{TYXo%FU4Sq}IL1NK|dT)UIY@ zOcdNB{%hR~Dbh^s=%JDPa_s+gm$uFK_1?LCw!kLu>*?#|4g-T-uyFU*k5aXS_YEQV zcKCQ)_N+wx{d)HnN8!+y3FMbBe!iXdtc2akr!Itp7HCKJmZ?=WqZG7M0Tl?75qkR!-D`K~PK)Wno93>$|U+xVrj4*WA_R zWaXwZ=?2VuqS0BnPdhG#C}o*TGU`}B+5V@9a-H&p5}j)H$WKh_a@o9|_bb*oIx=w5 zx7HO&K~Ta}kc#+VQm*Yk2fbV7UF zg!NIg691k1L17i}U+3&LmRHY_L?=(5Qie%iB4e8`?bdea%Z@5w?H<nvfl^c#*kFbJHz02y?Qo~z1q=n6!&;0#RP({MPE43YLB6mnmPO1*!g7O9Xu zGm0m)QqQ(FV4!I6W4<Ua5FN_YZlPa$z%>NmdLfiFkFOe_wX6fLOq)e z#yZCB!z*KB?OVRLw~lwDSw`XH%Kp}G^8VMqI|8@a?O@W%{b$RpURIjg>Ebzy6EM>qfNGo>PiKR+>Ia~-+qBJZ!L)(WW}+ZYjyLH!89OGr>*6cHpNrlY_!-a(Sv z3CVVmlSQ1~s)y1i(w&rYAR!?}x`nFnk&K|^B^nefk}nLV69p--)YVXSdYLpoYZq8S z!u)OI6t1*QC5oaMcw)SE)=81#;P>xoKBkU zuXxv}d~OTz{6E>&z;3|uC=~9tNs5-KHYUj{oUk?lz$F}+in4<|vL#E|Yf#l_&HRhU zlCi->IG(Yjd~UDEvbt>wN|%bwJXIcmeJ>J1yX|8?f|jFJNqZfXKo!zpA?c9F@0Ce7 z*&vmWbUPkZiC14bwcK*{tEKQ=z!;a9iB8N02c67Jjr5prkW4RPS9X72)*c=gvq2l{(m;V!rF*gW2=SUV)%qEn05r&u9b64~wVo1pQY9;;Cru!W zgotiYIyZ**qHWpnz#^UTLNn);qXtJ|jh2MuwHh^{zV7>R2H2E>77!vIUu1x`oy&`|el_I)QGV~~URz9hKc zAP4IQ%|8{(kp{X!24(7y90DBz93&;Z9Asm{X>P_1`(k{G$M}2mX;&tt6dymuMT@)K zh@26TIo@8QN9sm*mM+9`DSc9L7RwIYgRpg_BOHmmf$EcU^L2s&GUT5Z=EVb0mT=Ji z%Z|%bT$>tsx5Lhle`~}wI~L=h`G@&=l@P6Gy&nrLcPYCGrfy|l%6++^nGz(mCFe!d zEgt4xw>jmnMj9kw*#yN?Gu2t6n2q216M{NZkKjppJ5zsVStEuStjbbXd?^cIWD*opbsqCf6`9&pP zj)b6+l?}6gHwvzBUg21mj~neAv0cJ~N)v-GOJBHKPDHJiyJ>EAbn4QU!wG3n)G4TQK>~}tTe1pJ4 z${|%Nvswywx_EEX@XEa&_mOw3YsGe55zYt6VdG;`^-A}Z{wP&tytA}}0>q|oh+)o4 z(8z&9fbe2ao{0b+4Z%MWv`Wd8rH2RU$fnP^D&bKm&pv151omu`~AYH0y}X39%3wZe1XM6@qaTe<9A7-}sW_jMkmc$7VD?PR{o z`isYb?>f^DV>-{8?;pc=z}|*o${NslZP?r z)V*&2v8@R?$_MW^$b2@?yArE^IhV80$6pM!iy;HQai`Axcl2x@s%qYaHFz<5DABV-v|EkmV-p^lwn(YOF(#U0OP8XL4EJYyy8_FL7}X1C?m53net5uyOb~ zNSqOhHy;J_<+iYjNoe53O!% zmsjM=!ZlN9!Ya}D0K&c8N*s%NZF;!q$6pwmk&#bVz<)wAywh-I3X7H2g`u;o3Y5wr z&a5uIy{wRwsq)vUW)`$gb|e4_Ff6sjfLc^a#X=&KWnIen+%#hHdGrmsDOz^%8KX0t z@(u0!5JmA=bjVF?xU9WD0!M5)f3fGcpnn5pg0|mtZECcr^=M9-KEx)Mq;maJ!pW$$ zmFUgm9yLsYROPOY*s9JWeQaqa?O71I+N@6)@3V5H4lv4$>kFV+Oj`$hYJGNaA;l#eiNkecO2dQZ;U)d;lm)|vZYtZeqn0I( zQ=Em69rPv0Mwn8qgnoLnP|vzq|5|{BDMF(?)QeYoyDpWH=R`%0fiCj*fN`=fj!j0l zt@M?~I#V$9Hajsz+XO?kw39wza#uCcDtC{xZO@{(VlC*NJDq%F?sKo))q&vA+24c_F_Lu^v*-8bd`ZFrn-M3t1mOVaxOw25$>T` z3&Lw&%dArS=b&{$db6sg&3~M(=dF>se5R#oHwB_1M~gP*3(F(|x1GhfAClGVI5-S?yt{@t=d-tbS}K=;9OE%rn0U9NH1$HW)nATyLENNbh_v?dh&{1u z*crzB77(3wX{MY7Ry?=fFg2PpGnHZ&3ALak84o9;2U8Nb{6oWxTZwXYYdBoTq6&=3 zvgz~lTm2WuBt+sNKU~}#|F-d2j~*i9Cb=B-^(K^XLon0?lJozFdH$Gm!8+O!ZG%?cu}K<~aL3Kc5U^x4-{8qrQO><)KMewnKu-ZwO8(7cE&K zsb-l@ub0#P!>>sn&(~vwZ>l7t%!em0PtSCy$A`CZur$0OC_$ja1Qto_iHEoKLp&g4 zAY!0D&-3TCY47KN^VaXrPkn#Cx9>Rr)b_)xjYQDbwsKc1GGIzMI01BlZJ;J?zvX)X zdS2&Yqg-D9^a~z>K=RP!ou5Zd&Ew~dF7&xh+I4dC9Jfj5;~aA}@B_)`{OM};5j22* zPKR$&blfA^692ro4*`U5-UD~O`r_8Tic9GQ!=;pTT&Fj0IcA&L^3&Rje^jRCN->+? zH`Zy4Cso$lf;-K&wNu~ox^~qSDEZ7L9E`}`>w{WS<*@mf5`yDiRB zF6qI{jpixPt=nk67zYN#^gj3R!`nP+HYbj^nNYe~JV%Bt#wniRczyqxcUEpnto0F` z+M~B(=mYMxIo#D>vmoZp5x{XqWv*x}sd+r-NIYD|GQ*JCs3BF%dH|B;4q;G!6n|0@ zA)Ce^l0uHCK$(h|fHN}iqaYQGD{TS7espH>N2(b0KA-$D3M(H88 zvztbPAsoh51DK}iIL5S2GhAoa>S!c@CBd-iU_?R{4f}$m{jiWkDX*bdl3}_D=9Gy| z9fTOUoyi&#;57RvaT2tEC3iu&C5h(%Ev<1<{FvxifWPs202@p*ERqHjW&P4XZ~R!5 zg9sV}hHKuI5OTpF6Kn&}j#OO2G?t9_P{%5u4dP_{ceOfTvV39*Cu?u-cn;+Bt13{B zzp~wZn!1fQh2H_8_1taDszB1!j=i-Y*U&ZvZIh$Pqh;0|oWe@MtXPRU48NHZxEo!> zKvz+NzVi|kYi>^cubn{h8MKS-zjmP7S}I}-72q?*NewA(QQ`b^Xsr~J^!3fC9pcp* zFf4mZcdqy=cfLSv@DpwjCN&sZ?)Hq@&sCpGVCS9|ihI_+(O})<)Eemo?Q)is{aN*+ z0Df0fYfFj-)!!u@2#ZoaWuBhebJPuE4u_S}k#r>v>LE2Q5`d#7NeD852RY6^;L4`r zRe`qDl17(O52+UHN^%wunIUpp#Wl;j&Erc)Rp*h7h6g1Rh6At~UdSMoUm_^Zx88KF zac8N{a#5XNkY1=cD-F*vI!YX7@79mY4XUxCpEE5mPYK9tnB$CcX9{h&R1NZ&lumu8 zaw$fq8>8OfT+YL=BRMw{yW=$daL*HPQ;;)8;XG?r?hq3XIoo-_?qY{V}}qXoaAYU2XslKHQ$ge{RV+lIeA#uE((l* z*m$vXj4s+-9jhBwTfe4|klr<^YOP!?*7vsB?eWSDLVn2vzjnjMu=jC8FyI&$ z=tzYVAG>5nnW|o%n8iLi_BGaA&Xdrof}oCY7El(EtAOYh&>mqS&mhsMTnDF61m43} z^gmUQfE=_`-d9{dxU16RiKFVMXaqFPW|~_j^Rvul0*#|N9)&??-(gN}M@3w^G`OtB zd&7Mr$*d(YmIJ}aUQYKN_?0QD7&>30%i;_w2+z_@A{3(I=PakNz=|E=>r}v~7eq3n zIo@*^=yl%Fb7CDvQdXxP@hth_xN0j%2BB*O z*3Q^I9gdJmy7(By60B};l&SY=o?9ybuIqmN+s&?;sg7WBq=Q1TTH4IhOFo>yDR2Q6^ z&f3!dZ8Kf=OE$Uh+v_R$%w&4_NNpluv@v;|sLF_lU<&Eba4n7ze>DuRTy$SrX1C z6vFe0F3d6^J?^9>YnkWo5%oErY6tl5Ng?kbW2#kPE-^#=Ys1o197gIMZ!WhSqX~(6 z&DOY(2*Xe1)Aic(qGsNA_Rr^t_NR|%W=1g3*IXukYHQn9^r&qc2>RZm9=A$N#WCik z-eGG09h8`9yVu#512e>4*`IP5#ePd@W@ipY_L65^pI_CC2laE#UIoVrU|O?ba~;tW z5q%5!isza9N>&;Oq|rDNDKi!~W302GzoLhaBn+@-`luLEDlTP>M7!dZg2JS#&)!R^ z`AoSXESgy;R95xAyi71xvB72S(KMr2dBel`oY&aaQ|>5;PZAj4W84r!<5k_Y%jCSv zB>Ios1qw{}TH*`2A7>ilU&yttHLdQ7bLAC7?2ABS)QHW#T+!-nExgBOytOJ2Nc zZ00SpcaL=%Oemf&x=XLtj`mS410XdEUwr$(CHTC=7z8&4uce-y(Om|Gg6Fc)w?%cT}BcHXt3!h-fGI_5} z9-;;yp4%eLt^mjt+rBvBVj=(qV>a~$rd|X)QRnMZ9A64HWtjINSq)zBeb!$OFi(@{ z1et&Q-0m*x?M;NvwY<`Z-@W2BiOzWi96_UkfL3vgpV(TDlBo0nZ3^NsN%lsG6meTy zXera9O@?B%Q#^d_n}VE3Af0;!?`!#99OWY20NP9=*M4#|<2Zn1DnHLG=LBG8Y7}f< zx3$rkHr|^-Hj0k}{R_Jlt0wEkgqJ84dEp*O5rP$rUHUs%CT-lZS~vmLIqYo!aNBMc zspDYT1*$=E^I1qn_B(^urgF{v0+)@%QESNEY#erP9G5y#0UN)zoB@F*BX)`{J6Zdn z`Rme{m5hvC|4v&-HN}9&-FOoOZ0C(-7%F`~ojNbZ)3?Q#{K>Q1C1v9gprY!*Y-rD- z53J~%v^g95I=f5@!2@aM5+owj)ah6;%ZppNQb1wrSZ-OBz@ccIrUxq=;}DJ0r`p{T zR!~zLRh{y&r>${vDduf>?IIRPx*iuftu!9hR--rql8087zH zUevSI8#P?2P;+v~u1~yDhBk+PD~JCOw;D0*-nMN7jGSFr8%(b3WFU8Gp zE6=*sh$JMMp>ln`nlO+A6n0JERN&o$xGYF=oN@6(`?e;%Xds3%f$y2p8wr-%oi-#y zB4#G%gOr&X?AFuZsqjNZ%45e^W@%bvCMdbes^r}aVtzm(a|{Scuo|-p)|};}`Fkf@ zU4_q0(d(Ziw#ngA-b@0&75wfa?Q?N@{e^?5ndkJ8*^&g}YR%}oEDrda^Y|PT@p_17 zm#$Xv&FVj}!2esK?!Qq){{Lcu|AaVxe*Y|vY!R9x znz@NYW}LHa#}88#K%Mg;Nz?m~jKtB7oX$@->)A=>FrU9X;ee53q!NSVW@sGkG<>`t zR~KKVPxEbV`BWBVfB9(X)&Um#+rEADUklG&-40lFXJxE2WeNC9_+S8U3Y zYQOhmI1dw%;G3E%ER^-9vh3c1n7ek3$$FEd;m?YAqWdy6x*QDa$kEo9j3s6;w@{A7#kz zXc#e6j5V@1_nqoTe?Mv+t=v^zjA0!cYVX7PPb+k{p0rieduKoC`A&JIGqSBx#tpkI zU8B_IlQ;p}eJ^gYR@sf>u8f4vs@@(C+MU10t`J>b=HZwc3aNSXJkeZpXJ#ZLFDlHs z)VCmTKc$-rU=~wof#}8@a)y$K>TH7}(pTml6V5Y+vO}nINz$Uxlc=4br-Q|o;&gJ- zoFa+m(J+DmFu@r+mQ?=0#U!u}Ky@dXyv>pnovHKW2jXVO|5k#Z;=; z8gelWbIgonU$l)pi~DL`mM0=X&8$KeC3nkR0~Y9lchE1HV`$@^h^*IXCP~|_W!K)6 z)yDZ@2Sf*j7s@Y~4uB!_BR_J62t)OLFtVb9iL@BEF?S&m^A5+M&AkAC70^s8rd%qP zD?u~*@{0Ko7MZzQSVkTRj>R(ou^=bAKy8|rJD68ZF$h3`6a2NuGK|MFh=-#!nCV29 zEF%00_xqzyVHj@on2Ao!K_#jiK`Gir-{=HkDBlZAJ6f7Rt&Wb6ZBebAkyFA}!J#%ggeI`oc(KI|XYd2X3eo?(7)BRRGkp zg!~L)sY-F3Ohn)6-{0nCjhA8;punzrh0%o0j7Fp80z%Y*XJ-7Y~| z01A;Csv96toXA=*tKfV1mn`JdGjIuWA&SAMV_AHO4S&$qfr-^I|8+e{+Q< zaf#2o9)uHIERuvd$QuDD{?@K#6rf7GXr2a?j;c_+8p8q>s`URQoi3o<@8uo9Y|U#0 z(jAJq(+z^8xJCj_Pwilqft?QFGC^`%D|h)Qosy6=VU+#pShQ~!XWAh~mxql34O_OV z5U#SalTIlpWFt$nL5_Avj}~MhRbvZ~azI3q@kZoV9z2t4|ZwO0c56zlUc!}+B;o!ktZqYiqWSvMB}q}kVFIl%;VZ|FV`D; zV@;_EETzaa+CpQ>ZFCxcht0!dXN{FeTMB*2aCDwcZB-$&EN65V-epVo_n-fWD8R+FwN7SK~?}DNNQC& z3GJ;QF>=x8qV%f=vb?@o?;HuEc$J_w5f=*Awk|~x5_$Z;{QD?WU#4H{CQHb8l?-y3Oj8;evb=qv&xipd6naj=Z;`)eqNdPfr2TMj3(_rQuN2 zaLf*OZZ1n>!U1Stq+T#cv=Z8O5PJ~62aNeF8nB7!9KT=z-XG#=0t%H~2RB3ewB z%?*wI;4f=;LL2#=1c+0$oZR#ZtDA&yn4=7*ur!U26KES`Ckh!=1JgKog(L~zOo0$x zOH}j~i<_572n%Q#tgWouvkQwXkDipliN|EB`IWD(aTQS{s%r4Q%euJw0Y<*ZV=6ck z0hBgh&@mOA*6s`!lf@mmkkNryE zvoF43GomcmIfUqK`gqIVdbxMk{{%nj(RP+Ur`nRk3Sw3z5%9^W-2OfXR=)78`0GFF zI|V;-Ks#9vbQ}DgDa<%M_T(>Z_gny`p0W43z&L<+fhqGo|2zX~bNbHle;N_qDh`^D zbJT2%gJZQ{A!e#BBfN6V>oiEJ_o`tZ(|GgbJ>_ESvH1%1tPwqU)<@}ZD$Ejj5_;-M z4M~nJ)JV=8WXc8X?S}7O?u`?JTIyR?3P8Wb)>ajLSXtfx+q45HcU zpzsVu0(XkKo?Ne*1*biUiXU9=-ZuyF1%p~&m5@FT^N1zs(y88^SI#xxp@QwhXY9$} z$#p4|LRF^}|B|uoMBK~gu%9Aj;|2d9%h?TrZFpSmB{eQ_1lgLZ^A^o-TomK*Z+Z= z@()+>-&5fJx4S8HVm}~f)_*Y%p?=PPXnFsJEd0kE`3I1P&&~aF!ivxEU(|k44t&Oc zqapskgFv$WTQK1N9yMV8U;8irTI9d)i;w{R4>!`t;Ga=i=m%LyCoTD}Q4RlxAOGV? zN#p-asU(2!?CA0XpB9wCr<1jFv@x*$$ItpNY{P#&>3?FvpIiK=ru*l~{(ZXtnSaH? z%n$mg>9W}#hW{gkxuD1bxqG*CW4>LAni48)|aazm`%y_vYvW|gh8!* zv{b-WZ^+l@Jzmn|aPf2T_4iKF^S4`GoMCUFz9#SI;luKLwyYnQO;@QZ9@`g==YaLnk&Ng>)F?yI;K2d#?>ai;x~^}t_K%zXXFu-maXDyezOR>; z`B#uAIrL=pi$JPMyD#^wt$|z99_zz&FsPM5{U=+7rM5(Wo!#PRtIY4G?(UC|XSr|p z=VygR8x_7T9-nVz)adc`?kxL7$j@D(mBY*7c{qS6z+eD)YJWKZ0^k=2ctikpfbA>= zkDf=I>vgtcyyWI@C(nD;{C)|}y+B{FFsaN~h#kCE+wA2gN|@Tj=B7`j{AWObtTis- zZKHQ2fIzG3Y^=|ft@{b^&(1C?4?oTGoaIvA?boT8Dp9dYCVHPvSWmmWur<580>1Nl zrg?~Ae5S2d`46D+^>1xofSNAeQPP1O8;Ski zn#+wcK4_ldPTGbq26e9bXiJXY-!li~kF=LLQN(q&#OIHlWM8h~P$4NLT}r#|&vVeXr_ip}8dm+(n2omh|XIaWZA73a2cjoK?R%iU2$ z@qu+SeEu>3v=Ft>Xuz?4aL1VdgP{Y$&N#B9Uq4kiCb}cswLGfn z=e)Z;%`je#R?BH;$i76*K4Gg#p+14|KKF$QlQ_-_O@Jh@FC4h5`Wfq*5}3OAj~ddX zp@Gyx@RlA7OP=KL!@zjyZ!vIH$kW*`!;cYct0?E#TwvXlRG4tMoo*YFWpIB+{YSNC zB~`T)*43z>HHf5-8QmzpCHAtgn_9>Q_48nW9@UM4UB13}-k9 zksc$y2Bsyz46E`l)@u^3L2Lv?I-gfRCA*R&pQQ~`*&GuD|BEN*aXTJ{MBVy@mjqY* zUAA&}9`86nI-0`vXCS5b1)?RHICsE{*h77>nRGO|CdWmXtk1AlN@I&PQr(whr$3FJ z!QowMH61=sXNJ@akrT^HF5Do$n-U%Po^R^iIuk}PVY@aGZcFwA+u^j=7*ir5w4237 z$*nfvqySgAyQ`*2D4cXaaBJ+)T2MU4ZJ9C^x-GiZ9m`0gi_0C+=hq^<=(VVoqw5y! zNhcczyZv@XAH`e+RP(Eqyt}AbMJ2CG`L$1umx9l+`Y(dt+qrErxg$oB4-sE*ty4Z1 zP^rpTsOb{NrC%@neA3ad)Srt*=Ggp0gQh{OM=6#X0>@B^t-l;R-0CP&^@SvqQ8TM` z8BKs0hNMjjgUxklpkuY0XokeD^Q-mHfOm8X=JqmxyX8}(1{#6)6TrzEsSO^1nNMhO%Rs6mB%;)*8c_9`4`llViSqMROlLqm@8cr#vD(mDvUGPPPb2NXTr1em2m z5?|-ibS;FTGrxPGHML*GdRbBCswGF^;WgWRg}vP*6bTlu^5Hp95J@-|pxRtZS`=lj zT|X5JGI<-6)rFq9=GZ=8?CX3{WU{uLWP2Ju%Q>$|Hh>QIxCPeAaPcAQc>ol4yDvB$lq_4A9v<0~sqvbAJS? z*4@#%2jWvpVW?hq2Vl$++5i|NqKhl&GOeR9-k4byg@}`OQeaIHOng&cw;e}XDeBVC zLc^Z#?wT}5%c6Vuoeb8OB6yy_KBN&Hbvy9;mY|y7Ozq{=CtJNxwvDz3M*%Ac@=+|G zt>Ls1*(mU$xn8_iUD!GIrbDR|t|MYK`Oltf(FEp5iu^?7nF}T$lXojcz$qA~-JvT-I#pP}tfKlXCf;gGigp+TAiP zbjyrBe=ry@Ap|g!8!^^e485bP9LUlhxcp<%L=;&3Cf>_{*4Z3;DBv^IP#`Zn zP4NobHAJ@RD_BY+p`#TwpN#W!a~ixGWa{x7Zt6!H!|EIxXc|$hbd_{`Zu~cAP`Wz3 z-pf6>p9?*Yq{W*8~+^h!uGH{bMUA0dp*~zMV zXJx|4s~wzyvm9eudga)umS?Q%L5yGFx#bx!3exp;Ie~&(^TSfGJa?W!y0B3ge@%kl z1Xv)qxY85tTdE|cuz>#OLP?a__xz+j&$1hi17y0CYa42q#< zr}c=0pLef%BRB!xF5_Qt1Q*bf7jlOZnwWE|G)lmVEpL3=6~%rVL4VjWvjc7uNNf&K z(o2MZ0sr;a^5E&&mASqo8!2vIlls{;T>Rg6J& z2qaN%oBF2Tsfl0zfa^toE(AmhG)GKX*;{YODX9)_%I0s-7EHH9E*VH_5h7_SXi66# ztX=SxkT;aF)glf?{uwEPTcm8;X^9DQ=Ujq9<#k4Fo~kIDL~b9G2Z%m!!8;T(!=v&H z5Cp&@2yC zFlPp{LfTyPtu^)C`qEK@*LQWGFS6a2f!-O|p-v2cj-o4|&Rg8{99k>j&Rg;L8*ESh zx_&5pHrnvJ08fBA4b;HDE`ZuL{1^yPu|b^)aAE_gMPievZ86j|7_b90T(C=W!5_*l zer_cB>@HUk9``md)@rU%Q45DTsQIxYQnkjk?C8@y9`+1agYD7pkNmQt-jlZb30~3b zNnQTZBx3+`ve#*VpuI_tJzGW3Ah1g>+B;gK(OX|*OOQDW7mO_Chj4ckOM=YgnIo^i ziF@l&^Y!mrN#hYf*KJ|}eQwiTExsX8*A7h_F7(UpXj5iiKB$GLL~s0V4pD@I^b za?Xwoy#@z#0XPN)G#n}BQGb_xj@>(+eQsn*GQ$E}SLSEflFP6__Er2j!%duqt~)-= z51A9Yrx1QR^49*H*)@p+wz6U1?`{Wzps)?WnrDKL2ogi&J9?kWGc}r!fsGL2Eqa0M zh|Qo1p)G8bn}*OFawqCtU8W-k=!%X%)pu*PKZ3o?3cECF`U--JG(z^6f^fj(6KLY_ zW(Q%Gfru=KJq$_a5cksx8J#zq9C<~+{}P?QWALb_v3AwIeXb`(kX7U;SSHCMX=rk8 z*S1IT;EHj8rfqQs%8gGISLM}X-(L;<<_tg=r-yA1pzB5BXmh}KCmpmn3ca4u4sT#J zxB&;JgL&^-*pGE*c{eXIr?IR{7R07q+;y1s%2qoY81KzSbDZ?eGjpYYA}|ZtL~Jia^m(8qD9%Ke1LPzw+}9n zJ}2uY{2ak?*Gmvh{S*+tqW0)QXaQx&Chzhi;G46wZBsLdvdo303TJEDal2j{1W!Fz!@{2=VM9@*uWA^~L7A6N#}@~S zjuwMXGXeBvwnrjF6DKN9E?oxO89SqF2i0~nZHUh@H&gC#YM^#v@aB!R?IFFyseU7T ztdGuRazXHQwnFBXc$r+?({E9Dr}Zm3>Ma1lKWaRu`6E(jmwM|2tcqe8gE)_ShQ6t| z`Y8?KbP8fsa(#xukW;Nps!kK;f80iVcN|3{K-wqZh@wP~s0K*eovfihy+%>Y&RT52 zo7M%Ezu^_wx{5n*U0D|G#xjz2G$SK(k2)CE@L_yVNMwdy%%ki}y|n_9wDgI!;~~*m zJ(vpyn$HvZRdIuHtdY31iG3e=@AjHC^`?^@dH7JWG|+cGFBB~eSI zvoL!#;y9D@miHsOu{DwY)EjoPPIXyK*xLx{nGxD>jtmWtMtv9TR}O#^Jjx)a*nXZ& zX+&tM-P;tLzp@54x@M{Mn_CaWJFrDL|K-g;JYg62a3Jv;RQQT6V41&g$S&L$9D~bb zWT_8(lMo65*AT3rObu&KRS+pMgH(W=FT_^CzlSCw>=v?h$IlS2>qfprfsXB!lOquVb&)B61OjW+kR{VLP* zu8M4kUaiv*QKQH{LGV=4v{8qZ@wbA^0F7ElZN#53oWV+(k-51X6;d{fS+LkH;tZ}7 z<8UXIvULXS^gDhNFjq15vh;Q~UI1B~0*3~M-<#;N{$)D!9r4JOBAUN?-TBFmG+g~z z!wV0$--0^^Jj?Cy5W-$L1-S!%>=vj42vf zNF=x<%iJJ)zMT!^Yh4tY^=~hg1H`MyL8&U6zM5C1Jy3cQsUW$7pk=L(loO0>|Fp&E zCdZoCuQS>ezUqDN1Di31L?J-+0)S~^{&F^s9TDYzAEk9xz}KzVcseH+-86J*4;SbU zn!BY7uWo0I0`qzB;IeEHef=AnSmi66aPIhAA^R&rRhbMB@W407EvJJnR=~h@EC})X zldyZXOz<+w@uLT}qM@A9N`>SSx|&B`eBdxXFQ^%aWuG3uSUql;5VqUrfI5w8T zvV6}e&2u#lI*2JGSNFTrJp$Y>w6)Z5`=*F>mUsMcH{vf+^SL}ziyVMi1GR25w4}RW zEAGhtL^c;YJF5g|etY&aLd(e8^XM=-C+J_S)uex~b11r3+TTmhpqb5Kq#Nm{!XxwaZzzNR!cFtPlUFOjp+U^=?`ccJW!C+#dK&!%Q!!wnfvN5QZLwhxEB- z-fB|44$0$0)uyniR)!Y79~OW~(e$0t3s`8g;oy*#*qFmTd{smWH^v{kJved%lbMZ0 zwy7sOdY4WjfD9AGGEl}F7;|;qbNeRl57A(gG*6J7N!P#m%+8f$9Kv#wgt zdJZa02Qyw@O!gA37L!udTtHQVy1)5OqqZHmgq=CiAoY|}KsbYbdU^NCKMG?$4%qc( zQ__vP$dPkux2 zH@MXA^`BfKTjT#Cnf|+g`;QR)?~3dH38nmhzdHU;Vf6o)-SZ=8|F3fDS^u*o)y%BS z9RFQO^(D@F>}J#Lr*}veaPZM55IW!!wpR?0OaL+1-4-*0JTt{b!MC3Ho{6x2`wl5For_J+l#c{=FUKG@38}3}?u$-O*42LmcygJF#-Ah_a;p?bJ^K=dHH&22cCAxIMyD@%qr|YWqe|W%lM{^bx7UL?z+8yC-lwl z=|J-4j3wD?cgr~cnb`#Lo_QLy19;bV7k^-TU$a4{N-o&I0-s{VBg`|;?cB}%TF-Or!B&HxYKzIk2&4&h-p zaVjTfOva^-`LQa&|68)@-raaal z$%axFj5LH})>zC>$7)f59*nKyrxUmZZ>eyN;(<-PGCsud*{NoERnzdXt)qOYs?j7! zMc%4BMDe_1^cXe1UPxc#I=uITp2iWz9Q8^bdFQ}{Pke?YjKGdj&Z==ueD;ahFRyF5 z^|@^l21#J^<@-*)&CNgla)pG$d=;MN6(gmXlOLSjjBL>dVHP1yRO9=EiOwdBjAlbI zcm{=gSNN4!m1NcySOO=izVA+SGT&m!_68q_>8nnn^s*bi8a(==||tax_%&+XQxn47(joC=s-W zkY@oFRWY~qzliQwV$hcJct$XVy8^C>zs9U4I;4(N5+KsMQB1zDOZ&UU+;d@5^*gGa zqjdJD#&fO;j9|dAmj`N*aHmXQac=)~OSnhxFV`4ndhLF2r!!2#Krgv#q-;%uwU&TnlsJm>Q#q>8vl%iRXGqs#a$FZKV>%gpUIi?+ z0xJTu16rOWK9L?Q7d`uE$TcGa@7u@^j^luy5{t? zka#|FF*~(OBXA=z;HiiwrS<`AkBd^M@vm!Bp0Z;3(%f(qWuITu7)EWY?rT$ChOBO_ zg*xb82UORA>PJQwSoT7a91{au zSgTXBk$jN1{D7=347O1td_r>muJF+E9(z~P zWc4Dz*bq9XclC&&44luC*OTHGdmK)UXi8Oo>UCB6*NJ@RRx>?BkW`dCNx;_tx`^a> zU&Sv#;0EgCJkJ)9CCaQ9ydWc5;~EnQS%9UmnHjhIg%yRjf2^9a-|#3hAY%B<;MvQU@R&*h z3;8wPGN~}1lIL*Cy&%oXo&B5$0uC+)5R&&AQVWdM7B9RnghM!N8e^nH73CgxQ5o4A zT~Ghahbium5%&s5vdlx%Pz@{CBnAdo#U|dZvl)CF%ABl!sBG+-_JSl4v~^TmkttuI z32p0Q1TtJrYg!rw5QYg5G{j$9y8e?Z;*9rZ*;vwkPiYWJ+D!=vZaSxo*NClW zE{&~B-RFnL?WZe+(o35-+u>aCgTg3+Y|FcChZLrru05A=e?3{Y zfa^Fz)BfPV9a6uXy33k@V_E{mOQG%+Nu_t|c?PeL`vu>p7 z)jH9EAT9W`ErhLKYWSKW2|KIiLPA{{dvwcQ^FhyL>vnIIM)}_Rmj`S`%W73oyC`j) z{2~4Yw+-L0P*BonLd58lU^7}-c*N_Jfr;CdZe03Rw!9kJ2nu5Me6?8syfuR&$4;=0!ffy=Q`M+`j`3LcUf|J(&?{;biDZ`(|jWb6EAYSEYHVYX(q1ab2q_X0 zp)!AQ;ihJOQnC$z3{i9mg%IUJ&|w3eQ=jQw~%_>|>N8C>6LR9jN@EB%KvmY8l8wo+0GN=71$->Dnq! zMZuil*qFm6ZGV1&emw%XdY{zE*c5nQZevVa`K{~n^&pwwpT^iYWF8+~k@z2!$|Bkd zF!p5_mHz7|qOE8+x)or6|DeC(?t}t!@t@~f^UPq%0ksgIT=nZDDXE_QHt8ZL=}(nV za?c=jBpYrt0#afVcaR|gpm|InBhi3SSk+cnv1x8Pgx=*@KC%36CaFv0XIDWw7qZ*Wa9fm+B-hbb0H!>C|La9!2R?zvmor zvK;f1{*LFrJ4}LeF~YlsjAIs=O--|(+qKk03N}+9Q8UqUvRO1G)0yd6OGOaZO%KTO zlqrXPE=2xv-#7g;r)46mysvoTpZv+Hh)HJXz2@_O0Dzxx% zT-3M0t1?b@9#9I=lhy@qz_L1Fc+Fe^Hsy&AwmbE6K<63C4|UQ`r;kBcDT$2ON>o>} zBF?Ml_6aU#(4iT~8D&t#Qj@%};CV?&s=))T%rg*G*2&u1o24rW?jZxepQMtsj7^pN zu`53SRGrsJE+Nk~P=RS33$TsoGwtTn`OU5TxR2yb>N=dG8nhLDm6jOSPuPtyRJV^3 z7$W;_cqe0__gf1F;Iw2AK{7c4fHpn@HCt0+!AAC=4*4Ok;K7t=Xvt7Z2fV_b)uhEH z7wTfPW>u^Ri6Q-y`wZ&CU{qtWDgg^(>s%PJe*b)nM;NGg3Zzs`Y;P$BTbLF8ctxoA zY9Hx1)^o#sxFA_k#j``i#E}bVIvA_{8L$p|AxO}NcB0f;H4QQb7f7+b^#sG;ZZ>of zIf=@(nT3ME#wat^OI-hHzwox-cg9Xkk*X54VW-mZBmn&;E)XXThU{%W;)?&J2NvXt zh>dhx0EntdaiX9GjEO@T@P3WaNvxoMLX!jm|ecvewz-*T|FB^#xH1GAXCNsjg7G-*+ybg-I&M_f_FUMtTJXuy8{sN%k=R7%kDkjckdFFTq+}cP=0jEC zT_z8)l!k?b+SL78X3DI>|79Ri8|U6KmpGiKN0J+Cs&Z* zRaTm(u&PG7NY)*{t5xnPHG3{%E{Zelkjy3i{Yzj8Y`BYL2 z7rE-~hSnFudmrSUPJ$y1CV%9%8$X;~{&BI_HK4);{B2Rx{^=KWK_60!d0R8{T&5Q&_QXvayTjRDbA?8LpVcE`=<(DrILT=iF?nS5c! zX^{5id776oh1QGig^lRlHY@>66YI>aRuaDk6q?&Bzg82Sq?s-gnvxitdloDIoawSt z?RlItTRe+IE6*%8at!jfcQGLGxaA7?1=&!dOCwl@X(@xs*htawUb~%bJVX3EKAx@G zIIiEId@C*{9rru;p7uG7d->9_C^KGvM{5zm=s+&%js)&W+j5?El?4YB+eDt`Rh$5D(g^o$b{Z*tTtYD}=j5Av)|$4WChCW?VM@<4UFXSKY>Z#< zRRs81vreb-E6Wi-o8&CwA_%BRG{s-FQ;-iK z6!84e`|hw?|65!(Z-#ECQhyjMRQ+4>N10%_(9fpd`ApJi|w}&{KsfnXLr^EB@>Ub5U;rl*D#AVc_)?GR5=cD7(>1yxjX8!p;u zig4y*sObh@f87k;QFXo~_i;`3uT2E$rLb*;dxBBy$GvR8d!>`%^Sm3D-QTa7@=~Lo4dXrx zDUur7j28{`{c!mR;iy2+tXds)Z!xp&o$rkgGw+ag(;p>rGg5a=HvzeedK6uI`pT~G zZb0Gy@1i0>%yciLW7cS=>IOz=y{%6pNML># zZr7YyqZ#qx=z$uD&Gc32eGBQn1S+7+bnvXL#~t~eUpFYDK;cdU4ObDEIRFk>hQF@@ zW#w056;>QgTM@A)4vgfaH+K#~HFm*PkEum~|4bbyBLj0cf^ndfsvx)Y@w$Z{gPZ7K z9AOTb3q$~yek>qm$r(xid3W%PiB*^5-aSSmL-0;Pm2sqmqGXF}&1gC&o;C|f1$z!H zEg>_XC|#O4P|fA<`ChuMYvC$aFfH#G!Lc2^PdJAIOrWHRF4+KQF^>7~{J_ z1x6%;497WQu+qSQAA`w*Vi6<*SKlj+_KV3Ah926q01;x2a$63P9mT~bZx0ewYHWmemJq7n)8cn25Irjjy;Simk^fNRV*uvb6F)*pjS%-mCf z1KoC^Qbj`rGt#nwfB?mw6S;_owG{ZED0yz;H3qD;wx~Jx-hrKkA8Ye;vlq__zBnin z>j|ko>CcwjgdMHLnQX!V7(ym#gqQDcV$9<>j6!VeaTMGY?ttR8cn~=2m)g`wZ2aQA zVPHW$FISiPY(|2Sp(AGFIfCMnzlYek9AQ+)YakP8+n;Z2=u?d{Mt_`W*ui(Ovwqwg zhGt$g-)--w6yEV|6pPr0PI|c)ipe*R6sFkohESdF*ln5n!R!pD$|w6l7Utu%N~e(P z$cNUs^KFkUZnKZ|iiVMCH19cXgUn$SRer3ZMNh}NIw~Y;02I4 zAO7$m#7&r$^^tnQiVnjajGCy#hn7z`^P)iyu2G$G@;y)@R+NpE zJt#Imjm@}HE!i=X@(-GO(zBK$N-)T5ewT)F!ilvhp7>YD`*wZc9-m4E?y^b&sTK`` z=&MR!pfQsDPPMEIcem_Xx98C+5ce*bmahe_H8k5c&)0St zqT2TYDAxr+ge^ttk(i8JBhX_kn+T-DpeRG--vcO&7(@m2qC$nCrEo!<5jAEY*Yi0ZCj0mPAb^s`&dh0qkK%z>@Xkn+~rMbf8!-+S~pME zA}MSFWCXvQ4rm%8&T(-p14B7Qk1Z#)`9krfVt(UqbPfPK2T2AWJ-r@>7Xd9iB2 zv_0A%l{c4XWyHnTiDSHOVH`pN1^o^R*rS66Q&d8SnA`WeYK#h0o`|ddfkTpQ;L;S* zhqelJa;JLHvm&Z89viLh=rG$iw5$N$GbX{P7K|V*dRR%U+cVk|xa2B%J$hmLWNWXW z|0*tMiVj+Z|5!BK5X$2Xfww0OOrujH&c=7K;FV0LiMY^GL*Im2s1X~T1p)dcx)*D_qAnS29O&b6Zq(Cf*KQZG$uUi2bOi8Gt1`$+?Es3u@qlW~+tRt3Rl*Z4m zeQuMa&ul9Q89dg+SNzPLJEYI9h6KTN$)%oH7Eyo$)5@0aCiC2Wac@z!m(47ZD>fgv zsAcuFM;wA1jS!hXY1O44RUk%3y+|z5`;Z{6c+z_ULPo&|R;?Awr}alLE~`J0Sfo6e z%qb4HKbLrrhuQw&iBD1yxj;7onN2;qHy(zJLYHR9>d)T2+|R|Aq8(OLnes#q)BFuA zX+@Q@NvF8KTqpf8CRL8i$5+tSJ()b?Iz_cW=U-)!8)_!6Jvb$u0`K(wG3qcmZuPCF z*A&&BK@%PS@UH^jEp78upG|K25NR;4FYMMoOZ&8&iZZ1Dr7TmfH7@mKOz?U)O{D5w z4{Z%5ML*>$VmY5g1!fMZ6NfV?xj0git=Q%r{^r<-^VeL0vEC%>sjdFr50zNWg0tNIwHU4K&| zzsBMw%i4U#Xk>vx5i(!c$D8=e%R@sV$_9d8e&T2+! z)rp74f^AsNMcjT`{}CjSL>Z;Um%W9swqHc|i>Y!BPq*+)qa?{fzyKyJMm zFIoCk0W3qe_8cQDpgG1-BX(7CzaSWjVGOQ)!T*c9w~Wdw$hw4a4elD;-JReP+}+*X z-6ez&++82s-QC^Yo!|~b(%rMV=k4j&W@fGL`@!X@;&Q1|#gBW=K6~$Dc5@_(#PcG8 ztb-HTA`)3^D2|?Kbsw}5<#SJziyZxc7o9TB*+j(5PXT5TF{df;wKid$6yu834grtX zEc?O__mAOhX%Y3ndXk=d`y!qV9JK%*HKux%7*vhmEVP3}5Gw`(@p4G){`@@4~0@DHcu<<44b66Ff|4nuI~ z5aJ^OpH`9iUGK8;aMR>oyd0_GjVoKw7R+JjI7%`ZeW z=_PXx`#kp|&%GM*vQS%<%Wcj}e{!F%cjx+3B%bCsYcl2a)JM<$>`g^!<;o@&?+<3P zC?p%Z`)*Y`X~hVOa%F6`UGBLA%}XjOva_<`@;DuQSi9GI2l6(BZf94TGZLTXIvD|g4XKf;$XT^6GTZTtrD;Bo4)7oVy@iSGc-S2Jv)9$(E z7o6!HjifPOpl)d8ftn!Pryr1%Ix|00gq-WL1v|M=86UeE+X>H_iCpR#gJWkurXh;3 zEMHBS^zcC#zPOVc7k{d`Oeg1V$33N5DG86oFU;Q|okdx1U0X`a1F^U>bKK~_SCD3x zC{9)=Q${6atx$o79%{Xt&e?A*mQR%XRC|SQ;mXahJ1FS@Jo-m(NmDVnrwhuc9|RH@ z6UYOLKrADCNV3eFJ8MW;!DR<(S5y4MBhUt&#!*Y{$Nml?+1V1g%9KM!V%-o8X}Se< zdW%k>%GLAtl=x5R4@M3|rZ}31F5l*Li;6x^&pE z4vlw{eTBH~nog&`nY}?^n=lgkes!xowlN`ltUc&7`&afMy0N9*jMnP6nB&@}k@=fR zZhm3~zJo+0kJJb{BS*)HJ`g`Kp3bpVdCjj{=}i3yp2G-b9FcQdNqEiWiVt z1#h{Bbhx_+oUp{wK;v?n=OyY>e){u6(1|xwy3^~__~#c;EF3(-m?M*&B+p#(_RdL` zhbz`$a};BVAIX_It-@&DtSjwL$VLZETaj7{WZ^QK1$Fk+cR6N%7s$+XT1&8^X2>@Q@tz%<2%RZMCk#vvONegXiKwe`$@5DK8z_y_l-L_XwA~3ov zy!b-=@EC(&R=3kD$F8Y05h7X0;4WY&P2zAK6k@yYC0L&08K$34Ep2IkVlGdaY;BUj z8EmyNwIxUiBv7i1vjk$EKZ|MIayNmPHrz#-+CilDLe0Iz z^+5yA=Hw?iYez(1@M23(m-oS*{u+i^$|lYYRSial<*h`stZvzi-Cr7lTg(a>nT5xV zN}mX*C?i!yH7vU3n(ps;w7-e~D1*}gB9O80C=SlgX;@=uTqNJp;BaXnZ#VuV^FiSG z^Ip(3p$mQQA8Gu_-m6H}Z5^9eamVY!NH8VkXty7A2g9U|_uA`u&za^iiio!18z@@J z8R;@%R?q0P4zIF=DY4xwtS(ZBKQ*13Gd+Bg!a6X)y#p**a|p;13#{2_Ke{d88jdii z-R+bI#UN+1X^PpNHaz(3L7i9;j#3BVSBe1g8{`9bHS9krA^menCPx^0AzSAU@-YVt z{a14%M*>X(wm-T@1nht4!vySq`lJZhe^aFu2sr)_k_k9|*P}j0f0^X`%cS=IR)zG> z6aSxekNqQ``u}9fO2Ed(*6Gg{{UvbrKV)u#kHCdK_}d@)tBwThf31%xez2hpo&KWA z>PW!E{vRl2{eI>@ZqlE>_ra}pHgIycGbW&yGPkk(postGTMODc7#TZ!oYwCpF#KME zg0Z2~$C#6qj)|3kiHVc$BXUkA0;Uh4c-G%P7x=?3|4Z+lfT5GQtC{k1Lf&uRZHu75>DXX0dL{>N58&6N_81~l)BilPHQ%ldQV4|QGMLTP+lJBQBC zo4p}^cs%xR{Nl=*8VVBm=Uuy$cRgw6blP{`XJ5+{f^RkiVQDu?e@%fmy*!NUHAHFz zvmD)@(Id?sj}lRq4ktf+Q`>&`eRWxSd$_vZ>uIofeB4NE9E7L>+e-M5wt8`Te7jo7 zSEmookN?&Xc{5*{7Z5h__N#Dj;c{z3{3uAhOzNNlRh$m+OM?~=H{9ET+d*^x^efT# z^{HW_eL$snO%|(Y6A2PIr zaD+G|5pno8Ql{_XI^nzN;!Cn4&;0bZ7l{oQ=WR7$8OAF$rCRyZF|2kbJhGNV#9_57 zd^iCYEHUlK<_H}FEm%a}8@??)HPPM^mG5th^P(C-VI8E{K{Eh$6)~jNckf5>JlvRe zYlK3$JLzQTR!-X_dc&}98=20}TvX3_7d)q+mXEE%pE507LBP{sUBf2^E1AQ<^VqXR z2>UjIm&4Ff#KDO4?V==+u*L+>zcN~UGdv;{On&Cx3daIVaoT`xLhDYl z4|i)TlQ?;7N%tQGBjeFlN#wm5x5Jyx&z}Y;DvZ#~!GM@b;F>p;Pldk{QG4=4&Eu0CExht#(fxW!N>DO#PgwS8G_{TtUS^ zGYwwYaZ$PO=YHKH8Nic`9M*Tn<*~Qavq!JSd`z5UkY}6M>53$!kNn1L7W-Z=?~P-$ge*ez;4gdNS$m2ls{)bs%&b%#pGIlEEz{$#R69 zd2fl796lz&**?mtMQyE$Ivc%t&tYi88$$Q081?A8UY{Slz72i(4;Qz7JHP-Zp5fGy zqOvkqDa2g-s|-&6ZCz4vwXh`0(3yfxnJCPevrC%9`(*K=Kd)fpFyno51#6V{1=pxf zn&B-=kjfpivz7)V1V+PJOEvkP+_j!in%zg`jwM6|1-Wv_^gTPpk(a&W^7X8E->t4B zj5o&6^$S!BV2CINFNqbI@@%7J`zNQD663MXKn=5bHjIspyp{A4*z>|t(%;BYYE)SNtngBJkY#9%NLeDi?kyb4rPXwX)K zQrwyt*cuQ^{tPl_OMeb+_N~WQ21R)23un}zJi`rUCzcALk~?He97Oi>QWZpfGFY8dnb7# z1h%_?kJ0Wq20g+=O(zHa#GJ%=Z{CG4cy8Ex!WcjC34w&tU>S!Qa_O|6KZF+7C>}H! z+5wRIsb(wF0AF$;0Ars(6pcOD!-IIe{12DFaliapC48LZ%8O|`;W6?4cDA?wS$OfUREKAmj$%F9 zD!nLvqT~A4#F}%l?<_iHBp;@n#8C#)TW}oQak6=ru0NRgb|j_v@}SyU5t`-y&0SFMFuBf3lST}ks?5JGKa+Yc9&?$vwU)Au~-@Qmp+VrgX+AH<7*dM4WemzQ*FVrU}Qd?oEBT zoWKVZVKJVf912b}kC|v?I$9?kf>$OoR0&$|&qd@6)0=l-VxoMh1kjgtjy< zt2<{1bL>=4kRMGvvsbJ^ChocZ4eCCoKzZqcOi|klofqP6%2YP#!Jv39&ZGt*A+i10 ze7ZQx8d28Ze#W5%7{9>wnF-M)0u>=g2ON#vjj~as0YC*G{aAu^KL_Zb2$nKN(%F8{ zu=Ff{@Bg9*zZQ;E`p7f>Om$7Lm^)@``U?)Qk6-nO07LGQX7C9 z-Tg~NY%Lx+m}yX2LmV+7VQm@YsJ};`sWdl>HY!d7yIKt-UG2M-V;biSt{a)B;h7t? ze~dL_;5R!kP-jT{NTz-8jfA7%pse9b9;q+YveqHXwdUuJprsa_4k`1>u((e#cE=C_ zgIJt0Oy}3R4me?5huT{^-ezcTou;d8f75<`11@25f>w@8^BwX6tVFNkn`BN9% zUM8gp{N(%QTMI>z`3s#0)o0k91ZB3usbzG`M0u$sLRH&Sm)5x9NCy?x)5Tp2YQTsYF*9k)L*lDDUhoL~?@L$yfa|Dygmc0b;P=HRa zwC%_Q@N(f%m>vf3>jSSQG8Zy)Z4@0|r~U#m$)Yah5qkZnDsy;OI$L zIx}OXtXSGD>9s)i;*7Vf8-{<{RNE?%{8U&`K1%1ao>W7kDqvr9Z5}g@8$fP6MY!5Y zTr7I07HET`-{iJ2+iw*(DymL3sI!QML?+ojT$}0kUZ^0DR+>9rtF8Ie&VJC;j4aoM zT||n|P@fAy!C0tx5pow&uD^4Y0wt*6qjyBvMIR(562LA#^m9O)yQ zF%5*P|FDYu$Y#8+UwfhvK17Snz21WapiSAJ1t?6nUF{-$-|zbBeIFjydQ$0U@78?r zx24%O(I>4xzd!yu>rqAE=lgX3wU(gMtwq8%3J8tC=l;TX*=G~uT?%_gez3OnSC|jV zx<&)^MQwQAs;-q$+hfh@db{`a-WmM`+v0~=A{oGgwj~>b0qXZ#x%Fu97bVwHTD3Uhgrz@mjt0B%@nDkIk1nmAg z0BP~!JLdM5L1uN+MKRK{^LQoTG4lOPrlFD3+1 z7rAJl$c};$h#hML1hpAGXEkbH1zol}RWyF$Pxfaal6U*uc>+HEi=?JuQ8WpHhY$T| zc8=Jk3wOde%{Q3X=iOhCaRz|7EZ-65qTYcjT0-m{g9?NKR2yB08EyP-wS90Pj^r1< z;qQfa|2*w#jURm->`nKIc}r4lsU}2s+BMC)2zR@N-%8^dX1OTZFr2yLK{kUh0cjYF zKU%xoijiK?9i5$KCpqN3v+m`Zr;N)9C{yJi4JYKD%EvA~9 z{|$qS!>%`JkAB4K3r#LCB0z(SbP`)GTZZJe-GOVa8?IWD%RHaMk?O2__au8w45KhD z47WrF%fAgrWu8S9CSj|pV6pY|}pFukc z($c0p9z9uOGas*-3cuF?%g%!J@J+pN%ZH15Tf37A2SRo7tpTdh{uf3K^Be;=2w$=A z@>FtIm5rz%H;bg|Oq!5`q5Z6{&|yShLGrg6{SY}Fdf1U9!SL)jXf2?&*tctEu&;9$ zxIVus*$m0!bSGQ5z`9}>p_@*9O%kDB7D8IW#bTSth$f;$MsAuG-a;3uIWFRkNk)vW z+*g~FXhzzlL36l6`P>9NUed$NZnp!`$m&C{tl>vnNHrE!owJ{sCQFF~3#4F)kySrAhT{i_h3&x(PQ@#n;$J;+t5*;)76 z{d74bmo}Pi59uIh1`xp@|09?*C{T=tYQc$hVBFY8R*t~?0F?c2RGv5LtumN4G6>Tg z$~`s?KWik;mMOdU;q;Q@_fQJC-LzNK4tn4#eZJ*K#22g1nyDai%#0}Zod=GH>sBJn zcUMD%tv${%H7WXwf(m-3(?G_wk*@4w>`3hd*Y*$FgfAR)p#l2RMu%eT3w?P}(;$Tp zjzX0PJao!CH7Tozi-XCIM2BzvM+LIjBP>+h0C`*G`Y@>2ksG90`Lha`BK~)2EbhRP zlIAO4lAB0QSkK^9Gxii?Fo!HO>8&L0&!}hJGt0{?G3~TZVp{B2?i5$J84ZgLSgAumX;h@WKiaDBc;#xkAYv4+n zs)SAhqLt`2Jm7gXK1z~x5E+&BVnxO zc_4L^LGQFo!F*HFMj?7#GkUrL;ZM8xid5Yk;;=DsbA!1CV+}fZCz$XyKU5&ZYjf9> zX3M~^!_@>iSh^$1C~&CR@{w`H)w}NNv*#sw45@vl5r|Gf7)t!wd7hl~>qI2E^9GuIDJXNjs;i;ydtxc=@x*Wt zeXZ6coKFf#%w?t9vN#C%5mt|-wX8Q_5mRznc*B@PrV_e+Br&KKc#-^J__JmUFLdNH z@+xe2pGpPX{sTQ~U>=90$t6d(?fJx`2Ymzmfb*v;_MMNfwfiaE7)pz8J8;=a9<20* zWAxY*B|p8~JnQIE^23R`X^NvoKC|^FQpnFb29eXpiZdfv4nz}ED<6##8L$avv5J@U zke78{iO?f_qUt|~HZ-hsuNC>@etpL9me&Wd*2aOWBko`Q-lc7jFs*S2RE_tp-Pe3t z8$@MDExrfOS{xWEEWzW1=~Cu~;?-xgFe9Fp65h?Vf1dB_u8EeIRGlvUwibyp<4B+t)5EPP)XQ5&0G&!@%m|#=W2FH4UXY#Rk`Fskr(7w-+ zbojJ=3h~Ig_?@qw-*%eYm52kyY2}!tKSI)e4AzXmjT?b45qE6TDKC_OYsm@OZ@x8H zkE{S_kMxKZ_`$Gd?-U!1+XlO9S84`gjD;>%nTRlDK@6o z5Za@HB}4SUnY%@38hwSMkTOW`d3Jw1VJ$?lSI1y{^M|onmfOM4oJF>Gg~;S)p-cg= zc#g>xSws{1)8{88X=OXVtWV1ArY2d-5iP*G5G?Erk;rJ}XHuH-tIBKYQ3avORd-Y0 zckNt%NtLv}*mUX|E8On6f~pRQOwjV(_8ymyg~yQGbi1Eojnj=}@{fE|#|cu14ElJd z#idNY-YQoONnMZBx-75x+5;s5tBlFZu?b2ZYRrD1#(_F|0CVv80b91N*@;p zDpfJC9&|oKm#;q-&(76NrcBK^Q!~GX=O_tl9X7O`drU!{H<_nY8o$;~5}}%jRGU7O zf&hZi2!TFou=AT~C=?8%&5WP;VH2J=e= zm-#_30^&?(0YX|V#6$#|B@Sk=O&MxOn(5v`($XrmQk84#;>nS6g=rwrTqIA*(zT7p z)R}}S*x?P&?y6;_J1CBAZf3RqRND}uq%50$&*<}sh_67aZy-H?@V)679L`Ufv#}fu zW`)IV;*ktSSCup#>5jv`Zy56kFGfAU3DC@x?2$5*eCixFb5$lg4Vc(tXhWqQa>c2E zHjw-?B)KMYC5RvDZ7!L_5=&9E<+WG+Vd;IYFumIfPl*7>;W(gD@bCP&I~+2_v}VSt&!zKFO|OUQp8ThehVaF-h{uEtb!+U*3vG-K)cVtfVsG z{f~}a`&Sv(jG@(@7NP$AuKv(R2~SNA4P6BV(;E-3)=odDaU831o_lI{{n9C>#&Pv1 zvg}y6uO%ZKt?POM%;(Ft=8gwb9Pt9n34moy=;i|?cuzP}85hR2;uyCt;G~MiC|+#p zt=}6Qe*o#?rvx3|gAR5xEnJVAx7H^Cc_a(%^j~ml7^274L-m~bV{?vC!kc~!!g{px zJQ>*~F;{hDa%UVd5$TmwV<_8EFDZ=&$_3*^VfigiUQkb|;>-jdM80+&n4o<66*M{* zL=_^3+(sUhlkBXtq^!o!djcBTG>gXR2}QF#jwR^=cL%Q`xCE?s(tL^?%PsTJ1{E&} zxFeb&4Q~(F%WtriOWr4m<7HVd)p9k!b@E^RAi6RZ)3%biSyZUpf+RHXWC){J#ouuK z>XGTA^TASj$-~#5+iEb&X;*eE=f#NdAWbPMR7~dPL62&*Wd;`3xg9Br7Ya9tw=Z`J`wpup{lDSG|PoZ_` zW35vz2}| z(>^f43_kO~9ETFuuUxE{Q%hAN7(EvOVvH`BMGxcpVxFfxeriz$;LChZt*Z*!N{%^@1 z|0N)p=?@Uh%=jBJW#ssc0yD8N{~r8j!C-wm^AA9j-O$$IHwMgR=45U4PXJ%$KMae% z0i%D<%=jzj{2M&~PlDM@OdNjzUq-gy-x8cmY!yp4x7~L5|5A&D0XB1!F7i7>!Aa*vnPP*UnHD;m<$$McM^xyB(Y$CzP znYmF#6i7tENl>OI-cuiX3p3SkGv_0ZdJcLP0*wf6UVI*5Ta8p?13byf;5+;&U)~#B zXRZbsWJ577c5jXG=W_+n}|fZ%(`A2jUEYFHUD^6_X7u2~>`#xl z+d=!F-eO$jA>`?MK=j;|43Vq$G(#U1l`wVy)fOa`B_aw#!X27l;hSUr&Kp{-D2nqILnZ6#}za zOdzWW?dweQ1%9Hv0vBsPi~#ojh3CYbWmlrHU7{Gkxh3kpUo?s5SfV`}KFwh#3s#Qi zXc^!2Xzs=t?I@zJD}D-2rtRnB-_|+Rhc1+u+G&o8(amrX=On8u#t%X60tGJ|;5p&< z9I^@Kf=pY!n^Fhc(ZS|#)=dHg+80&I2pJbe5&qi8B+U}4U{TLRt>-z676u_tr5Et^ zhv5schHxh~r*)0p?VGHzUMOR;4?K@byK~9eYp2hZ-qD5d>#TSHN{fgorZV zFyX48_5_UR@!4d+A)k_u9T|lFBjRi5DHMjFE1teUZCpHgYnPW0L$-*mT27l?fO_$V zG16cs-l4GP7A}raFo6baMH1_Bn98yI*C-lDuWV4Noc}J6TaAO9`ni8?Ipj zwY1&p{i-48H&u}7W|~2XL-zFFTFoPD7IFk#r;8T+n=dJv+tPoMU~8GPpj2zeyv7rU zyC`eu<*=5NLwazWQg)KHMyoo`+1p}Wdo${DAl+~FY9Y90{rxT~Wu1fFL?BG3>Sw}`KB%BmMEp-F7>t~3wBy6`2M9qmj716&C$)IU0=E-ro|Z3} zL{AIxC^XLZl|boC_4-|PyJkV21JI&@oQDNwivr#55dngM3T;_gL>Ibl;hZM>`q|?v z>!25MfybMW6OL1v;pkc32pn^52$1Ur;P~XXigQ?FF1?{Ml_^kL?eXmP=LT4$lOr@; zX*q?Q3n7l)yIPbY3 zxDpZBpzk^hvmg<7m4+{Vv!~f85x2Ybc$EHOxTn!wcn@9frnb-UUNfl2u`;`Cxnjp6 zM@OtlSR$3}fvxwZsq9NmB0?g}DqyUN;(%07xe;uNs2{##!87wc9U5{jk9eKAy>KrR z*|xW-6eTg9-XIc~H!>?Kwwx3CQd2X$E=qW6uA!t=R(J{x{~+vVI8vfW%}tiJPcrnJ zR?4MS5TU)ngq@5%bU9`UW`?hABmrx8Ho&-IC#e#foKZQUsfaaKHgY(5tJF7l0Z=sI zmHPeGIj+}z=}WRvXH|k*$@qu|MOl#rGOJMFBx``*(QvPDJ2H!WkYA<>pcmDEjhf?l zF&W82tb%OS8P#EiiFq?)qvdXer<|*ze)qm7{D{;Q2h79HKOv5Qwf zbNdCcPP#&Gx)leEZaKV>2MU|*?*Vi)pY4{(J36hsC8kWzz_0mTZ}f@F0~j7`7r|f{ zG%b?B<{DcM;iairUTNnVry$r_>42?KB-So)_CQZ^#gyhXy9jq+!s$39>8>Tb!`T_I z&lwdI->f%*XF?CH*}qdtI(@o*!pPI_NeJ}>p#O? z0vKV(%Eg&CYGAP&sM!IvAznjO9r>WDDbmkl*a{Ald&llTYJ!z?(XR{VuoG4Vn_XDi z5;@kKNMq)V$*%VTtrKT=>`J5ldZ%9x%1(J+PQ}~=nUgZL4akB%e};)$odx)AIjlqB z3?;r@?X^b49Hs|ghLIINCS+JJfBox>odp3?<5c#Ac% zIouU5=dX3}7>L31FQn{boOz0dwY=cUI=CH|JPkA_BpibzSZ&1YNwBnXuDBZ6Bg3i3 zpJ_7qj#}w{tqmt#X^_iKJv;dj%^+QI_4ECn5-3;w(JOForQ7W6+iRuEp7xsk&9fj8 zXw7XdRq9js6&9_hBGlS#$eP<)D%`$ly+WInu2?OGa=k5nedgIo*d39{^Y_XCGujfX z4awt+rS^>ue|MXu_U|b+>eb$myK~WrZCG;n85%pr@D%WR(k!&jU#e_1ZI-<^2qC8G zm6qB?lwE4Pd0CfQjh@j(*I7gwEHBBby?N`(WrptX)H!FHxfoX(m`d8X(R_HGj-Fik z`_m1axF=icw~CSt6y_}#v1eFl)ZHuqCbw|QjqptB zKYKRs482E885u97QgM#LPsNhg+Xnt|skZVXbv7pq(>pOntxdll|G_^B zqV&fA-obaKMoE@u3;9Rb@~h2c`W|_t7anJhrPFPocV&Z^g~%VKlKL^5@Rp0T=3@p}Qrlud zc8oXhE@}V)z~JFXtOm-KHBxhG8b&8)raPdT8N=Sdk~l;{2)am$WGR!&$x$>f*1^)e z)dr$rkBY*oWvOKcbCg3_q^TV4r2+IsCJ$!02IBb=+w9K4pLlw_zFEpge^6B9eIEA3 z3Xlc(6=3mIfv@2V?>kXk(HRYN7&=<^LFX~zo2O8|L=a`^a8X8lxd(y3pa}Tn=*4U= zLbh#+o5b6{R%_qXZ$siMM&hTD?%Cd`?dMIo^1OBn%NNMAJyI8Qzg|KlpUt{SrQ5Ei` z;p()UoS%)LTyye^wXQ&3b+TNT`=v38z%A6RD!+5`Z|veCla=&+;@q1$b-Q9!%2M&q zh#gLhyA61ywKLHR4O*A#x9+a2Gzbhl)eZ-;7&)y16_OexXg){%mWz>y5xSXFN8rLL4AX7e^yK-di5Ss3fnNvBq<=7{BG3lC!SpX+c{x zPQy~&W2~3rc=uFBuX~hpCqCZ8CQ-0R#5ewmMhByuC%3#tjP@B&YohQhD&qnIrhSp1 zfvAQxvg^>RTd>y*h}1w+Qy*f3-*9~x-(_m)bFEk9uq#N|7;CS||I86@QmXl>WC7q4)fB6PjHN|X?ODG-gS_7F53sR-Be$R|3CGa9 z&mXrz7;yly#x$c8De!o6qqQinwDy^R-E`kCe6Y5nF4R84ajVxfw!mme*(`|C7UuHe zj#Qch$fav&9b|kfw^l5q!gZi-R>bv`r=N!2$90WoJiSd0tRKE^YA=FUX!v5^SA2fI zdTK!H=`mD13!_#3ly8%~h)2tLMus72pAs6Bk$;aQweiN|C2UvRK12asV?)^ZOP0yF zQz+aI3QZ%CZX}(IV6Ev;d)WV$61X(W(*xD=8S+)AIZ)X%pO%_kpcT}0?k0=@i>eh%bPox8OIDu&Ys1BL&}!7C#v0rbHJ_ETF_VXI{kL|n9sT(P)?3?SWDomg|)0aq#OX}_{*j4S0m{l4hsylB zrpKi_+EVKgI=s1B-N*}NeaEOtWhTl3uCsHphPn5R2h{FpsGrlqxVfie!ZkM-ZQ_a3 zYb|lDH$}ua`|@sNiX}y~0|X4pXz##hBg)QN%c`s5tXW?lqKsrLjXz%66W|%jl2c|b zsq~nUb5v>%I#`KRPOTA#ZaZ_sUJ&X*=z9N2UGm>@F8(k2l>ficRr#MKN{+v;9tvme>Ua+L>#|Y{;~d#U^xF=Ka^&E5B{^o$$u#4{X226|6MWf&q@9*j(^>? z#rnS};Am+ANE-gqwFPYXRUw|Pk|u4&vwtWM^gF@>Bu5pY9;9vB`{&taWk5@_=eP|n zRF%4?3kz-h@l~;ng|U^^Te4oj5q00∾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 diff --git a/docs/beta-1/readmes/core.html b/docs/beta-1/readmes/core.html index 533343d..3c30056 100644 --- a/docs/beta-1/readmes/core.html +++ b/docs/beta-1/readmes/core.html @@ -84,7 +84,7 @@

Exact version and candidate

Product component -civiccore 1.3.0.dev1 +townlight_core 1.3.0.dev1 Native desktop source version @@ -295,7 +295,7 @@

Native deployment installed workspace.

Technical deployments use TOWNLIGHT_PRODUCT_PROFILE, TOWNLIGHT_PROFILE_ROOT, DATABASE_URL, -CIVICSUITE_RUNTIME_PORT, PORTAL_MODE and the +TOWNLIGHT_RUNTIME_PORT, PORTAL_MODE and the runtime-managed secret files. Treat database URLs and native session proofs as secrets. The installed native domain runtime explicitly refuses non-loopback binding. PORTAL_MODE=private is the @@ -325,7 +325,7 @@

Trusted local HTTP example

permission check. Do not use real city data in development examples. A read response does not prove approval or publication.

$profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite'
+class="sourceCode powershell">$profilePath = Join-Path $env:LOCALAPPDATA 'Townlight'
 $sessionPath = Join-Path $profilePath 'config\local-session.json'
 $session = Get-Content -LiteralPath $sessionPath -Raw | ConvertFrom-Json
 $headers = @{ 'X-Townlight-Session' = $session.session_hash }
@@ -339,7 +339,7 @@ 

A synthetic write independently under the signed-in synthetic account. If a write times out, inspect current records before repeating it.

$profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite'
+class="sourceCode powershell">$profilePath = Join-Path $env:LOCALAPPDATA 'Townlight'
 $sessionPath = Join-Path $profilePath 'config/local-session.json'
 $session = Get-Content -LiteralPath $sessionPath -Raw | ConvertFrom-Json
 $headers = @{ 'X-Townlight-Session' = $session.session_hash }
@@ -446,11 +446,11 @@ 

Development and repository runtime lock when reproducing packaging.

Relevant source contracts:

    -
  • civiccore/auth
  • -
  • civiccore/catalog
  • -
  • civiccore/exemptions
  • -
  • civiccore/scaffold
  • -
  • civicsuite_runtime/services.py
  • +
  • townlight_core/auth
  • +
  • townlight_core/catalog
  • +
  • townlight_core/exemptions
  • +
  • townlight_core/scaffold
  • +
  • townlight_runtime/services.py
  • desktop/src-tauri/src/supervisor.rs

The desktop package defines npm run build, diff --git a/docs/beta-1/reference/component-metadata.json b/docs/beta-1/reference/component-metadata.json index e3d8ca5..6a78a48 100644 --- a/docs/beta-1/reference/component-metadata.json +++ b/docs/beta-1/reference/component-metadata.json @@ -1,7 +1,7 @@ { - "civicaccess-0.4.0.dist-info": { + "townlight_access-0.4.0.dist-info": { "Name": [ - "civicaccess" + "townlight_access" ], "Version": [ "0.4.0" @@ -10,7 +10,7 @@ ">=3.11" ], "Requires-Dist": [ - "civiccore @ https://github.com/townlight/core/releases/download/v1.2.0/civiccore-1.2.0-py3-none-any.whl#sha256=a94ce958e36fb03c8d961e4db4672ce5bcfa25765c57d75886e999cf15703ec7", + "townlight_core @ https://github.com/townlight/core/releases/download/v1.2.0/townlight_core-1.2.0-py3-none-any.whl#sha256=a94ce958e36fb03c8d961e4db4672ce5bcfa25765c57d75886e999cf15703ec7", "fastapi<1.0.0,>=0.115.0", "psycopg2-binary<3.0.0,>=2.9.0", "sqlalchemy<3.0.0,>=2.0.0", @@ -25,9 +25,9 @@ "AGPL-3.0-only" ] }, - "civicclerk-1.0.4.dist-info": { + "townlight_meetings-1.0.4.dist-info": { "Name": [ - "civicclerk" + "townlight_meetings" ], "Version": [ "1.0.4" @@ -37,7 +37,7 @@ ], "Requires-Dist": [ "celery[redis]<6.0.0,>=5.4.0", - "civiccore @ https://github.com/townlight/core/releases/download/v1.2.1/civiccore-1.2.1-py3-none-any.whl#sha256=8dde29408e206048bde63ec14156a8e6329382af4d16b12710d12aa5c27f3f59", + "townlight_core @ https://github.com/townlight/core/releases/download/v1.2.1/townlight_core-1.2.1-py3-none-any.whl#sha256=8dde29408e206048bde63ec14156a8e6329382af4d16b12710d12aa5c27f3f59", "fastapi<1.0.0,>=0.115.0", "httpx<1.0.0,>=0.27.0", "psycopg2-binary<3.0.0,>=2.9.0", @@ -52,9 +52,9 @@ ], "License-Expression": [] }, - "civiccode-1.0.8.dist-info": { + "townlight_code-1.0.8.dist-info": { "Name": [ - "civiccode" + "townlight_code" ], "Version": [ "1.0.8" @@ -65,7 +65,7 @@ "Requires-Dist": [ "alembic<2.0.0,>=1.13.0", "asyncpg<1.0.0,>=0.29.0", - "civiccore @ https://github.com/townlight/core/releases/download/v1.2.1/civiccore-1.2.1-py3-none-any.whl#sha256=8dde29408e206048bde63ec14156a8e6329382af4d16b12710d12aa5c27f3f59", + "townlight_core @ https://github.com/townlight/core/releases/download/v1.2.1/townlight_core-1.2.1-py3-none-any.whl#sha256=8dde29408e206048bde63ec14156a8e6329382af4d16b12710d12aa5c27f3f59", "fastapi<1.0.0,>=0.115.0", "psycopg2-binary<3.0.0,>=2.9.0", "pymupdf<2.0.0,>=1.26.0", @@ -82,9 +82,9 @@ ], "License-Expression": [] }, - "civiccore-1.3.0.dev1.dist-info": { + "townlight_core-1.3.0.dev1.dist-info": { "Name": [ - "civiccore\r" + "townlight_core\r" ], "Version": [ "1.3.0.dev1\r" @@ -135,9 +135,9 @@ "AGPL-3.0-only\r" ] }, - "civicinspect-0.3.0+dev.1.dist-info": { + "townlight_inspections-0.3.0+dev.1.dist-info": { "Name": [ - "civicinspect" + "townlight_inspections" ], "Version": [ "0.3.0+dev.1" @@ -147,7 +147,7 @@ ], "Requires-Dist": [ "alembic<2.0.0,>=1.14.0", - "civiccore @ https://github.com/townlight/core/releases/download/v1.2.1/civiccore-1.2.1-py3-none-any.whl#sha256=8dde29408e206048bde63ec14156a8e6329382af4d16b12710d12aa5c27f3f59", + "townlight_core @ https://github.com/townlight/core/releases/download/v1.2.1/townlight_core-1.2.1-py3-none-any.whl#sha256=8dde29408e206048bde63ec14156a8e6329382af4d16b12710d12aa5c27f3f59", "fastapi<1.0.0,>=0.115.0", "psycopg2-binary<3.0.0,>=2.9.0", "sqlalchemy<3.0.0,>=2.0.0", @@ -163,9 +163,9 @@ ], "License-Expression": [] }, - "civicnotice-0.2.0.dist-info": { + "townlight_notice-0.2.0.dist-info": { "Name": [ - "civicnotice" + "townlight_notice" ], "Version": [ "0.2.0" @@ -174,7 +174,7 @@ ">=3.11" ], "Requires-Dist": [ - "civiccore @ https://github.com/townlight/core/releases/download/v1.2.0/civiccore-1.2.0-py3-none-any.whl#sha256=a94ce958e36fb03c8d961e4db4672ce5bcfa25765c57d75886e999cf15703ec7", + "townlight_core @ https://github.com/townlight/core/releases/download/v1.2.0/townlight_core-1.2.0-py3-none-any.whl#sha256=a94ce958e36fb03c8d961e4db4672ce5bcfa25765c57d75886e999cf15703ec7", "fastapi<1.0.0,>=0.115.0", "sqlalchemy<3.0.0,>=2.0.0", "uvicorn[standard]<1.0.0,>=0.30.0", @@ -190,9 +190,9 @@ "AGPL-3.0-only" ] }, - "civicpermit-0.3.0+dev.1.dist-info": { + "townlight_permitting-0.3.0+dev.1.dist-info": { "Name": [ - "civicpermit" + "townlight_permitting" ], "Version": [ "0.3.0+dev.1" @@ -202,7 +202,7 @@ ], "Requires-Dist": [ "alembic<2.0.0,>=1.13.0", - "civiccore @ https://github.com/townlight/core/releases/download/v1.2.1/civiccore-1.2.1-py3-none-any.whl#sha256=8dde29408e206048bde63ec14156a8e6329382af4d16b12710d12aa5c27f3f59", + "townlight_core @ https://github.com/townlight/core/releases/download/v1.2.1/townlight_core-1.2.1-py3-none-any.whl#sha256=8dde29408e206048bde63ec14156a8e6329382af4d16b12710d12aa5c27f3f59", "fastapi<1.0.0,>=0.115.0", "sqlalchemy<3.0.0,>=2.0.0", "uvicorn[standard]<1.0.0,>=0.30.0", @@ -217,9 +217,9 @@ ], "License-Expression": [] }, - "civicplan-0.4.0.dev1.dist-info": { + "townlight_planning-0.4.0.dev1.dist-info": { "Name": [ - "civicplan" + "townlight_planning" ], "Version": [ "0.4.0.dev1" @@ -228,7 +228,7 @@ ">=3.11" ], "Requires-Dist": [ - "civiccore==1.3.0.dev1", + "townlight_core==1.3.0.dev1", "fastapi<1.0.0,>=0.115.0", "psycopg2-binary<3.0.0,>=2.9.0", "sqlalchemy<3.0.0,>=2.0.0", @@ -244,9 +244,9 @@ "AGPL-3.0-only" ] }, - "civicrecords_ai-1.8.0.dev1.dist-info": { + "townlight_records-1.8.0.dev1.dist-info": { "Name": [ - "civicrecords-ai\r" + "townlight_records\r" ], "Version": [ "1.8.0.dev1\r" @@ -267,7 +267,7 @@ "python-jose[cryptography]>=3.5.0\r", "passlib[bcrypt]>=1.7.4\r", "celery>=5.6.0\r", - "civiccore==1.3.0.dev1\r", + "townlight_core==1.3.0.dev1\r", "redis<8.0.0,>=5.0.0\r", "httpx>=0.28.0\r", "pdfplumber>=0.11.0\r", @@ -290,9 +290,9 @@ "AGPL-3.0-only\r" ] }, - "civicsuite_runtime-0.1.0.dist-info": { + "townlight_runtime-0.1.0.dist-info": { "Name": [ - "civicsuite-runtime" + "townlight_runtime" ], "Version": [ "0.1.0" @@ -310,9 +310,9 @@ "AGPL-3.0-only" ] }, - "civiczone-0.2.2.dist-info": { + "townlight_zoning-0.2.2.dist-info": { "Name": [ - "civiczone" + "townlight_zoning" ], "Version": [ "0.2.2" @@ -321,7 +321,7 @@ ">=3.11" ], "Requires-Dist": [ - "civiccore @ https://github.com/townlight/core/releases/download/v1.2.1/civiccore-1.2.1-py3-none-any.whl#sha256=8dde29408e206048bde63ec14156a8e6329382af4d16b12710d12aa5c27f3f59", + "townlight_core @ https://github.com/townlight/core/releases/download/v1.2.1/townlight_core-1.2.1-py3-none-any.whl#sha256=8dde29408e206048bde63ec14156a8e6329382af4d16b12710d12aa5c27f3f59", "fastapi<1.0.0,>=0.115.0", "uvicorn[standard]<1.0.0,>=0.30.0", "build<2.0.0,>=1.2.0; extra == 'dev'", diff --git a/docs/beta-1/reference/desktop-domain-openapi.json b/docs/beta-1/reference/desktop-domain-openapi.json index dfd2e93..bc0444d 100644 --- a/docs/beta-1/reference/desktop-domain-openapi.json +++ b/docs/beta-1/reference/desktop-domain-openapi.json @@ -11267,10 +11267,10 @@ } } }, - "/civiccode": { + "/townlight_code": { "get": { "summary": "Home", - "operationId": "home_civiccode_get", + "operationId": "home_townlight_code_get", "responses": { "200": { "description": "Successful Response", @@ -11285,10 +11285,10 @@ } } }, - "/civiccode/search": { + "/townlight_code/search": { "get": { "summary": "Search", - "operationId": "search_civiccode_search_get", + "operationId": "search_townlight_code_search_get", "parameters": [ { "name": "q", @@ -11325,10 +11325,10 @@ } } }, - "/civiccode/answer": { + "/townlight_code/answer": { "get": { "summary": "Answer", - "operationId": "answer_civiccode_answer_get", + "operationId": "answer_townlight_code_answer_get", "parameters": [ { "name": "q", @@ -11398,10 +11398,10 @@ } } }, - "/civiccode/sections/{section_ref}": { + "/townlight_code/sections/{section_ref}": { "get": { "summary": "Detail", - "operationId": "detail_civiccode_sections__section_ref__get", + "operationId": "detail_townlight_code_sections__section_ref__get", "parameters": [ { "name": "section_ref", @@ -11454,10 +11454,10 @@ } } }, - "/civiccode/sections/{section_ref}/export": { + "/townlight_code/sections/{section_ref}/export": { "get": { "summary": "Export", - "operationId": "export_civiccode_sections__section_ref__export_get", + "operationId": "export_townlight_code_sections__section_ref__export_get", "parameters": [ { "name": "section_ref", @@ -12274,10 +12274,10 @@ } } }, - "/civiczone/questions": { + "/townlight_zoning/questions": { "post": { "summary": "Public Question", - "operationId": "public_question_civiczone_questions_post", + "operationId": "public_question_townlight_zoning_questions_post", "requestBody": { "content": { "application/json": { @@ -12310,10 +12310,10 @@ } } }, - "/civiczone/parcels/lookup": { + "/townlight_zoning/parcels/lookup": { "post": { "summary": "Public Parcel Lookup", - "operationId": "public_parcel_lookup_civiczone_parcels_lookup_post", + "operationId": "public_parcel_lookup_townlight_zoning_parcels_lookup_post", "requestBody": { "content": { "application/json": { @@ -12376,7 +12376,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/civicsuite_runtime__planning_bridge__Import" + "$ref": "#/components/schemas/townlight_runtime__planning_bridge__Import" } } } @@ -12433,7 +12433,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/civicsuite_runtime__planning_bridge__Import" + "$ref": "#/components/schemas/townlight_runtime__planning_bridge__Import" } } } @@ -12752,7 +12752,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/civicsuite_runtime__planning_bridge__Search" + "$ref": "#/components/schemas/townlight_runtime__planning_bridge__Search" } } } @@ -13901,18 +13901,18 @@ } } }, - "/civicplan/policies/search": { + "/townlight_planning/policies/search": { "post": { "tags": [ "local-public-planning" ], "summary": "Public Policies", - "operationId": "public_policies_civicplan_policies_search_post", + "operationId": "public_policies_townlight_planning_policies_search_post", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/civicsuite_runtime__planning_bridge__Search" + "$ref": "#/components/schemas/townlight_runtime__planning_bridge__Search" } } }, @@ -13940,14 +13940,14 @@ } } }, - "/civicplan/plan-explore": { + "/townlight_planning/plan-explore": { "post": { "tags": [ "local-public-planning" ], "summary": "Public Plan Explore", "description": "Topic/goal/plan-type exploration over adopted public plan sources only.", - "operationId": "public_plan_explore_civicplan_plan_explore_post", + "operationId": "public_plan_explore_townlight_planning_plan_explore_post", "requestBody": { "content": { "application/json": { @@ -13980,13 +13980,13 @@ } } }, - "/civicplan/snapshots": { + "/townlight_planning/snapshots": { "get": { "tags": [ "local-public-planning" ], "summary": "Public Snapshots", - "operationId": "public_snapshots_civicplan_snapshots_get", + "operationId": "public_snapshots_townlight_planning_snapshots_get", "parameters": [ { "name": "limit", @@ -14035,13 +14035,13 @@ } } }, - "/civicplan/snapshots/{snapshot_id}": { + "/townlight_planning/snapshots/{snapshot_id}": { "get": { "tags": [ "local-public-planning" ], "summary": "Public Document", - "operationId": "public_document_civicplan_snapshots__snapshot_id__get", + "operationId": "public_document_townlight_planning_snapshots__snapshot_id__get", "parameters": [ { "name": "snapshot_id", @@ -14076,13 +14076,13 @@ } } }, - "/civicplan/revisions/{revision_id}/documents/{document_id}": { + "/townlight_planning/revisions/{revision_id}/documents/{document_id}": { "get": { "tags": [ "local-public-planning" ], "summary": "Public Original", - "operationId": "public_original_civicplan_revisions__revision_id__documents__document_id__get", + "operationId": "public_original_townlight_planning_revisions__revision_id__documents__document_id__get", "parameters": [ { "name": "revision_id", @@ -14156,7 +14156,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/civicsuite_runtime__permitting_bridge__Import" + "$ref": "#/components/schemas/townlight_runtime__permitting_bridge__Import" } } } @@ -14804,7 +14804,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/civicsuite_runtime__permitting_bridge__Search" + "$ref": "#/components/schemas/townlight_runtime__permitting_bridge__Search" } } } @@ -15557,7 +15557,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/civicsuite_runtime__inspections_bridge__Search" + "$ref": "#/components/schemas/townlight_runtime__inspections_bridge__Search" } } } @@ -19793,7 +19793,7 @@ }, "linked_sources": { "items": { - "$ref": "#/components/schemas/civicinspect__workflow_models__SourceLink" + "$ref": "#/components/schemas/townlight_inspections__workflow_models__SourceLink" }, "type": "array", "maxItems": 30, @@ -19915,7 +19915,7 @@ }, "linked_sources": { "items": { - "$ref": "#/components/schemas/civicpermit__workflow_models__SourceLink" + "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink" }, "type": "array", "maxItems": 30, @@ -21905,7 +21905,7 @@ "fee_link": { "anyOf": [ { - "$ref": "#/components/schemas/civicpermit__workflow_models__SourceLink" + "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink" }, { "type": "null" @@ -23580,7 +23580,7 @@ "fee_link": { "anyOf": [ { - "$ref": "#/components/schemas/civicpermit__workflow_models__SourceLink" + "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink" }, { "type": "null" @@ -26207,7 +26207,7 @@ ], "title": "_ParcelLookupIn" }, - "civicinspect__workflow_models__SourceLink": { + "townlight_inspections__workflow_models__SourceLink": { "properties": { "provider": { "type": "string", @@ -26235,7 +26235,7 @@ ], "title": "SourceLink" }, - "civicpermit__workflow_models__SourceLink": { + "townlight_permitting__workflow_models__SourceLink": { "properties": { "provider": { "type": "string", @@ -26266,7 +26266,7 @@ ], "title": "SourceLink" }, - "civicsuite_runtime__inspections_bridge__Search": { + "townlight_runtime__inspections_bridge__Search": { "properties": { "provider": { "type": "string", @@ -26288,7 +26288,7 @@ ], "title": "Search" }, - "civicsuite_runtime__permitting_bridge__Import": { + "townlight_runtime__permitting_bridge__Import": { "properties": { "bundle": { "$ref": "#/components/schemas/RequirementBundle" @@ -26313,7 +26313,7 @@ ], "title": "Import" }, - "civicsuite_runtime__permitting_bridge__Search": { + "townlight_runtime__permitting_bridge__Search": { "properties": { "provider": { "type": "string", @@ -26338,7 +26338,7 @@ ], "title": "Search" }, - "civicsuite_runtime__planning_bridge__Import": { + "townlight_runtime__planning_bridge__Import": { "properties": { "bundle": { "additionalProperties": true, @@ -26366,7 +26366,7 @@ ], "title": "Import" }, - "civicsuite_runtime__planning_bridge__Search": { + "townlight_runtime__planning_bridge__Search": { "properties": { "query": { "type": "string", diff --git a/docs/beta-1/reference/native.html b/docs/beta-1/reference/native.html index 6841318..5e4e403 100644 --- a/docs/beta-1/reference/native.html +++ b/docs/beta-1/reference/native.html @@ -1806,12 +1806,12 @@

main.rs

| "sign-minutes" | "record-closed-session" | "export-meeting-packet" - | "archive-meeting" => Some((vec!["civicclerk"], false)), - "civicnotice-calculate-deadline" - | "civicnotice-complete-checklist" - | "civicnotice-post-notice" - | "civicnotice-export-archive-packet" => Some((vec!["civicclerk", "civicnotice"], false)), - "record-adopted-legislation" => Some((vec!["civicclerk", "civiccode"], false)), + | "archive-meeting" => Some((vec!["townlight_meetings"], false)), + "townlight_notice-calculate-deadline" + | "townlight_notice-complete-checklist" + | "townlight_notice-post-notice" + | "townlight_notice-export-archive-packet" => Some((vec!["townlight_meetings", "townlight_notice"], false)), + "record-adopted-legislation" => Some((vec!["townlight_meetings", "townlight_code"], false)), "create-records-request" | "load-demo-town" | "submit-public-records-request" @@ -1838,7 +1838,7 @@

main.rs

| "export-records-response" | "fulfill-records-request" | "close-records-request" - | "mark-notification-sent" => Some((vec!["civicrecords-ai"], false)), + | "mark-notification-sent" => Some((vec!["townlight_records"], false)), "import-code-source" | "record-codifier-sync" | "record-codifier-sync-failure" @@ -1850,14 +1850,14 @@

main.rs

| "publish-code-source" | "unpublish-code-source" | "create-code-handoff" - | "answer-code-question" => Some((vec!["civiccode"], false)), + | "answer-code-question" => Some((vec!["townlight_code"], false)), "search-city-knowledge" => Some(( vec![ - "civicclerk", - "civicrecords-ai", - "civiccode", - "civicnotice", - "civicaccess", + "townlight_meetings", + "townlight_records", + "townlight_code", + "townlight_notice", + "townlight_access", ], true, )), @@ -1865,28 +1865,28 @@

main.rs

.and_then(|value| value.get("folder")) .and_then(Value::as_str) { - Some("meetings") => Some((vec!["civicclerk"], false)), - Some("records") => Some((vec!["civicrecords-ai"], false)), - Some("code") => Some((vec!["civiccode"], false)), - Some("notice") => Some((vec!["civicnotice"], false)), - Some("access") => Some((vec!["civicaccess"], false)), - Some("planning") => Some((vec!["civicplan"], false)), - Some("permitting") => Some((vec!["civicpermit"], false)), - Some("inspections") => Some((vec!["civicinspect"], false)), + Some("meetings") => Some((vec!["townlight_meetings"], false)), + Some("records") => Some((vec!["townlight_records"], false)), + Some("code") => Some((vec!["townlight_code"], false)), + Some("notice") => Some((vec!["townlight_notice"], false)), + Some("access") => Some((vec!["townlight_access"], false)), + Some("planning") => Some((vec!["townlight_planning"], false)), + Some("permitting") => Some((vec!["townlight_permitting"], false)), + Some("inspections") => Some((vec!["townlight_inspections"], false)), _ => Some(( - vec!["civicclerk", "civicrecords-ai", "civiccode", "civicnotice"], + vec!["townlight_meetings", "townlight_records", "townlight_code", "townlight_notice"], true, )), }, "accessibility-review" - | "civicaccess-records-export" - | "civicaccess-delete-review" - | "civicaccess-plain-language" - | "civicaccess-language-variant" - | "civicaccess-form-plan" - | "civicaccess-publishing-workflow" - | "civicaccess-ada-title-ii" - | "civicaccess-tagged-pdf" => Some((vec!["civicaccess"], false)), + | "townlight_access-records-export" + | "townlight_access-delete-review" + | "townlight_access-plain-language" + | "townlight_access-language-variant" + | "townlight_access-form-plan" + | "townlight_access-publishing-workflow" + | "townlight_access-ada-title-ii" + | "townlight_access-tagged-pdf" => Some((vec!["townlight_access"], false)), _ => None, } } @@ -1905,11 +1905,11 @@

main.rs

fn module_exports_folder(module_id: &str) -> Option<(&'static str, &'static str)> { match module_id { - "civicclerk" => Some(("meetings", "meeting exports")), - "civicrecords-ai" => Some(("records", "records exports")), - "civiccode" => Some(("code", "code exports")), - "civicnotice" => Some(("notice", "notice exports")), - "civicaccess" => Some(("access", "accessibility/records exports")), + "townlight_meetings" => Some(("meetings", "meeting exports")), + "townlight_records" => Some(("records", "records exports")), + "townlight_code" => Some(("code", "code exports")), + "townlight_notice" => Some(("notice", "notice exports")), + "townlight_access" => Some(("access", "accessibility/records exports")), _ => None, } } @@ -2163,7 +2163,7 @@

main.rs

} fn picked_file_path_for_desktop() -> Result<Option<String>, String> { - if let Ok(path) = std::env::var("CIVICSUITE_TEST_FILE_PICKER_PATH") { + if let Ok(path) = std::env::var("TOWNLIGHT_TEST_FILE_PICKER_PATH") { let trimmed = path.trim(); return Ok(if trimmed.is_empty() { None @@ -2187,7 +2187,7 @@

main.rs

} fn picked_folder_path_for_desktop() -> Result<Option<String>, String> { - if let Ok(path) = std::env::var("CIVICSUITE_TEST_FOLDER_PICKER_PATH") { + if let Ok(path) = std::env::var("TOWNLIGHT_TEST_FOLDER_PICKER_PATH") { let trimmed = path.trim(); return Ok(if trimmed.is_empty() { None @@ -2510,7 +2510,7 @@

main.rs

if !selection .enabled_module_ids .iter() - .any(|id| id == "civiczone") + .any(|id| id == "townlight_zoning") { return Err(domain_client::DomainError::denied()); } @@ -2535,7 +2535,7 @@

main.rs

if !selection .enabled_module_ids .iter() - .any(|id| id == "civiczone") + .any(|id| id == "townlight_zoning") { return Err(domain_client::DomainError::denied()); } @@ -2551,7 +2551,7 @@

main.rs

) || !selection .enabled_module_ids .iter() - .any(|id| id == "civicplan") + .any(|id| id == "townlight_planning") { return Err(domain_client::DomainError::denied()); } @@ -2587,7 +2587,7 @@

main.rs

) || !selection .enabled_module_ids .iter() - .any(|id| id == "civicpermit") + .any(|id| id == "townlight_permitting") { return Err(domain_client::DomainError::denied()); } @@ -2610,7 +2610,7 @@

main.rs

|| !selection .enabled_module_ids .iter() - .any(|id| id == "civicinspect") + .any(|id| id == "townlight_inspections") { return Err(domain_client::DomainError::denied()); } @@ -2816,13 +2816,13 @@

main.rs

fn with_clean_first_run_state<T>(test: impl FnOnce(PathBuf) -> T) -> T { let _guard = first_run::test_env_lock().lock().expect("test env lock"); let root = env::temp_dir().join(format!( - "civicsuite-desktop-app-state-test-{}", + "townlight-desktop-app-state-test-{}", std::process::id() )); let _ = fs::remove_dir_all(&root); - env::set_var("CIVICSUITE_DESKTOP_STATE_DIR", &root); + env::set_var("TOWNLIGHT_DESKTOP_STATE_DIR", &root); let result = test(root.clone()); - env::remove_var("CIVICSUITE_DESKTOP_STATE_DIR"); + env::remove_var("TOWNLIGHT_DESKTOP_STATE_DIR"); let _ = fs::remove_dir_all(root); result } @@ -2887,7 +2887,7 @@

main.rs

fn records_beta_modules_are_reported_installed() { module_registry::validate_default_registry().expect("module registry contract validates"); let modules = module_summaries().expect("module registry parses"); - for module_id in ["civiccore", "civicrecords-ai", "civicnotice", "civicaccess"] { + for module_id in ["townlight_core", "townlight_records", "townlight_notice", "townlight_access"] { let module = modules .iter() .find(|candidate| candidate.id == module_id) @@ -2897,7 +2897,7 @@

main.rs

"{module_id} should be installed in records-beta" ); } - for module_id in ["civicclerk", "civiccode"] { + for module_id in ["townlight_meetings", "townlight_code"] { let module = modules .iter() .find(|candidate| candidate.id == module_id) @@ -3061,7 +3061,7 @@

main.rs

create_first_admin(); let signed_out_result = - module_action("disable-module".to_string(), "civiccode".to_string()); + module_action("disable-module".to_string(), "townlight_code".to_string()); assert!(signed_out_result.is_err()); assert!(signed_out_result @@ -3070,7 +3070,7 @@

main.rs

.contains("Sign in as the Townlight admin")); sign_in_as_first_admin(); - let disabled = module_action("disable-module".to_string(), "civiccode".to_string()) + let disabled = module_action("disable-module".to_string(), "townlight_code".to_string()) .expect("module disable allowed"); assert!(disabled.accepted); assert_eq!(disabled.status, "Module disabled"); @@ -3078,38 +3078,38 @@

main.rs

.selection .installed_module_ids .iter() - .any(|module_id| module_id == "civiccode")); + .any(|module_id| module_id == "townlight_code")); assert!(!disabled .selection .enabled_module_ids .iter() - .any(|module_id| module_id == "civiccode")); + .any(|module_id| module_id == "townlight_code")); assert!(disabled .modules .iter() - .any(|module| module.id == "civiccode" && module.installed && !module.enabled)); + .any(|module| module.id == "townlight_code" && module.installed && !module.enabled)); - let enabled = module_action("enable-module".to_string(), "civiccode".to_string()) + let enabled = module_action("enable-module".to_string(), "townlight_code".to_string()) .expect("module enable allowed"); assert!(enabled .selection .enabled_module_ids .iter() - .any(|module_id| module_id == "civiccode")); + .any(|module_id| module_id == "townlight_code")); - let current = module_action("update-module".to_string(), "civiccode".to_string()) + let current = module_action("update-module".to_string(), "townlight_code".to_string()) .expect("module update check allowed"); assert_eq!(current.status, "Module current"); assert!(current.message.contains("pinned version")); let opened_exports = - module_action("open-module-exports".to_string(), "civiccode".to_string()) + module_action("open-module-exports".to_string(), "townlight_code".to_string()) .expect("module exports open"); assert_eq!(opened_exports.status, "Module exports opened"); assert!(opened_exports.message.contains("code exports")); assert!(root.join("Data").join("exports").join("code").is_dir()); - let removed = module_action("remove-module".to_string(), "civiccode".to_string()) + let removed = module_action("remove-module".to_string(), "townlight_code".to_string()) .expect("module remove allowed"); assert_eq!(removed.status, "Module removed"); assert!(removed.message.contains("verified profile backup")); @@ -3118,7 +3118,7 @@

main.rs

.selection .installed_module_ids .iter() - .any(|module_id| module_id == "civiccode")); + .any(|module_id| module_id == "townlight_code")); let backup_count = fs::read_dir(root.join("Backups")) .expect("backup root exists") .filter(|entry| { @@ -3131,21 +3131,21 @@

main.rs

assert_eq!(backup_count, 1); let removed_exports = - module_action("open-module-exports".to_string(), "civiccode".to_string()); + module_action("open-module-exports".to_string(), "townlight_code".to_string()); assert!(removed_exports.is_err()); assert!(removed_exports .err() .expect("removed module export error") .contains("is not installed in this local profile")); - let installed = module_action("install-module".to_string(), "civiccode".to_string()) + let installed = module_action("install-module".to_string(), "townlight_code".to_string()) .expect("module install allowed"); assert_eq!(installed.status, "Module installed"); assert!(installed .selection .enabled_module_ids .iter() - .any(|module_id| module_id == "civiccode")); + .any(|module_id| module_id == "townlight_code")); }); } @@ -3154,20 +3154,20 @@

main.rs

with_clean_first_run_state(|_| { create_first_admin(); env::set_var( - "CIVICSUITE_TEST_FILE_PICKER_PATH", + "TOWNLIGHT_TEST_FILE_PICKER_PATH", r"C:\City\Records\packet.pdf", ); let signed_out = choose_file_path(); - env::remove_var("CIVICSUITE_TEST_FILE_PICKER_PATH"); + env::remove_var("TOWNLIGHT_TEST_FILE_PICKER_PATH"); assert!(signed_out.is_err()); sign_in_as_first_admin(); env::set_var( - "CIVICSUITE_TEST_FILE_PICKER_PATH", + "TOWNLIGHT_TEST_FILE_PICKER_PATH", r"C:\City\Records\packet.pdf", ); let picked = choose_file_path().expect("signed-in file picker"); - env::remove_var("CIVICSUITE_TEST_FILE_PICKER_PATH"); + env::remove_var("TOWNLIGHT_TEST_FILE_PICKER_PATH"); assert_eq!(picked.as_deref(), Some(r"C:\City\Records\packet.pdf")); }); @@ -3177,29 +3177,29 @@

main.rs

fn choose_folder_path_allows_first_run_then_requires_local_admin() { with_clean_first_run_state(|_| { env::set_var( - "CIVICSUITE_TEST_FOLDER_PICKER_PATH", + "TOWNLIGHT_TEST_FOLDER_PICKER_PATH", r"C:\City\TownlightData", ); let first_run_folder = choose_folder_path().expect("pre-admin folder picker"); - env::remove_var("CIVICSUITE_TEST_FOLDER_PICKER_PATH"); + env::remove_var("TOWNLIGHT_TEST_FOLDER_PICKER_PATH"); assert_eq!(first_run_folder.as_deref(), Some(r"C:\City\TownlightData")); create_first_admin(); env::set_var( - "CIVICSUITE_TEST_FOLDER_PICKER_PATH", + "TOWNLIGHT_TEST_FOLDER_PICKER_PATH", r"C:\City\TownlightBackups", ); let signed_out = choose_folder_path(); - env::remove_var("CIVICSUITE_TEST_FOLDER_PICKER_PATH"); + env::remove_var("TOWNLIGHT_TEST_FOLDER_PICKER_PATH"); assert!(signed_out.is_err()); sign_in_as_first_admin(); env::set_var( - "CIVICSUITE_TEST_FOLDER_PICKER_PATH", + "TOWNLIGHT_TEST_FOLDER_PICKER_PATH", r"C:\City\TownlightBackups", ); let picked = choose_folder_path().expect("admin folder picker"); - env::remove_var("CIVICSUITE_TEST_FOLDER_PICKER_PATH"); + env::remove_var("TOWNLIGHT_TEST_FOLDER_PICKER_PATH"); assert_eq!(picked.as_deref(), Some(r"C:\City\TownlightBackups")); }); @@ -3335,8 +3335,8 @@

main.rs

with_clean_first_run_state(|_| { create_first_admin(); sign_in_as_first_admin(); - module_action("disable-module".to_string(), "civiccode".to_string()) - .expect("civiccode disabled"); + module_action("disable-module".to_string(), "townlight_code".to_string()) + .expect("townlight_code disabled"); let code_payload = serde_json::json!({ "title": "Backyard Chicken Rules", @@ -3355,11 +3355,11 @@

main.rs

} #[test] - fn civicaccess_only_profile_can_still_reach_search_city_knowledge() { + fn townlight_access_only_profile_can_still_reach_search_city_knowledge() { with_clean_first_run_state(|_| { create_first_admin(); sign_in_as_first_admin(); - for m in ["civiccode", "civicnotice", "civicclerk", "civicrecords-ai"] { + for m in ["townlight_code", "townlight_notice", "townlight_meetings", "townlight_records"] { module_action("disable-module".to_string(), m.to_string()).unwrap(); } require_enabled_city_modules("search-city-knowledge", None) @@ -3379,7 +3379,7 @@

main.rs

with_clean_first_run_state(|_| { create_first_admin(); sign_in_as_first_admin(); - module_action("disable-module".to_string(), "civiccode".to_string()).unwrap(); + module_action("disable-module".to_string(), "townlight_code".to_string()).unwrap(); let mut result = CityWorkActionResult { accepted: true, action: "search-city-knowledge".into(), @@ -3388,7 +3388,7 @@

main.rs

next_action: String::new(), state: CityWorkState::default(), search_results: vec![workflows::SearchResult { - module_id: "civiccode".into(), + module_id: "townlight_code".into(), record_id: "synthetic".into(), title: "Synthetic".into(), snippet: String::new(), @@ -3959,7 +3959,7 @@

planning_client.rs

PlanExplore { payload } => (Method::POST, "/plan-explore".into(), Some(payload)), }; let prefix = if public { - "/civicplan" + "/townlight_planning" } else { "/desktop/v1/planning" }; @@ -4048,7 +4048,7 @@

planning_client.rs

) .is_err()); let (_, path, _) = route(PlanningRequest::Snapshots { offset: 50 }, true).unwrap(); - assert_eq!(path, "/civicplan/snapshots?offset=50"); + assert_eq!(path, "/townlight_planning/snapshots?offset=50"); assert!(serde_json::from_value::<PlanningRequest>( serde_json::json!({"operation":"snapshot","id":"../../private"}) ) @@ -4203,7 +4203,7 @@

zoning_client.rs

} }; let prefix = if public { - "/civiczone" + "/townlight_zoning" } else { "/desktop/v1/zoning" }; diff --git a/docs/beta-1/reference/runtime-payload-lock.json b/docs/beta-1/reference/runtime-payload-lock.json index f19212c..7b1ff22 100644 --- a/docs/beta-1/reference/runtime-payload-lock.json +++ b/docs/beta-1/reference/runtime-payload-lock.json @@ -7,27 +7,27 @@ "publication_allowed": false, "wheels": [ { - "name": "civicinspect-0.3.0+dev.1-py3-none-any.whl", + "name": "townlight_inspections-0.3.0+dev.1-py3-none-any.whl", "sha256": "cf48a2a7efd4ee5f4fe1d2ee91314733be259af7c3dcd3cddeffba1247c2558d" }, { - "name": "civicpermit-0.3.0+dev.1-py3-none-any.whl", + "name": "townlight_permitting-0.3.0+dev.1-py3-none-any.whl", "sha256": "306d09973488d9c3343ee291a9b6a1a11c95fafb2dc25cbddd6eb6736b4be903" }, { - "name": "civicplan-0.4.0.dev1-py3-none-any.whl", + "name": "townlight_planning-0.4.0.dev1-py3-none-any.whl", "sha256": "4090e4c9fa80a976f0838ab8c98deefb2bd278598ca79bec634bb71bbbfb66f4" }, { - "name": "civicrecords_ai-1.8.0.dev1-py3-none-any.whl", + "name": "townlight_records-1.8.0.dev1-py3-none-any.whl", "sha256": "6015e6905d9bd6f817fe7e31a3e7a66d9fda332648e7590e757432c86df44e93" }, { - "name": "civicsuite_runtime-0.1.0-py3-none-any.whl", + "name": "townlight_runtime-0.1.0-py3-none-any.whl", "sha256": "9e069be6f1683871c262ce3010c84157f9f4a1f797b9c967bbb772286e6c7c1e" }, { - "name": "civiczone-0.2.2-py3-none-any.whl", + "name": "townlight_zoning-0.2.2-py3-none-any.whl", "sha256": "e6c3af637ce7e00d1e7cbaaf5fe2259d243eb003fb1540903e5c3f6f6ec865f4" }, { @@ -58,39 +58,39 @@ "publication_allowed": false, "wheels": [ { - "name": "civicaccess-0.4.0-py3-none-any.whl", + "name": "townlight_access-0.4.0-py3-none-any.whl", "sha256": "62a8518c418e9cd0c96a5901a0ce715e81b4769ca7d1e356cccc005e3ded92cb" }, { - "name": "civicclerk-1.0.4-py3-none-any.whl", + "name": "townlight_meetings-1.0.4-py3-none-any.whl", "sha256": "9fc95292ab3e6d798c1c3832e5179ccdddcb79b910b184d05894ce0ff62cbca5" }, { - "name": "civiccode-1.0.8-py3-none-any.whl", + "name": "townlight_code-1.0.8-py3-none-any.whl", "sha256": "fa2af4d1a456f2ed4377b422030de3f93ed0bd393bbe2ec5c334217ef56f287a" }, { - "name": "civicinspect-0.3.0+dev.1-py3-none-any.whl", + "name": "townlight_inspections-0.3.0+dev.1-py3-none-any.whl", "sha256": "c5fc1cbea4b2a98c5ab2b5b967b7c6f51f54e6a2c962e0f1da104905cd022d6d" }, { - "name": "civicnotice-0.2.0-py3-none-any.whl", + "name": "townlight_notice-0.2.0-py3-none-any.whl", "sha256": "7406bad6529f29c839d14998c5fed0519b60873cec7116fe260d1cbb2210d412" }, { - "name": "civicpermit-0.3.0+dev.1-py3-none-any.whl", + "name": "townlight_permitting-0.3.0+dev.1-py3-none-any.whl", "sha256": "3c629ed12b5195d937ccff5b72fe02c6f0993a129e208de9599bdbd45d44a994" }, { - "name": "civicplan-0.4.0.dev1-py3-none-any.whl", + "name": "townlight_planning-0.4.0.dev1-py3-none-any.whl", "sha256": "bdcb7b695bb0df442c6efae1b89218174583f73ecadd0a816914934dd951cbb0" }, { - "name": "civicsuite_runtime-0.1.0-py3-none-any.whl", + "name": "townlight_runtime-0.1.0-py3-none-any.whl", "sha256": "4b917583fa236a080fb6789a2d69b14805d5398bba6fa6456fc15960b8748907" }, { - "name": "civiczone-0.2.2-py3-none-any.whl", + "name": "townlight_zoning-0.2.2-py3-none-any.whl", "sha256": "4b08068ce55d5c85ab712778fd425d68af31bcc449b014e67b6c84b01a0403e8" }, { @@ -246,237 +246,237 @@ "sha256": "b62831d83e129a974bec04ee10fd71cfd15c8940f5c5c4dd11794b8f51cbd8d8" }, { - "path": "Lib/site-packages/civicaccess/main.py", + "path": "Lib/site-packages/townlight_access/main.py", "size_bytes": 17450, "sha256": "379d3c880dd949db3325fa055b8822cf5f59a20b8d7c4da3a84a8f12989134ab" }, { - "path": "Lib/site-packages/civicclerk/desktop_delivery.py", + "path": "Lib/site-packages/townlight_meetings/desktop_delivery.py", "size_bytes": 5096, "sha256": "cbb7f44aee90b9ea16c60c1f64efffa8bb7204765d49a5ce80fe52e2670d384e" }, { - "path": "Lib/site-packages/civicclerk/main.py", + "path": "Lib/site-packages/townlight_meetings/main.py", "size_bytes": 147419, "sha256": "d224d17b9869739b6faaddcd7213e202f8b710f72cda402479c0c6a84e737285" }, { - "path": "Lib/site-packages/civicclerk/migrations/versions/civicclerk_0017_meeting_authority.py", + "path": "Lib/site-packages/townlight_meetings/migrations/versions/townlight_meetings_0017_meeting_authority.py", "size_bytes": 2306, "sha256": "73c6266df0dd33b74223133a2a00d045112a1996ffc38025d3aa8ba7831f1082" }, { - "path": "Lib/site-packages/civicclerk/migrations/versions/civicclerk_0018_agenda_authority.py", + "path": "Lib/site-packages/townlight_meetings/migrations/versions/townlight_meetings_0018_agenda_authority.py", "size_bytes": 1675, "sha256": "7dc3993bf51db8239270fd53a651b98ebbff0dbfce56ccbb73414ac9bbac2464" }, { - "path": "Lib/site-packages/civicclerk/migrations/versions/civicclerk_0019_minutes_decisions.py", + "path": "Lib/site-packages/townlight_meetings/migrations/versions/townlight_meetings_0019_minutes_decisions.py", "size_bytes": 541, "sha256": "5f088e0026bef9f492cac6a4c4a6c16ee81409d6447b1ab1ee19c037cd56d9cc" }, { - "path": "Lib/site-packages/civicclerk/migrations/versions/civicclerk_0020_delivery_history.py", + "path": "Lib/site-packages/townlight_meetings/migrations/versions/townlight_meetings_0020_delivery_history.py", "size_bytes": 762, "sha256": "92a6779b59cb3228b3bbd963a9c4cef921163cbd07473381f015dbf474ba4005" }, { - "path": "Lib/site-packages/civicclerk/migrations/versions/civicclerk_0021_sources_archive.py", + "path": "Lib/site-packages/townlight_meetings/migrations/versions/townlight_meetings_0021_sources_archive.py", "size_bytes": 892, "sha256": "3220a0e7992d865b5a1f5a9bb71cb85722336f276fc974c13939d81fbfc1b29c" }, { - "path": "Lib/site-packages/civicclerk/records_sources.py", + "path": "Lib/site-packages/townlight_meetings/records_sources.py", "size_bytes": 1843, "sha256": "843b4808e4a335ab05a7801a33a3a5750dc49ce84d7e71961841e91e7532598f" }, { - "path": "Lib/site-packages/civicclerk/transcripts.py", + "path": "Lib/site-packages/townlight_meetings/transcripts.py", "size_bytes": 3334, "sha256": "33d5b6f97ce58b6f645e0c236a53a855c358d01db06ee048ec9c90100474bc98" }, { - "path": "Lib/site-packages/civiccode/main.py", + "path": "Lib/site-packages/townlight_code/main.py", "size_bytes": 84536, "sha256": "930e05298b82f10ec0338040770d8af83aa56a9d43016908931ab8f796e63f48" }, { - "path": "Lib/site-packages/civiccore/__init__.py", + "path": "Lib/site-packages/townlight_core/__init__.py", "size_bytes": 10775, "sha256": "22823aa2e5f34ff62c57276cc877fc52fb6c654877b5e3756d6dccdb40f7dc15" }, { - "path": "Lib/site-packages/civiccore/migrations/alembic.ini", + "path": "Lib/site-packages/townlight_core/migrations/alembic.ini", "size_bytes": 82, "sha256": "d519dafe29ef2eb3cd77de8f8fd769746a45275439a6b3c5f5e34d990cc61092" }, { - "path": "Lib/site-packages/civiccore/migrations/versions/civiccore_0003_local_task_queue.py", + "path": "Lib/site-packages/townlight_core/migrations/versions/townlight_core_0003_local_task_queue.py", "size_bytes": 1832, "sha256": "51276a0dc2737fd1fc2615f26d66d942c1df3be2ef40f1513436cd4579b1ecf0" }, { - "path": "Lib/site-packages/civicinspect/migrations/versions/civicinspect_0001_connected.py", + "path": "Lib/site-packages/townlight_inspections/migrations/versions/townlight_inspections_0001_connected.py", "size_bytes": 1305, "sha256": "0e71ed311993f45634eb42ba22f5c2b2c4a3854639b221857af76f826d1b68de" }, { - "path": "Lib/site-packages/civicinspect/workflow_store.py", + "path": "Lib/site-packages/townlight_inspections/workflow_store.py", "size_bytes": 17443, "sha256": "df4ff48879d5f8fe31d71a410a99ed8c359676ab05a267db65e1468cb4764146" }, { - "path": "Lib/site-packages/civicnotice/main.py", + "path": "Lib/site-packages/townlight_notice/main.py", "size_bytes": 23033, "sha256": "3aec4b0007a662276afbb8527fab22fe796e4d64c3568fe688ac97dc63bc69bc" }, { - "path": "Lib/site-packages/civicpermit/migrations/versions/civicpermit_0001_connected.py", + "path": "Lib/site-packages/townlight_permitting/migrations/versions/townlight_permitting_0001_connected.py", "size_bytes": 1272, "sha256": "e3fc90959836887334b429888407537140fa2d119c202886b63c538feb4e9360" }, { - "path": "Lib/site-packages/civicpermit/workflow_store.py", + "path": "Lib/site-packages/townlight_permitting/workflow_store.py", "size_bytes": 15222, "sha256": "c3415dd94aaed609a593d28b60d0719f2dc1a504a5f15391d9708714038ea259" }, { - "path": "Lib/site-packages/civicplan/migrations/__init__.py", + "path": "Lib/site-packages/townlight_planning/migrations/__init__.py", "size_bytes": 2111, "sha256": "daf5e64cefda400a5db1023d952e41bef6f7954db19406d63ea84770c82dccd9" }, { - "path": "Lib/site-packages/civicplan/migrations/versions/civicplan_0002_workflows.py", + "path": "Lib/site-packages/townlight_planning/migrations/versions/townlight_planning_0002_workflows.py", "size_bytes": 1023, "sha256": "7c6fcdfe4a1fa33c9289cef975a25f4b0f6746471c380226c14520f8a5f09dbf" }, { - "path": "Lib/site-packages/civicplan/migrations/versions/civicplan_0004_neighborhoods.py", + "path": "Lib/site-packages/townlight_planning/migrations/versions/townlight_planning_0004_neighborhoods.py", "size_bytes": 806, "sha256": "006f8f8f9859da76189efee9035d1f89c65e0b27172b5df9e316e1aa173434f8" }, { - "path": "Lib/site-packages/civicplan/source_bundle.py", + "path": "Lib/site-packages/townlight_planning/source_bundle.py", "size_bytes": 6466, "sha256": "f6547516067e27697dfcd6ba80de6e2ca03d1473370209aa354a5bf95b7db98a" }, { - "path": "Lib/site-packages/civicplan/workflow_store.py", + "path": "Lib/site-packages/townlight_planning/workflow_store.py", "size_bytes": 16971, "sha256": "4d4fec6d6c876997726ff1d8f2ff39302f44228fae748edc013739267d210741" }, { - "path": "Lib/site-packages/civicsuite_runtime/__init__.py", + "path": "Lib/site-packages/townlight_runtime/__init__.py", "size_bytes": 118, "sha256": "b68059cf70d9999804385a093caa3d7520c96d92f705ba9ee05fbc7d2c2b1f1d" }, { - "path": "Lib/site-packages/civicsuite_runtime/civicrecords_alembic/alembic.ini", + "path": "Lib/site-packages/townlight_runtime/townlight_records_alembic/alembic.ini", "size_bytes": 524, "sha256": "60e69c28e3c87e101995977223073125b196202555e1fc18902feed2afdc7e7e" }, { - "path": "Lib/site-packages/civicsuite_runtime/civicrecords_alembic/alembic/env.py", + "path": "Lib/site-packages/townlight_runtime/townlight_records_alembic/alembic/env.py", "size_bytes": 2784, "sha256": "72f25d2ff59a9fdc6b5282e9d995c8c475146068c2e37b334236c690748ba637" }, { - "path": "Lib/site-packages/civicsuite_runtime/civicrecords_alembic/alembic/versions/027_import_artifact_order.py", + "path": "Lib/site-packages/townlight_runtime/townlight_records_alembic/alembic/versions/027_import_artifact_order.py", "size_bytes": 430, "sha256": "9ef98e386a1dc848a1fab6893b009198d70556020482df207618519a3301faf8" }, { - "path": "Lib/site-packages/civicsuite_runtime/fixtures/redstone-valley-records-demo-v1.json", + "path": "Lib/site-packages/townlight_runtime/fixtures/redstone-valley-records-demo-v1.json", "size_bytes": 6140, "sha256": "2039eca2587b4ace6937ca73e21d0a936835420f8534292247458a1a67516553" }, { - "path": "Lib/site-packages/civicsuite_runtime/inspections_bridge.py", + "path": "Lib/site-packages/townlight_runtime/inspections_bridge.py", "size_bytes": 9755, "sha256": "b7429c3ab988005a198795d6f1dfc3f785c7f96f61410903f8cb0ad38c6f512c" }, { - "path": "Lib/site-packages/civicsuite_runtime/meetings_bridge.py", + "path": "Lib/site-packages/townlight_runtime/meetings_bridge.py", "size_bytes": 28863, "sha256": "37ea43e633b55e9428e928143e5da0d41a7a5906673b8cc54b40fa4d1748fa52" }, { - "path": "Lib/site-packages/civicsuite_runtime/migrate.py", + "path": "Lib/site-packages/townlight_runtime/migrate.py", "size_bytes": 5667, "sha256": "cf632a6c00a1c6e3bdea08edf841510a194665c0ce97705dbc4e16f964bb6145" }, { - "path": "Lib/site-packages/civicsuite_runtime/native_accounts.py", + "path": "Lib/site-packages/townlight_runtime/native_accounts.py", "size_bytes": 4077, "sha256": "e54d1dcfbbf5aecb2c61d7235884e787de05b8f48547f9c68348ba45a8ff9039" }, { - "path": "Lib/site-packages/civicsuite_runtime/permitting_bridge.py", + "path": "Lib/site-packages/townlight_runtime/permitting_bridge.py", "size_bytes": 8765, "sha256": "786abd0dfc18ed0ce7ada70fcd120f96795d8e1ee46f38ca0770a8217b4d6e1d" }, { - "path": "Lib/site-packages/civicsuite_runtime/planning_bridge.py", + "path": "Lib/site-packages/townlight_runtime/planning_bridge.py", "size_bytes": 14108, "sha256": "74a855b995b7f323873b9c788cd15bd4b0ebe3fc1c53879596e1b5043c2825bb" }, { - "path": "Lib/site-packages/civicsuite_runtime/planning_connections.py", + "path": "Lib/site-packages/townlight_runtime/planning_connections.py", "size_bytes": 2406, "sha256": "9991e58a4b168fbbdf5f00334e8515061a09ab06ce593a7625ae007e2fd840f9" }, { - "path": "Lib/site-packages/civicsuite_runtime/records_cutover.py", + "path": "Lib/site-packages/townlight_runtime/records_cutover.py", "size_bytes": 4627, "sha256": "62b93909757ce822fc1f235b6c602d081a669d68e20bca63719b7c773940abde" }, { - "path": "Lib/site-packages/civicsuite_runtime/records_demo.py", + "path": "Lib/site-packages/townlight_runtime/records_demo.py", "size_bytes": 7278, "sha256": "c1c4ef3dd1ffbca62ffaa84cef21a66ecfa57b9f0909a75c5e34bde068b2d4c5" }, { - "path": "Lib/site-packages/civicsuite_runtime/records_import.py", + "path": "Lib/site-packages/townlight_runtime/records_import.py", "size_bytes": 8585, "sha256": "ba8a017e2e83f7b08707b1c1dfe701fb9540d130aebf5aacd29e2c9699ddc8b3" }, { - "path": "Lib/site-packages/civicsuite_runtime/records_import_access.py", + "path": "Lib/site-packages/townlight_runtime/records_import_access.py", "size_bytes": 3194, "sha256": "c8d4052358b5679e64f1fd97097d5d6498b9fbcb4a71a4af3b688a766d5f3fb2" }, { - "path": "Lib/site-packages/civicsuite_runtime/records_import_store.py", + "path": "Lib/site-packages/townlight_runtime/records_import_store.py", "size_bytes": 16716, "sha256": "fe1acc8792fb8a2992d554568705663d2440d044616511891b98fff0e5eb35f7" }, { - "path": "Lib/site-packages/civicsuite_runtime/records_snapshot.py", + "path": "Lib/site-packages/townlight_runtime/records_snapshot.py", "size_bytes": 7066, "sha256": "800377214a5e0b52cd4f402aae015f9eb832d7d29a003cd4cc3b84316cd4a735" }, { - "path": "Lib/site-packages/civicsuite_runtime/zoning_bridge.py", + "path": "Lib/site-packages/townlight_runtime/zoning_bridge.py", "size_bytes": 14635, "sha256": "eb80d79ffc4fc736789aab4f3d3b75a4d9d01101d6414a69a29053c7d5f90505" }, { - "path": "Lib/site-packages/civicsuite_runtime/zoning_records.py", + "path": "Lib/site-packages/townlight_runtime/zoning_records.py", "size_bytes": 1694, "sha256": "045718aaa5f1f42876dbb493e4649e721a94187375d96bc8d7a34512e9ce9806" }, { - "path": "Lib/site-packages/civiczone/connected_sources.py", + "path": "Lib/site-packages/townlight_zoning/connected_sources.py", "size_bytes": 10879, "sha256": "68ad55c71b897eca689a6d028f4aee115dc5ca4b5ef005613385f9588387715b" }, { - "path": "Lib/site-packages/civiczone/geo_import.py", + "path": "Lib/site-packages/townlight_zoning/geo_import.py", "size_bytes": 13239, "sha256": "e49824301593f8c06dd6bc64832542721d7b1763d745deb7ba531f7b894cc4a0" }, { - "path": "Lib/site-packages/civiczone/migrations/versions/civiczone_0006_cited_questions.py", + "path": "Lib/site-packages/townlight_zoning/migrations/versions/townlight_zoning_0006_cited_questions.py", "size_bytes": 2262, "sha256": "65b8c591b5adf3f0022720a2c4e780c818f0f4b5b51db83b81cab78edb2a1f9d" }, diff --git a/docs/beta-1/reference/source-inventory.json b/docs/beta-1/reference/source-inventory.json index 04890db..7b307de 100644 --- a/docs/beta-1/reference/source-inventory.json +++ b/docs/beta-1/reference/source-inventory.json @@ -3,24 +3,24 @@ "basis": "Immutable corresponding source of signed candidate; AST extraction is not executed endpoint acceptance. Router mounts require runtime OpenAPI or source include_router context.", "products": { "core": { - "package": "civiccore", + "package": "townlight_core", "source": [ { - "source": "installed-owned-source/civiccore/__init__.py", + "source": "installed-owned-source/townlight_core/__init__.py", "sha256": "22823aa2e5f34ff62c57276cc877fc52fb6c654877b5e3756d6dccdb40f7dc15", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/audit/__init__.py", + "source": "installed-owned-source/townlight_core/audit/__init__.py", "sha256": "9066c9b752564f42427bb925f2ec72e92007f389fbec24b3bde90655cfb3c9d9", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/audit/primitives.py", + "source": "installed-owned-source/townlight_core/audit/primitives.py", "sha256": "293ba8cf2d89165bf50d1fb019c05a4a1e5a1ca22c3703be25f6c96014491d3a", "routes": [], "models": [ @@ -193,14 +193,14 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/auth/__init__.py", + "source": "installed-owned-source/townlight_core/auth/__init__.py", "sha256": "7a3f307c6fc4ac465688b2ad83b49b85d551721d248e569d0acbb8bf0db49f5a", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/auth/bearer.py", + "source": "installed-owned-source/townlight_core/auth/bearer.py", "sha256": "6515b07ecf4be9fc344ab05eeef891b165f3e0310387dfa3a59fc2531c5dacb9", "routes": [], "models": [ @@ -241,7 +241,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/auth/department_scope.py", + "source": "installed-owned-source/townlight_core/auth/department_scope.py", "sha256": "57905c13074c10acdf07f7a353634bf3e51b1f42f67cd6f7b3d8920dca91f7d1", "routes": [], "models": [ @@ -408,14 +408,14 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/auth/staff_key.py", + "source": "installed-owned-source/townlight_core/auth/staff_key.py", "sha256": "ef7dc371bcd7f419d6266cc61aad01884f263edbcca5db7d5ba4dc1e91d251db", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/auth/suite_session.py", + "source": "installed-owned-source/townlight_core/auth/suite_session.py", "sha256": "e33e13634568261accb2ba6706402de013975f3c58117b987cced3cd92c0db2e", "routes": [], "models": [ @@ -446,7 +446,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/auth/trusted_headers.py", + "source": "installed-owned-source/townlight_core/auth/trusted_headers.py", "sha256": "771e7cbf1f5d73dafad082d97ebb6e350a49b15362ce50eb36b261172e3b9c5c", "routes": [], "models": [ @@ -482,7 +482,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/catalog/__init__.py", + "source": "installed-owned-source/townlight_core/catalog/__init__.py", "sha256": "e323a7808ae719b4b90530c238dc945a107ee1cf9a9050cb00d7efbf5aa1a823", "routes": [], "models": [ @@ -570,14 +570,14 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/city_profile/__init__.py", + "source": "installed-owned-source/townlight_core/city_profile/__init__.py", "sha256": "c22e26dac2fcb454cbf91bcbf23311fdef9bf854fbb2bba2d76149945986bd72", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/city_profile/models.py", + "source": "installed-owned-source/townlight_core/city_profile/models.py", "sha256": "e34b6bbc69f44656ad22217de2b911b5c437fb226b594439f935705c95a47ed6", "routes": [], "models": [ @@ -710,14 +710,14 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/connectors/__init__.py", + "source": "installed-owned-source/townlight_core/connectors/__init__.py", "sha256": "92d5a39aa8241f8fed6405fd0a8b3068994fdeb66ea3f80975ff708dde673870", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/connectors/delta.py", + "source": "installed-owned-source/townlight_core/connectors/delta.py", "sha256": "d99e5624e0eebcc434146909d65040eba0023cc84b2d5d03ce1de2b36c70e52f", "routes": [], "models": [ @@ -768,7 +768,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/connectors/imports.py", + "source": "installed-owned-source/townlight_core/connectors/imports.py", "sha256": "1ed6dafe0072eb57327e7d61b12df801f79bfb9ea7ea1738548afb5a002e0606", "routes": [], "models": [ @@ -857,7 +857,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/connectors/manifest.py", + "source": "installed-owned-source/townlight_core/connectors/manifest.py", "sha256": "15caa167acce428facdf7683085d47dd4a01b02cc2d05df25d6aa1d157bb79bd", "routes": [], "models": [ @@ -918,7 +918,7 @@ "default": "" }, { - "name": "civiccore_version", + "name": "townlight_core_version", "type": "str", "default": "" }, @@ -980,7 +980,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/connectors/sync.py", + "source": "installed-owned-source/townlight_core/connectors/sync.py", "sha256": "ef8bb329bf9d385fd96c617e58a8495989dd76a5d641e0afae3fcf3cba2ca503", "routes": [], "models": [ @@ -1246,14 +1246,14 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/db/__init__.py", + "source": "installed-owned-source/townlight_core/db/__init__.py", "sha256": "19fc1241d2d81b136813d1ca7ebb47d3831a5ffccec8b548237577ddcd65aebb", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/exemptions/__init__.py", + "source": "installed-owned-source/townlight_core/exemptions/__init__.py", "sha256": "83575c21379e697bbbc42b124c8674d8dc99020006f4806237eed0fb71083173", "routes": [], "models": [ @@ -1337,7 +1337,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/exemptions/history.py", + "source": "installed-owned-source/townlight_core/exemptions/history.py", "sha256": "b6b1e5be26a6c7a16391d34b6e50e4c08eb19d5cc25788db8917b0b46044b0ea", "routes": [], "models": [ @@ -1506,7 +1506,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/exemptions/patterns.py", + "source": "installed-owned-source/townlight_core/exemptions/patterns.py", "sha256": "b8c4ea484f1fe521295d29eebcc36703c4560d274b36c88f5af28f5abded98af", "routes": [], "models": [ @@ -1585,14 +1585,14 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/exports/__init__.py", + "source": "installed-owned-source/townlight_core/exports/__init__.py", "sha256": "7b46221c065defc5c31f148cdc5d2464ff6f665d786499b90a0059474fe9713c", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/exports/bundle.py", + "source": "installed-owned-source/townlight_core/exports/bundle.py", "sha256": "22075c7ad189a9eb958b16a5cb4ef759213789f63e799e78b585a671a84ea5bd", "routes": [], "models": [ @@ -1613,9 +1613,9 @@ "default": "" }, { - "name": "civiccore_version", + "name": "townlight_core_version", "type": "str", - "default": "CIVICCORE_VERSION" + "default": "TOWNLIGHT_CORE_VERSION" }, { "name": "purpose", @@ -1640,14 +1640,14 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/ingest/__init__.py", + "source": "installed-owned-source/townlight_core/ingest/__init__.py", "sha256": "6bef6d820315269d126b92aafa02a6d023c6c8706e378003a0cbad434318b791", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/ingest/chunker.py", + "source": "installed-owned-source/townlight_core/ingest/chunker.py", "sha256": "cf9515ec9aecfa7a5b4bbe077c99711ecce651c6c155a4bef07475e404a96c83", "routes": [], "models": [ @@ -1683,7 +1683,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/ingest/contracts.py", + "source": "installed-owned-source/townlight_core/ingest/contracts.py", "sha256": "7536789de18c66e150ad16986c44a794c6ad3353c5dd9e1b29b10f24fa5afaca", "routes": [], "models": [ @@ -1864,7 +1864,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/ingest/embedder.py", + "source": "installed-owned-source/townlight_core/ingest/embedder.py", "sha256": "655ae601f7901c847507e7ef4ab7cc3b77463e7ca1011831d9006b44cb3045ea", "routes": [], "models": [], @@ -1877,7 +1877,7 @@ ] }, { - "source": "installed-owned-source/civiccore/ingest/llm_extractor.py", + "source": "installed-owned-source/townlight_core/ingest/llm_extractor.py", "sha256": "bfa082031b17b4a1af58472eb3faac4cd6cbc91f2d9a2f7e59763f5c92fa5680", "routes": [], "models": [], @@ -1890,7 +1890,7 @@ ] }, { - "source": "installed-owned-source/civiccore/ingest/models.py", + "source": "installed-owned-source/townlight_core/ingest/models.py", "sha256": "a10de63e573ec5d4df5d258265f07695e6ed1805b3cf02897828dfe6008f73bd", "routes": [], "models": [ @@ -2183,14 +2183,14 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/ingest/parsers/__init__.py", + "source": "installed-owned-source/townlight_core/ingest/parsers/__init__.py", "sha256": "f6d7f512bae3794abd587b16845f42af7689ada1f994aca134389f922a445537", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/ingest/parsers/base.py", + "source": "installed-owned-source/townlight_core/ingest/parsers/base.py", "sha256": "d2618295496026752492dcbab6230d8973ed51f4a91984f7150e1bb064c36423", "routes": [], "models": [ @@ -2259,56 +2259,56 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/ingest/parsers/csv_parser.py", + "source": "installed-owned-source/townlight_core/ingest/parsers/csv_parser.py", "sha256": "7c8208fed09911e4f8153ab3c7d1fcfc281b5aec016589b697a728769bdcb41c", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/ingest/parsers/docx.py", + "source": "installed-owned-source/townlight_core/ingest/parsers/docx.py", "sha256": "224542a9d2ebfdf9d3ef8947c7040ec683d13b507462a9c929e167c6b05529f3", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/ingest/parsers/email.py", + "source": "installed-owned-source/townlight_core/ingest/parsers/email.py", "sha256": "a83333d1ed5498fd56c61b47ce897b3d2c3b221070d7d13b000ea95336ea08e1", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/ingest/parsers/html.py", + "source": "installed-owned-source/townlight_core/ingest/parsers/html.py", "sha256": "a0383c330920702a913140377891e3eed43f029a3c756e9dceade4eb6d81b92e", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/ingest/parsers/pdf.py", + "source": "installed-owned-source/townlight_core/ingest/parsers/pdf.py", "sha256": "fe312d998d3224a5cc10ee28c6f76f50a856075b5338370baed56d83ebbc0032", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/ingest/parsers/text.py", + "source": "installed-owned-source/townlight_core/ingest/parsers/text.py", "sha256": "b77c107e8446d92e1fa0ce4f11ed54906e02c2bc5980c19e344c175d635c3441", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/ingest/parsers/xlsx.py", + "source": "installed-owned-source/townlight_core/ingest/parsers/xlsx.py", "sha256": "3bd37c6f389644b630d44fe4964f5f82623469ae2855c04e81437b0fbe9f8fe0", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/ingest/pipeline.py", + "source": "installed-owned-source/townlight_core/ingest/pipeline.py", "sha256": "6d1cbe9794d4bf98e22ddbf18ba4bed5bb96e8a0231f87075b92eeebac4bf570", "routes": [], "models": [ @@ -2331,14 +2331,14 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/llm/__init__.py", + "source": "installed-owned-source/townlight_core/llm/__init__.py", "sha256": "7f8341c07da53f39684a477f9b4fe88ce425a3dc5444f9ac6560eca9787bdac5", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/llm/context.py", + "source": "installed-owned-source/townlight_core/llm/context.py", "sha256": "e7df765626e5ff642e0b86c36771379662ce35594b147391fef0566835762daa", "routes": [], "models": [ @@ -2407,35 +2407,35 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/llm/factory.py", + "source": "installed-owned-source/townlight_core/llm/factory.py", "sha256": "0497147ca6d8af7c4b233a4157089fe4911bb49d0ea214f4fce9ac4c65e48aee", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/llm/providers/__init__.py", + "source": "installed-owned-source/townlight_core/llm/providers/__init__.py", "sha256": "4decd4720c452fa27d1b245a603d409b7dc99db1c5015dbdb3ae29d745ac61fc", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/llm/providers/anthropic.py", + "source": "installed-owned-source/townlight_core/llm/providers/anthropic.py", "sha256": "dba9eb64c724fe8a209dbac48743f99463f99e0c1c67b1306d9126985348b267", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/llm/providers/base.py", + "source": "installed-owned-source/townlight_core/llm/providers/base.py", "sha256": "fe430884bcaf7678f625db6203312e1f1dcdce617db36870623e87b5ac066b32", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/llm/providers/config.py", + "source": "installed-owned-source/townlight_core/llm/providers/config.py", "sha256": "db4ee77e2e0a3ac16fd71df4f0979fab89d36b2ff1985c1e2d4498299810fd3a", "routes": [], "models": [ @@ -2523,35 +2523,35 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/llm/providers/ollama.py", + "source": "installed-owned-source/townlight_core/llm/providers/ollama.py", "sha256": "bd1c78980c464dd41c7fdc24d9c362d17d20d343c9eac3c01000609bacd47e2b", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/llm/providers/openai.py", + "source": "installed-owned-source/townlight_core/llm/providers/openai.py", "sha256": "d54920131ea2f0f14b8eee8c970dce47bf5ee5886815626f09f765fd8d4f4a30", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/llm/providers/registry.py", + "source": "installed-owned-source/townlight_core/llm/providers/registry.py", "sha256": "2733af50366c7e8975c1b552fbe5302ed12d284abd59e65768ac8453d3639870", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/llm/registry/__init__.py", + "source": "installed-owned-source/townlight_core/llm/registry/__init__.py", "sha256": "9223edf2e5652dcee6612a2593299b12e06c6e46f24b4784d9d97bdda333a3d0", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/llm/registry/models.py", + "source": "installed-owned-source/townlight_core/llm/registry/models.py", "sha256": "f58ccb6ce42a7d344c4de7432ca3623e7865a59c91646736e1d397b565e07b0e", "routes": [], "models": [ @@ -2624,7 +2624,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/llm/registry/router.py", + "source": "installed-owned-source/townlight_core/llm/registry/router.py", "sha256": "03815bc31f8b2651acee939dd370f44c91a2c92e663ebe25273986540a379b2f", "routes": [ { @@ -2703,7 +2703,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/llm/registry/schemas.py", + "source": "installed-owned-source/townlight_core/llm/registry/schemas.py", "sha256": "324d0b48abc8d3d0b7a66f9763145a29fed4e81a6b8a59f865b63fb1ab980bfe", "routes": [], "models": [ @@ -2886,28 +2886,28 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/llm/registry/service.py", + "source": "installed-owned-source/townlight_core/llm/registry/service.py", "sha256": "9280f0161a4db25de8182f214fa9d143ef2b1bfc3dac65b1b83b570ed12ee407", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/llm/structured.py", + "source": "installed-owned-source/townlight_core/llm/structured.py", "sha256": "9f7ad6645f2a02aa6a41207906be09a6e1adfc70a89c6eb78387e78cb807477a", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/llm/templates/__init__.py", + "source": "installed-owned-source/townlight_core/llm/templates/__init__.py", "sha256": "a00806b2b0d3c3b7dd966dee85db8f2ee6178697c6f222c28abe4454518ba341", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/llm/templates/engine.py", + "source": "installed-owned-source/townlight_core/llm/templates/engine.py", "sha256": "cb4f72ba249be0264c827c4503b64dea8b61fe525ebb1a93870a9ba58b46d5df", "routes": [], "models": [ @@ -2948,14 +2948,14 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/llm/templates/exceptions.py", + "source": "installed-owned-source/townlight_core/llm/templates/exceptions.py", "sha256": "53bbdcfd915d751cc878edc148a39b52424b5c34a4d03ed8120d763464967a96", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/llm/templates/models.py", + "source": "installed-owned-source/townlight_core/llm/templates/models.py", "sha256": "c1a61785d12d40657aad28ead8f8d27c947634ab159bc48b4309788ae4ed674d", "routes": [], "models": [ @@ -2978,7 +2978,7 @@ { "name": "consumer_app", "type": "Mapped[str]", - "default": "mapped_column(String(100), nullable=False, server_default='civiccore')" + "default": "mapped_column(String(100), nullable=False, server_default='townlight_core')" }, { "name": "is_override", @@ -3038,21 +3038,21 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/llm/templates/overrides.py", + "source": "installed-owned-source/townlight_core/llm/templates/overrides.py", "sha256": "6a32018a76d803c74408937b75e6d3ad597f247d533e2d8092ce7bbccc0d0cd1", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/llm/templates/resolver.py", + "source": "installed-owned-source/townlight_core/llm/templates/resolver.py", "sha256": "389bf9b01902b046f8986fc3415125c859bf8a4923e07d146d0cdd75587b9636", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/llm/templates/schemas.py", + "source": "installed-owned-source/townlight_core/llm/templates/schemas.py", "sha256": "f012308c13d12ec8e338335c5ba451d73c171605697a79a8f3dba334f4af1854", "routes": [], "models": [ @@ -3085,7 +3085,7 @@ { "name": "consumer_app", "type": "str", - "default": "'civiccore'" + "default": "'townlight_core'" }, { "name": "is_override", @@ -3260,14 +3260,14 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/migrations/__init__.py", + "source": "installed-owned-source/townlight_core/migrations/__init__.py", "sha256": "6cb4358063e7a281454ae36e2aa4565e9048e00d193d1da0bab81df47a453703", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/migrations/env.py", + "source": "installed-owned-source/townlight_core/migrations/env.py", "sha256": "208de714d58a5b3fa8f3797c05eadba49d0b46105afeb20c50e7685e298fb4cb", "routes": [], "models": [], @@ -3285,14 +3285,14 @@ ] }, { - "source": "installed-owned-source/civiccore/migrations/guards.py", + "source": "installed-owned-source/townlight_core/migrations/guards.py", "sha256": "c55de91c7189b39537aed6130a1e9f50817f819bd13aa4728ae4e8dd4c863aad", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/migrations/runner.py", + "source": "installed-owned-source/townlight_core/migrations/runner.py", "sha256": "4f3b554197baf06924cc3676d42df083f14f3a9db1456a775601d975499e354e", "routes": [], "models": [], @@ -3305,91 +3305,91 @@ ] }, { - "source": "installed-owned-source/civiccore/migrations/versions/__init__.py", + "source": "installed-owned-source/townlight_core/migrations/versions/__init__.py", "sha256": "61c059e42b35e302a4372a1c7697ca495118b123f7303306d7c54ff15173c8c6", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/migrations/versions/civiccore_0001_baseline_v1.py", + "source": "installed-owned-source/townlight_core/migrations/versions/townlight_core_0001_baseline_v1.py", "sha256": "69186f3f798a01d61638ae42993761c3038ced04e143ea8dd292ebc1fc63afb7", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/migrations/versions/civiccore_0002_llm.py", + "source": "installed-owned-source/townlight_core/migrations/versions/townlight_core_0002_llm.py", "sha256": "fa273e35f651a6298842df0de87bd5548d1a83698adc27e1385ceb28449b00cd", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/migrations/versions/civiccore_0003_local_task_queue.py", + "source": "installed-owned-source/townlight_core/migrations/versions/townlight_core_0003_local_task_queue.py", "sha256": "51276a0dc2737fd1fc2615f26d66d942c1df3be2ef40f1513436cd4579b1ecf0", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/migrations/versions/civiccore_0004_catalog.py", + "source": "installed-owned-source/townlight_core/migrations/versions/townlight_core_0004_catalog.py", "sha256": "a9f46f8ca1bcde43a2796dd62891ad36840d1067220b16fdde8583a1f700a06d", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/migrations/versions/civiccore_0005_job_leases.py", + "source": "installed-owned-source/townlight_core/migrations/versions/townlight_core_0005_job_leases.py", "sha256": "a6651789d82cb0c39481f16855449bf09d65644c93a97bab1e33f8d7546157f7", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/migrations/versions/civiccore_0006_rule_history.py", + "source": "installed-owned-source/townlight_core/migrations/versions/townlight_core_0006_rule_history.py", "sha256": "ac29f724f60125de435235655a052ae3738a286467b1d6d8213a22558994a868", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/migrations/versions/civiccore_0007_module_inventory.py", + "source": "installed-owned-source/townlight_core/migrations/versions/townlight_core_0007_module_inventory.py", "sha256": "41aefee7ff2de883f92eebb7a39de2f0ed8b6bd4fecf88c6ebfd62a0b3cb7456", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/migrations/versions/civiccore_0008_department_authority.py", + "source": "installed-owned-source/townlight_core/migrations/versions/townlight_core_0008_department_authority.py", "sha256": "fa7328f869594d1af2f4daceb4b362cd8ebe304b7e1ecbefaa22497d08430b4a", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/migrations/versions/civiccore_0009_job_artifacts.py", + "source": "installed-owned-source/townlight_core/migrations/versions/townlight_core_0009_job_artifacts.py", "sha256": "ee8952caff749c4b9df5cbc15c379f69f7066351ea5f7690525136be1481d9d8", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/models/__init__.py", + "source": "installed-owned-source/townlight_core/models/__init__.py", "sha256": "213b3086e533a98047d460720e7a1becd7f6196f4a6db989a39253351b8894c9", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/notifications/__init__.py", + "source": "installed-owned-source/townlight_core/notifications/__init__.py", "sha256": "988bcb1091aef4451a1566202a6ec50e3b8908770707b5ad45398923bdb2d6be", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/notifications/notice.py", + "source": "installed-owned-source/townlight_core/notifications/notice.py", "sha256": "78c2542686403c647859b27f5a7bf7ff832cd29ca3ff4086b32c6e5fc098247b", "routes": [], "models": [ @@ -3516,14 +3516,14 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/onboarding/__init__.py", + "source": "installed-owned-source/townlight_core/onboarding/__init__.py", "sha256": "d4d47bddbea571ade848657d39a128849e7b02c45a2c5476bd4ee933033a5713", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/onboarding/profile.py", + "source": "installed-owned-source/townlight_core/onboarding/profile.py", "sha256": "76f82f3b710700d4d3913a1ec5575c15499e46c11b4bb9ddffa2455710b93a93", "routes": [], "models": [ @@ -3587,14 +3587,14 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/platform/__init__.py", + "source": "installed-owned-source/townlight_core/platform/__init__.py", "sha256": "a8618133480c425c95c6ab8b773261aa430f600603941248148b402341ac9f94", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/platform/backup.py", + "source": "installed-owned-source/townlight_core/platform/backup.py", "sha256": "15396fd6bdeaebbddead4a619e11090b427dfcb8744dccd582bbbaf5ca49b407", "routes": [], "models": [ @@ -3655,7 +3655,7 @@ "default": "Field(min_length=1)" }, { - "name": "civiccore_version", + "name": "townlight_core_version", "type": "str", "default": "Field(min_length=1)" }, @@ -3762,7 +3762,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/platform/health.py", + "source": "installed-owned-source/townlight_core/platform/health.py", "sha256": "41f35066ee9a5c1ea3948605f3acf39c568a8916340598468def3502a0ec1634", "routes": [], "models": [ @@ -3865,7 +3865,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/platform/inventory.py", + "source": "installed-owned-source/townlight_core/platform/inventory.py", "sha256": "b6b1936c8bc2d5ba459370e9406395b3bf899a24ba439ff92ac38ae393fe7dda", "routes": [], "models": [ @@ -3921,7 +3921,7 @@ "default": "'windows_local'" }, { - "name": "civiccore_version", + "name": "townlight_core_version", "type": "str", "default": "Field(min_length=1)" }, @@ -3998,7 +3998,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/platform/modules.py", + "source": "installed-owned-source/townlight_core/platform/modules.py", "sha256": "7d3af6bcdc8cc3af90c6c663f5e0ea4571cfe607b0c3ee76a3ce0f966cb8a0c3", "routes": [], "models": [ @@ -4354,7 +4354,7 @@ "default": "Field(min_length=1)" }, { - "name": "civiccore_min_version", + "name": "townlight_core_min_version", "type": "str", "default": "Field(min_length=1)" }, @@ -4494,12 +4494,12 @@ "default": "'windows_local'" }, { - "name": "civiccore_version", + "name": "townlight_core_version", "type": "str", "default": "Field(min_length=1)" }, { - "name": "civiccore_locked", + "name": "townlight_core_locked", "type": "bool", "default": "True" }, @@ -4516,7 +4516,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/platform/runtime.py", + "source": "installed-owned-source/townlight_core/platform/runtime.py", "sha256": "8c9ba7958b8fa08e7b0378a78d3693d8a586714555e5de9420a10626283f579a", "routes": [], "models": [ @@ -4624,7 +4624,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/platform/task_queue.py", + "source": "installed-owned-source/townlight_core/platform/task_queue.py", "sha256": "438c2e7364ef0232b62a4ea379b22a679c248c8c1ab9c0b3149fd87ec8e5fb46", "routes": [], "models": [ @@ -4712,7 +4712,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/platform/tasks.py", + "source": "installed-owned-source/townlight_core/platform/tasks.py", "sha256": "cbf2bf5323fb37c5ff58038d77597464b16c6637b205dcf00a03ad274d120847", "routes": [], "models": [ @@ -4875,14 +4875,14 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/provenance/__init__.py", + "source": "installed-owned-source/townlight_core/provenance/__init__.py", "sha256": "0f703072d5ba898b13a2683285eb8d57e66815356391103f27d63237467d0ab8", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/provenance/contracts.py", + "source": "installed-owned-source/townlight_core/provenance/contracts.py", "sha256": "56dfe26f57056ae1ea85fb8eb808a5259700609483d8e14e67625e123040d57c", "routes": [], "models": [ @@ -5085,7 +5085,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/release_provenance.py", + "source": "installed-owned-source/townlight_core/release_provenance.py", "sha256": "52df52fe6354b741a0cfb759156601fc6682aa34caed7cead9e624ac70e1faf7", "routes": [], "models": [], @@ -5103,28 +5103,28 @@ ] }, { - "source": "installed-owned-source/civiccore/scaffold/__init__.py", + "source": "installed-owned-source/townlight_core/scaffold/__init__.py", "sha256": "313ad60b0afe49ab6d7632c99d96a13deec90466a74e1d4d375a6c663e4a2266", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/scaffold/__main__.py", + "source": "installed-owned-source/townlight_core/scaffold/__main__.py", "sha256": "926a8bb2eede99ffb44ac34a5ff57950df4de748280d37edb38a8cf1c8441819", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/scaffold/cli.py", + "source": "installed-owned-source/townlight_core/scaffold/cli.py", "sha256": "a2228cce93986f97ae26cbdc5ce402ea31c5e83685b6b2cf31c1e52a4ee669d5", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/scaffold/project.py", + "source": "installed-owned-source/townlight_core/scaffold/project.py", "sha256": "343d74719e25beec71fdc0b855f4e1a38db1e338e3a4b62ef1c7b3951e070587", "routes": [], "models": [ @@ -5206,7 +5206,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/scaffold/spec.py", + "source": "installed-owned-source/townlight_core/scaffold/spec.py", "sha256": "603e6d89700bf64b4ffc285c06446b9cf9f66b318613de01ca8b5ef94cc134d2", "routes": [], "models": [ @@ -5237,7 +5237,7 @@ "default": "'0.1.0'" }, { - "name": "civiccore_min_version", + "name": "townlight_core_min_version", "type": "str", "default": "'1.3.0.dev1'" }, @@ -5277,63 +5277,63 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/scheduling/__init__.py", + "source": "installed-owned-source/townlight_core/scheduling/__init__.py", "sha256": "f887d66fc8bf298e094c46bae19fa42b67e5d26911522913d8c5a546d606b4cc", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/scheduling/cron.py", + "source": "installed-owned-source/townlight_core/scheduling/cron.py", "sha256": "a7c5688dc5a3e5c410466cc92a7d884a88a50fe92974d0a7642b0fbe954f0b08", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/search/__init__.py", + "source": "installed-owned-source/townlight_core/search/__init__.py", "sha256": "2450f3768c47b0e2869ca1056b188d41b9ba58f88a0865cad5ad854f03801908", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/security/__init__.py", + "source": "installed-owned-source/townlight_core/security/__init__.py", "sha256": "376e78b0875c2fd3074935b586cef2b806c371f140085ffc40eeb6aed09b9211", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/security/at_rest.py", + "source": "installed-owned-source/townlight_core/security/at_rest.py", "sha256": "eb339fa93cff4af29df7f01b3f5552fff56c6bdc676fef6cb9aad8356a610d3e", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/security/config_validation.py", + "source": "installed-owned-source/townlight_core/security/config_validation.py", "sha256": "e4064bf0394ffc7cdc0aafccfc689a2a17667cfd31d8455dc6f8a623d963af45", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/security/host_validation.py", + "source": "installed-owned-source/townlight_core/security/host_validation.py", "sha256": "3e62ec5540713eea903409c88c4e2255b0dd8d54a9d5d23fc69ad15e03c15045", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/tasks/__init__.py", + "source": "installed-owned-source/townlight_core/tasks/__init__.py", "sha256": "2b30985e76210900397d5e65b5060786e8fec6478d8762690e8971a37c49d5f1", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/tasks/artifacts.py", + "source": "installed-owned-source/townlight_core/tasks/artifacts.py", "sha256": "fbb9db7c76ce4b3bd91b3412ba2cfdcc52d3c67959ef117a0a765ee9dc3d972f", "routes": [], "models": [ @@ -5528,21 +5528,21 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/tasks/leased.py", + "source": "installed-owned-source/townlight_core/tasks/leased.py", "sha256": "eef2a9e339274c1caccde7cb3295a9d5bd88da6561090cbfc0a6bf10c8d29e1d", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/tasks/registry.py", + "source": "installed-owned-source/townlight_core/tasks/registry.py", "sha256": "96bf04036bdc4be3b9097d7bc85f447105fd5d82e8ef548cd3d88354f7b3fce8", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/tasks/worker.py", + "source": "installed-owned-source/townlight_core/tasks/worker.py", "sha256": "106d83f412c66d939e5d9a55276b51020c078ee89763135dc53f7c02ae20f76f", "routes": [], "models": [], @@ -5553,21 +5553,21 @@ "line": 34 }, { - "variable": "CIVICCORE_TASK_HANDLER_MODULES", + "variable": "TOWNLIGHT_CORE_TASK_HANDLER_MODULES", "default": "", "line": 37 } ] }, { - "source": "installed-owned-source/civiccore/testing/__init__.py", + "source": "installed-owned-source/townlight_core/testing/__init__.py", "sha256": "359cfd4ae5b7324db08f496a0ee5043456f1ce60a4ae34fa75761a8790b88d50", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/testing/mock_city.py", + "source": "installed-owned-source/townlight_core/testing/mock_city.py", "sha256": "c1bac5478d09e0958115da8d4f55f4d5211ec1531062e76829381f5a6c47e389", "routes": [], "models": [ @@ -5956,14 +5956,14 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccore/verification/__init__.py", + "source": "installed-owned-source/townlight_core/verification/__init__.py", "sha256": "79e2b135ad90bfad95db77a54f7d2c65d96eb13bb8ad1ed0a35e3655dc03a0e7", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccore/verification/browser_evidence.py", + "source": "installed-owned-source/townlight_core/verification/browser_evidence.py", "sha256": "493219d45f5c50d5c514a4ea9534ccfab35979d0c58a577a2e9afd01328c7fe1", "routes": [], "models": [ @@ -6001,7 +6001,7 @@ ], "bridge": [ { - "source": "installed-owned-source/civicsuite_runtime/services.py", + "source": "installed-owned-source/townlight_runtime/services.py", "sha256": "5dfb0f58ea1f94185081426a3734905c78624d7bcd5407fd2c4e0fa1fb054a6b", "routes": [ { @@ -6052,7 +6052,7 @@ "line": 56 }, { - "variable": "CIVICSUITE_DATA_DIR", + "variable": "TOWNLIGHT_DATA_DIR", "default": "", "line": 61 }, @@ -6067,7 +6067,7 @@ "line": 148 }, { - "variable": "CIVICSUITE_RUNTIME_HOST", + "variable": "TOWNLIGHT_RUNTIME_HOST", "default": "DEFAULT_HOST", "line": 479 }, @@ -6077,7 +6077,7 @@ "line": 113 }, { - "variable": "CIVICCODE_SOURCE_REGISTRY_DB_URL", + "variable": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", "default": "''", "line": 240 }, @@ -6087,7 +6087,7 @@ "line": 300 }, { - "variable": "CIVICSUITE_RUNTIME_PORT", + "variable": "TOWNLIGHT_RUNTIME_PORT", "default": "str(DEFAULT_PORT)", "line": 482 } @@ -6940,7 +6940,7 @@ { "name": "database_url", "type": "str", - "default": "'postgresql+asyncpg://civicrecords:civicrecords@postgres:5432/civicrecords'" + "default": "'postgresql+asyncpg://townlight_records:townlight_records@postgres:5432/townlight_records'" }, { "name": "jwt_secret", @@ -7030,7 +7030,7 @@ { "name": "smtp_from_email", "type": "str", - "default": "'noreply@civicrecords.local'" + "default": "'noreply@townlight_records.local'" }, { "name": "smtp_use_tls", @@ -19496,17 +19496,17 @@ ] }, "meetings": { - "package": "civicclerk", + "package": "townlight_meetings", "source": [ { - "source": "installed-owned-source/civicclerk/__init__.py", + "source": "installed-owned-source/townlight_meetings/__init__.py", "sha256": "e8c6f4d348bc657f507a748a9f941317ea223f13facbc6f71d5777872d472564", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicclerk/agenda_intake.py", + "source": "installed-owned-source/townlight_meetings/agenda_intake.py", "sha256": "efe504bf430447fdd19ee39fbeace4c03365c6bd5f967f29bba40bd3dd48cfd2", "routes": [], "models": [ @@ -19602,7 +19602,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civicclerk/agenda_lifecycle.py", + "source": "installed-owned-source/townlight_meetings/agenda_lifecycle.py", "sha256": "e1e3fb531ca432cbc94bb258454776b8f97112077c5bbcd7d015a6f82f751a14", "routes": [], "models": [ @@ -19681,7 +19681,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civicclerk/cc7_completeness.py", + "source": "installed-owned-source/townlight_meetings/cc7_completeness.py", "sha256": "683d4ba8f4bf4a047e0e3d87725497f30da5210c4496e4586eecc20b1784a468", "routes": [], "models": [ @@ -19750,7 +19750,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civicclerk/connector_import_sync.py", + "source": "installed-owned-source/townlight_meetings/connector_import_sync.py", "sha256": "1d30954f15c9b6d8a9afb5ef9392b4a7475bfd7d926b040707380a7005b8f96e", "routes": [], "models": [ @@ -19796,14 +19796,14 @@ "configuration": [] }, { - "source": "installed-owned-source/civicclerk/connectors.py", + "source": "installed-owned-source/townlight_meetings/connectors.py", "sha256": "31c19cd11f63ae32db9b51f0da57ac5cc8b637a63a16c6b1287c10a7d5afda9d", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicclerk/demo_seed.py", + "source": "installed-owned-source/townlight_meetings/demo_seed.py", "sha256": "d983fb6b80310ce84a0c703f55b5b35e5ecb73f8b5f0c407bab1f9edf27f5cbb", "routes": [], "models": [ @@ -19871,14 +19871,14 @@ "configuration": [] }, { - "source": "installed-owned-source/civicclerk/desktop_delivery.py", + "source": "installed-owned-source/townlight_meetings/desktop_delivery.py", "sha256": "cbb7f44aee90b9ea16c60c1f64efffa8bb7204765d49a5ce80fe52e2670d384e", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicclerk/integration_contracts.py", + "source": "installed-owned-source/townlight_meetings/integration_contracts.py", "sha256": "3899a7aad3af2464ab35d15fee07b952e130cb207a36d1a07dfb6986c67bd805", "routes": [], "models": [ @@ -19987,7 +19987,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civicclerk/main.py", + "source": "installed-owned-source/townlight_meetings/main.py", "sha256": "d224d17b9869739b6faaddcd7213e202f8b710f72cda402479c0c6a84e737285", "routes": [ { @@ -20879,7 +20879,7 @@ "signature": "meeting_id: str, payload: OrdinanceResolutionHandoffRetry | None=None", "returns": "dict[str, object]", "line": 2125, - "doc": "Retry CivicCode emission for failed or unconfigured ordinance handoffs.", + "doc": "Retry TownlightCode emission for failed or unconfigured ordinance handoffs.", "decorator": "app.post('/meetings/{meeting_id}/ordinance-resolution-handoff/retry')", "errors": [ "HTTPException(status_code=404, detail='Handoff not found.')" @@ -20988,7 +20988,7 @@ "decorator": "app.post('/meetings/{meeting_id}/public-record', status_code=201)", "errors": [ "HTTPException(status_code=404, detail='Meeting not found.')", - "HTTPException(status_code=404, detail={'message': 'Meeting not found in the public archive database.', 'fix': 'Point CIVICCLERK_PUBLIC_ARCHIVE_DB_URL at the same database as CIVICCLERK_MEETING_DB_URL so published records reference real meetings.'})" + "HTTPException(status_code=404, detail={'message': 'Meeting not found in the public archive database.', 'fix': 'Point TOWNLIGHT_MEETINGS_PUBLIC_ARCHIVE_DB_URL at the same database as TOWNLIGHT_MEETINGS_MEETING_DB_URL so published records reference real meetings.'})" ] }, { @@ -22255,69 +22255,69 @@ ], "configuration": [ { - "variable": "CIVICCLERK_EXPORT_ROOT", + "variable": "TOWNLIGHT_MEETINGS_EXPORT_ROOT", "default": "'exports'", "line": 3457 }, { - "variable": "CIVICCLERK_AGENDA_INTAKE_DB_URL", + "variable": "TOWNLIGHT_MEETINGS_AGENDA_INTAKE_DB_URL", "default": "", "line": 3463 }, { - "variable": "CIVICCLERK_AGENDA_ITEM_DB_URL", + "variable": "TOWNLIGHT_MEETINGS_AGENDA_ITEM_DB_URL", "default": "", "line": 3472 }, { - "variable": "CIVICCLERK_PACKET_ASSEMBLY_DB_URL", + "variable": "TOWNLIGHT_MEETINGS_PACKET_ASSEMBLY_DB_URL", "default": "", "line": 3483 }, { - "variable": "CIVICCLERK_NOTICE_CHECKLIST_DB_URL", + "variable": "TOWNLIGHT_MEETINGS_NOTICE_CHECKLIST_DB_URL", "default": "", "line": 3492 }, { - "variable": "CIVICCLERK_MEETING_BODY_DB_URL", + "variable": "TOWNLIGHT_MEETINGS_MEETING_BODY_DB_URL", "default": "", "line": 3501 }, { - "variable": "CIVICCLERK_MEETING_DB_URL", + "variable": "TOWNLIGHT_MEETINGS_MEETING_DB_URL", "default": "", "line": 3510 }, { - "variable": "CIVICCLERK_VENDOR_SYNC_DB_URL", + "variable": "TOWNLIGHT_MEETINGS_VENDOR_SYNC_DB_URL", "default": "", "line": 3521 }, { - "variable": "CIVICCLERK_MOTION_VOTE_DB_URL", + "variable": "TOWNLIGHT_MEETINGS_MOTION_VOTE_DB_URL", "default": "", "line": 3530 }, { - "variable": "CIVICCLERK_MINUTES_DB_URL", + "variable": "TOWNLIGHT_MEETINGS_MINUTES_DB_URL", "default": "", "line": 3541 }, { - "variable": "CIVICCLERK_PUBLIC_ARCHIVE_DB_URL", + "variable": "TOWNLIGHT_MEETINGS_PUBLIC_ARCHIVE_DB_URL", "default": "", "line": 3552 }, { - "variable": "CIVICCLERK_PUBLIC_ARCHIVE_DB_URL", + "variable": "TOWNLIGHT_MEETINGS_PUBLIC_ARCHIVE_DB_URL", "default": "", "line": 3563 } ] }, { - "source": "installed-owned-source/civicclerk/meeting_body.py", + "source": "installed-owned-source/townlight_meetings/meeting_body.py", "sha256": "21085a87b167afb85ddd1e20f561695f580f1e20e8259bc8586e29f5f40cc079", "routes": [], "models": [ @@ -22363,7 +22363,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civicclerk/meeting_lifecycle.py", + "source": "installed-owned-source/townlight_meetings/meeting_lifecycle.py", "sha256": "3eb5fdb3d1a259a6841280fca6ce1c1c56317ff8f79de39022e8b5e35fd9115e", "routes": [], "models": [ @@ -22452,14 +22452,14 @@ "configuration": [] }, { - "source": "installed-owned-source/civicclerk/migrations/__init__.py", + "source": "installed-owned-source/townlight_meetings/migrations/__init__.py", "sha256": "dd0a9b788de59eae83bec1152f0508532d3921e8bec7f175ba85f7caa5acc64f", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicclerk/migrations/env.py", + "source": "installed-owned-source/townlight_meetings/migrations/env.py", "sha256": "9b3b3726c41218c534b726516d30de7dce83cc3d8b2f5d02f561ae3460807d5f", "routes": [], "models": [], @@ -22472,168 +22472,168 @@ ] }, { - "source": "installed-owned-source/civicclerk/migrations/guards.py", + "source": "installed-owned-source/townlight_meetings/migrations/guards.py", "sha256": "5dfcd955681e2467f4ae52ebfe04cf3b5892c9aa68adeae3cb5a999c15ceb69e", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicclerk/migrations/versions/__init__.py", + "source": "installed-owned-source/townlight_meetings/migrations/versions/__init__.py", "sha256": "e08e35c06b073f92af22b7b5bb564ea2b9caaf2295b68e9c6c5ec175605dcc96", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicclerk/migrations/versions/civicclerk_0001_schema.py", + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0001_schema.py", "sha256": "21441c137f2570d037447bb832d9a8223dcba7ee16e4e7cd7a974d81f1824028", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicclerk/migrations/versions/civicclerk_0002_agenda_intake_queue.py", + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0002_agenda_intake_queue.py", "sha256": "e23ff5cf9360ab9657e183970c1e36d67111ebf57d5ab1025f9c820eb81f51b3", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicclerk/migrations/versions/civicclerk_0003_packet_assembly_records.py", + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0003_packet_assembly_records.py", "sha256": "28b2b1adc000bbbfd1d537df7abfed94c1a3120f9755542718c05478e96968cc", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicclerk/migrations/versions/civicclerk_0004_notice_checklist_records.py", + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0004_notice_checklist_records.py", "sha256": "a9759ee9a869cbae969e7f371800a296c53f2787ff6654dcb347c18117ce5fcf", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicclerk/migrations/versions/civicclerk_0005_meeting_records.py", + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0005_meeting_records.py", "sha256": "48d3c089a65d4733c164215ec9a18c153b20226f11d9cf06db0ec19d578ec4ea", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicclerk/migrations/versions/civicclerk_0006_agenda_item_lifecycle_records.py", + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0006_agenda_item_lifecycle_records.py", "sha256": "b030e37ee25d963ada7b51f907c28dbdd77949f2d9882dedf27ea5dc2cfdf32a", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicclerk/migrations/versions/civicclerk_0007_meeting_schedule_fields.py", + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0007_meeting_schedule_fields.py", "sha256": "e19e655c7fdbf347a85c22be379b2a537e8075a53748facd55f0856bf93ab598", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicclerk/migrations/versions/civicclerk_0008_agenda_intake_promotion.py", + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0008_agenda_intake_promotion.py", "sha256": "56d0019f2c413c731a09c8dae9150c4d2cd4ccf7b3911786d6e833b9d965dcc0", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicclerk/migrations/versions/civicclerk_0009_vendor_sync_persistence.py", + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0009_vendor_sync_persistence.py", "sha256": "83df336d1ba176f5e5ef4c01485b013dd5686e5cbb1c8ca935dd5bb1336b641d", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicclerk/migrations/versions/civicclerk_0010_vendor_sync_cursor.py", + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0010_vendor_sync_cursor.py", "sha256": "860c440f1696e8094d466c8b634b330416a7e0c0616a660820a1463542f6931b", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicclerk/migrations/versions/civicclerk_0011_data_model_completion.py", + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0011_data_model_completion.py", "sha256": "ee830e52b4fd24d37f234ad928b4beda378ef5267a35542739477a46e7b6a93e", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicclerk/migrations/versions/civicclerk_0012_action_item_actor.py", + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0012_action_item_actor.py", "sha256": "d7a9b4c893b3387ff7557015213cdc6dda893881998071e74b82cf15be2a986c", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicclerk/migrations/versions/civicclerk_0013_minutes_model_posted.py", + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0013_minutes_model_posted.py", "sha256": "908d75f2a666d4a2837823ff48b94cdc0394227d91b48c46deb6efcc9a69e962", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicclerk/migrations/versions/civicclerk_0014_public_meeting_records.py", + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0014_public_meeting_records.py", "sha256": "f92409988f5893fcc0da7dcaa5fa083e20b7c42056681c54e9ae8152b6bf1331", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicclerk/migrations/versions/civicclerk_0015_capture_seq.py", + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0015_capture_seq.py", "sha256": "092e93ad53ec9ee047bf4d0d634933f5d735c2b3fa46a1de1e13f1dc11408ff1", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicclerk/migrations/versions/civicclerk_0016_archive_indexes.py", + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0016_archive_indexes.py", "sha256": "3d91062951e78685411983f45ea206ab436b6fadb20627a79624880def896742", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicclerk/migrations/versions/civicclerk_0017_meeting_authority.py", + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0017_meeting_authority.py", "sha256": "73c6266df0dd33b74223133a2a00d045112a1996ffc38025d3aa8ba7831f1082", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicclerk/migrations/versions/civicclerk_0018_agenda_authority.py", + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0018_agenda_authority.py", "sha256": "7dc3993bf51db8239270fd53a651b98ebbff0dbfce56ccbb73414ac9bbac2464", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicclerk/migrations/versions/civicclerk_0019_minutes_decisions.py", + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0019_minutes_decisions.py", "sha256": "5f088e0026bef9f492cac6a4c4a6c16ee81409d6447b1ab1ee19c037cd56d9cc", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicclerk/migrations/versions/civicclerk_0020_delivery_history.py", + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0020_delivery_history.py", "sha256": "92a6779b59cb3228b3bbd963a9c4cef921163cbd07473381f015dbf474ba4005", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicclerk/migrations/versions/civicclerk_0021_sources_archive.py", + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0021_sources_archive.py", "sha256": "3220a0e7992d865b5a1f5a9bb71cb85722336f276fc974c13939d81fbfc1b29c", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicclerk/minutes.py", + "source": "installed-owned-source/townlight_meetings/minutes.py", "sha256": "d4d890d0c9faaa3fdd51643a156e5f6a29274f436eba858db63746ad0ebb1ea3", "routes": [], "models": [ @@ -22745,7 +22745,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civicclerk/mock_city_environment.py", + "source": "installed-owned-source/townlight_meetings/mock_city_environment.py", "sha256": "6df0969766b42257f372e2babf23675b50aead141a1c91e3e9b95237074f084f", "routes": [], "models": [ @@ -22834,14 +22834,14 @@ "configuration": [] }, { - "source": "installed-owned-source/civicclerk/models.py", + "source": "installed-owned-source/townlight_meetings/models.py", "sha256": "ffc262c2381523ee111259d53bc402938781de926624ca2c791f2ca23bb8072c", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicclerk/motion_vote.py", + "source": "installed-owned-source/townlight_meetings/motion_vote.py", "sha256": "8bc167f9e1ab291f7ee8a616f54786bf4baa686849deac1db33884d5a6d5eaef", "routes": [], "models": [ @@ -23036,7 +23036,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civicclerk/notice_checklist.py", + "source": "installed-owned-source/townlight_meetings/notice_checklist.py", "sha256": "093031a3501ad47e35075e5350f20a3cf5ad8f7d29aa9298ea654edcbd253f71", "routes": [], "models": [ @@ -23137,7 +23137,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civicclerk/oidc_auth.py", + "source": "installed-owned-source/townlight_meetings/oidc_auth.py", "sha256": "3c9ae9b5d1f664d4372048c6e708cc77589cceb071d3e15cab8b90cf76926120", "routes": [], "models": [ @@ -23218,7 +23218,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civicclerk/packet_assembly.py", + "source": "installed-owned-source/townlight_meetings/packet_assembly.py", "sha256": "5edc8d3316a5eb4965b8bcbd94468fb70ef5050ed75811facccc560cec6a4791", "routes": [], "models": [ @@ -23324,7 +23324,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civicclerk/packet_notice.py", + "source": "installed-owned-source/townlight_meetings/packet_notice.py", "sha256": "826b46e12dc114c10b25838bd68bc2d668dc5bdfa2e74bfafc841b6fddff3ffc", "routes": [], "models": [ @@ -23439,7 +23439,7 @@ "default": "" }, { - "name": "civiccore_version", + "name": "townlight_core_version", "type": "str", "default": "" }, @@ -23547,7 +23547,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civicclerk/prompt_evals.py", + "source": "installed-owned-source/townlight_meetings/prompt_evals.py", "sha256": "0c47c06b36500ae63a0ad9dda52edd4baadd8688010714701b6228d6ccca21bd", "routes": [], "models": [ @@ -23587,19 +23587,19 @@ ], "configuration": [ { - "variable": "CIVICCORE_LLM_PROVIDER", + "variable": "TOWNLIGHT_CORE_LLM_PROVIDER", "default": "''", "line": 128 }, { - "variable": "CIVICCLERK_EVAL_OFFLINE", + "variable": "TOWNLIGHT_MEETINGS_EVAL_OFFLINE", "default": "", "line": 129 } ] }, { - "source": "installed-owned-source/civicclerk/prompt_library.py", + "source": "installed-owned-source/townlight_meetings/prompt_library.py", "sha256": "433e349bb9c768d37359bae0a68c89715337da8f363ddaec5a62f37bddd563d9", "routes": [], "models": [ @@ -23683,7 +23683,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civicclerk/public_archive.py", + "source": "installed-owned-source/townlight_meetings/public_archive.py", "sha256": "389d714ee91ef1c4b0cbf49d960894bba49787232a29537ddaebcb9eecbe06b9", "routes": [], "models": [ @@ -23817,28 +23817,28 @@ "configuration": [] }, { - "source": "installed-owned-source/civicclerk/public_ui.py", + "source": "installed-owned-source/townlight_meetings/public_ui.py", "sha256": "4359447b52c4499727fa1d62f385e778154a4243af716cd2fb828e30af6f5db0", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicclerk/records_sources.py", + "source": "installed-owned-source/townlight_meetings/records_sources.py", "sha256": "843b4808e4a335ab05a7801a33a3a5750dc49ce84d7e71961841e91e7532598f", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicclerk/staff_ui.py", + "source": "installed-owned-source/townlight_meetings/staff_ui.py", "sha256": "158329afdeafeb52619ae70bb78cdc731a1cc65f21b31494e3cafd2884b5bdb3", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicclerk/suite_session_compat.py", + "source": "installed-owned-source/townlight_meetings/suite_session_compat.py", "sha256": "6b7cfc7719b722eb7da68fa137c3996d64f237d313ef925ba340f6c39d74474e", "routes": [], "models": [ @@ -23863,27 +23863,27 @@ } ], "line": 28, - "doc": "Validated CivicCore suite session principal." + "doc": "Validated TownlightCore suite session principal." } ], "configuration": [] }, { - "source": "installed-owned-source/civicclerk/transcripts.py", + "source": "installed-owned-source/townlight_meetings/transcripts.py", "sha256": "33d5b6f97ce58b6f645e0c236a53a855c358d01db06ee048ec9c90100474bc98", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicclerk/vendor_delta.py", + "source": "installed-owned-source/townlight_meetings/vendor_delta.py", "sha256": "cebd1ffb95726fd5beb874fbfd9726555681e6c35be7957b97dda26a69898cd3", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicclerk/vendor_live_sync.py", + "source": "installed-owned-source/townlight_meetings/vendor_live_sync.py", "sha256": "0a5048436302ad12e21d822952705ae754ed0ca7a76a7ea9080b292cc2489ab5", "routes": [], "models": [ @@ -23942,7 +23942,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civicclerk/vendor_network_sync.py", + "source": "installed-owned-source/townlight_meetings/vendor_network_sync.py", "sha256": "cf3a9c14de83f76b8deb87aabfaeb43e93bca98f26a65183f1dd4001a3df91e1", "routes": [], "models": [ @@ -24066,7 +24066,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civicclerk/vendor_sync_persistence.py", + "source": "installed-owned-source/townlight_meetings/vendor_sync_persistence.py", "sha256": "f719849f9cd2e1c667bc61f501dc281bf0efe26646e230b0b5b786afcb082d9b", "routes": [], "models": [ @@ -24215,13 +24215,13 @@ "configuration": [] }, { - "source": "installed-owned-source/civicclerk/worker.py", + "source": "installed-owned-source/townlight_meetings/worker.py", "sha256": "6e0aa475591252a06401a613e85d402c8981bdaaf23b460f30b442efbdd43a9b", "routes": [], "models": [], "configuration": [ { - "variable": "CIVICCLERK_REDIS_URL", + "variable": "TOWNLIGHT_MEETINGS_REDIS_URL", "default": "'redis://redis:6379/0'", "line": 46 } @@ -24230,7 +24230,7 @@ ], "bridge": [ { - "source": "installed-owned-source/civicsuite_runtime/meetings_bridge.py", + "source": "installed-owned-source/townlight_runtime/meetings_bridge.py", "sha256": "37ea43e633b55e9428e928143e5da0d41a7a5906673b8cc54b40fa4d1748fa52", "routes": [ { @@ -25101,17 +25101,17 @@ ] }, "code": { - "package": "civiccode", + "package": "townlight_code", "source": [ { - "source": "installed-owned-source/civiccode/__init__.py", + "source": "installed-owned-source/townlight_code/__init__.py", "sha256": "22abb4eaa2a94737461591a5b6f494bf7c4ad481b476fc3cf020fa090c97bcd8", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccode/ai_answer.py", + "source": "installed-owned-source/townlight_code/ai_answer.py", "sha256": "0d82f0c105e1b8102e0b640b97de85f95f79695cc6903008d56245ed79e6568d", "routes": [], "models": [ @@ -25146,29 +25146,29 @@ ], "configuration": [ { - "variable": "CIVICCODE_OLLAMA_URL", + "variable": "TOWNLIGHT_CODE_OLLAMA_URL", "default": "''", "line": 28 }, { - "variable": "CIVICCODE_OLLAMA_TIMEOUT_SECONDS", + "variable": "TOWNLIGHT_CODE_OLLAMA_TIMEOUT_SECONDS", "default": "'20'", "line": 35 }, { - "variable": "CIVICCODE_AI_MODE", + "variable": "TOWNLIGHT_CODE_AI_MODE", "default": "''", "line": 27 }, { - "variable": "CIVICCODE_OLLAMA_MODEL", + "variable": "TOWNLIGHT_CODE_OLLAMA_MODEL", "default": "'gemma4:e4b'", "line": 34 } ] }, { - "source": "installed-owned-source/civiccode/citation_contract.py", + "source": "installed-owned-source/townlight_code/citation_contract.py", "sha256": "58e2cc3b8e05987a801a94c174ad34a8a7af18f684d367b08f097ab420ff3e37", "routes": [], "models": [ @@ -25199,7 +25199,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccode/codifier_sync.py", + "source": "installed-owned-source/townlight_code/codifier_sync.py", "sha256": "9c8b9635a2534eaccd3f80cc0b2a9b5c4751830a9d99796bb125e773778bd57f", "routes": [], "models": [ @@ -25317,7 +25317,7 @@ } ], "line": 80, - "doc": "Configured codifier sync source backed by a registered CivicCode source." + "doc": "Configured codifier sync source backed by a registered TownlightCode source." }, { "name": "CodifierSyncRun", @@ -25346,7 +25346,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccode/import_connectors.py", + "source": "installed-owned-source/townlight_code/import_connectors.py", "sha256": "bf4013448af2bd851642baefdbd1abcd212dd7b5b3c0e91d5811414c85e792f0", "routes": [], "models": [ @@ -25417,7 +25417,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccode/main.py", + "source": "installed-owned-source/townlight_code/main.py", "sha256": "930e05298b82f10ec0338040770d8af83aa56a9d43016908931ab8f796e63f48", "routes": [ { @@ -25435,7 +25435,7 @@ }, { "method": "GET", - "path": "/civiccode", + "path": "/townlight_code", "router": "app", "prefix_resolved": true, "name": "public_lookup_home", @@ -25443,38 +25443,38 @@ "returns": "str", "line": 834, "doc": "Render the resident-facing public code lookup home page.", - "decorator": "app.get('/civiccode', response_class=HTMLResponse)", + "decorator": "app.get('/townlight_code', response_class=HTMLResponse)", "errors": [] }, { "method": "GET", - "path": "/civiccode/app", + "path": "/townlight_code/app", "router": "app", "prefix_resolved": true, - "name": "civiccode_frontend_app", + "name": "townlight_code_frontend_app", "signature": "", "returns": "Response", "line": 845, - "doc": "Serve the React/Vite CivicCode frontend when built.", - "decorator": "app.get('/civiccode/app')", + "doc": "Serve the React/Vite TownlightCode frontend when built.", + "decorator": "app.get('/townlight_code/app')", "errors": [] }, { "method": "GET", - "path": "/civiccode/app/", + "path": "/townlight_code/app/", "router": "app", "prefix_resolved": true, - "name": "civiccode_frontend_app", + "name": "townlight_code_frontend_app", "signature": "", "returns": "Response", "line": 845, - "doc": "Serve the React/Vite CivicCode frontend when built.", - "decorator": "app.get('/civiccode/app/')", + "doc": "Serve the React/Vite TownlightCode frontend when built.", + "decorator": "app.get('/townlight_code/app/')", "errors": [] }, { "method": "GET", - "path": "/civiccode/search", + "path": "/townlight_code/search", "router": "app", "prefix_resolved": true, "name": "public_lookup_search", @@ -25482,12 +25482,12 @@ "returns": "str", "line": 858, "doc": "Render public search results, empty states, or refusal states.", - "decorator": "app.get('/civiccode/search', response_class=HTMLResponse)", + "decorator": "app.get('/townlight_code/search', response_class=HTMLResponse)", "errors": [] }, { "method": "GET", - "path": "/civiccode/answer", + "path": "/townlight_code/answer", "router": "app", "prefix_resolved": true, "name": "public_lookup_answer", @@ -25495,12 +25495,12 @@ "returns": "str", "line": 878, "doc": "Render a resident-facing cited answer for one adopted section.", - "decorator": "app.get('/civiccode/answer', response_class=HTMLResponse)", + "decorator": "app.get('/townlight_code/answer', response_class=HTMLResponse)", "errors": [] }, { "method": "GET", - "path": "/civiccode/sections/{section_ref}", + "path": "/townlight_code/sections/{section_ref}", "router": "app", "prefix_resolved": true, "name": "public_section_detail", @@ -25508,12 +25508,12 @@ "returns": "str", "line": 901, "doc": "Render a public section detail page with citation and warning context.", - "decorator": "app.get('/civiccode/sections/{section_ref}', response_class=HTMLResponse)", + "decorator": "app.get('/townlight_code/sections/{section_ref}', response_class=HTMLResponse)", "errors": [] }, { "method": "GET", - "path": "/civiccode/sections/{section_ref}/export", + "path": "/townlight_code/sections/{section_ref}/export", "router": "app", "prefix_resolved": true, "name": "public_section_export", @@ -25521,7 +25521,7 @@ "returns": "str", "line": 937, "doc": "Render an accessible records-ready export page for a section.", - "decorator": "app.get('/civiccode/sections/{section_ref}/export', response_class=HTMLResponse)", + "decorator": "app.get('/townlight_code/sections/{section_ref}/export', response_class=HTMLResponse)", "errors": [] }, { @@ -25530,7 +25530,7 @@ "router": "app", "prefix_resolved": true, "name": "staff_source_workspace", - "signature": "x_civiccode_role: str | None=Header(default=None), x_civiccode_actor: str | None=Header(default=None)", + "signature": "x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", "returns": "HTMLResponse", "line": 953, "doc": "Render the staff source registry workspace.", @@ -25543,7 +25543,7 @@ "router": "app", "prefix_resolved": true, "name": "staff_code_workspace", - "signature": "x_civiccode_role: str | None=Header(default=None), x_civiccode_actor: str | None=Header(default=None)", + "signature": "x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", "returns": "HTMLResponse", "line": 970, "doc": "Render the staff code lifecycle workspace.", @@ -25556,7 +25556,7 @@ "router": "app", "prefix_resolved": true, "name": "staff_sync_workspace", - "signature": "x_civiccode_role: str | None=Header(default=None), x_civiccode_actor: str | None=Header(default=None)", + "signature": "x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", "returns": "HTMLResponse", "line": 983, "doc": "Render the staff codifier sync health workspace.", @@ -25569,7 +25569,7 @@ "router": "app", "prefix_resolved": true, "name": "staff_import_ledger", - "signature": "x_civiccode_role: str | None=Header(default=None), x_civiccode_actor: str | None=Header(default=None)", + "signature": "x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", "returns": "HTMLResponse", "line": 1000, "doc": "Render the staff import job and provenance ledger.", @@ -25591,20 +25591,20 @@ }, { "method": "GET", - "path": "/api/v1/civiccode/staff/operational-state", + "path": "/api/v1/townlight_code/staff/operational-state", "router": "app", "prefix_resolved": true, "name": "get_staff_operational_state", - "signature": "x_civiccode_role: str | None=Header(default=None), x_civiccode_actor: str | None=Header(default=None)", + "signature": "x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", "returns": "dict[str, Any]", "line": 1024, "doc": "Return current operational readiness state for staff operators.", - "decorator": "app.get('/api/v1/civiccode/staff/operational-state')", + "decorator": "app.get('/api/v1/townlight_code/staff/operational-state')", "errors": [] }, { "method": "GET", - "path": "/api/v1/civiccode/sources/catalog", + "path": "/api/v1/townlight_code/sources/catalog", "router": "app", "prefix_resolved": true, "name": "source_registry_catalog", @@ -25612,25 +25612,25 @@ "returns": "dict[str, Any]", "line": 1036, "doc": "Expose allowed source registry vocabulary for staff integration clients.", - "decorator": "app.get('/api/v1/civiccode/sources/catalog')", + "decorator": "app.get('/api/v1/townlight_code/sources/catalog')", "errors": [] }, { "method": "POST", - "path": "/api/v1/civiccode/sources", + "path": "/api/v1/townlight_code/sources", "router": "app", "prefix_resolved": true, "name": "create_source", - "signature": "request: SourceCreate, x_civiccode_role: str | None=Header(default=None), x_civiccode_actor: str | None=Header(default=None)", + "signature": "request: SourceCreate, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", "returns": "dict[str, Any]", "line": 1050, "doc": "Register a municipal code source without importing its contents yet.", - "decorator": "app.post('/api/v1/civiccode/sources', status_code=201)", + "decorator": "app.post('/api/v1/townlight_code/sources', status_code=201)", "errors": [] }, { "method": "GET", - "path": "/api/v1/civiccode/sources", + "path": "/api/v1/townlight_code/sources", "router": "app", "prefix_resolved": true, "name": "list_public_sources", @@ -25638,12 +25638,12 @@ "returns": "dict[str, Any]", "line": 1068, "doc": "List public-visible sources without exposing staff-only notes.", - "decorator": "app.get('/api/v1/civiccode/sources')", + "decorator": "app.get('/api/v1/townlight_code/sources')", "errors": [] }, { "method": "GET", - "path": "/api/v1/civiccode/sources/{source_id}", + "path": "/api/v1/townlight_code/sources/{source_id}", "router": "app", "prefix_resolved": true, "name": "get_public_source", @@ -25651,100 +25651,100 @@ "returns": "dict[str, Any]", "line": 1079, "doc": "Read a public source record without leaking staff-only notes.", - "decorator": "app.get('/api/v1/civiccode/sources/{source_id}')", + "decorator": "app.get('/api/v1/townlight_code/sources/{source_id}')", "errors": [ "HTTPException(status_code=404, detail={'message': f\"Source '{source_id}' is not public-visible.\", 'fix': 'Use the staff source endpoint if you are authorized to view it.'})" ] }, { "method": "GET", - "path": "/api/v1/civiccode/staff/sources", + "path": "/api/v1/townlight_code/staff/sources", "router": "app", "prefix_resolved": true, "name": "list_staff_sources", - "signature": "x_civiccode_role: str | None=Header(default=None), x_civiccode_actor: str | None=Header(default=None)", + "signature": "x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", "returns": "dict[str, Any]", "line": 1097, "doc": "List all registered sources for staff workflows.", - "decorator": "app.get('/api/v1/civiccode/staff/sources')", + "decorator": "app.get('/api/v1/townlight_code/staff/sources')", "errors": [] }, { "method": "GET", - "path": "/api/v1/civiccode/staff/sources/{source_id}", + "path": "/api/v1/townlight_code/staff/sources/{source_id}", "router": "app", "prefix_resolved": true, "name": "get_staff_source", - "signature": "source_id: str, x_civiccode_role: str | None=Header(default=None), x_civiccode_actor: str | None=Header(default=None)", + "signature": "source_id: str, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", "returns": "dict[str, Any]", "line": 1112, "doc": "Read a staff source record including staff-only notes.", - "decorator": "app.get('/api/v1/civiccode/staff/sources/{source_id}')", + "decorator": "app.get('/api/v1/townlight_code/staff/sources/{source_id}')", "errors": [] }, { "method": "POST", - "path": "/api/v1/civiccode/sources/{source_id}/transitions", + "path": "/api/v1/townlight_code/sources/{source_id}/transitions", "router": "app", "prefix_resolved": true, "name": "transition_source", - "signature": "source_id: str, request: SourceTransitionRequest, x_civiccode_role: str | None=Header(default=None), x_civiccode_actor: str | None=Header(default=None)", + "signature": "source_id: str, request: SourceTransitionRequest, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", "returns": "dict[str, Any]", "line": 1127, "doc": "Transition a source through the official registry lifecycle.", - "decorator": "app.post('/api/v1/civiccode/sources/{source_id}/transitions')", + "decorator": "app.post('/api/v1/townlight_code/sources/{source_id}/transitions')", "errors": [] }, { "method": "POST", - "path": "/api/v1/civiccode/titles", + "path": "/api/v1/townlight_code/titles", "router": "app", "prefix_resolved": true, "name": "create_title", - "signature": "request: TitleCreate, x_civiccode_role: str | None=Header(default=None), x_civiccode_actor: str | None=Header(default=None)", + "signature": "request: TitleCreate, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", "returns": "dict[str, Any]", "line": 1148, "doc": "Create a municipal code title container.", - "decorator": "app.post('/api/v1/civiccode/titles', status_code=201)", + "decorator": "app.post('/api/v1/townlight_code/titles', status_code=201)", "errors": [] }, { "method": "POST", - "path": "/api/v1/civiccode/chapters", + "path": "/api/v1/townlight_code/chapters", "router": "app", "prefix_resolved": true, "name": "create_chapter", - "signature": "request: ChapterCreate, x_civiccode_role: str | None=Header(default=None), x_civiccode_actor: str | None=Header(default=None)", + "signature": "request: ChapterCreate, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", "returns": "dict[str, Any]", "line": 1163, "doc": "Create a municipal code chapter under a title.", - "decorator": "app.post('/api/v1/civiccode/chapters', status_code=201)", + "decorator": "app.post('/api/v1/townlight_code/chapters', status_code=201)", "errors": [] }, { "method": "POST", - "path": "/api/v1/civiccode/sections", + "path": "/api/v1/townlight_code/sections", "router": "app", "prefix_resolved": true, "name": "create_section", - "signature": "request: SectionCreate, x_civiccode_role: str | None=Header(default=None), x_civiccode_actor: str | None=Header(default=None)", + "signature": "request: SectionCreate, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", "returns": "dict[str, Any]", "line": 1178, "doc": "Create a code section or subsection without generating answers.", - "decorator": "app.post('/api/v1/civiccode/sections', status_code=201)", + "decorator": "app.post('/api/v1/townlight_code/sections', status_code=201)", "errors": [] }, { "method": "POST", - "path": "/api/v1/civiccode/sections/{section_id}/versions", + "path": "/api/v1/townlight_code/sections/{section_id}/versions", "router": "app", "prefix_resolved": true, "name": "create_section_version", - "signature": "section_id: str, request: SectionVersionCreate, x_civiccode_role: str | None=Header(default=None), x_civiccode_actor: str | None=Header(default=None)", + "signature": "section_id: str, request: SectionVersionCreate, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", "returns": "dict[str, Any]", "line": 1193, "doc": "Create an immutable section version for adopted, pending, or retired text.", - "decorator": "app.post('/api/v1/civiccode/sections/{section_id}/versions', status_code=201)", + "decorator": "app.post('/api/v1/townlight_code/sections/{section_id}/versions', status_code=201)", "errors": [ "HTTPException(status_code=422, detail={'message': 'Path section_id must match request body section_id.', 'fix': 'Use the same section_id in the URL and JSON body.'})", "HTTPException(status_code=409, detail={'message': f\"Source '{source.source_id}' is {source.status} and cannot back section text.\", 'fix': 'Use an active source or refresh the source registry record first.'})", @@ -25754,7 +25754,7 @@ }, { "method": "GET", - "path": "/api/v1/civiccode/sections/lookup", + "path": "/api/v1/townlight_code/sections/lookup", "router": "app", "prefix_resolved": true, "name": "lookup_section", @@ -25762,25 +25762,25 @@ "returns": "dict[str, Any]", "line": 1244, "doc": "Lookup adopted section text by current flag or effective date.", - "decorator": "app.get('/api/v1/civiccode/sections/lookup')", + "decorator": "app.get('/api/v1/townlight_code/sections/lookup')", "errors": [] }, { "method": "POST", - "path": "/api/v1/civiccode/sections/resolve", + "path": "/api/v1/townlight_code/sections/resolve", "router": "app", "prefix_resolved": true, "name": "resolve_section", "signature": "request: SectionResolveRequest", "returns": "dict[str, Any]", "line": 1255, - "doc": "Resolve adopted code context for downstream CivicSuite module clients.", - "decorator": "app.post('/api/v1/civiccode/sections/resolve')", + "doc": "Resolve adopted code context for downstream Townlight module clients.", + "decorator": "app.post('/api/v1/townlight_code/sections/resolve')", "errors": [] }, { "method": "GET", - "path": "/api/v1/civiccode/sections/{section_id}/history", + "path": "/api/v1/townlight_code/sections/{section_id}/history", "router": "app", "prefix_resolved": true, "name": "section_history", @@ -25788,12 +25788,12 @@ "returns": "dict[str, Any]", "line": 1354, "doc": "Return immutable amendment/version history for a section.", - "decorator": "app.get('/api/v1/civiccode/sections/{section_id}/history')", + "decorator": "app.get('/api/v1/townlight_code/sections/{section_id}/history')", "errors": [] }, { "method": "GET", - "path": "/api/v1/civiccode/sections/{section_id}/permalink", + "path": "/api/v1/townlight_code/sections/{section_id}/permalink", "router": "app", "prefix_resolved": true, "name": "section_permalink", @@ -25801,12 +25801,12 @@ "returns": "dict[str, Any]", "line": 1363, "doc": "Return the stable public-facing permalink for a section.", - "decorator": "app.get('/api/v1/civiccode/sections/{section_id}/permalink')", + "decorator": "app.get('/api/v1/townlight_code/sections/{section_id}/permalink')", "errors": [] }, { "method": "GET", - "path": "/api/v1/civiccode/search", + "path": "/api/v1/townlight_code/search", "router": "app", "prefix_resolved": true, "name": "search_sections", @@ -25814,12 +25814,12 @@ "returns": "dict[str, Any]", "line": 1372, "doc": "Search public-visible code sections and related public materials.", - "decorator": "app.get('/api/v1/civiccode/search')", + "decorator": "app.get('/api/v1/townlight_code/search')", "errors": [] }, { "method": "GET", - "path": "/api/v1/civiccode/popular-questions", + "path": "/api/v1/townlight_code/popular-questions", "router": "app", "prefix_resolved": true, "name": "list_popular_questions", @@ -25827,28 +25827,28 @@ "returns": "dict[str, Any]", "line": 1381, "doc": "List staff-approved public popular questions as navigation aids.", - "decorator": "app.get('/api/v1/civiccode/popular-questions')", + "decorator": "app.get('/api/v1/townlight_code/popular-questions')", "errors": [] }, { "method": "POST", - "path": "/api/v1/civiccode/staff/popular-questions", + "path": "/api/v1/townlight_code/staff/popular-questions", "router": "app", "prefix_resolved": true, "name": "create_popular_question", - "signature": "request: PopularQuestionCreate, x_civiccode_role: str | None=Header(default=None), x_civiccode_actor: str | None=Header(default=None)", + "signature": "request: PopularQuestionCreate, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", "returns": "dict[str, Any]", "line": 1403, "doc": "Create a staff-approved public popular question tied to cited adopted code.", - "decorator": "app.post('/api/v1/civiccode/staff/popular-questions', status_code=201)", + "decorator": "app.post('/api/v1/townlight_code/staff/popular-questions', status_code=201)", "errors": [ - "HTTPException(status_code=422, detail={'message': 'Popular questions cannot ask CivicCode for a legal determination.', 'fix': \"Rewrite the question as a navigation prompt, such as 'Where do I read the backyard chicken permit rule?'\"})", + "HTTPException(status_code=422, detail={'message': 'Popular questions cannot ask TownlightCode for a legal determination.', 'fix': \"Rewrite the question as a navigation prompt, such as 'Where do I read the backyard chicken permit rule?'\"})", "HTTPException(status_code=409, detail={'message': citation_payload.get('reason', 'Citation could not be built.'), 'fix': citation_payload.get('fix', 'Attach the question to cited adopted code.')})" ] }, { "method": "GET", - "path": "/api/v1/civiccode/sections/{section_number}/related", + "path": "/api/v1/townlight_code/sections/{section_number}/related", "router": "app", "prefix_resolved": true, "name": "related_materials", @@ -25856,12 +25856,12 @@ "returns": "dict[str, Any]", "line": 1453, "doc": "List explicit public related materials for one adopted section.", - "decorator": "app.get('/api/v1/civiccode/sections/{section_number}/related')", + "decorator": "app.get('/api/v1/townlight_code/sections/{section_number}/related')", "errors": [] }, { "method": "GET", - "path": "/api/v1/civiccode/citations/build", + "path": "/api/v1/townlight_code/citations/build", "router": "app", "prefix_resolved": true, "name": "build_citation", @@ -25869,12 +25869,12 @@ "returns": "dict[str, Any]", "line": 1466, "doc": "Build a deterministic citation object or a structured refusal.", - "decorator": "app.get('/api/v1/civiccode/citations/build')", + "decorator": "app.get('/api/v1/townlight_code/citations/build')", "errors": [] }, { "method": "GET", - "path": "/api/v1/civiccode/sections/{section_ref}/export", + "path": "/api/v1/townlight_code/sections/{section_ref}/export", "router": "app", "prefix_resolved": true, "name": "export_section", @@ -25882,12 +25882,12 @@ "returns": "dict[str, Any]", "line": 1472, "doc": "Return a records-ready section export with citation and source provenance.", - "decorator": "app.get('/api/v1/civiccode/sections/{section_ref}/export')", + "decorator": "app.get('/api/v1/townlight_code/sections/{section_ref}/export')", "errors": [] }, { "method": "POST", - "path": "/api/v1/civiccode/questions/answer", + "path": "/api/v1/townlight_code/questions/answer", "router": "app", "prefix_resolved": true, "name": "answer_question", @@ -25895,235 +25895,235 @@ "returns": "dict[str, Any]", "line": 1478, "doc": "Answer code questions only when an adopted section citation grounds them.", - "decorator": "app.post('/api/v1/civiccode/questions/answer')", + "decorator": "app.post('/api/v1/townlight_code/questions/answer')", "errors": [] }, { "method": "POST", - "path": "/api/v1/civiccode/staff/sections/{section_id}/notes", + "path": "/api/v1/townlight_code/staff/sections/{section_id}/notes", "router": "app", "prefix_resolved": true, "name": "create_interpretation_note", - "signature": "section_id: str, request: InterpretationNoteCreate, x_civiccode_role: str | None=Header(default=None), x_civiccode_actor: str | None=Header(default=None)", + "signature": "section_id: str, request: InterpretationNoteCreate, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", "returns": "dict[str, Any]", "line": 1494, "doc": "Create a staff-only interpretation note without exposing it publicly.", - "decorator": "app.post('/api/v1/civiccode/staff/sections/{section_id}/notes', status_code=201)", + "decorator": "app.post('/api/v1/townlight_code/staff/sections/{section_id}/notes', status_code=201)", "errors": [] }, { "method": "GET", - "path": "/api/v1/civiccode/staff/sections/{section_id}/notes", + "path": "/api/v1/townlight_code/staff/sections/{section_id}/notes", "router": "app", "prefix_resolved": true, "name": "list_interpretation_notes", - "signature": "section_id: str, x_civiccode_role: str | None=Header(default=None), x_civiccode_actor: str | None=Header(default=None)", + "signature": "section_id: str, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", "returns": "dict[str, Any]", "line": 1517, "doc": "List staff-only interpretation notes for authorized staff clients.", - "decorator": "app.get('/api/v1/civiccode/staff/sections/{section_id}/notes')", + "decorator": "app.get('/api/v1/townlight_code/staff/sections/{section_id}/notes')", "errors": [] }, { "method": "GET", - "path": "/api/v1/civiccode/staff/audit-events", + "path": "/api/v1/townlight_code/staff/audit-events", "router": "app", "prefix_resolved": true, "name": "list_staff_audit_events", - "signature": "x_civiccode_role: str | None=Header(default=None), x_civiccode_actor: str | None=Header(default=None)", + "signature": "x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", "returns": "dict[str, Any]", "line": 1532, "doc": "List staff workbench audit events for authorized staff clients.", - "decorator": "app.get('/api/v1/civiccode/staff/audit-events')", + "decorator": "app.get('/api/v1/townlight_code/staff/audit-events')", "errors": [] }, { "method": "POST", - "path": "/api/v1/civiccode/staff/imports/local-bundle", + "path": "/api/v1/townlight_code/staff/imports/local-bundle", "router": "app", "prefix_resolved": true, "name": "create_local_import_job", - "signature": "request: ImportBundleCreate, x_civiccode_role: str | None=Header(default=None), x_civiccode_actor: str | None=Header(default=None)", + "signature": "request: ImportBundleCreate, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", "returns": "dict[str, Any]", "line": 1548, "doc": "Import a local codifier/file-drop fixture without outbound network calls.", - "decorator": "app.post('/api/v1/civiccode/staff/imports/local-bundle', status_code=201)", + "decorator": "app.post('/api/v1/townlight_code/staff/imports/local-bundle', status_code=201)", "errors": [] }, { "method": "POST", - "path": "/api/v1/civiccode/staff/imports/shared-pdf", + "path": "/api/v1/townlight_code/staff/imports/shared-pdf", "router": "app", "prefix_resolved": true, "name": "create_shared_pdf_import_job", - "signature": "request: SharedPdfImportCreate, x_civiccode_role: str | None=Header(default=None), x_civiccode_actor: str | None=Header(default=None)", + "signature": "request: SharedPdfImportCreate, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", "returns": "dict[str, Any]", "line": 1560, - "doc": "Ingest a municipal code PDF through CivicCore, then structure it for CivicCode.", - "decorator": "app.post('/api/v1/civiccode/staff/imports/shared-pdf', status_code=201)", + "doc": "Ingest a municipal code PDF through TownlightCore, then structure it for TownlightCode.", + "decorator": "app.post('/api/v1/townlight_code/staff/imports/shared-pdf', status_code=201)", "errors": [ - "HTTPException(status_code=409, detail={'message': 'Shared PDF ingestion requires a durable PostgreSQL runtime.', 'fix': 'Set CIVICCODE_SOURCE_REGISTRY_DB_URL or DATABASE_URL to the CivicCode PostgreSQL DSN.'})" + "HTTPException(status_code=409, detail={'message': 'Shared PDF ingestion requires a durable PostgreSQL runtime.', 'fix': 'Set TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL or DATABASE_URL to the TownlightCode PostgreSQL DSN.'})" ] }, { "method": "GET", - "path": "/api/v1/civiccode/staff/imports", + "path": "/api/v1/townlight_code/staff/imports", "router": "app", "prefix_resolved": true, "name": "list_import_jobs", - "signature": "x_civiccode_role: str | None=Header(default=None), x_civiccode_actor: str | None=Header(default=None)", + "signature": "x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", "returns": "dict[str, Any]", "line": 1594, "doc": "List local import jobs and their visible success/failure states.", - "decorator": "app.get('/api/v1/civiccode/staff/imports')", + "decorator": "app.get('/api/v1/townlight_code/staff/imports')", "errors": [] }, { "method": "GET", - "path": "/api/v1/civiccode/staff/imports/{job_id}", + "path": "/api/v1/townlight_code/staff/imports/{job_id}", "router": "app", "prefix_resolved": true, "name": "get_import_job", - "signature": "job_id: str, x_civiccode_role: str | None=Header(default=None), x_civiccode_actor: str | None=Header(default=None)", + "signature": "job_id: str, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", "returns": "dict[str, Any]", "line": 1604, "doc": "Read a local import job, including actionable failure details.", - "decorator": "app.get('/api/v1/civiccode/staff/imports/{job_id}')", + "decorator": "app.get('/api/v1/townlight_code/staff/imports/{job_id}')", "errors": [] }, { "method": "POST", - "path": "/api/v1/civiccode/staff/imports/{job_id}/retry", + "path": "/api/v1/townlight_code/staff/imports/{job_id}/retry", "router": "app", "prefix_resolved": true, "name": "retry_import_job", - "signature": "job_id: str, request: ImportBundleCreate, x_civiccode_role: str | None=Header(default=None), x_civiccode_actor: str | None=Header(default=None)", + "signature": "job_id: str, request: ImportBundleCreate, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", "returns": "dict[str, Any]", "line": 1619, "doc": "Retry a failed import job with a corrected local bundle.", - "decorator": "app.post('/api/v1/civiccode/staff/imports/{job_id}/retry', status_code=201)", + "decorator": "app.post('/api/v1/townlight_code/staff/imports/{job_id}/retry', status_code=201)", "errors": [] }, { "method": "GET", - "path": "/api/v1/civiccode/staff/imports/{job_id}/provenance", + "path": "/api/v1/townlight_code/staff/imports/{job_id}/provenance", "router": "app", "prefix_resolved": true, "name": "get_import_provenance", - "signature": "job_id: str, x_civiccode_role: str | None=Header(default=None), x_civiccode_actor: str | None=Header(default=None)", + "signature": "job_id: str, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", "returns": "dict[str, Any]", "line": 1635, "doc": "Return a provenance report for a local import job.", - "decorator": "app.get('/api/v1/civiccode/staff/imports/{job_id}/provenance')", + "decorator": "app.get('/api/v1/townlight_code/staff/imports/{job_id}/provenance')", "errors": [] }, { "method": "GET", - "path": "/api/v1/civiccode/staff/imports/{job_id}/tree", + "path": "/api/v1/townlight_code/staff/imports/{job_id}/tree", "router": "app", "prefix_resolved": true, "name": "get_imported_tree", - "signature": "job_id: str, x_civiccode_role: str | None=Header(default=None), x_civiccode_actor: str | None=Header(default=None)", + "signature": "job_id: str, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", "returns": "dict[str, Any]", "line": 1650, "doc": "Show imported title/chapter/section/version tree for staff verification.", - "decorator": "app.get('/api/v1/civiccode/staff/imports/{job_id}/tree')", + "decorator": "app.get('/api/v1/townlight_code/staff/imports/{job_id}/tree')", "errors": [] }, { "method": "POST", - "path": "/api/v1/civiccode/staff/sync/codifier-sources", + "path": "/api/v1/townlight_code/staff/sync/codifier-sources", "router": "app", "prefix_resolved": true, "name": "configure_codifier_sync_source", - "signature": "request: CodifierSyncConfigureRequest, x_civiccode_role: str | None=Header(default=None), x_civiccode_actor: str | None=Header(default=None)", + "signature": "request: CodifierSyncConfigureRequest, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", "returns": "dict[str, Any]", "line": 1673, "doc": "Enable staff-controlled codifier sync readiness for an official source.", - "decorator": "app.post('/api/v1/civiccode/staff/sync/codifier-sources', status_code=201)", + "decorator": "app.post('/api/v1/townlight_code/staff/sync/codifier-sources', status_code=201)", "errors": [] }, { "method": "GET", - "path": "/api/v1/civiccode/staff/sync/codifier-sources", + "path": "/api/v1/townlight_code/staff/sync/codifier-sources", "router": "app", "prefix_resolved": true, "name": "list_codifier_sync_sources", - "signature": "x_civiccode_role: str | None=Header(default=None), x_civiccode_actor: str | None=Header(default=None)", + "signature": "x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", "returns": "dict[str, Any]", "line": 1694, "doc": "List codifier sync readiness and circuit health for staff.", - "decorator": "app.get('/api/v1/civiccode/staff/sync/codifier-sources')", + "decorator": "app.get('/api/v1/townlight_code/staff/sync/codifier-sources')", "errors": [] }, { "method": "POST", - "path": "/api/v1/civiccode/staff/sync/codifier-sources/{source_id}/run", + "path": "/api/v1/townlight_code/staff/sync/codifier-sources/{source_id}/run", "router": "app", "prefix_resolved": true, "name": "run_codifier_sync_source", - "signature": "source_id: str, request: CodifierSyncRunRequest, x_civiccode_role: str | None=Header(default=None), x_civiccode_actor: str | None=Header(default=None)", + "signature": "source_id: str, request: CodifierSyncRunRequest, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", "returns": "dict[str, Any]", "line": 1709, "doc": "Run one staff-controlled codifier sync using an already fetched local payload.", - "decorator": "app.post('/api/v1/civiccode/staff/sync/codifier-sources/{source_id}/run', status_code=201)", + "decorator": "app.post('/api/v1/townlight_code/staff/sync/codifier-sources/{source_id}/run', status_code=201)", "errors": [] }, { "method": "POST", - "path": "/api/v1/civiccode/staff/civicclerk/ordinance-events", + "path": "/api/v1/townlight_code/staff/townlight_meetings/ordinance-events", "router": "app", "prefix_resolved": true, - "name": "create_civicclerk_ordinance_event", - "signature": "request: CivicClerkOrdinanceEventCreate, x_civiccode_role: str | None=Header(default=None), x_civiccode_actor: str | None=Header(default=None), x_civiccode_intake_auth: str | None=Header(default=None, alias=CIVICCODE_INTAKE_AUTH_HEADER), authorization: str | None=Header(default=None)", + "name": "create_townlight_meetings_ordinance_event", + "signature": "request: TownlightMeetingsOrdinanceEventCreate, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None), x_townlight_code_intake_auth: str | None=Header(default=None, alias=TOWNLIGHT_CODE_INTAKE_AUTH_HEADER), authorization: str | None=Header(default=None)", "returns": "dict[str, Any]", "line": 1730, - "doc": "Receive CivicClerk ordinance/adoption events without codifying them.", - "decorator": "app.post('/api/v1/civiccode/staff/civicclerk/ordinance-events', status_code=201)", + "doc": "Receive TownlightMeetings ordinance/adoption events without codifying them.", + "decorator": "app.post('/api/v1/townlight_code/staff/townlight_meetings/ordinance-events', status_code=201)", "errors": [] }, { "method": "POST", - "path": "/api/v1/civiccode/staff/civicclerk/ordinance-events/{event_id}/resolve", + "path": "/api/v1/townlight_code/staff/townlight_meetings/ordinance-events/{event_id}/resolve", "router": "app", "prefix_resolved": true, - "name": "resolve_civicclerk_ordinance_event", - "signature": "event_id: str, request: CivicClerkOrdinanceEventResolve, x_civiccode_role: str | None=Header(default=None), x_civiccode_actor: str | None=Header(default=None), x_civiccode_intake_auth: str | None=Header(default=None, alias=CIVICCODE_INTAKE_AUTH_HEADER), authorization: str | None=Header(default=None)", + "name": "resolve_townlight_meetings_ordinance_event", + "signature": "event_id: str, request: TownlightMeetingsOrdinanceEventResolve, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None), x_townlight_code_intake_auth: str | None=Header(default=None, alias=TOWNLIGHT_CODE_INTAKE_AUTH_HEADER), authorization: str | None=Header(default=None)", "returns": "dict[str, Any]", "line": 1756, - "doc": "Mark a CivicClerk handoff codified after staff creates the adopted code version.", - "decorator": "app.post('/api/v1/civiccode/staff/civicclerk/ordinance-events/{event_id}/resolve')", + "doc": "Mark a TownlightMeetings handoff codified after staff creates the adopted code version.", + "decorator": "app.post('/api/v1/townlight_code/staff/townlight_meetings/ordinance-events/{event_id}/resolve')", "errors": [] }, { "method": "POST", - "path": "/api/v1/civiccode/staff/sections/{section_id}/summaries", + "path": "/api/v1/townlight_code/staff/sections/{section_id}/summaries", "router": "app", "prefix_resolved": true, "name": "create_plain_language_summary", - "signature": "section_id: str, request: PlainLanguageSummaryCreate, x_civiccode_role: str | None=Header(default=None), x_civiccode_actor: str | None=Header(default=None)", + "signature": "section_id: str, request: PlainLanguageSummaryCreate, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", "returns": "dict[str, Any]", "line": 1806, "doc": "Create a staff-drafted plain-language summary tied to adopted code text.", - "decorator": "app.post('/api/v1/civiccode/staff/sections/{section_id}/summaries', status_code=201)", + "decorator": "app.post('/api/v1/townlight_code/staff/sections/{section_id}/summaries', status_code=201)", "errors": [] }, { "method": "POST", - "path": "/api/v1/civiccode/staff/summaries/{summary_id}/approve", + "path": "/api/v1/townlight_code/staff/summaries/{summary_id}/approve", "router": "app", "prefix_resolved": true, "name": "approve_plain_language_summary", - "signature": "summary_id: str, x_civiccode_role: str | None=Header(default=None), x_civiccode_actor: str | None=Header(default=None)", + "signature": "summary_id: str, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", "returns": "dict[str, Any]", "line": 1841, "doc": "Approve a plain-language summary for public display after staff review.", - "decorator": "app.post('/api/v1/civiccode/staff/summaries/{summary_id}/approve')", + "decorator": "app.post('/api/v1/townlight_code/staff/summaries/{summary_id}/approve')", "errors": [] }, { "method": "GET", - "path": "/api/v1/civiccode/sections/{section_id}/summaries", + "path": "/api/v1/townlight_code/sections/{section_id}/summaries", "router": "app", "prefix_resolved": true, "name": "list_public_plain_language_summaries", @@ -26131,20 +26131,20 @@ "returns": "dict[str, Any]", "line": 1866, "doc": "List public approved summaries while keeping authoritative code visible.", - "decorator": "app.get('/api/v1/civiccode/sections/{section_id}/summaries')", + "decorator": "app.get('/api/v1/townlight_code/sections/{section_id}/summaries')", "errors": [] }, { "method": "POST", - "path": "/api/v1/civiccode/staff/questions/answer", + "path": "/api/v1/townlight_code/staff/questions/answer", "router": "app", "prefix_resolved": true, "name": "answer_staff_question", - "signature": "request: QuestionAnswerRequest, x_civiccode_role: str | None=Header(default=None), x_civiccode_actor: str | None=Header(default=None)", + "signature": "request: QuestionAnswerRequest, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", "returns": "dict[str, Any]", "line": 1895, "doc": "Answer staff questions with staff-only notes kept out of public responses.", - "decorator": "app.post('/api/v1/civiccode/staff/questions/answer')", + "decorator": "app.post('/api/v1/townlight_code/staff/questions/answer')", "errors": [] } ], @@ -26620,7 +26620,7 @@ "doc": "Request body for staff-drafted plain-language summaries." }, { - "name": "CivicClerkOrdinanceEventCreate", + "name": "TownlightMeetingsOrdinanceEventCreate", "bases": [ "BaseModel" ], @@ -26636,12 +26636,12 @@ "default": "Field(min_length=1)" }, { - "name": "civicclerk_meeting_id", + "name": "townlight_meetings_meeting_id", "type": "str", "default": "Field(min_length=1)" }, { - "name": "civicclerk_agenda_item_id", + "name": "townlight_meetings_agenda_item_id", "type": "str", "default": "Field(min_length=1)" }, @@ -26692,10 +26692,10 @@ } ], "line": 435, - "doc": "Request body for CivicClerk ordinance/adoption handoff intake." + "doc": "Request body for TownlightMeetings ordinance/adoption handoff intake." }, { - "name": "CivicClerkOrdinanceEventResolve", + "name": "TownlightMeetingsOrdinanceEventResolve", "bases": [ "BaseModel" ], @@ -26782,7 +26782,7 @@ } ], "line": 479, - "doc": "Request body for CivicCore shared PDF ingestion into CivicCode." + "doc": "Request body for TownlightCore shared PDF ingestion into TownlightCode." }, { "name": "CodifierSyncConfigureRequest", @@ -26832,47 +26832,47 @@ ], "configuration": [ { - "variable": "CIVICCODE_SOURCE_REGISTRY_DB_URL", + "variable": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", "default": "", "line": 1988 }, { - "variable": "CIVICCODE_SOURCE_REGISTRY_DB_URL", + "variable": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", "default": "", "line": 1999 }, { - "variable": "CIVICCODE_SOURCE_REGISTRY_DB_URL", + "variable": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", "default": "", "line": 2010 }, { - "variable": "CIVICCODE_DEMO_ACTOR", + "variable": "TOWNLIGHT_CODE_DEMO_ACTOR", "default": "'demo-seed@portland.example.gov'", "line": 2062 }, { - "variable": "CIVICCODE_SOURCE_REGISTRY_DB_URL", + "variable": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", "default": "", "line": 173 }, { - "variable": "CIVICCODE_SOURCE_REGISTRY_DB_URL", + "variable": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", "default": "", "line": 201 }, { - "variable": "CIVICCODE_SOURCE_REGISTRY_DB_URL", + "variable": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", "default": "", "line": 224 }, { - "variable": "CIVICCODE_SOURCE_REGISTRY_DB_URL", + "variable": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", "default": "", "line": 252 }, { - "variable": "CIVICCODE_SOURCE_REGISTRY_DB_URL", + "variable": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", "default": "", "line": 1567 }, @@ -26882,26 +26882,26 @@ "line": 1567 }, { - "variable": "CIVICCODE_SOURCE_REGISTRY_DB_URL", + "variable": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", "default": "", "line": 2020 }, { - "variable": "CIVICCODE_DEMO_SEED", + "variable": "TOWNLIGHT_CODE_DEMO_SEED", "default": "''", "line": 2056 } ] }, { - "source": "installed-owned-source/civiccode/migrations/__init__.py", + "source": "installed-owned-source/townlight_code/migrations/__init__.py", "sha256": "4c8b91a2b40fe7951bf11bd74070344c9967b0feb5170a68d490305dc8333b8e", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccode/migrations/env.py", + "source": "installed-owned-source/townlight_code/migrations/env.py", "sha256": "5526b8ac01c1bc652c77861bb77209503668127d5c9a8d810dda351dff7a158e", "routes": [], "models": [], @@ -26914,105 +26914,105 @@ ] }, { - "source": "installed-owned-source/civiccode/migrations/guards.py", + "source": "installed-owned-source/townlight_code/migrations/guards.py", "sha256": "110cca437db7e2507374b9e0d9d32739dbdbaf57c664ac89d8a4c56472c05d7f", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccode/migrations/versions/__init__.py", + "source": "installed-owned-source/townlight_code/migrations/versions/__init__.py", "sha256": "74446fe86c7d899c1e4942b131ef47880cbb716011970d702ac78799902cc7ac", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccode/migrations/versions/civiccode_0001_schema.py", + "source": "installed-owned-source/townlight_code/migrations/versions/townlight_code_0001_schema.py", "sha256": "3361408fb75b2330c3dffa4c343bffa39ec96cb41b25d7c3e980f3efea69a950", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccode/migrations/versions/civiccode_0002_source_registry_records.py", + "source": "installed-owned-source/townlight_code/migrations/versions/townlight_code_0002_source_registry_records.py", "sha256": "a237d274d614a260242b2eee1661845fa96476445a8496c1fc2e8ff773fcc85c", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccode/migrations/versions/civiccode_0003_popular_question_records.py", + "source": "installed-owned-source/townlight_code/migrations/versions/townlight_code_0003_popular_question_records.py", "sha256": "d973ad1e13a5b84cc4bcc19d9977d9532d09388451c3872549180fa02ecfe609", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccode/migrations/versions/civiccode_0004_section_lifecycle_records.py", + "source": "installed-owned-source/townlight_code/migrations/versions/townlight_code_0004_section_lifecycle_records.py", "sha256": "e11d0b3c4d08f32c00e513bbf336bf9f3ee2459c929aca0fed7c2158b688299f", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccode/migrations/versions/civiccode_0005_staff_summary_records.py", + "source": "installed-owned-source/townlight_code/migrations/versions/townlight_code_0005_staff_summary_records.py", "sha256": "04d9a42402dbf503f9988dc07c4fe264390470d798d8e2d51983a1d7b8a5e601", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccode/migrations/versions/civiccode_0006_ordinance_handoff_records.py", + "source": "installed-owned-source/townlight_code/migrations/versions/townlight_code_0006_ordinance_handoff_records.py", "sha256": "bd2c85f222a0d4946298bdb580a36af174be378fbb3bdf62641457b87d5499fa", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccode/migrations/versions/civiccode_0007_import_job_records.py", + "source": "installed-owned-source/townlight_code/migrations/versions/townlight_code_0007_import_job_records.py", "sha256": "d965ccf019d4059fe56ffd234955f45193d51d52a38b20fa1ba66e809493cb67", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccode/migrations/versions/civiccode_0008_codifier_sync.py", + "source": "installed-owned-source/townlight_code/migrations/versions/townlight_code_0008_codifier_sync.py", "sha256": "10b417a95e25d79ea3cc48fb3feedec0eea878f9580eba0b3c9e0b9413886366", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccode/migrations/versions/civiccode_0009_operational_state.py", + "source": "installed-owned-source/townlight_code/migrations/versions/townlight_code_0009_operational_state.py", "sha256": "5ff5a28d099a69b55c121fbf6ff9336cb8dee51e385966900510aba5df9a7540", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccode/migrations/versions/civiccode_0010_handoff_resolution.py", + "source": "installed-owned-source/townlight_code/migrations/versions/townlight_code_0010_handoff_resolution.py", "sha256": "ed20579ff39863de49bd01a97a47b77d84b380f54f0aba7473c1aad360b11b4a", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccode/migrations/versions/civiccode_0011_semantic_search.py", + "source": "installed-owned-source/townlight_code/migrations/versions/townlight_code_0011_semantic_search.py", "sha256": "4bf32028058db6ff90c19e2cf891886fef6d4e958ed7e72165e9a224ebd1b19d", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccode/migrations/versions/civiccode_0012_drop_local_search.py", + "source": "installed-owned-source/townlight_code/migrations/versions/townlight_code_0012_drop_local_search.py", "sha256": "6ac60feecb72efbe78a788066ac58d790f6e6c460f4a71eea6ecf6cf30a6570d", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccode/mock_city_environment.py", + "source": "installed-owned-source/townlight_code/mock_city_environment.py", "sha256": "91c1e1089e2956417fd520725847950c544166f0a93f2a0a63b7c1a9859c1189", "routes": [], "models": [ @@ -27126,21 +27126,21 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccode/models.py", + "source": "installed-owned-source/townlight_code/models.py", "sha256": "15f328be4b05481401d8ccd296110136ef98e98634fe59af1c2aa729340e8e4f", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccode/operational_readiness.py", + "source": "installed-owned-source/townlight_code/operational_readiness.py", "sha256": "002130b66583a7645218e271d515ca6b9295f7a8fe19ee9e85e6e52adacc07a9", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccode/operational_state.py", + "source": "installed-owned-source/townlight_code/operational_state.py", "sha256": "6d73c3201fc449de9bf6678d129184533323960f82ccb0a5c0f6dcb147421b0f", "routes": [], "models": [ @@ -27236,7 +27236,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccode/ordinance_handoff.py", + "source": "installed-owned-source/townlight_code/ordinance_handoff.py", "sha256": "5e98eefc3e510efaf0d5973927aa3506f8b652d319320f745a831bef0cb5897b", "routes": [], "models": [ @@ -27255,12 +27255,12 @@ "default": "" }, { - "name": "civicclerk_meeting_id", + "name": "townlight_meetings_meeting_id", "type": "str", "default": "" }, { - "name": "civicclerk_agenda_item_id", + "name": "townlight_meetings_agenda_item_id", "type": "str", "default": "" }, @@ -27375,7 +27375,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccode/plain_language.py", + "source": "installed-owned-source/townlight_code/plain_language.py", "sha256": "074b7aae42a3c4ee7ae5e64726a5fbbe151039cb51467f89f47b977e93e9b2bd", "routes": [], "models": [ @@ -27479,7 +27479,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccode/public_discovery.py", + "source": "installed-owned-source/townlight_code/public_discovery.py", "sha256": "f87497befbd3f75db94c4db0f36fb04fc1a34af8eba73a425ff49edb8dfc20ae", "routes": [], "models": [ @@ -27560,21 +27560,21 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccode/public_exports.py", + "source": "installed-owned-source/townlight_code/public_exports.py", "sha256": "2d413d312f8baf1e790bb4205ad93ac25928f1afefa3aca1898d91092085bcc4", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccode/public_lookup.py", + "source": "installed-owned-source/townlight_code/public_lookup.py", "sha256": "a3c62b6aaa3de1ef98ac824fd5806e61bd444ae61241e2a19f0f7dff3a3cca79", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccode/qa_harness.py", + "source": "installed-owned-source/townlight_code/qa_harness.py", "sha256": "bc040cb0c4ff124f13a63e10fbcb26d478a06da5364e7fa18d177b40af269797", "routes": [], "models": [ @@ -27605,7 +27605,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccode/real_municipal_fixtures.py", + "source": "installed-owned-source/townlight_code/real_municipal_fixtures.py", "sha256": "a88b400d5b5bb8d6a74ec8a29d793c3e51ab94226e0f0b8abbde7030f667280a", "routes": [], "models": [ @@ -27666,7 +27666,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccode/section_lifecycle.py", + "source": "installed-owned-source/townlight_code/section_lifecycle.py", "sha256": "34096b4ca4fa8f65628d33761609044f29a03bf0d89a5da09085440e56d149f2", "routes": [], "models": [ @@ -27885,14 +27885,14 @@ ], "configuration": [ { - "variable": "CIVICCODE_SEMANTIC_SCORE_FLOOR", + "variable": "TOWNLIGHT_CODE_SEMANTIC_SCORE_FLOOR", "default": "", "line": 929 } ] }, { - "source": "installed-owned-source/civiccode/semantic_search.py", + "source": "installed-owned-source/townlight_code/semantic_search.py", "sha256": "85de9cb0b861a7551a701bd4082ec3343728831c8bf20e45d90719db60f8b78c", "routes": [], "models": [ @@ -27950,17 +27950,17 @@ ], "configuration": [ { - "variable": "CIVICCODE_OLLAMA_EMBEDDING_MODEL", + "variable": "TOWNLIGHT_CODE_OLLAMA_EMBEDDING_MODEL", "default": "DEFAULT_EMBEDDING_MODEL", "line": 49 }, { - "variable": "CIVICCODE_OLLAMA_EMBEDDING_URL", + "variable": "TOWNLIGHT_CODE_OLLAMA_EMBEDDING_URL", "default": "", "line": 45 }, { - "variable": "CIVICCODE_OLLAMA_URL", + "variable": "TOWNLIGHT_CODE_OLLAMA_URL", "default": "", "line": 46 }, @@ -27970,19 +27970,19 @@ "line": 47 }, { - "variable": "CIVICCODE_OLLAMA_EMBEDDING_TIMEOUT_SECONDS", + "variable": "TOWNLIGHT_CODE_OLLAMA_EMBEDDING_TIMEOUT_SECONDS", "default": "'30'", "line": 50 }, { - "variable": "CIVICCODE_EMBEDDING_MODE", + "variable": "TOWNLIGHT_CODE_EMBEDDING_MODE", "default": "''", "line": 40 } ] }, { - "source": "installed-owned-source/civiccode/shared_ingestion.py", + "source": "installed-owned-source/townlight_code/shared_ingestion.py", "sha256": "caf8ec1c4d1da5a485ec96d0ae04e800e29f02fe1a71809cbebe0718c574f987", "routes": [], "models": [ @@ -28002,7 +28002,7 @@ } ], "line": 65, - "doc": "A CivicCore-ingested document plus a CivicCode local-bundle payload." + "doc": "A TownlightCore-ingested document plus a TownlightCode local-bundle payload." } ], "configuration": [ @@ -28012,29 +28012,29 @@ "line": 172 }, { - "variable": "CIVICCODE_SHARED_INGEST_CHUNK_SIZE", + "variable": "TOWNLIGHT_CODE_SHARED_INGEST_CHUNK_SIZE", "default": "'500'", "line": 88 }, { - "variable": "CIVICCODE_SHARED_INGEST_CHUNK_OVERLAP", + "variable": "TOWNLIGHT_CODE_SHARED_INGEST_CHUNK_OVERLAP", "default": "'50'", "line": 89 }, { - "variable": "CIVICCODE_SHARED_INGEST_ALLOWED_DIRS", + "variable": "TOWNLIGHT_CODE_SHARED_INGEST_ALLOWED_DIRS", "default": "", "line": 252 }, { - "variable": "CIVICCODE_SHARED_INGEST_ALLOWED_DIR", + "variable": "TOWNLIGHT_CODE_SHARED_INGEST_ALLOWED_DIR", "default": "", "line": 252 } ] }, { - "source": "installed-owned-source/civiccode/source_registry.py", + "source": "installed-owned-source/townlight_code/source_registry.py", "sha256": "292e2286802f36458a7468b749f81ff82277cc5f404fbf7b0ac7dd88f5d79651", "routes": [], "models": [ @@ -28135,35 +28135,35 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccode/staff_code.py", + "source": "installed-owned-source/townlight_code/staff_code.py", "sha256": "90b3d8ac3c6eb0c65831b47d8f6fa63ce3ac3d2350442c0913e15f7a768e317d", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccode/staff_imports.py", + "source": "installed-owned-source/townlight_code/staff_imports.py", "sha256": "f5ccf4e1d8d24bd23b62f922013f0f8eb2a8b633737b0a1134002ea0ea51e8df", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccode/staff_sources.py", + "source": "installed-owned-source/townlight_code/staff_sources.py", "sha256": "b7d00f3e051f131fde7142426b911e4484076987e4711685d18cf85dcee15412", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccode/staff_sync.py", + "source": "installed-owned-source/townlight_code/staff_sync.py", "sha256": "92361f57357bd12e22dff589a6f2353de3602947ed739b8738d8479e2462791d", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiccode/staff_workbench.py", + "source": "installed-owned-source/townlight_code/staff_workbench.py", "sha256": "13893408816cb0794c266c78d78e30e8182171b92830e757353001afea4f79fd", "routes": [], "models": [ @@ -28252,7 +28252,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civiccode/suite_session_auth.py", + "source": "installed-owned-source/townlight_code/suite_session_auth.py", "sha256": "b30a449b95838c04098d33373f3b6b030539b7a8ea2a998210333b314f9f4582", "routes": [], "models": [ @@ -28277,7 +28277,7 @@ } ], "line": 32, - "doc": "Validated CivicCore suite-session identity." + "doc": "Validated TownlightCore suite-session identity." } ], "configuration": [] @@ -28285,7 +28285,7 @@ ], "bridge": [ { - "source": "installed-owned-source/civicsuite_runtime/code_bridge.py", + "source": "installed-owned-source/townlight_runtime/code_bridge.py", "sha256": "901f1473aa6f4db4b089925a2fec17e963cef7a27c6bf885099a362df1fe15e9", "routes": [ { @@ -28516,12 +28516,12 @@ "configuration": [] }, { - "source": "installed-owned-source/civicsuite_runtime/code_public.py", + "source": "installed-owned-source/townlight_runtime/code_public.py", "sha256": "0fe956329a96e54e138b669d4ab4f69ab0d6f489b647a115cfd126cfa58742a5", "routes": [ { "method": "GET", - "path": "/civiccode", + "path": "/townlight_code", "router": "router", "prefix_resolved": true, "name": "home", @@ -28534,7 +28534,7 @@ }, { "method": "GET", - "path": "/civiccode/search", + "path": "/townlight_code/search", "router": "router", "prefix_resolved": true, "name": "search", @@ -28547,7 +28547,7 @@ }, { "method": "GET", - "path": "/civiccode/answer", + "path": "/townlight_code/answer", "router": "router", "prefix_resolved": true, "name": "answer", @@ -28560,7 +28560,7 @@ }, { "method": "GET", - "path": "/civiccode/sections/{section_ref}", + "path": "/townlight_code/sections/{section_ref}", "router": "router", "prefix_resolved": true, "name": "detail", @@ -28575,7 +28575,7 @@ }, { "method": "GET", - "path": "/civiccode/sections/{section_ref}/export", + "path": "/townlight_code/sections/{section_ref}/export", "router": "router", "prefix_resolved": true, "name": "export", @@ -28593,7 +28593,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civicsuite_runtime/code_meetings_bridge.py", + "source": "installed-owned-source/townlight_runtime/code_meetings_bridge.py", "sha256": "831045dc48508e866472a9ff6d9d837e8eed0a46c91c8f93b41eec526650c7c5", "routes": [ { @@ -28845,38 +28845,38 @@ ] }, "zoning": { - "package": "civiczone", + "package": "townlight_zoning", "source": [ { - "source": "installed-owned-source/civiczone/__init__.py", + "source": "installed-owned-source/townlight_zoning/__init__.py", "sha256": "528eaa60c6814c1cf2b3ceb5a510c059380c37670f48928c27a02d765a2d4d15", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiczone/cited_questions.py", + "source": "installed-owned-source/townlight_zoning/cited_questions.py", "sha256": "7a154dd540eae464090b4c12e6e0c1ca263670525df6a7328d317b0dd1e79a43", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiczone/cited_rules.py", + "source": "installed-owned-source/townlight_zoning/cited_rules.py", "sha256": "4fb421ff3cd9e27be7689de75711bba8d1cd3ede304547868c204cf7a0daa43a", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiczone/connected_sources.py", + "source": "installed-owned-source/townlight_zoning/connected_sources.py", "sha256": "68ad55c71b897eca689a6d028f4aee115dc5ca4b5ef005613385f9588387715b", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiczone/discretionary.py", + "source": "installed-owned-source/townlight_zoning/discretionary.py", "sha256": "919a5a573109fc76840290b4656e8fc63be91cdd10a6b3ff21fd106b52218ca5", "routes": [], "models": [ @@ -29028,28 +29028,28 @@ "configuration": [] }, { - "source": "installed-owned-source/civiczone/geo_import.py", + "source": "installed-owned-source/townlight_zoning/geo_import.py", "sha256": "e49824301593f8c06dd6bc64832542721d7b1763d745deb7ba531f7b894cc4a0", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiczone/geo_spatial.py", + "source": "installed-owned-source/townlight_zoning/geo_spatial.py", "sha256": "dfe4c88a940a20825c5c493babacb0cb0a96a70cb31a831c3ff1ecb4b77ebc13", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiczone/geo_validate.py", + "source": "installed-owned-source/townlight_zoning/geo_validate.py", "sha256": "65b4a2b84722be8c25decfaeb80c6177ff30588259379927e853f7727d767178", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiczone/integration_mocks.py", + "source": "installed-owned-source/townlight_zoning/integration_mocks.py", "sha256": "ed14fba1a58020377ebee28c20ef042f5b50126ca2351efb73e46d7a2d80982c", "routes": [], "models": [ @@ -29136,7 +29136,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civiczone/main.py", + "source": "installed-owned-source/townlight_zoning/main.py", "sha256": "cdbc4bd6f20650c08ca4a81c7e9d2fc7c85e0896bbd3d1c4e982dfe178c7bb93", "routes": [ { @@ -29167,33 +29167,33 @@ }, { "method": "GET", - "path": "/civiczone", + "path": "/townlight_zoning", "router": "app", "prefix_resolved": true, - "name": "public_civiczone_page", + "name": "public_townlight_zoning_page", "signature": "", "returns": "str", "line": 104, "doc": "Return the accessible public sample UI.", - "decorator": "app.get('/civiczone', response_class=HTMLResponse)", + "decorator": "app.get('/townlight_zoning', response_class=HTMLResponse)", "errors": [] }, { "method": "GET", - "path": "/civiczone/staff", + "path": "/townlight_zoning/staff", "router": "app", "prefix_resolved": true, - "name": "staff_civiczone_page", + "name": "staff_townlight_zoning_page", "signature": "", "returns": "str", "line": 111, "doc": "Return the staff workflow shell without exposing staff data in HTML.", - "decorator": "app.get('/civiczone/staff', response_class=HTMLResponse)", + "decorator": "app.get('/townlight_zoning/staff', response_class=HTMLResponse)", "errors": [] }, { "method": "POST", - "path": "/api/v1/civiczone/parcels/lookup", + "path": "/api/v1/townlight_zoning/parcels/lookup", "router": "app", "prefix_resolved": true, "name": "parcel_lookup", @@ -29201,15 +29201,15 @@ "returns": "dict[str, object]", "line": 220, "doc": "", - "decorator": "app.post('/api/v1/civiczone/parcels/lookup')", + "decorator": "app.post('/api/v1/townlight_zoning/parcels/lookup')", "errors": [ - "HTTPException(status_code=422, detail={'message': 'Provide either parcel_number or address.', 'fix': \"Send parcel_number '100-200-300' or address '123 Main St', or load local parcel records into CIVICZONE_PARCEL_RULE_DB_URL.\"})", + "HTTPException(status_code=422, detail={'message': 'Provide either parcel_number or address.', 'fix': \"Send parcel_number '100-200-300' or address '123 Main St', or load local parcel records into TOWNLIGHT_ZONING_PARCEL_RULE_DB_URL.\"})", "HTTPException(status_code=404, detail={'message': result.message, 'fix': result.fix})" ] }, { "method": "POST", - "path": "/api/v1/civiczone/rules/use", + "path": "/api/v1/townlight_zoning/rules/use", "router": "app", "prefix_resolved": true, "name": "use_rule_lookup", @@ -29217,14 +29217,14 @@ "returns": "dict[str, str]", "line": 246, "doc": "", - "decorator": "app.post('/api/v1/civiczone/rules/use')", + "decorator": "app.post('/api/v1/townlight_zoning/rules/use')", "errors": [ "HTTPException(status_code=404, detail={'message': result.message, 'fix': result.fix})" ] }, { "method": "POST", - "path": "/api/v1/civiczone/rules/dimensional", + "path": "/api/v1/townlight_zoning/rules/dimensional", "router": "app", "prefix_resolved": true, "name": "dimensional_rule_lookup", @@ -29232,14 +29232,14 @@ "returns": "dict[str, str]", "line": 261, "doc": "", - "decorator": "app.post('/api/v1/civiczone/rules/dimensional')", + "decorator": "app.post('/api/v1/townlight_zoning/rules/dimensional')", "errors": [ "HTTPException(status_code=404, detail={'message': result.message, 'fix': result.fix})" ] }, { "method": "POST", - "path": "/api/v1/civiczone/standards/process-explanation", + "path": "/api/v1/townlight_zoning/standards/process-explanation", "router": "app", "prefix_resolved": true, "name": "discretionary_explanation", @@ -29247,12 +29247,12 @@ "returns": "dict[str, object]", "line": 283, "doc": "Explain the variance/CUP process a question is about, with citations.\n\nReturns an explicit ``unavailable`` payload when the loaded rule dataset cannot\nsupport an answer; never a guessed standard, and never a determination.", - "decorator": "app.post('/api/v1/civiczone/standards/process-explanation')", + "decorator": "app.post('/api/v1/townlight_zoning/standards/process-explanation')", "errors": [] }, { "method": "POST", - "path": "/api/v1/civiczone/questions/answer", + "path": "/api/v1/townlight_zoning/questions/answer", "router": "app", "prefix_resolved": true, "name": "zone_question_answer", @@ -29260,12 +29260,12 @@ "returns": "dict[str, object]", "line": 353, "doc": "", - "decorator": "app.post('/api/v1/civiczone/questions/answer')", + "decorator": "app.post('/api/v1/townlight_zoning/questions/answer')", "errors": [] }, { "method": "POST", - "path": "/api/v1/civiczone/planner-review/classify", + "path": "/api/v1/townlight_zoning/planner-review/classify", "router": "app", "prefix_resolved": true, "name": "planner_review_classify", @@ -29273,12 +29273,12 @@ "returns": "dict[str, str]", "line": 378, "doc": "", - "decorator": "app.post('/api/v1/civiczone/planner-review/classify')", + "decorator": "app.post('/api/v1/townlight_zoning/planner-review/classify')", "errors": [] }, { "method": "GET", - "path": "/api/v1/civiczone/staff/precedents/{precedent_id}", + "path": "/api/v1/townlight_zoning/staff/precedents/{precedent_id}", "router": "app", "prefix_resolved": true, "name": "staff_precedent", @@ -29286,14 +29286,14 @@ "returns": "dict[str, str]", "line": 384, "doc": "", - "decorator": "app.get('/api/v1/civiczone/staff/precedents/{precedent_id}')", + "decorator": "app.get('/api/v1/townlight_zoning/staff/precedents/{precedent_id}')", "errors": [ "HTTPException(status_code=404, detail={'message': 'Staff precedent not found.', 'fix': \"Try precedent_id 'historic-adu'.\"})" ] }, { "method": "POST", - "path": "/api/v1/civiczone/staff/questions/answer", + "path": "/api/v1/townlight_zoning/staff/questions/answer", "router": "app", "prefix_resolved": true, "name": "staff_question_answer", @@ -29301,12 +29301,12 @@ "returns": "dict[str, object]", "line": 402, "doc": "", - "decorator": "app.post('/api/v1/civiczone/staff/questions/answer')", + "decorator": "app.post('/api/v1/townlight_zoning/staff/questions/answer')", "errors": [] }, { "method": "POST", - "path": "/api/v1/civiczone/staff/ambiguity-reviews", + "path": "/api/v1/townlight_zoning/staff/ambiguity-reviews", "router": "app", "prefix_resolved": true, "name": "create_ambiguity_review", @@ -29314,12 +29314,12 @@ "returns": "dict[str, object]", "line": 415, "doc": "", - "decorator": "app.post('/api/v1/civiczone/staff/ambiguity-reviews')", + "decorator": "app.post('/api/v1/townlight_zoning/staff/ambiguity-reviews')", "errors": [] }, { "method": "GET", - "path": "/api/v1/civiczone/staff/ambiguity-reviews", + "path": "/api/v1/townlight_zoning/staff/ambiguity-reviews", "router": "app", "prefix_resolved": true, "name": "list_ambiguity_reviews", @@ -29327,12 +29327,12 @@ "returns": "dict[str, object]", "line": 429, "doc": "", - "decorator": "app.get('/api/v1/civiczone/staff/ambiguity-reviews')", + "decorator": "app.get('/api/v1/townlight_zoning/staff/ambiguity-reviews')", "errors": [] }, { "method": "PATCH", - "path": "/api/v1/civiczone/staff/ambiguity-reviews/{item_id}", + "path": "/api/v1/townlight_zoning/staff/ambiguity-reviews/{item_id}", "router": "app", "prefix_resolved": true, "name": "update_ambiguity_review", @@ -29340,7 +29340,7 @@ "returns": "dict[str, object]", "line": 443, "doc": "", - "decorator": "app.patch('/api/v1/civiczone/staff/ambiguity-reviews/{item_id}')", + "decorator": "app.patch('/api/v1/townlight_zoning/staff/ambiguity-reviews/{item_id}')", "errors": [ "HTTPException(status_code=404, detail={'message': 'Ambiguity review item was not found.', 'fix': 'List staff ambiguity reviews and retry with an existing item id.'})", "HTTPException(status_code=422, detail={'message': 'Ambiguity review update is invalid.', 'fix': str(exc)})" @@ -29348,7 +29348,7 @@ }, { "method": "GET", - "path": "/api/v1/civiczone/staff/questions/analytics", + "path": "/api/v1/townlight_zoning/staff/questions/analytics", "router": "app", "prefix_resolved": true, "name": "staff_question_analytics", @@ -29356,12 +29356,12 @@ "returns": "dict[str, object]", "line": 472, "doc": "", - "decorator": "app.get('/api/v1/civiczone/staff/questions/analytics')", + "decorator": "app.get('/api/v1/townlight_zoning/staff/questions/analytics')", "errors": [] }, { "method": "POST", - "path": "/api/v1/civiczone/staff/reports/outline", + "path": "/api/v1/townlight_zoning/staff/reports/outline", "router": "app", "prefix_resolved": true, "name": "staff_report_outline", @@ -29369,12 +29369,12 @@ "returns": "dict[str, object]", "line": 496, "doc": "", - "decorator": "app.post('/api/v1/civiczone/staff/reports/outline')", + "decorator": "app.post('/api/v1/townlight_zoning/staff/reports/outline')", "errors": [] }, { "method": "POST", - "path": "/api/v1/civiczone/staff/flagged-answers", + "path": "/api/v1/townlight_zoning/staff/flagged-answers", "router": "app", "prefix_resolved": true, "name": "create_flagged_answer_review", @@ -29382,12 +29382,12 @@ "returns": "dict[str, object]", "line": 520, "doc": "", - "decorator": "app.post('/api/v1/civiczone/staff/flagged-answers')", + "decorator": "app.post('/api/v1/townlight_zoning/staff/flagged-answers')", "errors": [] }, { "method": "PATCH", - "path": "/api/v1/civiczone/staff/flagged-answers/{review_id}/improve", + "path": "/api/v1/townlight_zoning/staff/flagged-answers/{review_id}/improve", "router": "app", "prefix_resolved": true, "name": "improve_flagged_answer_review", @@ -29395,7 +29395,7 @@ "returns": "dict[str, object]", "line": 536, "doc": "", - "decorator": "app.patch('/api/v1/civiczone/staff/flagged-answers/{review_id}/improve')", + "decorator": "app.patch('/api/v1/townlight_zoning/staff/flagged-answers/{review_id}/improve')", "errors": [ "HTTPException(status_code=404, detail={'message': 'Flagged answer review was not found.', 'fix': 'Create or list the flagged answer review before submitting improvements.'})" ] @@ -29703,21 +29703,21 @@ ], "configuration": [ { - "variable": "CIVICZONE_PARCEL_RULE_DB_URL", + "variable": "TOWNLIGHT_ZONING_PARCEL_RULE_DB_URL", "default": "", "line": 559 } ] }, { - "source": "installed-owned-source/civiczone/migrations/__init__.py", + "source": "installed-owned-source/townlight_zoning/migrations/__init__.py", "sha256": "38cbccb2471a214eac40f174b618d28d0367c43a0e66d3eb5807dad737142765", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiczone/migrations/env.py", + "source": "installed-owned-source/townlight_zoning/migrations/env.py", "sha256": "3baae8fbf8726f8811647eb75d257e310d2d9660b0150833f17220dd8fa431ba", "routes": [], "models": [], @@ -29730,63 +29730,63 @@ ] }, { - "source": "installed-owned-source/civiczone/migrations/guards.py", + "source": "installed-owned-source/townlight_zoning/migrations/guards.py", "sha256": "9346e9812f238cfee1bdd21f5487fb5c51ee4cabeda45da9aaed6ac2db9b5f7c", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiczone/migrations/versions/__init__.py", + "source": "installed-owned-source/townlight_zoning/migrations/versions/__init__.py", "sha256": "a1087a2a3cedf40641ab02c8e97838630305726600105ad59e30727b61a2f95d", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiczone/migrations/versions/civiczone_0001_schema.py", + "source": "installed-owned-source/townlight_zoning/migrations/versions/townlight_zoning_0001_schema.py", "sha256": "0a6985e6fda034f4e654e63f2cb47610bf2af75dd028fc8f43473604550a2a18", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiczone/migrations/versions/civiczone_0002_parcel_rule_lookup_records.py", + "source": "installed-owned-source/townlight_zoning/migrations/versions/townlight_zoning_0002_parcel_rule_lookup_records.py", "sha256": "8a473e69469f9fdbca5adefcdb7e9a41d50850f1a7460381691da5a4f137314d", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiczone/migrations/versions/civiczone_0003_question_ledger.py", + "source": "installed-owned-source/townlight_zoning/migrations/versions/townlight_zoning_0003_question_ledger.py", "sha256": "fd654ca0d15832acb727b88ece26acce25cb45da1ff8b438152ad7c766df0abc", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiczone/migrations/versions/civiczone_0004_staff_workflows.py", + "source": "installed-owned-source/townlight_zoning/migrations/versions/townlight_zoning_0004_staff_workflows.py", "sha256": "3c0a145ff691077453b65413f2f08a6b7107a55f3ff21c072a8bc3788028b952", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiczone/migrations/versions/civiczone_0005_geo_import.py", + "source": "installed-owned-source/townlight_zoning/migrations/versions/townlight_zoning_0005_geo_import.py", "sha256": "8d4c34c15197ddc856c712d7fb8f9005cb553a2befd38a093a2c952a321d20ce", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiczone/migrations/versions/civiczone_0006_cited_questions.py", + "source": "installed-owned-source/townlight_zoning/migrations/versions/townlight_zoning_0006_cited_questions.py", "sha256": "65b8c591b5adf3f0022720a2c4e780c818f0f4b5b51db83b81cab78edb2a1f9d", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiczone/models.py", + "source": "installed-owned-source/townlight_zoning/models.py", "sha256": "206d16a1b4aa343eceee7bb25bdf39411f2b57e947a98a8be45607664635aba9", "routes": [], "models": [ @@ -29832,7 +29832,7 @@ { "name": "__table_args__", "type": "ClassVar[dict]", - "default": "{'schema': 'civiczone'}" + "default": "{'schema': 'townlight_zoning'}" }, { "name": "code", @@ -29879,7 +29879,7 @@ { "name": "__table_args__", "type": "ClassVar[dict]", - "default": "{'schema': 'civiczone'}" + "default": "{'schema': 'townlight_zoning'}" }, { "name": "code", @@ -29921,7 +29921,7 @@ { "name": "__table_args__", "type": "ClassVar[dict]", - "default": "{'schema': 'civiczone'}" + "default": "{'schema': 'townlight_zoning'}" }, { "name": "parcel_number", @@ -29936,7 +29936,7 @@ { "name": "zone_id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(ForeignKey('civiczone.zones.id'), nullable=False)" + "default": "mapped_column(ForeignKey('townlight_zoning.zones.id'), nullable=False)" }, { "name": "overlay_payload", @@ -29968,7 +29968,7 @@ { "name": "__table_args__", "type": "ClassVar[dict]", - "default": "{'schema': 'civiczone'}" + "default": "{'schema': 'townlight_zoning'}" }, { "name": "code", @@ -30000,17 +30000,17 @@ { "name": "__table_args__", "type": "ClassVar[dict]", - "default": "{'schema': 'civiczone'}" + "default": "{'schema': 'townlight_zoning'}" }, { "name": "zone_id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(ForeignKey('civiczone.zones.id'), nullable=False)" + "default": "mapped_column(ForeignKey('townlight_zoning.zones.id'), nullable=False)" }, { "name": "use_category_id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(ForeignKey('civiczone.use_categories.id'), nullable=False)" + "default": "mapped_column(ForeignKey('townlight_zoning.use_categories.id'), nullable=False)" }, { "name": "status", @@ -30047,12 +30047,12 @@ { "name": "__table_args__", "type": "ClassVar[dict]", - "default": "{'schema': 'civiczone'}" + "default": "{'schema': 'townlight_zoning'}" }, { "name": "zone_id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(ForeignKey('civiczone.zones.id'), nullable=False)" + "default": "mapped_column(ForeignKey('townlight_zoning.zones.id'), nullable=False)" }, { "name": "rule_type", @@ -30089,7 +30089,7 @@ { "name": "__table_args__", "type": "ClassVar[dict]", - "default": "{'schema': 'civiczone'}" + "default": "{'schema': 'townlight_zoning'}" }, { "name": "source_section_ref", @@ -30126,7 +30126,7 @@ { "name": "__table_args__", "type": "ClassVar[dict]", - "default": "{'schema': 'civiczone'}" + "default": "{'schema': 'townlight_zoning'}" }, { "name": "title", @@ -30168,12 +30168,12 @@ { "name": "__table_args__", "type": "ClassVar[dict]", - "default": "{'schema': 'civiczone'}" + "default": "{'schema': 'townlight_zoning'}" }, { "name": "zone_id", "type": "Mapped[uuid.UUID | None]", - "default": "mapped_column(ForeignKey('civiczone.zones.id'))" + "default": "mapped_column(ForeignKey('townlight_zoning.zones.id'))" }, { "name": "note_text", @@ -30205,7 +30205,7 @@ { "name": "__table_args__", "type": "ClassVar[dict]", - "default": "{'schema': 'civiczone'}" + "default": "{'schema': 'townlight_zoning'}" }, { "name": "question_text", @@ -30245,7 +30245,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civiczone/parcel_lookup.py", + "source": "installed-owned-source/townlight_zoning/parcel_lookup.py", "sha256": "3629424d9af4d5ac514f285835f9b8179c1cf6ceb22d586576603a270edb5671", "routes": [], "models": [ @@ -30319,14 +30319,14 @@ "configuration": [] }, { - "source": "installed-owned-source/civiczone/public_ui.py", + "source": "installed-owned-source/townlight_zoning/public_ui.py", "sha256": "75d1542af38b920b5a4527da79af374ade3abf03d7a78f5d9ad2b075790681a5", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiczone/qa.py", + "source": "installed-owned-source/townlight_zoning/qa.py", "sha256": "374b232775a482a3a02ce283d047652e0c188f7f856e0046e465d663ef863315", "routes": [], "models": [ @@ -30377,7 +30377,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civiczone/question_ledger.py", + "source": "installed-owned-source/townlight_zoning/question_ledger.py", "sha256": "0fca91aa0a7338771f760fe9032da442023c3407584d0ee0c621ce0290a65e7b", "routes": [], "models": [ @@ -30448,7 +30448,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civiczone/rule_lookup.py", + "source": "installed-owned-source/townlight_zoning/rule_lookup.py", "sha256": "5c53135c7a413e0eecf663061593945c56330eae6a96808d61d69bd4e6d996a2", "routes": [], "models": [ @@ -30545,7 +30545,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civiczone/staff_context.py", + "source": "installed-owned-source/townlight_zoning/staff_context.py", "sha256": "50784c2b595741098e2de9d9ad90a7957607ae09839afe6167af13e38037c91c", "routes": [], "models": [ @@ -30599,14 +30599,14 @@ "configuration": [] }, { - "source": "installed-owned-source/civiczone/staff_ui.py", + "source": "installed-owned-source/townlight_zoning/staff_ui.py", "sha256": "69448abc334931b5f19168fdffbef81497e250dd61f1912811d4ebdb28ee0b25", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civiczone/staff_workflows.py", + "source": "installed-owned-source/townlight_zoning/staff_workflows.py", "sha256": "27cf6da89c7a1472b23cbcace93adb63a0384be443b95228c882eb3bfb0ed642", "routes": [], "models": [ @@ -30967,7 +30967,7 @@ ], "bridge": [ { - "source": "installed-owned-source/civicsuite_runtime/zoning_bridge.py", + "source": "installed-owned-source/townlight_runtime/zoning_bridge.py", "sha256": "eb80d79ffc4fc736789aab4f3d3b75a4d9d01101d6414a69a29053c7d5f90505", "routes": [ { @@ -31151,7 +31151,7 @@ }, { "method": "POST", - "path": "/civiczone/questions", + "path": "/townlight_zoning/questions", "router": "public_router", "prefix_resolved": true, "name": "public_question", @@ -31164,7 +31164,7 @@ }, { "method": "POST", - "path": "/civiczone/parcels/lookup", + "path": "/townlight_zoning/parcels/lookup", "router": "public_router", "prefix_resolved": true, "name": "public_parcel_lookup", @@ -31445,7 +31445,7 @@ ], "configuration": [ { - "variable": "CIVICZONE_PARCEL_RULE_DB_URL", + "variable": "TOWNLIGHT_ZONING_PARCEL_RULE_DB_URL", "default": "", "line": 359 } @@ -31454,24 +31454,24 @@ ] }, "planning": { - "package": "civicplan", + "package": "townlight_planning", "source": [ { - "source": "installed-owned-source/civicplan/__init__.py", + "source": "installed-owned-source/townlight_planning/__init__.py", "sha256": "d6a014eba48a6bdcdaea2a444cfcaa743cd2ba33cec6d63ea5e450266ad71c82", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicplan/connections.py", + "source": "installed-owned-source/townlight_planning/connections.py", "sha256": "649c8474e787fca1e30a11f153d2f776283204b5dc8053b7e88fbc325cdcf944", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicplan/consistency.py", + "source": "installed-owned-source/townlight_planning/consistency.py", "sha256": "d18ef439391d859f0d1a020356edaf91d2441333eacf36036d03d1b7ea467210", "routes": [], "models": [ @@ -31512,7 +31512,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civicplan/integration_mocks.py", + "source": "installed-owned-source/townlight_planning/integration_mocks.py", "sha256": "09c350c13fe4e14c3f385549021f57c09341c8dbe110b18e6e4739cf70ac6254", "routes": [], "models": [ @@ -31576,7 +31576,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civicplan/main.py", + "source": "installed-owned-source/townlight_planning/main.py", "sha256": "34aaae27da4bc8f34570849cc446a134efb78c004294425ac62ef2c80abb1adf", "routes": [ { @@ -31607,20 +31607,20 @@ }, { "method": "GET", - "path": "/civicplan", + "path": "/townlight_planning", "router": "app", "prefix_resolved": true, - "name": "public_civicplan_page", + "name": "public_townlight_planning_page", "signature": "q: str='', goal: str='', topic: str='', plan_type: str='', clear: str='', neighborhood: str=''", "returns": "str", "line": 193, "doc": "Explore the adopted plan sources this deployment actually holds.\n\nPublic readers get only adopted, effective, public municipal revisions. When\nno plan database is configured the page says so instead of showing sample text.", - "decorator": "app.get('/civicplan', response_class=HTMLResponse)", + "decorator": "app.get('/townlight_planning', response_class=HTMLResponse)", "errors": [] }, { "method": "GET", - "path": "/api/v1/civicplan/public/plan-explore", + "path": "/api/v1/townlight_planning/public/plan-explore", "router": "app", "prefix_resolved": true, "name": "public_plan_explore", @@ -31628,14 +31628,14 @@ "returns": "dict[str, object]", "line": 220, "doc": "The same persisted-source exploration as the page, as JSON.", - "decorator": "app.get('/api/v1/civicplan/public/plan-explore')", + "decorator": "app.get('/api/v1/townlight_planning/public/plan-explore')", "errors": [ "HTTPException(503, 'No plan source database is configured for this deployment.')" ] }, { "method": "GET", - "path": "/api/v1/civicplan/public/policy/{revision_id}/{policy_id}", + "path": "/api/v1/townlight_planning/public/policy/{revision_id}/{policy_id}", "router": "app", "prefix_resolved": true, "name": "public_policy_citation", @@ -31643,7 +31643,7 @@ "returns": "dict[str, object]", "line": 237, "doc": "One cited policy for a public reader, or a refusal.\n\nA staff-only, pending, superseded or non-effective revision is refused here by\nthe service; naming its id does not reach it.", - "decorator": "app.get('/api/v1/civicplan/public/policy/{revision_id}/{policy_id}')", + "decorator": "app.get('/api/v1/townlight_planning/public/policy/{revision_id}/{policy_id}')", "errors": [ "HTTPException(503, 'No plan source database is configured for this deployment.')", "HTTPException(404, str(exc))" @@ -31651,7 +31651,7 @@ }, { "method": "POST", - "path": "/api/v1/civicplan/policies/lookup", + "path": "/api/v1/townlight_planning/policies/lookup", "router": "app", "prefix_resolved": true, "name": "policy_lookup", @@ -31659,29 +31659,29 @@ "returns": "dict[str, object]", "line": 256, "doc": "", - "decorator": "app.post('/api/v1/civicplan/policies/lookup')", + "decorator": "app.post('/api/v1/townlight_planning/policies/lookup')", "errors": [ "HTTPException(404, 'No supported adopted policy found; inspect imported sources.')" ] }, { "method": "POST", - "path": "/api/v1/civicplan/policies/ingest", + "path": "/api/v1/townlight_planning/policies/ingest", "router": "app", "prefix_resolved": true, "name": "ingest_policy", - "signature": "request: PolicyIngestRequest, x_civicplan_role: Annotated[str | None, Header()]=None, x_civicplan_staff_key: Annotated[str | None, Header()]=None", + "signature": "request: PolicyIngestRequest, x_townlight_planning_role: Annotated[str | None, Header()]=None, x_townlight_planning_staff_key: Annotated[str | None, Header()]=None", "returns": "dict[str, object]", "line": 270, "doc": "", - "decorator": "app.post('/api/v1/civicplan/policies/ingest')", + "decorator": "app.post('/api/v1/townlight_planning/policies/ingest')", "errors": [ - "HTTPException(409, detail={'message': 'Metadata-only ingestion cannot establish plan provenance.', 'fix': 'Use POST /api/v1/civicplan/source-imports with a staff-verified source bundle.'})" + "HTTPException(409, detail={'message': 'Metadata-only ingestion cannot establish plan provenance.', 'fix': 'Use POST /api/v1/townlight_planning/source-imports with a staff-verified source bundle.'})" ] }, { "method": "GET", - "path": "/api/v1/civicplan/plans/navigator", + "path": "/api/v1/townlight_planning/plans/navigator", "router": "app", "prefix_resolved": true, "name": "plans_navigator", @@ -31689,12 +31689,12 @@ "returns": "dict[str, object]", "line": 283, "doc": "", - "decorator": "app.get('/api/v1/civicplan/plans/navigator')", + "decorator": "app.get('/api/v1/townlight_planning/plans/navigator')", "errors": [] }, { "method": "POST", - "path": "/api/v1/civicplan/questions/answer", + "path": "/api/v1/townlight_planning/questions/answer", "router": "app", "prefix_resolved": true, "name": "plan_question_answer", @@ -31702,12 +31702,12 @@ "returns": "dict[str, object]", "line": 292, "doc": "", - "decorator": "app.post('/api/v1/civicplan/questions/answer')", + "decorator": "app.post('/api/v1/townlight_planning/questions/answer')", "errors": [] }, { "method": "POST", - "path": "/api/v1/civicplan/plans/synthesis", + "path": "/api/v1/townlight_planning/plans/synthesis", "router": "app", "prefix_resolved": true, "name": "plan_synthesis", @@ -31715,25 +31715,25 @@ "returns": "dict[str, object]", "line": 306, "doc": "", - "decorator": "app.post('/api/v1/civicplan/plans/synthesis')", + "decorator": "app.post('/api/v1/townlight_planning/plans/synthesis')", "errors": [] }, { "method": "POST", - "path": "/api/v1/civicplan/context/civicclerk", + "path": "/api/v1/townlight_planning/context/townlight_meetings", "router": "app", "prefix_resolved": true, - "name": "civicclerk_context", - "signature": "request: CivicClerkContextRequest, is_staff=Depends(audience)", + "name": "townlight_meetings_context", + "signature": "request: TownlightMeetingsContextRequest, is_staff=Depends(audience)", "returns": "dict[str, object]", "line": 314, "doc": "", - "decorator": "app.post('/api/v1/civicplan/context/civicclerk')", + "decorator": "app.post('/api/v1/townlight_planning/context/townlight_meetings')", "errors": [] }, { "method": "POST", - "path": "/api/v1/civicplan/integrations/mock", + "path": "/api/v1/townlight_planning/integrations/mock", "router": "app", "prefix_resolved": true, "name": "integration_mock", @@ -31741,14 +31741,14 @@ "returns": "dict[str, object]", "line": 328, "doc": "", - "decorator": "app.post('/api/v1/civicplan/integrations/mock')", + "decorator": "app.post('/api/v1/townlight_planning/integrations/mock')", "errors": [ "HTTPException(status_code=422, detail={'message': result.message, 'fix': result.fix, 'code': result.code, 'provider': result.provider})" ] }, { "method": "POST", - "path": "/api/v1/civicplan/context/zoning", + "path": "/api/v1/townlight_planning/context/zoning", "router": "app", "prefix_resolved": true, "name": "zoning_policy_context", @@ -31756,12 +31756,12 @@ "returns": "dict[str, object]", "line": 349, "doc": "", - "decorator": "app.post('/api/v1/civicplan/context/zoning')", + "decorator": "app.post('/api/v1/townlight_planning/context/zoning')", "errors": [] }, { "method": "POST", - "path": "/api/v1/civicplan/consistency/check", + "path": "/api/v1/townlight_planning/consistency/check", "router": "app", "prefix_resolved": true, "name": "consistency_check", @@ -31769,43 +31769,43 @@ "returns": "dict[str, object]", "line": 378, "doc": "", - "decorator": "app.post('/api/v1/civicplan/consistency/check')", + "decorator": "app.post('/api/v1/townlight_planning/consistency/check')", "errors": [] }, { "method": "POST", - "path": "/api/v1/civicplan/staff-analysis/draft", + "path": "/api/v1/townlight_planning/staff-analysis/draft", "router": "app", "prefix_resolved": true, "name": "staff_analysis", - "signature": "request: StaffAnalysisRequest, x_civicplan_role: Annotated[str | None, Header()]=None, x_civicplan_staff_key: Annotated[str | None, Header()]=None", + "signature": "request: StaffAnalysisRequest, x_townlight_planning_role: Annotated[str | None, Header()]=None, x_townlight_planning_staff_key: Annotated[str | None, Header()]=None", "returns": "dict[str, object]", "line": 392, "doc": "", - "decorator": "app.post('/api/v1/civicplan/staff-analysis/draft')", + "decorator": "app.post('/api/v1/townlight_planning/staff-analysis/draft')", "errors": [ "HTTPException(404, 'No supported adopted policy found.')" ] }, { "method": "GET", - "path": "/api/v1/civicplan/staff-analysis/{analysis_id}", + "path": "/api/v1/townlight_planning/staff-analysis/{analysis_id}", "router": "app", "prefix_resolved": true, "name": "get_staff_analysis", - "signature": "analysis_id: str, native_request: Request, x_civicplan_role: Annotated[str | None, Header()]=None, x_civicplan_staff_key: Annotated[str | None, Header()]=None", + "signature": "analysis_id: str, native_request: Request, x_townlight_planning_role: Annotated[str | None, Header()]=None, x_townlight_planning_staff_key: Annotated[str | None, Header()]=None", "returns": "dict[str, object]", "line": 419, "doc": "", - "decorator": "app.get('/api/v1/civicplan/staff-analysis/{analysis_id}')", + "decorator": "app.get('/api/v1/townlight_planning/staff-analysis/{analysis_id}')", "errors": [ - "HTTPException(status_code=503, detail={'message': 'Townlight Planning policy persistence is not configured.', 'fix': 'Set CIVICPLAN_POLICY_DB_URL to retrieve persisted staff-analysis records.'})", - "HTTPException(status_code=404, detail={'message': 'Staff-analysis record not found.', 'fix': 'Use an analysis_id returned by POST /api/v1/civicplan/staff-analysis/draft.'})" + "HTTPException(status_code=503, detail={'message': 'Townlight Planning policy persistence is not configured.', 'fix': 'Set TOWNLIGHT_PLANNING_POLICY_DB_URL to retrieve persisted staff-analysis records.'})", + "HTTPException(status_code=404, detail={'message': 'Staff-analysis record not found.', 'fix': 'Use an analysis_id returned by POST /api/v1/townlight_planning/staff-analysis/draft.'})" ] }, { "method": "POST", - "path": "/api/v1/civicplan/export", + "path": "/api/v1/townlight_planning/export", "router": "app", "prefix_resolved": true, "name": "policy_export", @@ -31813,7 +31813,7 @@ "returns": "dict[str, object]", "line": 451, "doc": "", - "decorator": "app.post('/api/v1/civicplan/export')", + "decorator": "app.post('/api/v1/townlight_planning/export')", "errors": [ "HTTPException(403, 'Staff authentication is required to export analysis snapshots.')", "HTTPException(422, 'Select a reviewed immutable snapshot; a policy ID alone is not an export.')", @@ -31879,7 +31879,7 @@ "default": "Field(default='comprehensive', min_length=1, max_length=120)" }, { - "name": "civiczone_context_id", + "name": "townlight_zoning_context_id", "type": "str | None", "default": "Field(default=None, max_length=160)" } @@ -32053,7 +32053,7 @@ "doc": "" }, { - "name": "CivicClerkContextRequest", + "name": "TownlightMeetingsContextRequest", "bases": [ "BaseModel" ], @@ -32095,74 +32095,74 @@ ], "configuration": [ { - "variable": "CIVICPLAN_POLICY_DB_URL", + "variable": "TOWNLIGHT_PLANNING_POLICY_DB_URL", "default": "", "line": 469 }, { - "variable": "CIVICPLAN_DEMO_MODE", + "variable": "TOWNLIGHT_PLANNING_DEMO_MODE", "default": "", "line": 496 } ] }, { - "source": "installed-owned-source/civicplan/migrations/__init__.py", + "source": "installed-owned-source/townlight_planning/migrations/__init__.py", "sha256": "daf5e64cefda400a5db1023d952e41bef6f7954db19406d63ea84770c82dccd9", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicplan/migrations/__main__.py", + "source": "installed-owned-source/townlight_planning/migrations/__main__.py", "sha256": "321e543984ca92e2540d1f4d9eca54658dc608987b95bc5abc61b651b4305fd6", "routes": [], "models": [], "configuration": [ { - "variable": "CIVICPLAN_POLICY_DB_URL", + "variable": "TOWNLIGHT_PLANNING_POLICY_DB_URL", "default": "", "line": 7 } ] }, { - "source": "installed-owned-source/civicplan/migrations/env.py", + "source": "installed-owned-source/townlight_planning/migrations/env.py", "sha256": "832a41b6c40d14da47178b486650eba98bff574a66652e3b614cc782db04f8df", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicplan/migrations/versions/civicplan_0001_sources.py", + "source": "installed-owned-source/townlight_planning/migrations/versions/townlight_planning_0001_sources.py", "sha256": "807e5a18d1fa295d482f3963f7799f244f046ab98297bfc33cbd17131fb44d17", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicplan/migrations/versions/civicplan_0002_workflows.py", + "source": "installed-owned-source/townlight_planning/migrations/versions/townlight_planning_0002_workflows.py", "sha256": "7c6fcdfe4a1fa33c9289cef975a25f4b0f6746471c380226c14520f8a5f09dbf", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicplan/migrations/versions/civicplan_0003_municipal.py", + "source": "installed-owned-source/townlight_planning/migrations/versions/townlight_planning_0003_municipal.py", "sha256": "64735db3119b22b54a232e0a4486657a91b5304e4a253b14ce7cae1acb204681", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicplan/migrations/versions/civicplan_0004_neighborhoods.py", + "source": "installed-owned-source/townlight_planning/migrations/versions/townlight_planning_0004_neighborhoods.py", "sha256": "006f8f8f9859da76189efee9035d1f89c65e0b27172b5df9e316e1aa173434f8", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicplan/municipal.py", + "source": "installed-owned-source/townlight_planning/municipal.py", "sha256": "dbd5bd841f3f90d2ab7256eafb30ed8b7ba6036bd3921e23595d7df6715b8555", "routes": [], "models": [ @@ -32345,12 +32345,12 @@ "configuration": [] }, { - "source": "installed-owned-source/civicplan/municipal_api.py", + "source": "installed-owned-source/townlight_planning/municipal_api.py", "sha256": "b71876bd1b6f354f7a9ad8d06f19d8ae7c071a0315f19421d3ff4df07bb8dc1f", "routes": [ { "method": "POST", - "path": "/api/v1/civicplan/initiatives", + "path": "/api/v1/townlight_planning/initiatives", "router": "router", "prefix_resolved": true, "name": "create_initiative", @@ -32363,7 +32363,7 @@ }, { "method": "POST", - "path": "/api/v1/civicplan/initiatives/{item_id}/revisions", + "path": "/api/v1/townlight_planning/initiatives/{item_id}/revisions", "router": "router", "prefix_resolved": true, "name": "update_initiative", @@ -32376,7 +32376,7 @@ }, { "method": "POST", - "path": "/api/v1/civicplan/amendments", + "path": "/api/v1/townlight_planning/amendments", "router": "router", "prefix_resolved": true, "name": "create_amendment", @@ -32389,7 +32389,7 @@ }, { "method": "POST", - "path": "/api/v1/civicplan/amendments/{item_id}/revisions", + "path": "/api/v1/townlight_planning/amendments/{item_id}/revisions", "router": "router", "prefix_resolved": true, "name": "update_amendment", @@ -32402,7 +32402,7 @@ }, { "method": "GET", - "path": "/api/v1/civicplan/municipal-work/{item_id}/history", + "path": "/api/v1/townlight_planning/municipal-work/{item_id}/history", "router": "router", "prefix_resolved": true, "name": "history", @@ -32417,7 +32417,7 @@ }, { "method": "GET", - "path": "/api/v1/civicplan/progress/targets", + "path": "/api/v1/townlight_planning/progress/targets", "router": "router", "prefix_resolved": true, "name": "progress", @@ -32430,7 +32430,7 @@ }, { "method": "GET", - "path": "/api/v1/civicplan/amendments/history", + "path": "/api/v1/townlight_planning/amendments/history", "router": "router", "prefix_resolved": true, "name": "amendments", @@ -32446,7 +32446,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civicplan/persistence.py", + "source": "installed-owned-source/townlight_planning/persistence.py", "sha256": "30d920165ab9b4f9675a0d61dd887587823b6c075ef160e3a56670db95d2cc7e", "routes": [], "models": [ @@ -32512,7 +32512,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civicplan/plan_workflows.py", + "source": "installed-owned-source/townlight_planning/plan_workflows.py", "sha256": "e69084e3608fa33bbc6ab140d4570efa3850cb04317000b407c5a5f5ca635115", "routes": [], "models": [ @@ -32672,7 +32672,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civicplan/policy_lookup.py", + "source": "installed-owned-source/townlight_planning/policy_lookup.py", "sha256": "eef53ba621332d75f069f00ddcac34c19bca42d469a697fd22555eb3d11c68b2", "routes": [], "models": [ @@ -32723,14 +32723,14 @@ "configuration": [] }, { - "source": "installed-owned-source/civicplan/policy_service.py", + "source": "installed-owned-source/townlight_planning/policy_service.py", "sha256": "c5e5461fadea4b32cba43366e1c9795ecb4cd8212db30734f5eadd24a9144808", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicplan/public_explore.py", + "source": "installed-owned-source/townlight_planning/public_explore.py", "sha256": "c5cbb2de92661538857e52b25f2e0bc4e7cd4f5c9d91eb0fa7d0518b28374720", "routes": [], "models": [ @@ -32801,21 +32801,21 @@ "configuration": [] }, { - "source": "installed-owned-source/civicplan/public_explore_ui.py", + "source": "installed-owned-source/townlight_planning/public_explore_ui.py", "sha256": "bd137701e16391a4ee820c4c88b5db583944491d5fc487ff7580b1083e944e5d", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicplan/public_ui.py", + "source": "installed-owned-source/townlight_planning/public_ui.py", "sha256": "8551ce36f854a4a7fc4573a20b73dbb0b6f01d7b60b7267d8c73b5f21f246ccc", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicplan/records_export.py", + "source": "installed-owned-source/townlight_planning/records_export.py", "sha256": "6894fb9450f5d0177ebf86babcd489be1a789a714ce2c3c825c7afd5ed51bb23", "routes": [], "models": [ @@ -32856,12 +32856,12 @@ "configuration": [] }, { - "source": "installed-owned-source/civicplan/source_api.py", + "source": "installed-owned-source/townlight_planning/source_api.py", "sha256": "4af39debaf4f9cbb219c294ddfeaea642495d45e492e62852049372e296f1df4", "routes": [ { "method": "POST", - "path": "/api/v1/civicplan/source-imports", + "path": "/api/v1/townlight_planning/source-imports", "router": "router", "prefix_resolved": true, "name": "import_sources", @@ -32876,7 +32876,7 @@ }, { "method": "GET", - "path": "/api/v1/civicplan/source-plans/{plan_id}/history", + "path": "/api/v1/townlight_planning/source-plans/{plan_id}/history", "router": "router", "prefix_resolved": true, "name": "source_history", @@ -32889,7 +32889,7 @@ }, { "method": "GET", - "path": "/api/v1/civicplan/source-revisions/{revision_id}", + "path": "/api/v1/townlight_planning/source-revisions/{revision_id}", "router": "router", "prefix_resolved": true, "name": "source_revision", @@ -32904,7 +32904,7 @@ }, { "method": "GET", - "path": "/api/v1/civicplan/source-revisions/{revision_id}/documents/{document_id}", + "path": "/api/v1/townlight_planning/source-revisions/{revision_id}/documents/{document_id}", "router": "router", "prefix_resolved": true, "name": "source_document", @@ -32942,14 +32942,14 @@ ], "configuration": [ { - "variable": "CIVICPLAN_POLICY_DB_URL", + "variable": "TOWNLIGHT_PLANNING_POLICY_DB_URL", "default": "", "line": 31 } ] }, { - "source": "installed-owned-source/civicplan/source_bundle.py", + "source": "installed-owned-source/townlight_planning/source_bundle.py", "sha256": "f6547516067e27697dfcd6ba80de6e2ca03d1473370209aa354a5bf95b7db98a", "routes": [], "models": [ @@ -33182,21 +33182,21 @@ "configuration": [] }, { - "source": "installed-owned-source/civicplan/source_schema.py", + "source": "installed-owned-source/townlight_planning/source_schema.py", "sha256": "1c429c22247cda2aaec5abe6807639177f035cae843993666dbf8b2824bbdbf1", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicplan/source_store.py", + "source": "installed-owned-source/townlight_planning/source_store.py", "sha256": "97022c50baa5b7e81bcc12fccd6c2e429af35f163680542cbf99b65722905d82", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicplan/staff_analysis.py", + "source": "installed-owned-source/townlight_planning/staff_analysis.py", "sha256": "71ab2f06804f1c01678f708c60a27714d7bd9b14444e1d2c8546cedb8ac1bd69", "routes": [], "models": [ @@ -33242,12 +33242,12 @@ "configuration": [] }, { - "source": "installed-owned-source/civicplan/workflow_api.py", + "source": "installed-owned-source/townlight_planning/workflow_api.py", "sha256": "6a48664442a3a8bae19a8cea7676e91f53ca3360f65e912dec666504862e792b", "routes": [ { "method": "POST", - "path": "/api/v1/civicplan/analyses", + "path": "/api/v1/townlight_planning/analyses", "router": "router", "prefix_resolved": true, "name": "create_analysis", @@ -33262,7 +33262,7 @@ }, { "method": "POST", - "path": "/api/v1/civicplan/analyses/{analysis_id}/revisions", + "path": "/api/v1/townlight_planning/analyses/{analysis_id}/revisions", "router": "router", "prefix_resolved": true, "name": "revise_analysis", @@ -33277,7 +33277,7 @@ }, { "method": "GET", - "path": "/api/v1/civicplan/analyses/{analysis_id}", + "path": "/api/v1/townlight_planning/analyses/{analysis_id}", "router": "router", "prefix_resolved": true, "name": "read_analysis", @@ -33292,7 +33292,7 @@ }, { "method": "GET", - "path": "/api/v1/civicplan/analyses/{analysis_id}/history", + "path": "/api/v1/townlight_planning/analyses/{analysis_id}/history", "router": "router", "prefix_resolved": true, "name": "analysis_history", @@ -33305,7 +33305,7 @@ }, { "method": "POST", - "path": "/api/v1/civicplan/analyses/{analysis_id}/snapshots", + "path": "/api/v1/townlight_planning/analyses/{analysis_id}/snapshots", "router": "router", "prefix_resolved": true, "name": "create_snapshot", @@ -33318,7 +33318,7 @@ }, { "method": "GET", - "path": "/api/v1/civicplan/snapshots/{snapshot_id}", + "path": "/api/v1/townlight_planning/snapshots/{snapshot_id}", "router": "router", "prefix_resolved": true, "name": "read_snapshot", @@ -33333,7 +33333,7 @@ }, { "method": "GET", - "path": "/api/v1/civicplan/snapshots/{snapshot_id}/export", + "path": "/api/v1/townlight_planning/snapshots/{snapshot_id}/export", "router": "router", "prefix_resolved": true, "name": "export_snapshot", @@ -33346,7 +33346,7 @@ }, { "method": "POST", - "path": "/api/v1/civicplan/snapshots/{snapshot_id}/access-advice", + "path": "/api/v1/townlight_planning/snapshots/{snapshot_id}/access-advice", "router": "router", "prefix_resolved": true, "name": "access_advice", @@ -33359,7 +33359,7 @@ }, { "method": "POST", - "path": "/api/v1/civicplan/policies/search", + "path": "/api/v1/townlight_planning/policies/search", "router": "router", "prefix_resolved": true, "name": "search_policies", @@ -33372,7 +33372,7 @@ }, { "method": "POST", - "path": "/api/v1/civicplan/connections/search", + "path": "/api/v1/townlight_planning/connections/search", "router": "router", "prefix_resolved": true, "name": "search_connections", @@ -33385,7 +33385,7 @@ }, { "method": "GET", - "path": "/api/v1/civicplan/policy-sources/{revision_id}/documents/{document_id}", + "path": "/api/v1/townlight_planning/policy-sources/{revision_id}/documents/{document_id}", "router": "router", "prefix_resolved": true, "name": "public_original", @@ -33465,7 +33465,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civicplan/workflow_models.py", + "source": "installed-owned-source/townlight_planning/workflow_models.py", "sha256": "d22e978fe778d7f4fdc3989a043370d9f6966b1e4920ed2c75698c73a8ee4e04", "routes": [], "models": [ @@ -33633,14 +33633,14 @@ "configuration": [] }, { - "source": "installed-owned-source/civicplan/workflow_schema.py", + "source": "installed-owned-source/townlight_planning/workflow_schema.py", "sha256": "11d864214fabc6d509351fdc7f3e3eb90a910a5db1a137f84a7a8efca5d0002e", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicplan/workflow_store.py", + "source": "installed-owned-source/townlight_planning/workflow_store.py", "sha256": "4d4fec6d6c876997726ff1d8f2ff39302f44228fae748edc013739267d210741", "routes": [], "models": [], @@ -33649,7 +33649,7 @@ ], "bridge": [ { - "source": "installed-owned-source/civicsuite_runtime/planning_bridge.py", + "source": "installed-owned-source/townlight_runtime/planning_bridge.py", "sha256": "74a855b995b7f323873b9c788cd15bd4b0ebe3fc1c53879596e1b5043c2825bb", "routes": [ { @@ -33890,7 +33890,7 @@ }, { "method": "POST", - "path": "/civicplan/policies/search", + "path": "/townlight_planning/policies/search", "router": "public_router", "prefix_resolved": true, "name": "public_policies", @@ -33903,7 +33903,7 @@ }, { "method": "POST", - "path": "/civicplan/plan-explore", + "path": "/townlight_planning/plan-explore", "router": "public_router", "prefix_resolved": true, "name": "public_plan_explore", @@ -33916,7 +33916,7 @@ }, { "method": "GET", - "path": "/civicplan/snapshots", + "path": "/townlight_planning/snapshots", "router": "public_router", "prefix_resolved": true, "name": "public_snapshots", @@ -33929,7 +33929,7 @@ }, { "method": "GET", - "path": "/civicplan/snapshots/{snapshot_id}", + "path": "/townlight_planning/snapshots/{snapshot_id}", "router": "public_router", "prefix_resolved": true, "name": "public_document", @@ -33942,7 +33942,7 @@ }, { "method": "GET", - "path": "/civicplan/revisions/{revision_id}/documents/{document_id}", + "path": "/townlight_planning/revisions/{revision_id}/documents/{document_id}", "router": "public_router", "prefix_resolved": true, "name": "public_original", @@ -34162,24 +34162,24 @@ ] }, "permitting": { - "package": "civicpermit", + "package": "townlight_permitting", "source": [ { - "source": "installed-owned-source/civicpermit/__init__.py", + "source": "installed-owned-source/townlight_permitting/__init__.py", "sha256": "a5b97430c7d8d5cfff984857fe16a7c72868d652340640cb9bdcdfe39ddb209c", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicpermit/connections.py", + "source": "installed-owned-source/townlight_permitting/connections.py", "sha256": "4159a4eb4a407bebbefeb49bb760788cff3ac51a45c34af094d3be4b5a746798", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicpermit/intake_review.py", + "source": "installed-owned-source/townlight_permitting/intake_review.py", "sha256": "694f531a12e56c283579e92f85651d08da776e916021ab19f4d7108c3120b41d", "routes": [], "models": [ @@ -34220,7 +34220,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civicpermit/integration_mocks.py", + "source": "installed-owned-source/townlight_permitting/integration_mocks.py", "sha256": "d1f1b614d502ada64a87d879703e9afa72402b69e8df5a1cf25cbd78f783e111", "routes": [], "models": [ @@ -34261,7 +34261,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civicpermit/main.py", + "source": "installed-owned-source/townlight_permitting/main.py", "sha256": "d1186d8d291225cfff5dc66e40ab435d899d8a059506a6be6f3b413b7a5c8b90", "routes": [ { @@ -34292,20 +34292,20 @@ }, { "method": "GET", - "path": "/civicpermit", + "path": "/townlight_permitting", "router": "app", "prefix_resolved": true, - "name": "public_civicpermit_page", + "name": "public_townlight_permitting_page", "signature": "", "returns": "str", "line": 163, "doc": "Return the public sample permit pre-application UI.", - "decorator": "app.get('/civicpermit', response_class=HTMLResponse)", + "decorator": "app.get('/townlight_permitting', response_class=HTMLResponse)", "errors": [] }, { "method": "POST", - "path": "/api/v1/civicpermit/requirements/lookup", + "path": "/api/v1/townlight_permitting/requirements/lookup", "router": "app", "prefix_resolved": true, "name": "requirement_lookup", @@ -34313,25 +34313,25 @@ "returns": "dict[str, object]", "line": 170, "doc": "", - "decorator": "app.post('/api/v1/civicpermit/requirements/lookup')", + "decorator": "app.post('/api/v1/townlight_permitting/requirements/lookup')", "errors": [] }, { "method": "POST", - "path": "/api/v1/civicpermit/intake/review", + "path": "/api/v1/townlight_permitting/intake/review", "router": "app", "prefix_resolved": true, "name": "intake_review", - "signature": "request: IntakeReviewRequest, x_civicpermit_role: Annotated[str | None, Header()]=None, x_civicpermit_staff_key: Annotated[str | None, Header()]=None", + "signature": "request: IntakeReviewRequest, x_townlight_permitting_role: Annotated[str | None, Header()]=None, x_townlight_permitting_staff_key: Annotated[str | None, Header()]=None", "returns": "dict[str, object]", "line": 179, "doc": "", - "decorator": "app.post('/api/v1/civicpermit/intake/review')", + "decorator": "app.post('/api/v1/townlight_permitting/intake/review')", "errors": [] }, { "method": "POST", - "path": "/api/v1/civicpermit/pathway/explain", + "path": "/api/v1/townlight_permitting/pathway/explain", "router": "app", "prefix_resolved": true, "name": "pathway_explain", @@ -34339,12 +34339,12 @@ "returns": "dict[str, object]", "line": 305, "doc": "Cited likely pathway/attachments/timeline/explainer, no model call.", - "decorator": "app.post('/api/v1/civicpermit/pathway/explain')", + "decorator": "app.post('/api/v1/townlight_permitting/pathway/explain')", "errors": [] }, { "method": "POST", - "path": "/api/v1/civicpermit/pathway/explain-assisted", + "path": "/api/v1/townlight_permitting/pathway/explain-assisted", "router": "app", "prefix_resolved": true, "name": "pathway_explain_assisted", @@ -34352,12 +34352,12 @@ "returns": "dict[str, object]", "line": 319, "doc": "Same, plus an actual configured-provider call; `assistance` says what ran.", - "decorator": "app.post('/api/v1/civicpermit/pathway/explain-assisted')", + "decorator": "app.post('/api/v1/townlight_permitting/pathway/explain-assisted')", "errors": [] }, { "method": "POST", - "path": "/api/v1/civicpermit/context/development-review", + "path": "/api/v1/townlight_permitting/context/development-review", "router": "app", "prefix_resolved": true, "name": "development_review_context", @@ -34365,12 +34365,12 @@ "returns": "dict[str, object]", "line": 339, "doc": "", - "decorator": "app.post('/api/v1/civicpermit/context/development-review')", + "decorator": "app.post('/api/v1/townlight_permitting/context/development-review')", "errors": [] }, { "method": "POST", - "path": "/api/v1/civicpermit/integrations/mock/development-review", + "path": "/api/v1/townlight_permitting/integrations/mock/development-review", "router": "app", "prefix_resolved": true, "name": "integration_mock_development_review", @@ -34378,28 +34378,28 @@ "returns": "dict[str, object]", "line": 372, "doc": "", - "decorator": "app.post('/api/v1/civicpermit/integrations/mock/development-review')", + "decorator": "app.post('/api/v1/townlight_permitting/integrations/mock/development-review')", "errors": [] }, { "method": "GET", - "path": "/api/v1/civicpermit/intake/{intake_id}", + "path": "/api/v1/townlight_permitting/intake/{intake_id}", "router": "app", "prefix_resolved": true, "name": "get_intake_review", - "signature": "intake_id: str, x_civicpermit_role: Annotated[str | None, Header()]=None, x_civicpermit_staff_key: Annotated[str | None, Header()]=None", + "signature": "intake_id: str, x_townlight_permitting_role: Annotated[str | None, Header()]=None, x_townlight_permitting_staff_key: Annotated[str | None, Header()]=None", "returns": "dict[str, object]", "line": 384, "doc": "", - "decorator": "app.get('/api/v1/civicpermit/intake/{intake_id}')", + "decorator": "app.get('/api/v1/townlight_permitting/intake/{intake_id}')", "errors": [ - "HTTPException(status_code=503, detail={'message': 'Townlight Permitting intake persistence is not configured.', 'fix': 'Set CIVICPERMIT_INTAKE_DB_URL to retrieve persisted intake review records.'})", - "HTTPException(status_code=404, detail={'message': 'Permit intake record not found.', 'fix': 'Use an intake_id returned by POST /api/v1/civicpermit/intake/review.'})" + "HTTPException(status_code=503, detail={'message': 'Townlight Permitting intake persistence is not configured.', 'fix': 'Set TOWNLIGHT_PERMITTING_INTAKE_DB_URL to retrieve persisted intake review records.'})", + "HTTPException(status_code=404, detail={'message': 'Permit intake record not found.', 'fix': 'Use an intake_id returned by POST /api/v1/townlight_permitting/intake/review.'})" ] }, { "method": "POST", - "path": "/api/v1/civicpermit/submittal/outline", + "path": "/api/v1/townlight_permitting/submittal/outline", "router": "app", "prefix_resolved": true, "name": "submittal_outline", @@ -34407,12 +34407,12 @@ "returns": "dict[str, object]", "line": 411, "doc": "", - "decorator": "app.post('/api/v1/civicpermit/submittal/outline')", + "decorator": "app.post('/api/v1/townlight_permitting/submittal/outline')", "errors": [] }, { "method": "POST", - "path": "/api/v1/civicpermit/export", + "path": "/api/v1/townlight_permitting/export", "router": "app", "prefix_resolved": true, "name": "permit_export", @@ -34420,46 +34420,46 @@ "returns": "dict[str, object]", "line": 421, "doc": "", - "decorator": "app.post('/api/v1/civicpermit/export')", + "decorator": "app.post('/api/v1/townlight_permitting/export')", "errors": [] }, { "method": "POST", - "path": "/api/v1/civicpermit/staff/reviews", + "path": "/api/v1/townlight_permitting/staff/reviews", "router": "app", "prefix_resolved": true, "name": "create_staff_review", - "signature": "request: StaffReviewCreateRequest, x_civicpermit_role: Annotated[str | None, Header()]=None, x_civicpermit_staff_key: Annotated[str | None, Header()]=None", + "signature": "request: StaffReviewCreateRequest, x_townlight_permitting_role: Annotated[str | None, Header()]=None, x_townlight_permitting_staff_key: Annotated[str | None, Header()]=None", "returns": "dict[str, object]", "line": 431, "doc": "", - "decorator": "app.post('/api/v1/civicpermit/staff/reviews')", + "decorator": "app.post('/api/v1/townlight_permitting/staff/reviews')", "errors": [] }, { "method": "GET", - "path": "/api/v1/civicpermit/staff/reviews", + "path": "/api/v1/townlight_permitting/staff/reviews", "router": "app", "prefix_resolved": true, "name": "list_staff_reviews", - "signature": "status: str | None=None, x_civicpermit_role: Annotated[str | None, Header()]=None, x_civicpermit_staff_key: Annotated[str | None, Header()]=None", + "signature": "status: str | None=None, x_townlight_permitting_role: Annotated[str | None, Header()]=None, x_townlight_permitting_staff_key: Annotated[str | None, Header()]=None", "returns": "dict[str, object]", "line": 449, "doc": "", - "decorator": "app.get('/api/v1/civicpermit/staff/reviews')", + "decorator": "app.get('/api/v1/townlight_permitting/staff/reviews')", "errors": [] }, { "method": "PATCH", - "path": "/api/v1/civicpermit/staff/reviews/{review_id}", + "path": "/api/v1/townlight_permitting/staff/reviews/{review_id}", "router": "app", "prefix_resolved": true, "name": "update_staff_review", - "signature": "review_id: str, request: StaffReviewUpdateRequest, x_civicpermit_role: Annotated[str | None, Header()]=None, x_civicpermit_staff_key: Annotated[str | None, Header()]=None", + "signature": "review_id: str, request: StaffReviewUpdateRequest, x_townlight_permitting_role: Annotated[str | None, Header()]=None, x_townlight_permitting_staff_key: Annotated[str | None, Header()]=None", "returns": "dict[str, object]", "line": 466, "doc": "", - "decorator": "app.patch('/api/v1/civicpermit/staff/reviews/{review_id}')", + "decorator": "app.patch('/api/v1/townlight_permitting/staff/reviews/{review_id}')", "errors": [ "HTTPException(status_code=404, detail={'message': 'Townlight Permitting staff review item was not found.', 'fix': 'List staff reviews and retry with an existing review_id.'})", "HTTPException(status_code=422, detail={'message': 'Staff review update is invalid.', 'fix': str(exc)})" @@ -34467,15 +34467,15 @@ }, { "method": "GET", - "path": "/api/v1/civicpermit/staff/reviews/summary", + "path": "/api/v1/townlight_permitting/staff/reviews/summary", "router": "app", "prefix_resolved": true, "name": "staff_review_summary", - "signature": "x_civicpermit_role: Annotated[str | None, Header()]=None, x_civicpermit_staff_key: Annotated[str | None, Header()]=None", + "signature": "x_townlight_permitting_role: Annotated[str | None, Header()]=None, x_townlight_permitting_staff_key: Annotated[str | None, Header()]=None", "returns": "dict[str, object]", "line": 498, "doc": "", - "decorator": "app.get('/api/v1/civicpermit/staff/reviews/summary')", + "decorator": "app.get('/api/v1/townlight_permitting/staff/reviews/summary')", "errors": [] } ], @@ -34708,45 +34708,45 @@ ], "configuration": [ { - "variable": "CIVICPERMIT_INTAKE_DB_URL", + "variable": "TOWNLIGHT_PERMITTING_INTAKE_DB_URL", "default": "", "line": 508 }, { - "variable": "CIVICPERMIT_LLM_MODEL", + "variable": "TOWNLIGHT_PERMITTING_LLM_MODEL", "default": "", "line": 233 }, { - "variable": "CIVICPERMIT_LLM_PROVIDER", + "variable": "TOWNLIGHT_PERMITTING_LLM_PROVIDER", "default": "''", "line": 218 } ] }, { - "source": "installed-owned-source/civicpermit/migrations/__init__.py", + "source": "installed-owned-source/townlight_permitting/migrations/__init__.py", "sha256": "01c6b95137260717ee792116a0479392b3f2da330542c55dbd181c4a93d404a3", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicpermit/migrations/env.py", + "source": "installed-owned-source/townlight_permitting/migrations/env.py", "sha256": "91715ad26e140d1b25b30ad38b3418d36ea63da4a195348aa5fe621c99edbe5e", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicpermit/migrations/versions/civicpermit_0001_connected.py", + "source": "installed-owned-source/townlight_permitting/migrations/versions/townlight_permitting_0001_connected.py", "sha256": "e3fc90959836887334b429888407537140fa2d119c202886b63c538feb4e9360", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicpermit/pathway.py", + "source": "installed-owned-source/townlight_permitting/pathway.py", "sha256": "b1e311809d61f4efab043c681efa9d711d5bf4bf76b5f33f808c1769e3687d08", "routes": [], "models": [ @@ -34763,7 +34763,7 @@ } ], "line": 74, - "doc": "Structural type of the civiccore LLM provider used for the explainer." + "doc": "Structural type of the townlight_core LLM provider used for the explainer." }, { "name": "PathwayStage", @@ -34913,7 +34913,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civicpermit/persistence.py", + "source": "installed-owned-source/townlight_permitting/persistence.py", "sha256": "cea7301cde02497e65601351e58100b3211cf79e85e3036f251107f7d21fe95b", "routes": [], "models": [ @@ -35070,14 +35070,14 @@ "configuration": [] }, { - "source": "installed-owned-source/civicpermit/public_ui.py", + "source": "installed-owned-source/townlight_permitting/public_ui.py", "sha256": "0f06685bd18b171987cc08413bc930112f400a03468c0f27e98badba6b732f29", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicpermit/records_export.py", + "source": "installed-owned-source/townlight_permitting/records_export.py", "sha256": "231801e8bd30b92f0fe6aeb0a8f2aed2d5097acae5f2cc5eda2e18f9c9a1fae8", "routes": [], "models": [ @@ -35118,7 +35118,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civicpermit/requirement_lookup.py", + "source": "installed-owned-source/townlight_permitting/requirement_lookup.py", "sha256": "f9a1fbd111096e7d4c00cc6cb7f25b9cf91af522f26c743f86234a0ecffe783c", "routes": [], "models": [ @@ -35169,14 +35169,14 @@ "configuration": [] }, { - "source": "installed-owned-source/civicpermit/sources.py", + "source": "installed-owned-source/townlight_permitting/sources.py", "sha256": "8e26b8c98635689f985e14d57a0137f6538145c50414da918ba0cb41a7f489a3", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicpermit/submittal_outline.py", + "source": "installed-owned-source/townlight_permitting/submittal_outline.py", "sha256": "f6465de3058d51bb47b7d278e10b67a2ac1ac46aeefa2563eabd041dcb54aae1", "routes": [], "models": [ @@ -35222,7 +35222,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civicpermit/workflow_models.py", + "source": "installed-owned-source/townlight_permitting/workflow_models.py", "sha256": "3d09f3ae137c5c48091e22a60a3e732ea3ec299236778d377df55807bb8bbfdd", "routes": [], "models": [ @@ -35495,14 +35495,14 @@ "configuration": [] }, { - "source": "installed-owned-source/civicpermit/workflow_schema.py", + "source": "installed-owned-source/townlight_permitting/workflow_schema.py", "sha256": "07dfc3dfafd5131ffee8b087add38fd7ebf446c2cf104100920636e732aaee59", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicpermit/workflow_store.py", + "source": "installed-owned-source/townlight_permitting/workflow_store.py", "sha256": "c3415dd94aaed609a593d28b60d0719f2dc1a504a5f15391d9708714038ea259", "routes": [], "models": [], @@ -35511,7 +35511,7 @@ ], "bridge": [ { - "source": "installed-owned-source/civicsuite_runtime/permitting_bridge.py", + "source": "installed-owned-source/townlight_runtime/permitting_bridge.py", "sha256": "786abd0dfc18ed0ce7ada70fcd120f96795d8e1ee46f38ca0770a8217b4d6e1d", "routes": [ { @@ -35775,31 +35775,31 @@ ] }, "inspections": { - "package": "civicinspect", + "package": "townlight_inspections", "source": [ { - "source": "installed-owned-source/civicinspect/__init__.py", + "source": "installed-owned-source/townlight_inspections/__init__.py", "sha256": "eff685acecf3985653f811403aaabc6862d52ce7e343c38aa5242f40d4266c47", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicinspect/_whistle_driver.py", + "source": "installed-owned-source/townlight_inspections/_whistle_driver.py", "sha256": "90ce9276c7d1de4d3259a2c00ff581e5d55d28dd8da913ed7b8bd2d7c89a5264", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicinspect/adapters.py", + "source": "installed-owned-source/townlight_inspections/adapters.py", "sha256": "ab76d8c1a8b57167acf759390b49a3941f04b4483a606be2abbae69f4f8165db", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicinspect/case_lookup.py", + "source": "installed-owned-source/townlight_inspections/case_lookup.py", "sha256": "b68030ecdf6a7f83ed35aec636afcb70c5ce247a40ed7d60a3283655bfdb3214", "routes": [], "models": [ @@ -35845,14 +35845,14 @@ "configuration": [] }, { - "source": "installed-owned-source/civicinspect/connections.py", + "source": "installed-owned-source/townlight_inspections/connections.py", "sha256": "82221673e19e1bd48215cfc9dbeab837070cd9a6bdd3f3cf57cf3034f3ac3bef", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicinspect/integration_mocks.py", + "source": "installed-owned-source/townlight_inspections/integration_mocks.py", "sha256": "dfc700d977badb104db5abddded3120b1bff99445a6bbf18f7a6925c9087c797", "routes": [], "models": [ @@ -35893,7 +35893,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civicinspect/main.py", + "source": "installed-owned-source/townlight_inspections/main.py", "sha256": "16306b47d0e6e526176c050b2eb2edb6a047edea3bb5f313df48c026a81cc53e", "routes": [ { @@ -35924,20 +35924,20 @@ }, { "method": "GET", - "path": "/civicinspect", + "path": "/townlight_inspections", "router": "app", "prefix_resolved": true, - "name": "public_civicinspect_page", + "name": "public_townlight_inspections_page", "signature": "", "returns": "str", "line": 162, "doc": "Return the public sample inspection support UI.", - "decorator": "app.get('/civicinspect', response_class=HTMLResponse)", + "decorator": "app.get('/townlight_inspections', response_class=HTMLResponse)", "errors": [] }, { "method": "POST", - "path": "/api/v1/civicinspect/cases/repeat-lookup", + "path": "/api/v1/townlight_inspections/cases/repeat-lookup", "router": "app", "prefix_resolved": true, "name": "repeat_case_lookup", @@ -35945,12 +35945,12 @@ "returns": "dict[str, object]", "line": 169, "doc": "", - "decorator": "app.post('/api/v1/civicinspect/cases/repeat-lookup')", + "decorator": "app.post('/api/v1/townlight_inspections/cases/repeat-lookup')", "errors": [] }, { "method": "POST", - "path": "/api/v1/civicinspect/reports/draft", + "path": "/api/v1/townlight_inspections/reports/draft", "router": "app", "prefix_resolved": true, "name": "inspection_report_draft", @@ -35958,12 +35958,12 @@ "returns": "dict[str, object]", "line": 178, "doc": "", - "decorator": "app.post('/api/v1/civicinspect/reports/draft')", + "decorator": "app.post('/api/v1/townlight_inspections/reports/draft')", "errors": [] }, { "method": "GET", - "path": "/api/v1/civicinspect/reports/{report_id}", + "path": "/api/v1/townlight_inspections/reports/{report_id}", "router": "app", "prefix_resolved": true, "name": "get_inspection_report", @@ -35971,15 +35971,15 @@ "returns": "dict[str, object]", "line": 215, "doc": "", - "decorator": "app.get('/api/v1/civicinspect/reports/{report_id}')", + "decorator": "app.get('/api/v1/townlight_inspections/reports/{report_id}')", "errors": [ - "HTTPException(status_code=503, detail={'message': 'Townlight Inspections case persistence is not configured.', 'fix': 'Set CIVICINSPECT_CASE_DB_URL to retrieve persisted inspection report records.'})", - "HTTPException(status_code=404, detail={'message': 'Inspection report record not found.', 'fix': 'Use a report_id returned by POST /api/v1/civicinspect/reports/draft.'})" + "HTTPException(status_code=503, detail={'message': 'Townlight Inspections case persistence is not configured.', 'fix': 'Set TOWNLIGHT_INSPECTIONS_CASE_DB_URL to retrieve persisted inspection report records.'})", + "HTTPException(status_code=404, detail={'message': 'Inspection report record not found.', 'fix': 'Use a report_id returned by POST /api/v1/townlight_inspections/reports/draft.'})" ] }, { "method": "POST", - "path": "/api/v1/civicinspect/evidence/retain", + "path": "/api/v1/townlight_inspections/evidence/retain", "router": "app", "prefix_resolved": true, "name": "retain_evidence_route", @@ -35987,12 +35987,12 @@ "returns": "dict[str, object]", "line": 291, "doc": "Retain original evidence bytes (photos, documents and raw audio) with hashes.", - "decorator": "app.post('/api/v1/civicinspect/evidence/retain')", + "decorator": "app.post('/api/v1/townlight_inspections/evidence/retain')", "errors": [] }, { "method": "POST", - "path": "/api/v1/civicinspect/media/analyse", + "path": "/api/v1/townlight_inspections/media/analyse", "router": "app", "prefix_resolved": true, "name": "media_analyse", @@ -36000,12 +36000,12 @@ "returns": "dict[str, object]", "line": 307, "doc": "Draft-only analysis of retained media; inspector review always required.", - "decorator": "app.post('/api/v1/civicinspect/media/analyse')", + "decorator": "app.post('/api/v1/townlight_inspections/media/analyse')", "errors": [] }, { "method": "POST", - "path": "/api/v1/civicinspect/notices/draft", + "path": "/api/v1/townlight_inspections/notices/draft", "router": "app", "prefix_resolved": true, "name": "notice_draft", @@ -36013,12 +36013,12 @@ "returns": "dict[str, object]", "line": 325, "doc": "", - "decorator": "app.post('/api/v1/civicinspect/notices/draft')", + "decorator": "app.post('/api/v1/townlight_inspections/notices/draft')", "errors": [] }, { "method": "POST", - "path": "/api/v1/civicinspect/context/inspection-review", + "path": "/api/v1/townlight_inspections/context/inspection-review", "router": "app", "prefix_resolved": true, "name": "inspection_review_context", @@ -36026,12 +36026,12 @@ "returns": "dict[str, object]", "line": 336, "doc": "", - "decorator": "app.post('/api/v1/civicinspect/context/inspection-review')", + "decorator": "app.post('/api/v1/townlight_inspections/context/inspection-review')", "errors": [] }, { "method": "POST", - "path": "/api/v1/civicinspect/integrations/mock/inspection-context", + "path": "/api/v1/townlight_inspections/integrations/mock/inspection-context", "router": "app", "prefix_resolved": true, "name": "integration_mock_inspection_context", @@ -36039,12 +36039,12 @@ "returns": "dict[str, object]", "line": 365, "doc": "", - "decorator": "app.post('/api/v1/civicinspect/integrations/mock/inspection-context')", + "decorator": "app.post('/api/v1/townlight_inspections/integrations/mock/inspection-context')", "errors": [] }, { "method": "POST", - "path": "/api/v1/civicinspect/export", + "path": "/api/v1/townlight_inspections/export", "router": "app", "prefix_resolved": true, "name": "inspection_export", @@ -36052,12 +36052,12 @@ "returns": "dict[str, object]", "line": 377, "doc": "", - "decorator": "app.post('/api/v1/civicinspect/export')", + "decorator": "app.post('/api/v1/townlight_inspections/export')", "errors": [] }, { "method": "POST", - "path": "/api/v1/civicinspect/staff/reviews", + "path": "/api/v1/townlight_inspections/staff/reviews", "router": "app", "prefix_resolved": true, "name": "create_staff_review", @@ -36065,12 +36065,12 @@ "returns": "dict[str, object]", "line": 387, "doc": "", - "decorator": "app.post('/api/v1/civicinspect/staff/reviews')", + "decorator": "app.post('/api/v1/townlight_inspections/staff/reviews')", "errors": [] }, { "method": "GET", - "path": "/api/v1/civicinspect/staff/reviews", + "path": "/api/v1/townlight_inspections/staff/reviews", "router": "app", "prefix_resolved": true, "name": "list_staff_reviews", @@ -36078,12 +36078,12 @@ "returns": "dict[str, object]", "line": 403, "doc": "", - "decorator": "app.get('/api/v1/civicinspect/staff/reviews')", + "decorator": "app.get('/api/v1/townlight_inspections/staff/reviews')", "errors": [] }, { "method": "PATCH", - "path": "/api/v1/civicinspect/staff/reviews/{review_id}", + "path": "/api/v1/townlight_inspections/staff/reviews/{review_id}", "router": "app", "prefix_resolved": true, "name": "update_staff_review", @@ -36091,7 +36091,7 @@ "returns": "dict[str, object]", "line": 418, "doc": "", - "decorator": "app.patch('/api/v1/civicinspect/staff/reviews/{review_id}')", + "decorator": "app.patch('/api/v1/townlight_inspections/staff/reviews/{review_id}')", "errors": [ "HTTPException(status_code=404, detail={'message': 'Townlight Inspections staff review item was not found.', 'fix': 'List staff reviews and retry with an existing review_id.'})", "HTTPException(status_code=422, detail={'message': 'Staff review update is invalid.', 'fix': str(exc)})" @@ -36099,7 +36099,7 @@ }, { "method": "GET", - "path": "/api/v1/civicinspect/staff/reviews/summary", + "path": "/api/v1/townlight_inspections/staff/reviews/summary", "router": "app", "prefix_resolved": true, "name": "staff_review_summary", @@ -36107,7 +36107,7 @@ "returns": "dict[str, object]", "line": 448, "doc": "", - "decorator": "app.get('/api/v1/civicinspect/staff/reviews/summary')", + "decorator": "app.get('/api/v1/townlight_inspections/staff/reviews/summary')", "errors": [] } ], @@ -36455,14 +36455,14 @@ ], "configuration": [ { - "variable": "CIVICINSPECT_CASE_DB_URL", + "variable": "TOWNLIGHT_INSPECTIONS_CASE_DB_URL", "default": "", "line": 456 } ] }, { - "source": "installed-owned-source/civicinspect/media_analysis.py", + "source": "installed-owned-source/townlight_inspections/media_analysis.py", "sha256": "be51101ee98596bca3055f99136531e3a76e28f2dc584148cf26098d75a94c5a", "routes": [], "models": [ @@ -36522,7 +36522,7 @@ } ], "line": 110, - "doc": "The owned civiccore provider shape (multimodal generate)." + "doc": "The owned townlight_core provider shape (multimodal generate)." }, { "name": "TranscriptionProvider", @@ -36591,28 +36591,28 @@ "configuration": [] }, { - "source": "installed-owned-source/civicinspect/migrations/__init__.py", + "source": "installed-owned-source/townlight_inspections/migrations/__init__.py", "sha256": "e18fc02330135cd7d0dd678a3e17f9e81966a9e187c3ed0ec002439fa8d3bbb1", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicinspect/migrations/env.py", + "source": "installed-owned-source/townlight_inspections/migrations/env.py", "sha256": "9612897b28e02e86d1fa5b9ed48d951b76bb5a87151112d0c1cdbe10a0d343e3", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicinspect/migrations/versions/civicinspect_0001_connected.py", + "source": "installed-owned-source/townlight_inspections/migrations/versions/townlight_inspections_0001_connected.py", "sha256": "0e71ed311993f45634eb42ba22f5c2b2c4a3854639b221857af76f826d1b68de", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicinspect/notice_draft.py", + "source": "installed-owned-source/townlight_inspections/notice_draft.py", "sha256": "ef44c7d6bcf131bc703f6d0282510fe8a49cc6b5988f6252d01353e15551a2f6", "routes": [], "models": [ @@ -36658,7 +36658,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civicinspect/persistence.py", + "source": "installed-owned-source/townlight_inspections/persistence.py", "sha256": "a4c75976a7fe2cc25d2c9a9074eee1a2870eb47bcf6890564d2fb31b113579e3", "routes": [], "models": [ @@ -36815,14 +36815,14 @@ "configuration": [] }, { - "source": "installed-owned-source/civicinspect/public_ui.py", + "source": "installed-owned-source/townlight_inspections/public_ui.py", "sha256": "c14bd5b3d45dc1434edeffb931cd6abb8804bff675989769c8eb89c85a46f965", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicinspect/records_export.py", + "source": "installed-owned-source/townlight_inspections/records_export.py", "sha256": "6adcb9a04cbff7d9d455f41598a0bdb1dfd736aa13f439a61f1e2ed98f8b49bb", "routes": [], "models": [ @@ -36863,7 +36863,7 @@ "configuration": [] }, { - "source": "installed-owned-source/civicinspect/report_draft.py", + "source": "installed-owned-source/townlight_inspections/report_draft.py", "sha256": "40faeb3103ac9ba5ae45fd74136d5cff0a96c5fa73acb96f4a16a34d1cb7ebd5", "routes": [], "models": [ @@ -36914,25 +36914,25 @@ "configuration": [] }, { - "source": "installed-owned-source/civicinspect/transcription.py", + "source": "installed-owned-source/townlight_inspections/transcription.py", "sha256": "0289536c591fa63b6bfa25512444c4a36edc1f160a93d195d3e5aea9e718289f", "routes": [], "models": [], "configuration": [ { - "variable": "CIVICINSPECT_FFMPEG", + "variable": "TOWNLIGHT_INSPECTIONS_FFMPEG", "default": "", "line": 53 }, { - "variable": "CIVICINSPECT_TEXTFLOWKIT_PYTHON", + "variable": "TOWNLIGHT_INSPECTIONS_TEXTFLOWKIT_PYTHON", "default": "", "line": 49 } ] }, { - "source": "installed-owned-source/civicinspect/workflow_models.py", + "source": "installed-owned-source/townlight_inspections/workflow_models.py", "sha256": "7f61e6c7bde5b79202b562d9183c5558d5504fe19eda9ed8fe52541d92152377", "routes": [], "models": [ @@ -37235,14 +37235,14 @@ "configuration": [] }, { - "source": "installed-owned-source/civicinspect/workflow_schema.py", + "source": "installed-owned-source/townlight_inspections/workflow_schema.py", "sha256": "2f8638e3319939ce8b3f7b0b1ef59013f3344b8bcaf9be7d1ad6f3bd4b30ac68", "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/civicinspect/workflow_store.py", + "source": "installed-owned-source/townlight_inspections/workflow_store.py", "sha256": "df4ff48879d5f8fe31d71a410a99ed8c359676ab05a267db65e1468cb4764146", "routes": [], "models": [], @@ -37251,7 +37251,7 @@ ], "bridge": [ { - "source": "installed-owned-source/civicsuite_runtime/inspections_bridge.py", + "source": "installed-owned-source/townlight_runtime/inspections_bridge.py", "sha256": "b7429c3ab988005a198795d6f1dfc3f785c7f96f61410903f8cb0ad38c6f512c", "routes": [ { diff --git a/docs/beta-1/versions.html b/docs/beta-1/versions.html index b34162d..4a621bf 100644 --- a/docs/beta-1/versions.html +++ b/docs/beta-1/versions.html @@ -1,5 +1,6 @@ -Versions -and Candidate Identity | Townlight Beta 1
townlightTownlight Beta 1
-
Townlight Beta 1

Versions -and Candidate -Identity

Staff guide and technical reference

Documentation edition 30 October 2026
Existing component versions retained
Signed suite installer 1.6.0.1
Private beta documentation companion

Candidate identity

- ---- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IdentityValue
Public documentation identityTownlight Beta 1
Installer version1.6.0.1
Native desktop source version1.6.0-1
Candidate MSI SHA25698bcdef11ebdf5c767f620c904ff49f85115fde3b5c23f62703b111e645aaf86
Corresponding-source SHA25684a23e1297e42d17b16cfc9e51b2dd78bc46414c0de8ad7ebd2466c1a409d06b
Current owned software licenseAGPL-3.0-only
Supported acceptance profileWindows x64 fresh install; inspections-preview; separate Station -configuration
-

“Townlight Beta 1” identifies this coordinated beta delivery. It does -not renumber the installer, native binary, Python packages or historical -receipts. Component versions may differ. This documentation is a later -companion to unchanged signed bytes, not a rebuilt installer. Historical -release pages and manuals describe their own versions and are not the -download instructions for this private candidate.

-

Existing component versions

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ProductPackageVersion
Coreciviccore1.3.0.dev1
Recordscivicrecords-ai1.8.0.dev1
Meetingscivicclerk1.0.4
Codeciviccode1.0.8
Zoningciviczone0.2.2
Planningcivicplan0.4.0.dev1
Permittingcivicpermit0.3.0+dev.1
Inspectionscivicinspect0.3.0+dev.1
Stationtownlight-station0.3.0
-

Versioning policy

-

Use Townlight Beta 1 as the coordinated documentation label. Keep -existing package, binary and installer versions. Advance technical -versions only with an actual software change and its packaging decision. -Never rewrite historical receipts to make their versions match a display -label.

- \ No newline at end of file + + +
Townlight +
+

Naming, Access and Notice source candidate · 2 November 2026

+

Prepared documentation. Build, signing, installed acceptance and publication remain pending.

+ + +

Component versions

+

This is the prepared naming, Access and Notice candidate. It has not +yet passed signed Windows installed acceptance or been published.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ProductDistributionCandidate version
Townlight Coretownlight-core1.3.0.dev2
Townlight Recordstownlight-records1.8.0.dev2
Townlight Meetingstownlight-meetings1.0.5
Townlight Codetownlight-code1.0.9
Townlight Accesstownlight-access0.5.0
Townlight Noticetownlight-notice0.3.0
Townlight Zoningtownlight-zoning0.2.3
Townlight Planningtownlight-planning0.4.0.dev2
Townlight Permittingtownlight-permitting0.3.0+dev.2
Townlight Inspectionstownlight-inspections0.3.0+dev.2
Townlight Stationtownlight-station0.3.0
Runtimetownlight-runtime0.2.0
+

Desktop source version: 1.7.0-1. Intended MSI version: +1.7.0.1. Candidate MSI, signature, hashes and installed +acceptance remain pending.

+

Historical releases retain their original package identities, version +numbers and evidence. These candidate names do not rename historical +artifacts.

+

Station remains the existing Beta 1 Python service. Its separate Rust +development line and standalone CivicCast are outside this +migration.

+
Townlight · AGPL-3.0-only · Candidate evidence applies only to its identified artifacts.
\ No newline at end of file diff --git a/docs/catalog-beta.md b/docs/catalog-beta.md index 9e7e0d1..b0440ad 100644 --- a/docs/catalog-beta.md +++ b/docs/catalog-beta.md @@ -1,9 +1,9 @@ # Shared systems catalog candidate -`civiccore.catalog` provides async `domains(session)`, `system_catalog(session, domain=None)`, `connectors_for(session, domain)` and `import_catalog(session, payload, actor_id=...)`. The caller supplies its authenticated SQLAlchemy session and commits or rolls back. Core does not authenticate arbitrary callers or make vendor connections. +`townlight_core.catalog` provides async `domains(session)`, `system_catalog(session, domain=None)`, `connectors_for(session, domain)` and `import_catalog(session, payload, actor_id=...)`. The caller supplies its authenticated SQLAlchemy session and commits or rolls back. Core does not authenticate arbitrary callers or make vendor connections. -Apply Core migrations before using the new candidate. Existing `system_catalog`/`connector_templates` tables retain their data and shape. The new `civiccore_catalog_imports` ledger records complete imports and their SHA-256, actor, count and time. Reusing a version with changed or incomplete contents raises `ValueError`; nothing is silently replaced. Unknown domains return empty results. Connector templates are distinguished from commissioned connections. +Apply Core migrations before using the new candidate. Existing `system_catalog`/`connector_templates` tables retain their data and shape. The new `townlight_core_catalog_imports` ledger records complete imports and their SHA-256, actor, count and time. Reusing a version with changed or incomplete contents raises `ValueError`; nothing is silently replaced. Unknown domains return empty results. Connector templates are distinguished from commissioned connections. Records' catalog routes and loader delegate to this contract, retaining staff/admin authorization. The reference catalog is shared non-secret product metadata; it does not contain municipal documents or serve as an authorization filter for search. Department-bound search remains another C1 requirement. -The current systems listing retains historical versions to preserve the existing Records API behavior. A version-selection UI, city-specific commissioning and general catalog administration remain outstanding. Installed-module inventory and recommendations are a separate contract in `civiccore.platform.inventory`—see [module-inventory.md](module-inventory.md) and [ADR-0008](adr/ADR-0008-beta-module-inventory.md)—and are deliberately not derived from catalog rows: reference data about vendor systems is not evidence that a module is installed. The broader `civiccore.catalog` promise is therefore not yet complete. +The current systems listing retains historical versions to preserve the existing Records API behavior. A version-selection UI, city-specific commissioning and general catalog administration remain outstanding. Installed-module inventory and recommendations are a separate contract in `townlight_core.platform.inventory`—see [module-inventory.md](module-inventory.md) and [ADR-0008](adr/ADR-0008-beta-module-inventory.md)—and are deliberately not derived from catalog rows: reference data about vendor systems is not evidence that a module is installed. The broader `townlight_core.catalog` promise is therefore not yet complete. diff --git a/docs/department-authority.md b/docs/department-authority.md index 537f18b..5f5a65b 100644 --- a/docs/department-authority.md +++ b/docs/department-authority.md @@ -1,6 +1,6 @@ # Department-scoped shared authority -`civiccore.auth.department_scope` is Core's single authorization contract for department-scoped +`townlight_core.auth.department_scope` is Core's single authorization contract for department-scoped material. It answers one question for every consumer: *may this already-authenticated subject reach this department in this deployment scope, and with which roles?* Search results and snippets, export bundles and model context all pass through the same object, so there is no @@ -13,7 +13,7 @@ search service (see [What this does not do](#what-this-does-not-do)). ## The trust boundary The only admissible source of a department claim is the persisted, server-side grant ledger -`civiccore_department_grant_events`, read through `active_department_grants` and keyed by +`townlight_core_department_grant_events`, read through `active_department_grants` and keyed by `(scope_id, subject, department_id)`. A department named in a request body, query string, cookie, HTTP header, environment variable, @@ -22,13 +22,13 @@ parameter that accepts one, and `DepartmentAuthority` cannot be constructed with resolver's private provenance token: ```python -from civiccore.auth import DepartmentAuthority +from townlight_core.auth import DepartmentAuthority DepartmentAuthority(...) # AuthorityProvenanceError: caller-supplied claims are not authority ``` -Credential verification stays where it already lives: `civiccore.auth.bearer`, -`civiccore.auth.trusted_headers` (with `enforce_trusted_proxy_source` proving the proxy really -is the proxy), `civiccore.auth.staff_key` and `civiccore.auth.suite_session`. This module only +Credential verification stays where it already lives: `townlight_core.auth.bearer`, +`townlight_core.auth.trusted_headers` (with `enforce_trusted_proxy_source` proving the proxy really +is the proxy), `townlight_core.auth.staff_key` and `townlight_core.auth.suite_session`. This module only consumes the `AuthenticatedPrincipal` those helpers return, and only for the four identity sources in `TRUSTED_AUTH_METHODS`. @@ -85,11 +85,11 @@ erase the authority history that allowed earlier access. Reusing the shipped helpers rather than adding new engines: - `scope_search_results(authority, records, department_for=...)` — drops results before snippets - or facets are built. Internally uses `civiccore.search.roles_grant_access`. + or facets are built. Internally uses `townlight_core.search.roles_grant_access`. - `authorize_export(authority, department_id=..., purpose=...)` — the gate a static export bundle - must pass before `civiccore.exports` writes anything. + must pass before `townlight_core.exports` writes anything. - `scope_model_context_chunks(authority, chunks, department_for=...)` — returns the exact - `chunks` list `civiccore.llm.context.assemble_context` accepts, so there is one context + `chunks` list `townlight_core.llm.context.assemble_context` accepts, so there is one context builder and one permission gate in front of it. ## What this does not do @@ -110,7 +110,7 @@ Reusing the shipped helpers rather than adding new engines: Contract tests (no database): `tests/test_department_authority.py`. Real PostgreSQL: `work/beta-foundations/core-authority-01/harness.py` starts one disposable owned -cluster, applies the real Core chain to head `civiccore_0008_authority`, and asserts nine checks +cluster, applies the real Core chain to head `townlight_core_0008_authority`, and asserts nine checks covering deny-by-default on real rows, idempotent attributed grants, two-department isolation of results/snippets/exports, immediate revocation with retained history, scope isolation, database append-only/CHECK guards, concurrent sequence assignment, and restart survival. @@ -118,4 +118,4 @@ append-only/CHECK guards, concurrent sequence assignment, and restart survival. ## Compatibility Purely additive: no existing table, function or export changed meaning. The pre-existing public -symbols of `civiccore.auth` remain exported, and the new names are added alongside them. +symbols of `townlight_core.auth` remain exported, and the new names are added alongside them. diff --git a/docs/diagrams/civiccore-extraction-map.svg b/docs/diagrams/civiccore-extraction-map.svg deleted file mode 100644 index a5c10c9..0000000 --- a/docs/diagrams/civiccore-extraction-map.svg +++ /dev/null @@ -1 +0,0 @@ -

Planned extraction targets — placeholder __init__.py only, no implementation

civiccore.auth

civiccore.audit

civiccore.catalog

civiccore.connectors

civiccore.exemptions

civiccore.ingest

civiccore.notifications

civiccore.onboarding

civiccore.scaffold

civiccore.search

civiccore.verification

civiccore v1.2.0 - shipped core surface

civiccore.migrations
runner + idempotent guards
civiccore_0001_baseline_v1
civiccore_0002_llm
civiccore_0003_local_task_queue

civiccore.db.Base
shared SQLAlchemy
declarative base

civiccore.llm
providers + templates +
registry + context +
structured output

\ No newline at end of file diff --git a/docs/diagrams/migration-order.svg b/docs/diagrams/migration-order.svg index b0be701..34ec9d2 100644 --- a/docs/diagrams/migration-order.svg +++ b/docs/diagrams/migration-order.svg @@ -1 +1 @@ -alembic_versionalembic_version_civiccoreciviccore.migrations.runner.upgrade_to_headConsumer app(records-ai env.py)alembic_versionalembic_version_civiccoreciviccore.migrations.runner.upgrade_to_headConsumer app(records-ai env.py)Two separate version tablesprevent revision-name collisionsbetween civiccore and consumers.upgrade_to_head() [subprocess]1civiccore_0001_baseline_v12civiccore_0002_llm (ALTER prompt_templates)3civiccore_0003_local_task_queue4stamp 'civiccore_0003_local_task_queue'5done6run consumer-side alembic chain7stamp '020_phase2_consumer_app_backfill'8 \ No newline at end of file +alembic_versionalembic_version_townlight_coretownlight_core.migrations.runner.upgrade_to_headConsumer app(records-ai env.py)alembic_versionalembic_version_townlight_coretownlight_core.migrations.runner.upgrade_to_headConsumer app(records-ai env.py)Two separate version tablesprevent revision-name collisionsbetween townlight_core and consumers.upgrade_to_head() [subprocess]1townlight_core_0001_baseline_v12townlight_core_0002_llm (ALTER prompt_templates)3townlight_core_0003_local_task_queue4stamp 'townlight_core_0003'5done6run consumer-side alembic chain7stamp '020_phase2_consumer_app_backfill'8 \ No newline at end of file diff --git a/docs/diagrams/provider-abstraction.svg b/docs/diagrams/provider-abstraction.svg index a8fae3a..f536ff3 100644 --- a/docs/diagrams/provider-abstraction.svg +++ b/docs/diagrams/provider-abstraction.svg @@ -1 +1 @@ -

civiccore.llm.providers

implements

implements

implements

implements

Consumer code
(records-ai, future modules)

LLMProvider ABC
generate / embed /
embed_batch / name /
supports_images

PROVIDER_REGISTRY
+ register_provider

build_provider(name, config)

OllamaConfig

OpenAIConfig

AnthropicConfig

OllamaProvider
local /api/generate

OpenAIProvider
cloud, optional extra

AnthropicProvider
cloud, optional extra

Third-party
@register_provider('custom')

\ No newline at end of file +

townlight_core.llm.providers

implements

implements

implements

implements

Consumer code
(records-ai, future modules)

LLMProvider ABC
generate / embed /
embed_batch / name /
supports_images

PROVIDER_REGISTRY
+ register_provider

build_provider(name, config)

OllamaConfig

OpenAIConfig

AnthropicConfig

OllamaProvider
local /api/generate

OpenAIProvider
cloud, optional extra

AnthropicProvider
cloud, optional extra

Third-party
@register_provider('custom')

\ No newline at end of file diff --git a/docs/diagrams/civiccore-extraction-map.mmd b/docs/diagrams/townlight_core-extraction-map.mmd similarity index 100% rename from docs/diagrams/civiccore-extraction-map.mmd rename to docs/diagrams/townlight_core-extraction-map.mmd diff --git a/docs/diagrams/civiccore-extraction-map.png b/docs/diagrams/townlight_core-extraction-map.png similarity index 100% rename from docs/diagrams/civiccore-extraction-map.png rename to docs/diagrams/townlight_core-extraction-map.png diff --git a/docs/diagrams/townlight_core-extraction-map.svg b/docs/diagrams/townlight_core-extraction-map.svg new file mode 100644 index 0000000..a8d89a2 --- /dev/null +++ b/docs/diagrams/townlight_core-extraction-map.svg @@ -0,0 +1 @@ +

Planned extraction targets — placeholder __init__.py only, no implementation

townlight_core.auth

townlight_core.audit

townlight_core.catalog

townlight_core.connectors

townlight_core.exemptions

townlight_core.ingest

townlight_core.notifications

townlight_core.onboarding

townlight_core.scaffold

townlight_core.search

townlight_core.verification

townlight_core v1.2.0 - shipped core surface

townlight_core.migrations
runner + idempotent guards
townlight_core_0001_baseline_v1
townlight_core_0002_llm
townlight_core_0003_local_task_queue

townlight_core.db.Base
shared SQLAlchemy
declarative base

townlight_core.llm
providers + templates +
registry + context +
structured output

\ No newline at end of file diff --git a/docs/github-discussions-seed.md b/docs/github-discussions-seed.md index 58c341f..da6cb7d 100644 --- a/docs/github-discussions-seed.md +++ b/docs/github-discussions-seed.md @@ -1,44 +1,44 @@ -# civiccore — GitHub Discussions seed posts +# townlight_core — GitHub Discussions seed posts Drafts for the initial Discussions categories on https://github.com/townlight/core/discussions. Edit inline before posting. --- -## Announcements: civiccore v0.2.0 released — Phase 2 LLM module +## Announcements: townlight_core v0.2.0 released — Phase 2 LLM module -civiccore v0.2.0 ships the LLM module: provider abstraction, prompt-template engine + 3-step override resolver, model registry service, context utilities, and structured-output helper. The full public API surface is importable from `civiccore.llm`. +townlight_core v0.2.0 ships the LLM module: provider abstraction, prompt-template engine + 3-step override resolver, model registry service, context utilities, and structured-output helper. The full public API surface is importable from `townlight_core.llm`. **What's new since v0.1.0:** -- `civiccore.llm.providers` — `LLMProvider` ABC, decorator registry, built-in Ollama/OpenAI/Anthropic + Pydantic config schemas + `build_provider` factory -- `civiccore.llm.templates` — string.Template engine, 3-step override resolver (DB override → app code override → civiccore default), `OVERRIDE_REGISTRY` -- `civiccore.llm.registry` — `ModelRegistry` ORM, async service, FastAPI admin router -- `civiccore.llm.context` — token-budget assembly, prompt-injection sanitization -- `civiccore.llm.structured` — Pydantic-validated output with retry-on-malformed -- Migration `civiccore_0002_llm` — `prompt_templates` schema evolution +- `townlight_core.llm.providers` — `LLMProvider` ABC, decorator registry, built-in Ollama/OpenAI/Anthropic + Pydantic config schemas + `build_provider` factory +- `townlight_core.llm.templates` — string.Template engine, 3-step override resolver (DB override → app code override → townlight_core default), `OVERRIDE_REGISTRY` +- `townlight_core.llm.registry` — `ModelRegistry` ORM, async service, FastAPI admin router +- `townlight_core.llm.context` — token-budget assembly, prompt-injection sanitization +- `townlight_core.llm.structured` — Pydantic-validated output with retry-on-malformed +- Migration `townlight_core_0002_llm` — `prompt_templates` schema evolution -**Install:** `pip install https://github.com/CivicSuite/civiccore/releases/download/v0.2.0/civiccore-0.2.0-py3-none-any.whl` +**Install:** `pip install https://github.com/Townlight/townlight_core/releases/download/v0.2.0/townlight_core-0.2.0-py3-none-any.whl` **Compatibility:** records-ai v1.4.0 consumes this release. --- -## Q&A: How do I use civiccore in a new module? +## Q&A: How do I use townlight_core in a new module? -Add the wheel pin to your `pyproject.toml` and consume the public API from `civiccore.llm`: +Add the wheel pin to your `pyproject.toml` and consume the public API from `townlight_core.llm`: ```toml dependencies = [ - "civiccore @ https://github.com/CivicSuite/civiccore/releases/download/v0.2.0/civiccore-0.2.0-py3-none-any.whl", + "townlight_core @ https://github.com/Townlight/townlight_core/releases/download/v0.2.0/townlight_core-0.2.0-py3-none-any.whl", ] ``` -Run civiccore migrations as part of your alembic chain (records-ai's `backend/alembic/env.py` shows the pattern: subprocess-invoke `civiccore.migrations.runner.upgrade_to_head()` before your own migrations run). +Run townlight_core migrations as part of your alembic chain (records-ai's `backend/alembic/env.py` shows the pattern: subprocess-invoke `townlight_core.migrations.runner.upgrade_to_head()` before your own migrations run). --- ## Dev / Architecture: Provider registry decorator pattern -`civiccore.llm.providers` uses an in-process decorator registry rather than setuptools entry-points. Trade-offs: +`townlight_core.llm.providers` uses an in-process decorator registry rather than setuptools entry-points. Trade-offs: - **For** decorator: zero startup cost, no packaging metadata complexity, simple to reason about - **Against** decorator: third-party providers require a consumer-side import to register @@ -48,30 +48,30 @@ ADR-0004 §6 has the full rationale. Discussion welcome on whether/when entry-po --- -## Ideas: Future civiccore modules +## Ideas: Future townlight_core modules -What modules belong in civiccore vs. in their own consumer repos? +What modules belong in townlight_core vs. in their own consumer repos? -Currently in civiccore: +Currently in townlight_core: - migrations runner + idempotency guards - shared declarative `Base` - `llm.{providers,templates,registry,context,structured}` -Likely candidates for future civiccore modules: +Likely candidates for future townlight_core modules: - shared notification / channel abstraction (multi-consumer relevance) -- shared connector framework (records-ai already has connectors; civicclerk will too) +- shared connector framework (records-ai already has connectors; townlight_meetings will too) -Likely **not** civiccore concerns: +Likely **not** townlight_core concerns: - domain-specific workflows (FOIA exemptions, meeting agendas) - consumer-specific frontends --- -## Compatibility: civicrecords-ai v1.4.0 pairing +## Compatibility: townlight_records v1.4.0 pairing -records-ai v1.4.0 (released 2026-04-25) is the first downstream release consuming civiccore v0.2.0. Compatibility statement: +records-ai v1.4.0 (released 2026-04-25) is the first downstream release consuming townlight_core v0.2.0. Compatibility statement: -| civiccore | civicrecords-ai | Status | +| townlight_core | townlight_records | Status | |---|---|---| | 0.2.0 | 1.4.0 | Supported | | 0.1.0 | 1.3.0 | Supported (Phase 1) | diff --git a/docs/index.html b/docs/index.html index 8ec3c9c..0d4b7bf 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1 +1 @@ -Townlight Core | Townlight Beta 1
townlightTownlight Beta 1
Townlight Core · Townlight Beta 1

A shared foundation for accountable municipal work.

Core provides the shared contracts, ingestion, identity helpers, task infrastructure and recovery foundation used by Townlight. Staff encounter these capabilities through Setup, Settings and System Health. Business decisions stay with their owning product.

civiccore 1.3.0.dev1AGPL-3.0-onlyPrivate beta · Windows fresh-install scope
For IT administrators and platform maintainers

What the workflow delivers

  1. Complete setup. Choose folders and the full product composition. Create the city profile and the first named administrator. Choose a protected backup location. Defer optional local AI if it is not needed.
  2. Activate the runtime. Run the first-run health check, wait for readiness and open Townlight. In System Health select Finish Records Migration to activate the canonical Python and PostgreSQL services. A running process alone is not a ready database.
  3. Create staff access. Use Settings to create named staff. Sign out and confirm that staff can sign in with their own account. Keep administrator privileges with people responsible for setup; ordinary staff cannot administer users.
  4. Import through the right product. Use the source library of Code, Zoning, Planning or Permitting. Inspect provenance and permissions there. Core ingestion helpers do not bypass the owning product’s source review.

Connected evidence

All products use selected Core contracts. Core does not create unrestricted access between products. Notice and Access are supporting components, rather than additional products in this nine-product beta.

Know the beta boundary

Shared catalog, exemption and module-generator code exists in this private candidate. It is not a centrally hosted federation service. A business product still owns its decisions, identity mapping and permission checks. Historical placeholder ADRs are retained as history, rather than descriptions of the current implementation.

Architecture

Where the evidence goes

Townlight Core architecture and evidence flow

All products use selected Core contracts. Core does not create unrestricted access between products. Notice and Access are supporting components, rather than additional products in this nine-product beta.

Evidence rather than promises

Selected staff workflows passed.

The signed private candidate passed normal first-run and selected synthetic workflows in a fresh Windows Sandbox profile. This is not a claim that every screen, vendor, upgrade or city equipment configuration has been certified.

Read the exact acceptance and limits →

Ready to evaluate?

Begin with the manual and the identified private candidate from the beta coordinator. Configure the chosen test site and have its staff review source applicability and run the existing workflows.

\ No newline at end of file +Townlight Core | Townlight Beta 1
townlightTownlight Beta 1
Townlight Core · Townlight Beta 1

A shared foundation for accountable municipal work.

Core provides the shared contracts, ingestion, identity helpers, task infrastructure and recovery foundation used by Townlight. Staff encounter these capabilities through Setup, Settings and System Health. Business decisions stay with their owning product.

townlight-core 1.3.0.dev2AGPL-3.0-onlyPrivate beta · Windows fresh-install scope
For IT administrators and platform maintainers

What the workflow delivers

  1. Complete setup. Choose folders and the full product composition. Create the city profile and the first named administrator. Choose a protected backup location. Defer optional local AI if it is not needed.
  2. Activate the runtime. Run the first-run health check, wait for readiness and open Townlight. In System Health select Finish Records Migration to activate the canonical Python and PostgreSQL services. A running process alone is not a ready database.
  3. Create staff access. Use Settings to create named staff. Sign out and confirm that staff can sign in with their own account. Keep administrator privileges with people responsible for setup; ordinary staff cannot administer users.
  4. Import through the right product. Use the source library of Code, Zoning, Planning or Permitting. Inspect provenance and permissions there. Core ingestion helpers do not bypass the owning product’s source review.

Connected evidence

All products use selected Core contracts. Core does not create unrestricted access between products. Access and Notice provide the bounded staff workflows described in their current manuals; installed acceptance remains pending.

Know the beta boundary

Shared catalog, exemption and module-generator code exists in this private candidate. It is not a centrally hosted federation service. A business product still owns its decisions, identity mapping and permission checks. Historical placeholder ADRs are retained as history, rather than descriptions of the current implementation.

Architecture

Where the evidence goes

Townlight Core architecture and evidence flow

All products use selected Core contracts. Core does not create unrestricted access between products. Access and Notice provide the bounded staff workflows described in their current manuals; installed acceptance remains pending.

Evidence rather than promises

Candidate installed acceptance remains pending.

Earlier releases have their own first-run and synthetic Windows Sandbox evidence. This changed source candidate requires a new signed installer and installed acceptance. This is not a claim that every screen, vendor, upgrade or city equipment configuration has been certified.

Read the exact acceptance and limits →

Ready to evaluate?

Begin with the current manual; obtain this candidate only after its exact installer and acceptance are identified. Configure the chosen test site and have its staff review source applicability and run the existing workflows.

\ No newline at end of file diff --git a/docs/job-artifacts.md b/docs/job-artifacts.md index 365c72e..cb2b60b 100644 --- a/docs/job-artifacts.md +++ b/docs/job-artifacts.md @@ -1,6 +1,6 @@ # Claim-bound ingest and media artifacts -`civiccore.tasks.artifacts` is the shared answer to one question: *may this derived file +`townlight_core.tasks.artifacts` is the shared answer to one question: *may this derived file become durable, and does the job that produced it still own the work?* It is the executable part of the `C1.jobs` adapter gap ("consumers must enforce claim-bound artifact receipts"), built on the queue contract in [job-leases.md](job-leases.md). It is **not** a media @@ -63,7 +63,7 @@ symlink-privilege case) cover identity binding, every refusal reason, traversal path refusal, idempotency, name conflict, staging cleanup and tamper detection. Real PostgreSQL acceptance (`work/beta-foundations/core-job-adapters-01/harness.py`, 9/9 -checks, 0 skips, head `civiccore_0009_job_artifacts`): a claimed synthetic job publishes +checks, 0 skips, head `townlight_core_0009_job_artifacts`): a claimed synthetic job publishes three derived artifacts (chunked text, chunks JSON, and metadata measured from a stdlib-generated 0.25 s WAV), bound to the job identity, claim token, recorder and source hashes. Expired-lease, superseded-token, cancelled and unattributed acceptances are refused diff --git a/docs/job-leases.md b/docs/job-leases.md index f67233c..e2c008c 100644 --- a/docs/job-leases.md +++ b/docs/job-leases.md @@ -2,7 +2,7 @@ The existing Core PostgreSQL queue is extended rather than replaced. The lease/claim pattern is adapted from TownReporter's `src/lib/news/jobs.ts` at the inspected donor baseline `ab9984bce2e5806c021ebb7435642b2c0fa98b08`. It does not transplant the newsroom application or model/provider routing. -Apply Core migrations through `civiccore_0005_job_leases`. Enqueue serializes idempotency admission and rejects a reused key with different module/type/payload/audit subject. Claims have a random token and deadline. Expired work is reclaimed with a new token, with a bounded failed-attempt count. Completion, failure and heartbeat require current unexpired ownership. Cancellation records its actor and fences further results. +Apply Core migrations through `townlight_core_0005_job_leases`. Enqueue serializes idempotency admission and rejects a reused key with different module/type/payload/audit subject. Claims have a random token and deadline. Expired work is reclaimed with a new token, with a bounded failed-attempt count. Completion, failure and heartbeat require current unexpired ownership. Cancellation records its actor and fences further results. Existing same-session `claim_next_local_task` then complete/fail calls retain compatibility through the token captured in that session. A different session must explicitly carry the claim token. A caller cannot acquire authority by simply reloading a task row. Applications must authorize queue operations before invoking the library, including module/department scope for cancellation. @@ -10,6 +10,6 @@ The CLI uses `run_leased_task`: it commits the claim before execution, renews it A fenced job result is not an exactly-once promise for external side effects. Handlers must use an idempotent artifact/operation receipt and verify their current claim before authoritative writes. Native child termination and media/provider containment are the handler's responsibility; this queue does not falsely certify external cleanup. Consumer transcription/extraction adapters and their acceptance remain work. -Claim-bound **artifact acceptance** now exists as `civiccore.tasks.artifacts` (migration `civiccore_0009_job_artifacts`): a derived file is published only inside a configured store root, only for the job identity and live claim token carried by the claimed envelope, with a computed and re-verified sha256 and an attributed append-only receipt. `civiccore.platform.task_queue.require_active_claim` is the read-only fence it calls before the authoritative write. See [job-artifacts.md](job-artifacts.md) and [ADR-0010](adr/ADR-0010-claim-bound-artifacts.md). It adds no transcription, OCR, transcoding, embedding or provider call; consumer adapters, large-original storage and retention/redaction remain work. +Claim-bound **artifact acceptance** now exists as `townlight_core.tasks.artifacts` (migration `townlight_core_0009_job_artifacts`): a derived file is published only inside a configured store root, only for the job identity and live claim token carried by the claimed envelope, with a computed and re-verified sha256 and an attributed append-only receipt. `townlight_core.platform.task_queue.require_active_claim` is the read-only fence it calls before the authoritative write. See [job-artifacts.md](job-artifacts.md) and [ADR-0010](adr/ADR-0010-claim-bound-artifacts.md). It adds no transcription, OCR, transcoding, embedding or provider call; consumer adapters, large-original storage and retention/redaction remain work. Verified on actual isolated PostgreSQL: concurrent duplicate submission, changed-payload rejection, expired-claim recovery, stale success/failure rejection, heartbeat preservation beyond one lease, attributed cancellation, bounded timeout and same-session compatibility. No installed job worker was changed. diff --git a/docs/module-inventory.md b/docs/module-inventory.md index 1c4232e..0b73ba4 100644 --- a/docs/module-inventory.md +++ b/docs/module-inventory.md @@ -4,7 +4,7 @@ Status: private beta candidate (Core 1.3.0.dev1 source). Not released, not insta packaged. See [ADR-0008](adr/ADR-0008-beta-module-inventory.md) for the decision record and `outputs/beta-plan/core-module-inventory-01/` for executed evidence. -`civiccore.platform.inventory` records what one deployment scope *declares* it has installed and +`townlight_core.platform.inventory` records what one deployment scope *declares* it has installed and enabled, and derives deterministic suggestions from those declarations. It is the installed-module half of CORE-08 / `C1.catalog.modules`. @@ -14,13 +14,13 @@ half of CORE-08 / `C1.catalog.modules`. endpoint. There is no network call anywhere in this module. * **Not an installer.** No package is downloaded, installed, enabled, disabled, repaired or uninstalled here, and no runtime action is triggered. -* **Not the municipal systems catalog.** `civiccore.catalog` describes *vendor systems* (domains, +* **Not the municipal systems catalog.** `townlight_core.catalog` describes *vendor systems* (domains, vendors, protocol templates). This module describes *Townlight module packages*. A catalog row never implies a module is installed, and an inventory row never implies a vendor is connected. The two do not share tables or rows. * **Not a second resolver.** Admission, minimum Core version, dependency minimums, transitive blocking and required cycles all come from - `civiccore.platform.modules.build_module_registry`. This module only stores declarations and + `townlight_core.platform.modules.build_module_registry`. This module only stores declarations and asks that resolver what they admit. * **Not proof.** A recommendation is advice over declared metadata. It does not prove a package is present, running, healthy or licensed. @@ -28,7 +28,7 @@ half of CORE-08 / `C1.catalog.modules`. ## Public surface ```python -from civiccore.platform import ( +from townlight_core.platform import ( ModuleInventory, ModuleInventoryEntry, ModuleRecommendation, record_inventory, current_inventory, inventory_revision, inventory_history, require_installed, module_recommendations, @@ -36,8 +36,8 @@ from civiccore.platform import ( ) ``` -Import these from `civiccore.platform` (as with `civiccore.catalog` and -`civiccore.exemptions.history`), not from the package root. +Import these from `townlight_core.platform` (as with `townlight_core.catalog` and +`townlight_core.exemptions.history`), not from the package root. ### Declaring an inventory @@ -47,7 +47,7 @@ outcome = await record_inventory( ModuleInventory( scope_id="city-a", # caller-supplied deployment scope revision=1, # next revision; append-only - civiccore_version="1.3.0.dev1", + townlight_core_version="1.3.0.dev1", entries=[ModuleInventoryEntry(module_id="records", version="1.8.0", enabled=True, manifest=manifest)], ), @@ -76,7 +76,7 @@ declared and compatible"), and plain `operator_action` copy. | `install` | The package was handed in as available, is not declared installed, and every required dependency would be satisfied. | | `enable` | Declared installed but switched off, and turning it on would be admitted. | | `resolve-dependency` | A required module dependency is missing, below its minimum version, blocked, or cyclically required. | -| `upgrade-core` | The module needs a newer CivicCore than this deployment declares. | +| `upgrade-core` | The module needs a newer Townlight Core than this deployment declares. | | `not-supported` | The module does not support the declared install profile (e.g. `windows_local`). | A module that is installed, enabled and admitted produces **no** recommendation. Silence is not @@ -106,12 +106,12 @@ history cannot be rewritten even outside this library. ## Persistence -Migration `civiccore_0007_module_inventory` (down_revision `civiccore_0006_rule_history`) adds, +Migration `townlight_core_0007_module_inventory` (down_revision `townlight_core_0006_rule_history`) adds, additively: -* `civiccore_module_inventory` — one row per `(scope_id, revision)`: profile, declared - CivicCore version, content SHA-256, recorder, time. -* `civiccore_module_inventory_entries` — one row per declared module: version, enabled flag and +* `townlight_core_module_inventory` — one row per `(scope_id, revision)`: profile, declared + Townlight Core version, content SHA-256, recorder, time. +* `townlight_core_module_inventory_entries` — one row per declared module: version, enabled flag and the full manifest as `jsonb`, keyed `(scope_id, revision, module_id)` with a composite foreign key to the header. diff --git a/docs/ops/cleanroom-harness.md b/docs/ops/cleanroom-harness.md index e0e721b..01e9b3e 100644 --- a/docs/ops/cleanroom-harness.md +++ b/docs/ops/cleanroom-harness.md @@ -1,4 +1,4 @@ - + # Townlight Core Cleanroom Harness @@ -22,7 +22,7 @@ then runs an offline smoke with Docker networking disabled. From a fresh clone: ```bash -bash scripts/run-civiccore-cleanroom.sh +bash scripts/run-townlight_core-cleanroom.sh ``` The host must have Docker and a usable Python interpreter on `PATH`. The @@ -33,13 +33,13 @@ comparison. The script defaults to two runs so auditors can compare stable manifests: ```bash -CLEANROOM_RUN_COUNT=2 bash scripts/run-civiccore-cleanroom.sh +CLEANROOM_RUN_COUNT=2 bash scripts/run-townlight_core-cleanroom.sh ``` Evidence is written to: ```text -docs/evidence/co6-civiccore-cleanroom-/ +docs/evidence/co6-townlight_core-cleanroom-/ ``` ## Pinned Inputs @@ -74,9 +74,9 @@ runs pass when those stable manifest hashes match. Network is allowed only for provisioning and verification endpoints: -- `https://github.com/CivicSuite/civiccore.git` -- `https://github.com/CivicSuite/civiccore/releases/download/v0.22.1/*` -- `https://api.github.com/repos/CivicSuite/civiccore/*` +- `https://github.com/Townlight/townlight_core.git` +- `https://github.com/Townlight/townlight_core/releases/download/v0.22.1/*` +- `https://api.github.com/repos/Townlight/townlight_core/*` - `https://github.com/sigstore/cosign/releases/download/v3.0.6/cosign-linux-amd64` - `https://pypi.org/*` - `https://files.pythonhosted.org/*` diff --git a/docs/ops/co-4-cross-module-retrofit-report.md b/docs/ops/co-4-cross-module-retrofit-report.md index 6f512f9..4bfc71e 100644 --- a/docs/ops/co-4-cross-module-retrofit-report.md +++ b/docs/ops/co-4-cross-module-retrofit-report.md @@ -28,9 +28,9 @@ in that product repository. | Repository | PR | Base | Merge commit | Scope | | --- | --- | --- | --- | --- | -| `townlight/sunshine` | [#67](https://github.com/CivicSuite/civicrecords-ai/pull/67) | `master` | `3b1f38c3d88050c1cf299cf8254eedf65f58a52a` | Ledgered `v1.4.10`, updated current Townlight Core dependency/docs to `v0.22.1`, added browser QA evidence, and copied ledger evidence into the backend image so CI verifies it. | -| `townlight/meetings` | [#142](https://github.com/CivicSuite/civicclerk/pull/142) | `main` | `b068233e87608931ff9165fad435a10fbade24a8` | Ledgered `v0.1.20`, updated current Townlight Core dependency/docs/workflows/rehearsal health checks to `v0.22.1`, and refreshed browser QA evidence. | -| `townlight/ordinances` | [#47](https://github.com/CivicSuite/civiccode/pull/47) | `main` | `4450931de51c1173adcff91d47e5373382670d89` | Ledgered `v0.1.17` and `v0.1.18`, updated current Townlight Core dependency/docs/workflows to `v0.22.1`, and added browser QA evidence. | +| `townlight/sunshine` | [#67](https://github.com/Townlight/townlight_records/pull/67) | `master` | `3b1f38c3d88050c1cf299cf8254eedf65f58a52a` | Ledgered `v1.4.10`, updated current Townlight Core dependency/docs to `v0.22.1`, added browser QA evidence, and copied ledger evidence into the backend image so CI verifies it. | +| `townlight/meetings` | [#142](https://github.com/Townlight/townlight_meetings/pull/142) | `main` | `b068233e87608931ff9165fad435a10fbade24a8` | Ledgered `v0.1.20`, updated current Townlight Core dependency/docs/workflows/rehearsal health checks to `v0.22.1`, and refreshed browser QA evidence. | +| `townlight/ordinances` | [#47](https://github.com/Townlight/townlight_code/pull/47) | `main` | `4450931de51c1173adcff91d47e5373382670d89` | Ledgered `v0.1.17` and `v0.1.18`, updated current Townlight Core dependency/docs/workflows to `v0.22.1`, and added browser QA evidence. | ## Evidence diff --git a/docs/ops/co-7-freeze-readiness.md b/docs/ops/co-7-freeze-readiness.md index c8119df..8ba9878 100644 --- a/docs/ops/co-7-freeze-readiness.md +++ b/docs/ops/co-7-freeze-readiness.md @@ -1,4 +1,4 @@ - + # CO-7 Townlight Core Freeze Readiness @@ -27,7 +27,7 @@ CO-7 reconciles the shipped Townlight Core surface against Townlight unified spe section 6 and the Townlight Core README. The shipped freeze candidate includes: - migrations and shared SQLAlchemy `Base` -- `civiccore.llm` provider, template, registry, context, and structured-output helpers +- `townlight_core.llm` provider, template, registry, context, and structured-output helpers - audit, persisted audit-log verification, provenance, manifest, and export-bundle primitives - city profile models and onboarding profile interview helpers - auth helpers for bearer roles and trusted-header proxy boundaries @@ -45,9 +45,9 @@ Townlight PR so those shipped surfaces no longer appear as silent drift. The three README-listed placeholder namespaces now have Townlight Core ADRs: -- `docs/adr/ADR-0001-defer-civiccore-catalog.md` -- `docs/adr/ADR-0002-defer-civiccore-exemptions.md` -- `docs/adr/ADR-0003-defer-civiccore-scaffold.md` +- `docs/adr/ADR-0001-defer-townlight_core-catalog.md` +- `docs/adr/ADR-0002-defer-townlight_core-exemptions.md` +- `docs/adr/ADR-0003-defer-townlight_core-scaffold.md` Each ADR names the deferral rationale, target phase, and downstream consumption rule: no module depends on the placeholder namespace until it ships in a @@ -58,12 +58,12 @@ versioned Townlight Core release artifact. Local command: ```powershell -git -C grep -n -E 'civiccore\.(catalog|exemptions|scaffold)|from civiccore import (catalog|exemptions|scaffold)|import civiccore\.(catalog|exemptions|scaffold)' -- . +git -C grep -n -E 'townlight_core\.(catalog|exemptions|scaffold)|from townlight_core import (catalog|exemptions|scaffold)|import townlight_core\.(catalog|exemptions|scaffold)' -- . ``` Result: no production-code reliance found across the compatibility-matrix module set. Townlight Meetings and Townlight Code contain test-only references to -`civiccore.exemptions` and `civiccore.catalog` inside guard tests that assert +`townlight_core.exemptions` and `townlight_core.catalog` inside guard tests that assert module schemas do not foreign-key into unreleased Townlight Core placeholder targets. A production-code-only sweep excluding tests returned clean for every module in @@ -74,7 +74,7 @@ the compatibility matrix. Local checks completed on 2026-05-05 before any freeze tag publication: - `python -m pytest tests/test_placeholder_adrs.py -q`: 3 passed. -- `python -m ruff check tests/test_placeholder_adrs.py civiccore/catalog/__init__.py civiccore/exemptions/__init__.py civiccore/scaffold/__init__.py`: passed. +- `python -m ruff check tests/test_placeholder_adrs.py townlight_core/catalog/__init__.py townlight_core/exemptions/__init__.py townlight_core/scaffold/__init__.py`: passed. - `python -m pytest --collect-only -q`: 260 tests collected. - `bash scripts/verify-release.sh`: passed, including 260 tests, Ruff, docs checks, build artifacts, and fresh virtualenv import/version smoke. @@ -88,9 +88,9 @@ Local checks completed on 2026-05-05 before any freeze tag publication: `bash scripts/verify-docs.sh` passed. - Companion Townlight suite-state verification: `python scripts/verify-suite-state.py --remote-only` passed for all 26 repos - and confirmed `civiccore 0.22.1`. + and confirmed `townlight_core 0.22.1`. - Companion Townlight browser QA: - `docs/browser-qa-co7-civiccore-freeze-lockstep-summary.md` passed with + `docs/browser-qa-co7-townlight_core-freeze-lockstep-summary.md` passed with desktop 1280x900 and mobile 390x844 screenshots, zero browser console messages, zero page errors, no horizontal overflow, keyboard focus proof, contrast proof, and copy review. diff --git a/docs/ops/co-9-audit-full-release-gate.md b/docs/ops/co-9-audit-full-release-gate.md index b154d3b..d8456ba 100644 --- a/docs/ops/co-9-audit-full-release-gate.md +++ b/docs/ops/co-9-audit-full-release-gate.md @@ -2,14 +2,14 @@ Date: 2026-05-05. -Repo: `CivicSuite/civiccore`. +Repo: `Townlight/townlight_core`. Audit mode: release-gate. Auditor: Codex, no subagents. Post-publication addendum: the `v1.0` GitHub release is now published at -[`civiccore v1.0`](https://github.com/CivicSuite/civiccore/releases/tag/v1.0). +[`townlight_core v1.0`](https://github.com/Townlight/townlight_core/releases/tag/v1.0). The live tag target is `a699814c6b97ff3ef13ecd9f04b5f4a2d76f7438`, release workflow run `25408733597` completed successfully, and the release page carries the wheel, sdist, `SHA256SUMS.txt`, `release-attestation.json`, and @@ -19,7 +19,7 @@ former PR/main-CI and release-publication gaps. ## 1. Executive Audit -Scope: CivicCore local release-prep checkout for CO-9 v1.0, plus live GitHub +Scope: Townlight Core local release-prep checkout for CO-9 v1.0, plus live GitHub remote state. Post-publication addendum scope includes the merged `main` source tree and live `v1.0` GitHub release. @@ -29,7 +29,7 @@ Local-vs-live parity: checked before release-prep edits. Local `main`, merged `main` commit and `v1.0` target `a699814c6b97ff3ef13ecd9f04b5f4a2d76f7438`. -Overall verdict: PASS for CivicCore `v1.0` publication posture. No open +Overall verdict: PASS for Townlight Core `v1.0` publication posture. No open Blocker or Critical findings remain. PR CI, main CI, release workflow, publication, and post-publication release-asset checks are now complete. @@ -57,24 +57,24 @@ paths, and now publishes notes with evidence-pack and provenance commands. | Lane | Status | Evidence summary | Blocker | |---|---|---|---| -| Remote parity | Checked | `origin` is `https://github.com/CivicSuite/civiccore.git`; pre-edit local main matched `origin/main` at `a1c52c9`. | None | +| Remote parity | Checked | `origin` is `https://github.com/Townlight/townlight_core.git`; pre-edit local main matched `origin/main` at `a1c52c9`. | None | | Local-vs-live commit truth | Checked | Post-publication local `main`, `origin/main`, and `v1.0^{}` match `a699814c6b97ff3ef13ecd9f04b5f4a2d76f7438`. | None | | CI/workflow presence | Checked | Four workflows present; workflow YAML parse test passes. | None | -| Windows install path | Checked | `bash scripts/verify-release.sh` built and installed `civiccore-1.0.0` in a fresh venv. | None | +| Windows install path | Checked | `bash scripts/verify-release.sh` built and installed `townlight_core-1.0.0` in a fresh venv. | None | | Linux or Unix install path | Checked | Git Bash path passed locally; GitHub Linux CI and release workflow completed successfully for `v1.0`. | None | | Platform parity verdict | Checked | Local Windows verification and GitHub Linux CI/release verification are green for `v1.0`. | None | -| First boot | Checked | Library import smoke checks `civiccore.__version__ == "1.0.0"` and public helpers. | None | +| First boot | Checked | Library import smoke checks `townlight_core.__version__ == "1.0.0"` and public helpers. | None | | Required post-install steps | Checked | Docs describe wheel install plus SHA256/Sigstore verification; no app bootstrap required. | None | | Migrations | Checked | Baseline idempotency tests and migration tests collected and passed in release verifier. | None | -| Seed/bootstrap requirements | Not applicable | CivicCore is a library with no seed data path. | None | +| Seed/bootstrap requirements | Not applicable | Townlight Core is a library with no seed data path. | None | | Runtime dependency and model requirements | Checked | LLM provider tests are mocked; no live model pull at import. | None | -| First-boot dependency truth | Checked | README/manual identify CivicCore as a library, not an end-user app. | None | +| First-boot dependency truth | Checked | README/manual identify Townlight Core as a library, not an end-user app. | None | | Secrets and credential handling | Checked | Remote URL carries no embedded token; security config validation tests pass. | None | | Auth and session handling | Checked | Bearer/trusted-header auth tests passed. | None | | Authorization and role boundaries | Checked | Role parsing, trusted proxy source checks, and optional auth helpers are tested. | None | | Response-schema sensitive-data exposure | Checked | Public API tests and security tests cover exposed helper surface; no app responses ship. | None | | Audit and compliance logging | Checked | Audit chain and persisted audit hash tests pass. | None | -| External and admin surfaces | Checked | CivicCore exposes library/admin router primitives only; no standalone public service. | None | +| External and admin surfaces | Checked | Townlight Core exposes library/admin router primitives only; no standalone public service. | None | | Connector implementation completeness | Checked | Docs now distinguish shipped local/import/sync primitives from unshipped vendor adapters. | None | | Connector docs truth | Checked | README/manual/docs index scoped vendor-specific adapters as unshipped. | None | | Background jobs and schedulers | Checked | Scheduling helpers ship; scheduler runtime/task queue remain module-owned. | None | @@ -85,7 +85,7 @@ paths, and now publishes notes with evidence-pack and provenance commands. | Partial states | Not applicable | Static local HTML renders all sections. | None | | Accessibility cues | Checked | Keyboard focus sample and contrast ratios recorded in browser QA. | None | | Docs truthfulness | Checked | Version/install copy moved to v1.0; ingest docs drift fixed. | None | -| Version consistency | Checked | `pyproject.toml`, `civiccore.__version__`, smoke test, docs, and SBOM align on `1.0.0`/`v1.0`. | None | +| Version consistency | Checked | `pyproject.toml`, `townlight_core.__version__`, smoke test, docs, and SBOM align on `1.0.0`/`v1.0`. | None | | Release artifact consistency | Checked | Workflow expected assets are wheel, sdist, SHA256SUMS, attestation JSON, and bundle. | None | | Test realism | Checked | 273 tests collected in the post-publication quality pause; release verifier runs full test suite, ruff, build, fresh install. | None | | Runtime, build, and test verification | Checked | `VERIFY-RELEASE: PASSED`. | None | @@ -96,11 +96,11 @@ paths, and now publishes notes with evidence-pack and provenance commands. | Claim | Source | Verdict | Evidence | |---|---|---|---| -| CivicCore is a shared platform library, not an end-user app. | README, manual, docs index | True | No app boot path; import smoke only. | +| Townlight Core is a shared platform library, not an end-user app. | README, manual, docs index | True | No app boot path; import smoke only. | | v1.0 is the downstream productization release. | README, docs index, closeout | True | Package version `1.0.0`; install URL uses `v1.0`. | | v0.22.1 remains the first attested baseline. | Historical policy, ledger | True | Baseline tag and ledger unchanged. | -| Freeze tag is `civiccore-m1-freeze`. | CO-7 evidence, release list | True | Live release and live Tier 1 check verify attestation assets. | -| Final v1.0 SBOM is present. | CO-8 evidence pack | True | `sbom-v1.0-pip-inspect.json`; test verifies `civiccore` `1.0.0`. | +| Freeze tag is `townlight_core-m1-freeze`. | CO-7 evidence, release list | True | Live release and live Tier 1 check verify attestation assets. | +| Final v1.0 SBOM is present. | CO-8 evidence pack | True | `sbom-v1.0-pip-inspect.json`; test verifies `townlight_core` `1.0.0`. | | Release workflow publishes exact asset paths. | `.github/workflows/release.yml` | True | Workflow test asserts no wildcard `release-assets/*` upload. | | Release notes include auditor commands. | `.github/workflows/release.yml` | True | Test asserts evidence-pack and provenance command text. | | Docs landing page install path is current. | `docs/index.html` | True | Browser QA copy checks passed. | @@ -132,7 +132,7 @@ Can defer if consciously accepted: ## 5. Next-Sprint Watchlist -Architecture: Keep downstream modules pinned to `civiccore-m1-freeze` until +Architecture: Keep downstream modules pinned to `townlight_core-m1-freeze` until their compatibility matrices move deliberately. Security and compliance debt: Preserve release bundles and trust-root context @@ -141,13 +141,13 @@ for offline procurement review. UX debt: Future docs pages should avoid long status paragraphs if the static landing page becomes more app-like. -Docs debt: CivicClerk must reference the freeze tag and CO-8/CO-9 evidence pack +Docs debt: Townlight Meetings must reference the freeze tag and CO-8/CO-9 evidence pack when its productization lane starts. Install and bootstrap debt: Downstream modules need cleanroom harnesses pinned -to the freeze tag, not moving CivicCore main. +to the freeze tag, not moving Townlight Core main. -Test debt: Add downstream compatibility tests as soon as CivicClerk begins. +Test debt: Add downstream compatibility tests as soon as Townlight Meetings begins. Operational and release debt: Keep post-publication release verification linked from the release record for every future release. @@ -163,7 +163,7 @@ separates preflight, build/attest/verify, and publication jobs. Findings: none open. Verification gaps: None for the shipped `v1.0` source tree; downstream -module compatibility remains tracked outside this CivicCore audit. +module compatibility remains tracked outside this Townlight Core audit. ## 7. Security And Authorization Deep Dive @@ -175,7 +175,7 @@ commit, and target tree. The remote URL contains no credential-bearing token. Findings: none open. -Verification gaps: None for CivicCore `v1.0`; the Sigstore bundle is published +Verification gaps: None for Townlight Core `v1.0`; the Sigstore bundle is published with the GitHub release. ## 8. UI/UX Deep Dive @@ -196,11 +196,11 @@ Verdict: PASS. Strengths: The docs now distinguish the downstream productization release (`v1.0`) from the first attested baseline (`v0.22.1`) and the freeze-line tag -(`civiccore-m1-freeze`). This avoids overstating historical releases. +(`townlight_core-m1-freeze`). This avoids overstating historical releases. Findings: none open. -Verification gaps: None for CivicCore `v1.0`; CivicClerk gating moved to its +Verification gaps: None for Townlight Core `v1.0`; Townlight Meetings gating moved to its own productization lane after the release went live. ## 10. Documentation Deep Dive @@ -209,7 +209,7 @@ Verdict: PASS. Strengths: README, text README, user manual, docs index, changelog, evidence pack, closeout report, release workflow notes, and Tier 1 ledger docs were -updated together. The docs drift that described `civiccore.ingest` as entirely +updated together. The docs drift that described `townlight_core.ingest` as entirely unshipped was corrected. Findings: none open. @@ -222,8 +222,8 @@ verification commands. Verdict: PASS. -Strengths: CivicCore has no seed/bootstrap path. The install path is a GitHub -release wheel; verifier built `civiccore-1.0.0`, installed it into a fresh venv, +Strengths: Townlight Core has no seed/bootstrap path. The install path is a GitHub +release wheel; verifier built `townlight_core-1.0.0`, installed it into a fresh venv, and imported public helpers. Findings: none open. @@ -235,7 +235,7 @@ available through the GitHub release URL. Verdict: PASS. -Strengths: `pyproject.toml`, `civiccore/__init__.py`, smoke tests, README, +Strengths: `pyproject.toml`, `townlight_core/__init__.py`, smoke tests, README, README.txt, manuals, docs landing page, changelog, and final SBOM agree on package version `1.0.0` and release tag `v1.0`. Historical `v0.22.1` references remain as baseline history, not current install copy. @@ -256,7 +256,7 @@ workflow note content, smoke version, and live ledger parity rules. Findings: none open. Verification gaps: Mutation/adversarial downstream compatibility remains for -CivicClerk and CivicCode lanes, not CO-9 CivicCore release prep. +Townlight Meetings and Townlight Code lanes, not CO-9 Townlight Core release prep. ## 14. Runtime QA Deep Dive @@ -266,18 +266,18 @@ Verdict: PASS for local runtime QA. - `python -m pytest tests/test_tier1_retrofit_ledger.py tests/test_co8_procurement_evidence_pack.py tests/test_github_workflows.py tests/test_smoke.py -q` -> 16 passed, 1 warning. - `python -m ruff check ...` -> all checks passed. -- `python scripts/check-tier1-ledger.py --live` -> 25 historical tags ledgered; post-baseline `civiccore-m1-freeze` attestation assets verified live. +- `python scripts/check-tier1-ledger.py --live` -> 25 historical tags ledgered; post-baseline `townlight_core-m1-freeze` attestation assets verified live. - `python -m pytest --collect-only -q` -> 273 tests collected. - Browser QA summary -> PASS. - `bash scripts/verify-release.sh` -> full test suite passed, ruff passed, version lockstep `1.0.0`, build passed, fresh venv install/import smoke passed, `VERIFY-RELEASE: PASSED`. [DEV-REPORTED] -- CO-7 downstream temporary harnesses: CivicClerk 553 passed; CivicCode 162 passed. +- CO-7 downstream temporary harnesses: Townlight Meetings 553 passed; Townlight Code 162 passed. Findings: none open. -Verification gaps: None for CivicCore `v1.0` release publication; downstream +Verification gaps: None for Townlight Core `v1.0` release publication; downstream module compatibility remains separate. ## 15. Cross-Cutting Synthesis @@ -294,9 +294,9 @@ published `v1.0` release and its attestation assets. | Gap | Why it remains | Exact closing check | Blocks sign-off? | |---|---|---|---| -| Downstream module compatibility | CivicCore `v1.0` is published, but each module still owns its compatibility matrix and pin movement. | Run each downstream module's release gate after changing its CivicCore pin. | Limits downstream sign-off only. | -| Offline procurement reproduction | Local audit checked live metadata and local release verification; full offline cosign/SHA reproduction depends on the reviewer's environment. | Download release assets in a clean environment and run the release-note verification commands. | Confidence limit, not a CivicCore source blocker. | +| Downstream module compatibility | Townlight Core `v1.0` is published, but each module still owns its compatibility matrix and pin movement. | Run each downstream module's release gate after changing its Townlight Core pin. | Limits downstream sign-off only. | +| Offline procurement reproduction | Local audit checked live metadata and local release verification; full offline cosign/SHA reproduction depends on the reviewer's environment. | Download release assets in a clean environment and run the release-note verification commands. | Confidence limit, not a Townlight Core source blocker. | Sign-off limit: this report began as a release-prep audit and now includes a -post-publication addendum. It signs off CivicCore `v1.0` publication posture, +post-publication addendum. It signs off Townlight Core `v1.0` publication posture, while downstream module compatibility remains outside this report. diff --git a/docs/ops/co-9-civiccore-v1-closeout.md b/docs/ops/co-9-townlight_core-v1-closeout.md similarity index 59% rename from docs/ops/co-9-civiccore-v1-closeout.md rename to docs/ops/co-9-townlight_core-v1-closeout.md index 95b6a3e..218e207 100644 --- a/docs/ops/co-9-civiccore-v1-closeout.md +++ b/docs/ops/co-9-townlight_core-v1-closeout.md @@ -1,4 +1,4 @@ - + # CO-9 Townlight Core v1.0 Closeout Report @@ -19,7 +19,7 @@ The release-class operation is covered by explicit chat authorization for: | Sprint | Authorized operation | Scope | |---|---|---| | CO-2c | Cut Townlight Core `v0.22.1` | First Sigstore-attested baseline release. | -| CO-7 | Cut `civiccore-m1-freeze` | Freeze-line release for downstream module pins. | +| CO-7 | Cut `townlight_core-m1-freeze` | Freeze-line release for downstream module pins. | | CO-9 | Cut Townlight Core `v1.0` | Downstream productization release. | The CO-9 release payload is: @@ -29,11 +29,11 @@ The CO-9 release payload is: | Sprint ID | CO-9 | | Repo | `townlight/core` | | Target SHA | The GitHub-merged CO-9 release-prep commit on `main` | -| Tag / release name | `v1.0` / `civiccore v1.0` | +| Tag / release name | `v1.0` / `townlight_core v1.0` | | Package version | `1.0.0` | -| Release assets | `civiccore-1.0.0-py3-none-any.whl`, `civiccore-1.0.0.tar.gz`, `SHA256SUMS.txt`, `release-attestation.json`, `release-attestation.json.bundle` | -| Auditor verification command | `python scripts/verify-release-provenance.py v1.0 --repo CivicSuite/civiccore --attestation release-attestation.json --bundle release-attestation.json.bundle --artifacts-dir .` | -| Expected Sigstore identity | `https://github.com/CivicSuite/civiccore/.github/workflows/release.yml@refs/tags/v1.0` | +| Release assets | `townlight_core-1.0.0-py3-none-any.whl`, `townlight_core-1.0.0.tar.gz`, `SHA256SUMS.txt`, `release-attestation.json`, `release-attestation.json.bundle` | +| Auditor verification command | `python scripts/verify-release-provenance.py v1.0 --repo Townlight/townlight_core --attestation release-attestation.json --bundle release-attestation.json.bundle --artifacts-dir .` | +| Expected Sigstore identity | `https://github.com/Townlight/townlight_core/.github/workflows/release.yml@refs/tags/v1.0` | | Expected Sigstore issuer | `https://token.actions.githubusercontent.com` | | Failure plan | If tag creation succeeds but release publication fails, stop release work, file a failure report, and do not delete, move, edit, or republish any public artifact without fresh release-class authorization. | @@ -41,16 +41,16 @@ The CO-9 release payload is: | Release | Role | Verification surface | |---|---|---| -| [`v0.22.1`](https://github.com/CivicSuite/civiccore/releases/tag/v0.22.1) | First Sigstore-attested baseline release. | `release-attestation.json`, `release-attestation.json.bundle`, `SHA256SUMS.txt`, historical-provenance policy. | -| [`civiccore-m1-freeze`](https://github.com/CivicSuite/civiccore/releases/tag/civiccore-m1-freeze) | CO-7 downstream freeze-line release. | Freeze workflow run `25405991283`, target commit `3c4c34ccd153eeae705a57139f6713c356328b6d`, target tree `1e92d8b900b3d0134c4e8bc5b9133becff7822e6`. | -| [`v1.0`](https://github.com/CivicSuite/civiccore/releases/tag/v1.0) | CO-9 downstream productization release. | Release workflow, final SBOM, release attestation, SHA256SUMS, and post-publication provenance verification. | +| [`v0.22.1`](https://github.com/Townlight/townlight_core/releases/tag/v0.22.1) | First Sigstore-attested baseline release. | `release-attestation.json`, `release-attestation.json.bundle`, `SHA256SUMS.txt`, historical-provenance policy. | +| [`townlight_core-m1-freeze`](https://github.com/Townlight/townlight_core/releases/tag/townlight_core-m1-freeze) | CO-7 downstream freeze-line release. | Freeze workflow run `25405991283`, target commit `3c4c34ccd153eeae705a57139f6713c356328b6d`, target tree `1e92d8b900b3d0134c4e8bc5b9133becff7822e6`. | +| [`v1.0`](https://github.com/Townlight/townlight_core/releases/tag/v1.0) | CO-9 downstream productization release. | Release workflow, final SBOM, release attestation, SHA256SUMS, and post-publication provenance verification. | ## Retrofit Decisions | Decision | Record | |---|---| | Historical release tags are preserved, not rewritten. | [`historical-provenance.md`](historical-provenance.md). | -| `v0.22.1` is the first attested baseline; older releases remain historical. | [`civiccore-tier1-retrofit-ledger.md`](civiccore-tier1-retrofit-ledger.md). | +| `v0.22.1` is the first attested baseline; older releases remain historical. | [`townlight_core-tier1-retrofit-ledger.md`](townlight_core-tier1-retrofit-ledger.md). | | Cross-module historical retrofit findings are repo-controlled evidence, not desktop-only notes. | [`co-4-cross-module-retrofit-report.md`](co-4-cross-module-retrofit-report.md). | | Future release trust is Sigstore attestation plus artifact hashes, not the GitHub "Verified" badge alone. | [`release-signing.md`](release-signing.md). | @@ -58,22 +58,22 @@ The CO-9 release payload is: | Surface | Resolution | |---|---| -| Placeholder namespaces `civiccore.catalog`, `civiccore.exemptions`, and `civiccore.scaffold`. | ADR-deferred with downstream no-dependency rule in [`../adr/index.md`](../adr/index.md). | +| Placeholder namespaces `townlight_core.catalog`, `townlight_core.exemptions`, and `townlight_core.scaffold`. | ADR-deferred with downstream no-dependency rule in [`../adr/index.md`](../adr/index.md). | | Historical release provenance drift. | Disclosed and governed by [`historical-provenance.md`](historical-provenance.md). | -| Downstream module freeze dependency. | `civiccore-m1-freeze` is the freeze-line tag; Townlight Meetings and Townlight Code productization lanes pin to the freeze, not moving `main`. | +| Downstream module freeze dependency. | `townlight_core-m1-freeze` is the freeze-line tag; Townlight Meetings and Townlight Code productization lanes pin to the freeze, not moving `main`. | | Procurement evidence gap. | CO-8 evidence pack plus CO-9 final SBOM. | ## Evidence Anchors | Evidence | Location | |---|---| -| CO-8 procurement pack | [`../evidence/co8-civiccore-procurement-evidence-pack/index.md`](../evidence/co8-civiccore-procurement-evidence-pack/index.md) | -| Final v1.0 SBOM | [`../evidence/co8-civiccore-procurement-evidence-pack/sbom-v1.0-pip-inspect.json`](../evidence/co8-civiccore-procurement-evidence-pack/sbom-v1.0-pip-inspect.json) | +| CO-8 procurement pack | [`../evidence/co8-townlight_core-procurement-evidence-pack/index.md`](../evidence/co8-townlight_core-procurement-evidence-pack/index.md) | +| Final v1.0 SBOM | [`../evidence/co8-townlight_core-procurement-evidence-pack/sbom-v1.0-pip-inspect.json`](../evidence/co8-townlight_core-procurement-evidence-pack/sbom-v1.0-pip-inspect.json) | | Cleanroom harness | [`cleanroom-harness.md`](cleanroom-harness.md) | | CO-9 audit-full release gate | [`co-9-audit-full-release-gate.md`](co-9-audit-full-release-gate.md) | | Release signing runbook | [`release-signing.md`](release-signing.md) | | Historical provenance policy | [`historical-provenance.md`](historical-provenance.md) | -| Tier 1 retrofit ledger | [`civiccore-tier1-retrofit-ledger.md`](civiccore-tier1-retrofit-ledger.md) | +| Tier 1 retrofit ledger | [`townlight_core-tier1-retrofit-ledger.md`](townlight_core-tier1-retrofit-ledger.md) | ## Verification Gate @@ -92,7 +92,7 @@ The tag push then runs the release workflow, which rebuilds artifacts, creates `SHA256SUMS.txt`, signs `release-attestation.json`, verifies provenance before publication, and publishes the GitHub release. - + ## Townlight Meetings Unblock Rule diff --git a/docs/ops/historical-provenance.md b/docs/ops/historical-provenance.md index e28dad6..4c7dae9 100644 --- a/docs/ops/historical-provenance.md +++ b/docs/ops/historical-provenance.md @@ -1,22 +1,22 @@ # Historical Provenance Disclosure Policy -Status: operative CivicSuite policy, effective 2026-05-05. +Status: operative Townlight policy, effective 2026-05-05. -Baseline: `civiccore v0.22.1`, released 2026-05-05 at 16:23:36Z, is the +Baseline: `townlight_core v0.22.1`, released 2026-05-05 at 16:23:36Z, is the baseline release under the attested provenance model. The live release and trust artifacts are: -- Release: [`v0.22.1`](https://github.com/CivicSuite/civiccore/releases/tag/v0.22.1) +- Release: [`v0.22.1`](https://github.com/Townlight/townlight_core/releases/tag/v0.22.1) - Attestation: - [`release-attestation.json`](https://github.com/CivicSuite/civiccore/releases/download/v0.22.1/release-attestation.json) + [`release-attestation.json`](https://github.com/Townlight/townlight_core/releases/download/v0.22.1/release-attestation.json) - Cosign bundle: - [`release-attestation.json.bundle`](https://github.com/CivicSuite/civiccore/releases/download/v0.22.1/release-attestation.json.bundle) + [`release-attestation.json.bundle`](https://github.com/Townlight/townlight_core/releases/download/v0.22.1/release-attestation.json.bundle) - Checksums: - [`SHA256SUMS.txt`](https://github.com/CivicSuite/civiccore/releases/download/v0.22.1/SHA256SUMS.txt) + [`SHA256SUMS.txt`](https://github.com/Townlight/townlight_core/releases/download/v0.22.1/SHA256SUMS.txt) ## Summary -CivicSuite strengthened its release provenance model during the synthetic +Townlight strengthened its release provenance model during the synthetic development phase. The prior model relied on GitHub-native release pages and tag references. A backfill scan found that historical releases were either lightweight tags or unsigned annotated tag objects. GitHub's release UI can show @@ -28,7 +28,7 @@ The new model treats tags as release pointers and makes a Sigstore-signed must include the attestation, cosign bundle, artifact checksums, evidence bundle hashes, and an exact per-repo/per-tag verification command. -This model shift was driven by the CivicSuite synthetic-phase adversarial audit +This model shift was driven by the Townlight synthetic-phase adversarial audit contract. The external auditor flagged that the release-page "Verified" signal was misleading for release provenance, the development team built a fixture-driven gate, the gate surfaced an organization-wide historical baseline @@ -40,8 +40,8 @@ rewriting release history. The 2026-05-05 policy promotion is anchored to the following evidence: - The live `v0.22.1` release attestation URL listed above. -- CivicCore's Tier 1 retrofit ledger: - [`docs/ops/civiccore-tier1-retrofit-ledger.md`](civiccore-tier1-retrofit-ledger.md) +- Townlight Core's Tier 1 retrofit ledger: + [`docs/ops/townlight_core-tier1-retrofit-ledger.md`](townlight_core-tier1-retrofit-ledger.md) - The cross-module retrofit closeout report: [`docs/ops/co-4-cross-module-retrofit-report.md`](co-4-cross-module-retrofit-report.md) - Release verification command and result: `bash scripts/verify-release.sh`, @@ -54,7 +54,7 @@ The 2026-05-05 policy promotion is anchored to the following evidence: - Historical releases before 2026-05-05 were produced under a weaker GitHub-native provenance model. -- The backfill scan covered CivicSuite release tags across the organization as +- The backfill scan covered Townlight release tags across the organization as of 2026-05-04 and found 119 historical releases failing the strengthened gate: 83 lightweight tags and 36 unsigned annotated tag objects. - Those releases are not retroactively deleted or rewritten. @@ -81,12 +81,12 @@ Worked example for the first attested Townlight Core baseline release: ```bash cosign verify-blob release-attestation.json \ --bundle release-attestation.json.bundle \ - --certificate-identity "https://github.com/CivicSuite/civiccore/.github/workflows/release.yml@refs/tags/v0.22.1" \ + --certificate-identity "https://github.com/Townlight/townlight_core/.github/workflows/release.yml@refs/tags/v0.22.1" \ --certificate-oidc-issuer https://token.actions.githubusercontent.com sha256sum -c SHA256SUMS.txt python scripts/verify-release-provenance.py v0.22.1 \ - --repo CivicSuite/civiccore \ + --repo Townlight/townlight_core \ --attestation release-attestation.json \ --bundle release-attestation.json.bundle \ --artifacts-dir . @@ -95,15 +95,15 @@ python scripts/verify-release-provenance.py v0.22.1 \ ## Canonical Sources - Live attested baseline release: - [`v0.22.1`](https://github.com/CivicSuite/civiccore/releases/tag/v0.22.1) + [`v0.22.1`](https://github.com/Townlight/townlight_core/releases/tag/v0.22.1) - Gate implementation: - [`civiccore/release_provenance.py`](../../civiccore/release_provenance.py) + [`townlight_core/release_provenance.py`](../../townlight_core/release_provenance.py) - Thin CLI wrapper: [`scripts/verify-release-provenance.py`](../../scripts/verify-release-provenance.py) - Versioned attestation schema: [`docs/ops/release-attestation.schema.json`](release-attestation.schema.json) - Townlight Core Tier 1 retrofit ledger: - [`docs/ops/civiccore-tier1-retrofit-ledger.md`](civiccore-tier1-retrofit-ledger.md) + [`docs/ops/townlight_core-tier1-retrofit-ledger.md`](townlight_core-tier1-retrofit-ledger.md) - CO-4 cross-module retrofit report: [`docs/ops/co-4-cross-module-retrofit-report.md`](co-4-cross-module-retrofit-report.md) - Adversarial fixture suite: diff --git a/docs/ops/release-attestation.schema.json b/docs/ops/release-attestation.schema.json index fc34910..0e4bae3 100644 --- a/docs/ops/release-attestation.schema.json +++ b/docs/ops/release-attestation.schema.json @@ -1,14 +1,14 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://civicsuite.dev/schemas/release-attestation.v1.json", - "title": "CivicSuite Release Attestation", + "$id": "https://townlight.dev/schemas/release-attestation.v1.json", + "title": "Townlight Release Attestation", "type": "object", "additionalProperties": false, "required": ["schema_version", "subject", "build", "artifacts", "evidence_bundles"], "properties": { "schema_version": { "const": 1, - "description": "Versioned CivicSuite release-attestation contract." + "description": "Versioned Townlight release-attestation contract." }, "subject": { "type": "object", diff --git a/docs/ops/release-signing.md b/docs/ops/release-signing.md index 4c323e7..a40fd20 100644 --- a/docs/ops/release-signing.md +++ b/docs/ops/release-signing.md @@ -1,8 +1,8 @@ # Release Signing and Provenance Townlight Core is the canonical home for Townlight release-provenance gate logic. -Downstream modules should call `python -m civiccore.release_provenance` or a -thin local wrapper around `civiccore.release_provenance.main()`. +Downstream modules should call `python -m townlight_core.release_provenance` or a +thin local wrapper around `townlight_core.release_provenance.main()`. Release provenance is a pre-flight gate, not post-publication forensics. A failing gate produces no release assets. There is no dev-process exemption, no @@ -25,7 +25,7 @@ The acceptable release shape is: `docs/ops/release-attestation.schema.json`. 4. Serialize the attestation canonically with sorted JSON object keys, no extra whitespace, and UTF-8 bytes. In Python, use - `civiccore.release_provenance.canonical_json_bytes()`. + `townlight_core.release_provenance.canonical_json_bytes()`. 5. Sign the attestation with keyless Sigstore/cosign from GitHub Actions OIDC. 6. Run the adversarial fixture suite before checking the real release: @@ -37,7 +37,7 @@ The acceptable release shape is: ```bash python scripts/verify-release-provenance.py vX.Y.Z \ - --repo CivicSuite/civiccore \ + --repo Townlight/townlight_core \ --attestation release-attestation.json \ --bundle release-attestation.json.bundle \ --artifacts-dir dist \ @@ -50,7 +50,7 @@ The acceptable release shape is: The exact Sigstore certificate identity must be pinned per repo and per tag: ```text -https://github.com/CivicSuite/civiccore/.github/workflows/release.yml@refs/tags/vX.Y.Z +https://github.com/Townlight/townlight_core/.github/workflows/release.yml@refs/tags/vX.Y.Z ``` Do not replace this with an org-wide or repo-wide wildcard. A wildcard requires @@ -87,12 +87,12 @@ For online verification, download the release assets and run: ```bash cosign verify-blob release-attestation.json \ --bundle release-attestation.json.bundle \ - --certificate-identity "https://github.com/CivicSuite/civiccore/.github/workflows/release.yml@refs/tags/vX.Y.Z" \ + --certificate-identity "https://github.com/Townlight/townlight_core/.github/workflows/release.yml@refs/tags/vX.Y.Z" \ --certificate-oidc-issuer https://token.actions.githubusercontent.com sha256sum -c SHA256SUMS.txt python scripts/verify-release-provenance.py vX.Y.Z \ - --repo CivicSuite/civiccore \ + --repo Townlight/townlight_core \ --attestation release-attestation.json \ --bundle release-attestation.json.bundle \ --artifacts-dir . @@ -130,7 +130,7 @@ review environment cannot validate the bundle, the auditor treats that as offline reviewer can distinguish "signature invalid" from "reviewer lacks the required trust-root material." -## CivicCore v0.22.0 Historical Defect Statement +## Townlight Core v0.22.0 Historical Defect Statement Historical pre-baseline artifact: `v0.22.0` @@ -148,7 +148,7 @@ Reproducer after the new model is active: ```bash python scripts/verify-release-provenance.py v0.22.0 \ - --repo CivicSuite/civiccore \ + --repo Townlight/townlight_core \ --attestation release-attestation.json \ --bundle release-attestation.json.bundle \ --artifacts-dir . @@ -162,7 +162,7 @@ FAIL: Live release verification requires --attestation and --bundle under the Si This release is ledgered as pre-gate, no attestation, do not promote as baseline in -[`docs/ops/civiccore-tier1-retrofit-ledger.md`](civiccore-tier1-retrofit-ledger.md). +[`docs/ops/townlight_core-tier1-retrofit-ledger.md`](townlight_core-tier1-retrofit-ledger.md). Do not add attestation assets, edit release notes, delete, or recreate it without explicit chat authorization for that specific release. @@ -184,10 +184,10 @@ instead of inventing a false path. The strengthened gate surfaced an org-wide historical provenance baseline problem during the synthetic development phase: all 119 checked historical -CivicSuite release tags failed under the earlier tag-signature bar, split +Townlight release tags failed under the earlier tag-signature bar, split between lightweight tags and unsigned annotated tag objects. That finding is now understood as evidence that GitHub-native tags cannot carry the trust -burden for CivicSuite. +burden for Townlight. Historical releases are disclosed honestly rather than mass-deleted. The new baseline begins with releases that include Sigstore-signed release attestations @@ -227,9 +227,9 @@ actual file. The historical provenance disclosure is operative policy as of 2026-05-05 and lives at `docs/ops/historical-provenance.md`. -The policy names `civiccore v0.22.1`, released 2026-05-05 at 16:23:36Z, as the -first attested CivicCore baseline release and links the live release -attestation, CivicCore Tier 1 retrofit ledger, and CO-4 cross-module retrofit +The policy names `townlight_core v0.22.1`, released 2026-05-05 at 16:23:36Z, as the +first attested Townlight Core baseline release and links the live release +attestation, Townlight Core Tier 1 retrofit ledger, and CO-4 cross-module retrofit report. Do not change the baseline release, edit historical public release notes, or diff --git a/docs/ops/sigstore-release-workflow-draft.yml b/docs/ops/sigstore-release-workflow-draft.yml index a4c5422..02faff7 100644 --- a/docs/ops/sigstore-release-workflow-draft.yml +++ b/docs/ops/sigstore-release-workflow-draft.yml @@ -5,7 +5,7 @@ # 1. build release artifacts # 2. generate release-attestation.json using canonical JSON # 3. sign the attestation with keyless Sigstore/cosign from this workflow -# 4. run the CivicCore provenance gate against fixtures and the prospective tag +# 4. run the TownlightCore provenance gate against fixtures and the prospective tag # 5. publish only after the preflight gate passes name: release-with-sigstore-attestation diff --git a/docs/ops/civiccore-tier1-retrofit-ledger.json b/docs/ops/townlight_core-tier1-retrofit-ledger.json similarity index 79% rename from docs/ops/civiccore-tier1-retrofit-ledger.json rename to docs/ops/townlight_core-tier1-retrofit-ledger.json index 3376f8a..53174b7 100644 --- a/docs/ops/civiccore-tier1-retrofit-ledger.json +++ b/docs/ops/townlight_core-tier1-retrofit-ledger.json @@ -1,6 +1,6 @@ { "schema_version": 1, - "repo": "CivicSuite/civiccore", + "repo": "Townlight/townlight_core", "sprint_id": "CO-3", "baseline_tag": "v0.22.1", "checked_at": "2026-05-05T00:00:00-06:00", @@ -8,7 +8,7 @@ "command": "gh release list --limit 200", "release_count": 25, "latest_release": "v0.22.1", - "latest_release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.22.1" + "latest_release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.22.1" }, "policy": { "baseline_rule": "Use v0.22.1 or a later Sigstore-attested release as the provenance baseline.", @@ -19,32 +19,32 @@ { "tag": "v0.22.1", "published_at": "2026-05-05T16:23:36Z", - "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.22.1", + "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.22.1", "tag_ref_type": "lightweight_tag", "tag_ref_sha": "46c99854adbce6dc8a056ae5215278bb1eba9a19", "target_commit": "46c99854adbce6dc8a056ae5215278bb1eba9a19", "release_assets": [ - "civiccore-0.22.1-py3-none-any.whl", - "civiccore-0.22.1.tar.gz", + "townlight_core-0.22.1-py3-none-any.whl", + "townlight_core-0.22.1.tar.gz", "SHA256SUMS.txt", "release-attestation.json", "release-attestation.json.bundle" ], "ledger_status": "attested_baseline", "attestation_status": "sigstore_verified", - "rationale": "First CivicCore release produced after the Sigstore release-provenance gate. The release workflow signed and verified release-attestation.json before publication, and the direct cosign verification command returned Verified OK.", + "rationale": "First TownlightCore release produced after the Sigstore release-provenance gate. The release workflow signed and verified release-attestation.json before publication, and the direct cosign verification command returned Verified OK.", "downstream_rule": "Use this tag, or a later attested tag, when procurement-grade release provenance is required." }, { "tag": "v0.22.0", "published_at": "2026-05-03T06:39:51Z", - "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.22.0", + "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.22.0", "tag_ref_type": "lightweight_tag", "tag_ref_sha": "483a224aaf2ae08868bd4cd4caf842bfda97db94", "target_commit": "483a224aaf2ae08868bd4cd4caf842bfda97db94", "release_assets": [ - "civiccore-0.22.0-py3-none-any.whl", - "civiccore-0.22.0.tar.gz", + "townlight_core-0.22.0-py3-none-any.whl", + "townlight_core-0.22.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -55,13 +55,13 @@ { "tag": "v0.21.0", "published_at": "2026-05-02T17:00:33Z", - "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.21.0", + "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.21.0", "tag_ref_type": "annotated_tag_object", "tag_ref_sha": "a701834c125dbdcefab35994c1ce04a3dafd36dd", "target_commit": "4a1eb718ee9565a9a1911da9eff71a5c9f0b3e3e", "release_assets": [ - "civiccore-0.21.0-py3-none-any.whl", - "civiccore-0.21.0.tar.gz", + "townlight_core-0.21.0-py3-none-any.whl", + "townlight_core-0.21.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -72,13 +72,13 @@ { "tag": "v0.20.0", "published_at": "2026-05-02T15:06:14Z", - "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.20.0", + "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.20.0", "tag_ref_type": "lightweight_tag", "tag_ref_sha": "ad66681132c28bf17c48681c82943d153897b099", "target_commit": "ad66681132c28bf17c48681c82943d153897b099", "release_assets": [ - "civiccore-0.20.0-py3-none-any.whl", - "civiccore-0.20.0.tar.gz", + "townlight_core-0.20.0-py3-none-any.whl", + "townlight_core-0.20.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -89,13 +89,13 @@ { "tag": "v0.19.0", "published_at": "2026-05-02T10:26:56Z", - "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.19.0", + "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.19.0", "tag_ref_type": "annotated_tag_object", "tag_ref_sha": "8d187ce9da4ffbbf9a5cb0a2a9cedf3181e3f030", "target_commit": "7ae2acbe01568b8f1397975286754179f9836a52", "release_assets": [ - "civiccore-0.19.0-py3-none-any.whl", - "civiccore-0.19.0.tar.gz", + "townlight_core-0.19.0-py3-none-any.whl", + "townlight_core-0.19.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -106,13 +106,13 @@ { "tag": "v0.18.1", "published_at": "2026-05-02T06:37:09Z", - "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.18.1", + "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.18.1", "tag_ref_type": "lightweight_tag", "tag_ref_sha": "fd068e72767901a9541185fe782071ec2ffddc3b", "target_commit": "fd068e72767901a9541185fe782071ec2ffddc3b", "release_assets": [ - "civiccore-0.18.1-py3-none-any.whl", - "civiccore-0.18.1.tar.gz", + "townlight_core-0.18.1-py3-none-any.whl", + "townlight_core-0.18.1.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -123,13 +123,13 @@ { "tag": "v0.18.0", "published_at": "2026-05-02T06:25:30Z", - "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.18.0", + "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.18.0", "tag_ref_type": "lightweight_tag", "tag_ref_sha": "0785e34b65470803299273acef8f033570071b41", "target_commit": "0785e34b65470803299273acef8f033570071b41", "release_assets": [ - "civiccore-0.18.0-py3-none-any.whl", - "civiccore-0.18.0.tar.gz", + "townlight_core-0.18.0-py3-none-any.whl", + "townlight_core-0.18.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -140,13 +140,13 @@ { "tag": "v0.17.0", "published_at": "2026-05-01T23:40:12Z", - "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.17.0", + "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.17.0", "tag_ref_type": "annotated_tag_object", "tag_ref_sha": "d8cd894a5e41583bda40cdb19960a60ea64e3205", "target_commit": "e9dca05ad2b45c6b19cf97fb829cb7c8e1946343", "release_assets": [ - "civiccore-0.17.0-py3-none-any.whl", - "civiccore-0.17.0.tar.gz", + "townlight_core-0.17.0-py3-none-any.whl", + "townlight_core-0.17.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -157,13 +157,13 @@ { "tag": "v0.16.0", "published_at": "2026-04-30T05:23:09Z", - "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.16.0", + "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.16.0", "tag_ref_type": "lightweight_tag", "tag_ref_sha": "a8d287e40d2c9ded183f0d3e35c6c5fb4d89137c", "target_commit": "a8d287e40d2c9ded183f0d3e35c6c5fb4d89137c", "release_assets": [ - "civiccore-0.16.0-py3-none-any.whl", - "civiccore-0.16.0.tar.gz", + "townlight_core-0.16.0-py3-none-any.whl", + "townlight_core-0.16.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -174,13 +174,13 @@ { "tag": "v0.15.0", "published_at": "2026-04-30T03:51:46Z", - "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.15.0", + "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.15.0", "tag_ref_type": "lightweight_tag", "tag_ref_sha": "27702e2fe3ddb659a224f9c57f86b960da1792a7", "target_commit": "27702e2fe3ddb659a224f9c57f86b960da1792a7", "release_assets": [ - "civiccore-0.15.0-py3-none-any.whl", - "civiccore-0.15.0.tar.gz", + "townlight_core-0.15.0-py3-none-any.whl", + "townlight_core-0.15.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -191,13 +191,13 @@ { "tag": "v0.14.1", "published_at": "2026-04-30T03:16:15Z", - "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.14.1", + "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.14.1", "tag_ref_type": "annotated_tag_object", "tag_ref_sha": "22c31133f0932cd3f579d7e5862f928f44e6f686", "target_commit": "36080f75c372c62e27e0407ec3f6cbb2dbbd4012", "release_assets": [ - "civiccore-0.14.1-py3-none-any.whl", - "civiccore-0.14.1.tar.gz", + "townlight_core-0.14.1-py3-none-any.whl", + "townlight_core-0.14.1.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -208,13 +208,13 @@ { "tag": "v0.14.0", "published_at": "2026-04-30T02:42:46Z", - "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.14.0", + "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.14.0", "tag_ref_type": "annotated_tag_object", "tag_ref_sha": "bf9136c0af6f46786c5cfca2487b7e0e5bf0b26b", "target_commit": "09bfe262f91b897799c49a0c7708feabfa067239", "release_assets": [ - "civiccore-0.14.0-py3-none-any.whl", - "civiccore-0.14.0.tar.gz", + "townlight_core-0.14.0-py3-none-any.whl", + "townlight_core-0.14.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -225,13 +225,13 @@ { "tag": "v0.13.0", "published_at": "2026-04-29T23:45:49Z", - "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.13.0", + "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.13.0", "tag_ref_type": "annotated_tag_object", "tag_ref_sha": "27fbbc872b81be6d4b2930313e56dcee66d974b1", "target_commit": "5657806c9b583a2426b5cd028726fd5fda77963e", "release_assets": [ - "civiccore-0.13.0-py3-none-any.whl", - "civiccore-0.13.0.tar.gz", + "townlight_core-0.13.0-py3-none-any.whl", + "townlight_core-0.13.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -242,13 +242,13 @@ { "tag": "v0.12.0", "published_at": "2026-04-29T22:36:17Z", - "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.12.0", + "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.12.0", "tag_ref_type": "lightweight_tag", "tag_ref_sha": "d2f24b28ba05cc0b3c601babf389cea2713c11d0", "target_commit": "d2f24b28ba05cc0b3c601babf389cea2713c11d0", "release_assets": [ - "civiccore-0.12.0-py3-none-any.whl", - "civiccore-0.12.0.tar.gz", + "townlight_core-0.12.0-py3-none-any.whl", + "townlight_core-0.12.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -259,13 +259,13 @@ { "tag": "v0.11.0", "published_at": "2026-04-29T21:09:30Z", - "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.11.0", + "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.11.0", "tag_ref_type": "lightweight_tag", "tag_ref_sha": "b21001b1cebd7de01ac8011d4ec342ab99d9bf86", "target_commit": "b21001b1cebd7de01ac8011d4ec342ab99d9bf86", "release_assets": [ - "civiccore-0.11.0-py3-none-any.whl", - "civiccore-0.11.0.tar.gz" + "townlight_core-0.11.0-py3-none-any.whl", + "townlight_core-0.11.0.tar.gz" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", "attestation_status": "none_pre_gate", @@ -275,13 +275,13 @@ { "tag": "v0.10.0", "published_at": "2026-04-29T20:08:51Z", - "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.10.0", + "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.10.0", "tag_ref_type": "annotated_tag_object", "tag_ref_sha": "9bfcf754fce7e8298ffc6423358938bba68aa8c1", "target_commit": "8db660e546f002352b3df5f2519bb2a92d3282e7", "release_assets": [ - "civiccore-0.10.0-py3-none-any.whl", - "civiccore-0.10.0.tar.gz" + "townlight_core-0.10.0-py3-none-any.whl", + "townlight_core-0.10.0.tar.gz" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", "attestation_status": "none_pre_gate", @@ -291,13 +291,13 @@ { "tag": "v0.9.0", "published_at": "2026-04-29T18:32:51Z", - "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.9.0", + "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.9.0", "tag_ref_type": "annotated_tag_object", "tag_ref_sha": "52ca2c866d5e3f665c890b6aab13a34262f2c317", "target_commit": "8010e9fd9b5ab599f579c257f24f3c1ae3cea3e2", "release_assets": [ - "civiccore-0.9.0-py3-none-any.whl", - "civiccore-0.9.0.tar.gz", + "townlight_core-0.9.0-py3-none-any.whl", + "townlight_core-0.9.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -308,13 +308,13 @@ { "tag": "v0.8.0", "published_at": "2026-04-29T17:48:23Z", - "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.8.0", + "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.8.0", "tag_ref_type": "annotated_tag_object", "tag_ref_sha": "d4336082b20d2df3467b76d987feee54f2ec802e", "target_commit": "b7cfaeb9d9490ff0c68aad255df6f69da912d6be", "release_assets": [ - "civiccore-0.8.0-py3-none-any.whl", - "civiccore-0.8.0.tar.gz", + "townlight_core-0.8.0-py3-none-any.whl", + "townlight_core-0.8.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -325,13 +325,13 @@ { "tag": "v0.7.0", "published_at": "2026-04-29T16:43:12Z", - "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.7.0", + "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.7.0", "tag_ref_type": "annotated_tag_object", "tag_ref_sha": "3dc905a865d397551384d35d1fa7dc0978e6d964", "target_commit": "943da60abd6ef4e906b63eecbf7dcbc8de77550d", "release_assets": [ - "civiccore-0.7.0-py3-none-any.whl", - "civiccore-0.7.0.tar.gz", + "townlight_core-0.7.0-py3-none-any.whl", + "townlight_core-0.7.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -342,13 +342,13 @@ { "tag": "v0.6.0", "published_at": "2026-04-29T16:07:58Z", - "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.6.0", + "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.6.0", "tag_ref_type": "annotated_tag_object", "tag_ref_sha": "64c1f62f9c4224f987853864bd598a70f78806c0", "target_commit": "95890075c7886e66c9711e0e8e84517a705e3530", "release_assets": [ - "civiccore-0.6.0-py3-none-any.whl", - "civiccore-0.6.0.tar.gz", + "townlight_core-0.6.0-py3-none-any.whl", + "townlight_core-0.6.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -359,13 +359,13 @@ { "tag": "v0.5.0", "published_at": "2026-04-29T15:23:28Z", - "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.5.0", + "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.5.0", "tag_ref_type": "lightweight_tag", "tag_ref_sha": "bcb9b7852ba200302371bec3f425726230c435b3", "target_commit": "bcb9b7852ba200302371bec3f425726230c435b3", "release_assets": [ - "civiccore-0.5.0-py3-none-any.whl", - "civiccore-0.5.0.tar.gz", + "townlight_core-0.5.0-py3-none-any.whl", + "townlight_core-0.5.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -376,13 +376,13 @@ { "tag": "v0.4.0", "published_at": "2026-04-29T04:38:47Z", - "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.4.0", + "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.4.0", "tag_ref_type": "annotated_tag_object", "tag_ref_sha": "8c3eedc411570bba67c11ee750bfb2c168999026", "target_commit": "fab33a41f1c4c3ef3684dee1069f7069d31ac115", "release_assets": [ - "civiccore-0.4.0-py3-none-any.whl", - "civiccore-0.4.0.tar.gz", + "townlight_core-0.4.0-py3-none-any.whl", + "townlight_core-0.4.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -393,13 +393,13 @@ { "tag": "v0.3.0", "published_at": "2026-04-28T06:28:20Z", - "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.3.0", + "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.3.0", "tag_ref_type": "lightweight_tag", "tag_ref_sha": "7b3fbbf79b6c71513fac399658fe47195722b5e5", "target_commit": "7b3fbbf79b6c71513fac399658fe47195722b5e5", "release_assets": [ - "civiccore-0.3.0-py3-none-any.whl", - "civiccore-0.3.0.tar.gz", + "townlight_core-0.3.0-py3-none-any.whl", + "townlight_core-0.3.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -410,13 +410,13 @@ { "tag": "v0.2.0", "published_at": "2026-04-25T18:11:21Z", - "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.2.0", + "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.2.0", "tag_ref_type": "annotated_tag_object", "tag_ref_sha": "11ba8a6fa0c3c85f76d049eb76356e4eb6b5bfa8", "target_commit": "a8246ed34405d97be1e20adabd7dc8536e1246eb", "release_assets": [ - "civiccore-0.2.0-py3-none-any.whl", - "civiccore-0.2.0.tar.gz", + "townlight_core-0.2.0-py3-none-any.whl", + "townlight_core-0.2.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -427,13 +427,13 @@ { "tag": "v0.1.0", "published_at": "2026-04-24T23:30:45Z", - "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.1.0", + "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.1.0", "tag_ref_type": "annotated_tag_object", "tag_ref_sha": "feaefd2366d30ceead5a324e15c475a503b3be34", "target_commit": "9ac20f0274fbe6fc9730bdc509d5e6d4cedf6231", "release_assets": [ - "civiccore-0.1.0-py3-none-any.whl", - "civiccore-0.1.0.tar.gz", + "townlight_core-0.1.0-py3-none-any.whl", + "townlight_core-0.1.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", diff --git a/docs/ops/civiccore-tier1-retrofit-ledger.md b/docs/ops/townlight_core-tier1-retrofit-ledger.md similarity index 95% rename from docs/ops/civiccore-tier1-retrofit-ledger.md rename to docs/ops/townlight_core-tier1-retrofit-ledger.md index 85aaf8b..0c3101b 100644 --- a/docs/ops/civiccore-tier1-retrofit-ledger.md +++ b/docs/ops/townlight_core-tier1-retrofit-ledger.md @@ -1,4 +1,4 @@ - + # Townlight Core Tier 1 Retrofit Ledger @@ -22,7 +22,7 @@ repo-controlled ledger plus documentation truth update. matrix permits it. Structured source of truth: -[`docs/ops/civiccore-tier1-retrofit-ledger.json`](civiccore-tier1-retrofit-ledger.json). +[`docs/ops/townlight_core-tier1-retrofit-ledger.json`](townlight_core-tier1-retrofit-ledger.json). Verification: @@ -42,11 +42,11 @@ but the live check permits them only when the GitHub release exposes both - Live releases scanned: 25 - Latest release: `v0.22.1` - Baseline release: - [`v0.22.1`](https://github.com/CivicSuite/civiccore/releases/tag/v0.22.1) + [`v0.22.1`](https://github.com/Townlight/townlight_core/releases/tag/v0.22.1) - Baseline target commit: `46c99854adbce6dc8a056ae5215278bb1eba9a19` - Baseline Sigstore identity: - `https://github.com/CivicSuite/civiccore/.github/workflows/release.yml@refs/tags/v0.22.1` + `https://github.com/Townlight/townlight_core/.github/workflows/release.yml@refs/tags/v0.22.1` ## Entries diff --git a/docs/process/5-lens-self-audit.md b/docs/process/5-lens-self-audit.md index 68c3e34..2728d35 100644 --- a/docs/process/5-lens-self-audit.md +++ b/docs/process/5-lens-self-audit.md @@ -1,13 +1,13 @@ # 5-lens self-audit (before every push) -This is the implementation-side counterpart to the verification-side audit protocol at `C:\Users\scott\OneDrive\Desktop\Claude\CIVICSUITE_AUDIT_PROTOCOL.md`. The verification protocol governs how the auditing agent (Claude) audits work that has already landed. This document governs how the implementing agent (Codex) audits its own work *before* a push, so the verification turn finds less to fix. +This is the implementation-side counterpart to the verification-side audit protocol at `C:\Users\scott\OneDrive\Desktop\Claude\TOWNLIGHT_AUDIT_PROTOCOL.md`. The verification protocol governs how the auditing agent (Claude) audits work that has already landed. This document governs how the implementing agent (Codex) audits its own work *before* a push, so the verification turn finds less to fix. Both Codex and Claude read this file. The rule body, the artifact-state checklist, and the report format below are shared. The implementing-agent-side discipline (chat-promise rejection) and the verifier-side discipline (mandatory 10-section output) live in their respective files. ## Roles in this project - **Implementing agent:** Codex. Writes code, docs, status artifacts across 26 module repos. Runs this 5-lens self-audit before every push. -- **Auditing agent:** Claude. Verifies Codex's claims against actual artifacts. Produces the mandatory 10-section output defined in `CIVICSUITE_AUDIT_PROTOCOL.md`. +- **Auditing agent:** Claude. Verifies Codex's claims against actual artifacts. Produces the mandatory 10-section output defined in `TOWNLIGHT_AUDIT_PROTOCOL.md`. ## The rule @@ -27,30 +27,30 @@ Each lens is *hostile* — assume the diff lies until evidence proves otherwise. 2. **UX.** For any user-visible string, message, label, or workflow change: read it cold as if you'd never seen the feature. Does it make sense to a first-time operator? Does it match the copy in adjacent module READMEs (terminology, voice, formality)? Does an error path have a "Next step" line? Does the install script's "Generated secrets visible via docker exec env" warning actually appear in the doc's table of contents? Hostile means: assume the user is confused until the copy proves it doesn't confuse them. -3. **Tests.** For any logic / data-flow / public-interface change: is there a test? Does it run? Does it lock the behavior, or does it merely *exercise* the code path? Does it actually execute in CI, or does it skip? CivicSuite-specific: does the test cover the LIVE-STATE classification path AND the SHAPE-GUARD negative-assertion path? Hostile means: a green check is not a real assertion; "passes" is not "covers." Skip predicates lie by default — verify they don't apply. +3. **Tests.** For any logic / data-flow / public-interface change: is there a test? Does it run? Does it lock the behavior, or does it merely *exercise* the code path? Does it actually execute in CI, or does it skip? Townlight-specific: does the test cover the LIVE-STATE classification path AND the SHAPE-GUARD negative-assertion path? Hostile means: a green check is not a real assertion; "passes" is not "covers." Skip predicates lie by default — verify they don't apply. -4. **Docs.** For every code change: did the umbrella CHANGELOG move with it? The per-module CHANGELOG? The `.agent-workflows/HANDOFF_.md` (per-module if applicable, umbrella always)? The umbrella PR body? The `docs/release-recovery-status.md`? The audit punchlist row in `audit-civicsuite-2026-05-09/sprint-punchlist.md`? Hostile means: a doc that's silent about a change you just made is wrong, not "OK because the code is right." +4. **Docs.** For every code change: did the umbrella CHANGELOG move with it? The per-module CHANGELOG? The `.agent-workflows/HANDOFF_.md` (per-module if applicable, umbrella always)? The umbrella PR body? The `docs/release-recovery-status.md`? The audit punchlist row in `audit-townlight-2026-05-09/sprint-punchlist.md`? Hostile means: a doc that's silent about a change you just made is wrong, not "OK because the code is right." 5. **QA.** Read the final state, not the diff. Open the changed files as the next agent walking in cold. Are there contradictions across files? Does the umbrella CHANGELOG say one thing while the module CHANGELOG says another? Does the audit punchlist top-totals row reconcile with the row count? Are status words used per the audit protocol (`Closed` / `Implemented` / `Open` / `Deferred by Scott` / `Blocked`, never `done` / `ready` / `taggable` / `shippable`)? Does `verify-suite-state.py --remote-only` show what the CHANGELOG claims? Hostile means: assume drift until cross-file reading proves there is none. ## Artifact-state checklist -This is the specific drift that has bitten CivicSuite most. Run every item before push. +This is the specific drift that has bitten Townlight most. Run every item before push. -- [ ] Audit punchlist (`audit-civicsuite-2026-05-09/sprint-punchlist.md`) top-totals row matches the actual row count by severity. Every `[x]` row has a `Cross-ref: ` AND a proof citation (commit SHA, PR number, file path, or verifier output). +- [ ] Audit punchlist (`audit-townlight-2026-05-09/sprint-punchlist.md`) top-totals row matches the actual row count by severity. Every `[x]` row has a `Cross-ref: ` AND a proof citation (commit SHA, PR number, file path, or verifier output). - [ ] No row says `(this commit)` — replace with the actual SHA before pushing. - [ ] Umbrella PR body matches branch state: no stale `N of M` counts, no checkbox left unchecked for an item now Closed, no missing run IDs. Has `release-tag` label if and only if the PR includes truth artifacts (spec, verifier, modules.json, CHANGELOG, release-recovery-status, downstream-pins). - [ ] Umbrella CHANGELOG matches what shipped — no "All exit criteria met" if there was a carve-out, no stale test counts. Per-module CHANGELOG also updated for module-level changes. -- [ ] `.agent-workflows/HANDOFF_.md` names the current branch, current HEAD, current PR, current tag (if any), and the CivicSuite-wide verifier output (`VERIFY-SUITE-STATE: PASSED` or named failures). +- [ ] `.agent-workflows/HANDOFF_.md` names the current branch, current HEAD, current PR, current tag (if any), and the Townlight-wide verifier output (`VERIFY-SUITE-STATE: PASSED` or named failures). - [ ] Verification log on tag candidates: no "Ready to tag" claim without the tag-blocking gates Closed with proof. The release-lockstep-gate green status is captured. - [ ] Status words: no `done`, `green`, `ready`, `taggable`, `shippable`, `complete` unless the release gate actually supports them (`VERIFY-SUITE-STATE: PASSED` + `release-lockstep-gate` green + release object exists with all artifacts). - [ ] Working tree clean except intentional/declared uncommitted work. The pre-existing dirty `installer/dist/` and `installer/generated/` files predate the recovery sweep — state this explicitly in the report rather than silently accepting them. - [ ] Cleanroom claims qualified: CI cleanroom skips are CI-only; local cleanroom skips are local-only; never collapse them. - [ ] Whole-PR diff scope check: `git diff --name-status main..HEAD` must contain only the slice's intended file set. `git status --short` is not sufficient; sibling commits can land unrelated files. - [ ] Non-ASCII scan on every new/modified durable doc: em-dashes, arrows, section signs should be ASCII unless intentional. Run `LC_ALL=C.UTF-8 grep -P '[^\x00-\x7F]' ` before push. -- [ ] **SHA citations are full-length.** Every SHA256 citation is exactly 64 hex characters; every SHA1 citation is exactly 40. Run `grep -E '[a-f0-9]{56,63}\b' ` and inspect any hits as candidates for truncation. Origin receipt: CivicClerk B1 handoff 2026-05-10 required PR #119 to correct. +- [ ] **SHA citations are full-length.** Every SHA256 citation is exactly 64 hex characters; every SHA1 citation is exactly 40. Run `grep -E '[a-f0-9]{56,63}\b' ` and inspect any hits as candidates for truncation. Origin receipt: Townlight Meetings B1 handoff 2026-05-10 required PR #119 to correct. - [ ] **release-lockstep-gate alignment.** If the umbrella PR has the `release-tag` label, verify every required truth artifact path appears in `gh pr diff `: spec §18 truth table, `scripts/verify-suite-state.py` (if version constants changed), `installer/modules.json`, `CHANGELOG.md`, `docs/release-recovery-status.md`, `docs/release-lockstep/downstream-pins.md`. Origin receipt: release-lockstep-gate exists because Sprint A landed 7 false v1.0 tags that bypassed truth coordination. -- [ ] **Tag-move record present if any tag moves happened.** Completion handoff includes a tag-move table (Tag / Initial SHA / Final SHA / Moves / Notes) for every tag that moved during the sprint. Origin receipt: CivicRecords AI v1.5.0 — 4 tag moves recorded. +- [ ] **Tag-move record present if any tag moves happened.** Completion handoff includes a tag-move table (Tag / Initial SHA / Final SHA / Moves / Notes) for every tag that moved during the sprint. Origin receipt: Townlight Records v1.5.0 — 4 tag moves recorded. ## Post-push SHA-propagation step @@ -96,7 +96,7 @@ Artifact-state: [pass | findings: ...] Post-push propagation: [pass | findings: ...] ``` -If any lens has findings, fix before push. If after a push Claude (auditor) still finds drift, that is direct evidence this rule isn't sticking; Claude's directive will add a new artifact-state check to this document or a new entry to section 22 of `CIVICSUITE_AUDIT_PROTOCOL.md`. +If any lens has findings, fix before push. If after a push Claude (auditor) still finds drift, that is direct evidence this rule isn't sticking; Claude's directive will add a new artifact-state check to this document or a new entry to section 22 of `TOWNLIGHT_AUDIT_PROTOCOL.md`. ## Chat-promise rejection @@ -104,7 +104,7 @@ A chat-side promise ("I will keep this in mind") is not a behavior change. The b ## Cross-references -- `C:\Users\scott\OneDrive\Desktop\Claude\CIVICSUITE_AUDIT_PROTOCOL.md` — the verification-side audit protocol (Claude reads this). The mandatory 10-section output shape and the verifier's evidence-pass rules live there. Section 21 ("Implementation-side rule pointer") and section 22 ("Known drift patterns") pair with this document. -- `C:\Users\scott\OneDrive\Desktop\Claude\CIVICSUITE_AUDIT_GATE.md` — the short mandatory gate Claude reads every turn. +- `C:\Users\scott\OneDrive\Desktop\Claude\TOWNLIGHT_AUDIT_PROTOCOL.md` — the verification-side audit protocol (Claude reads this). The mandatory 10-section output shape and the verifier's evidence-pass rules live there. Section 21 ("Implementation-side rule pointer") and section 22 ("Known drift patterns") pair with this document. +- `C:\Users\scott\OneDrive\Desktop\Claude\TOWNLIGHT_AUDIT_GATE.md` — the short mandatory gate Claude reads every turn. - `~/.codex/skills/project-control-plane/SKILL.md` — Codex's skill that points at this file as the before-every-push discipline. - `C:\Users\scott\OneDrive\Desktop\Claude\agentic-pipeline\` — the agentic-pipeline plugin. v0.2 governs execution (4-phase module-release). v0.3 governs audit handoff (this document + the protocol + the gate). diff --git a/docs/qa/civiccore-longmont-ingest-proof-2026-05-21.md b/docs/qa/townlight_core-longmont-ingest-proof-2026-05-21.md similarity index 74% rename from docs/qa/civiccore-longmont-ingest-proof-2026-05-21.md rename to docs/qa/townlight_core-longmont-ingest-proof-2026-05-21.md index dca8faa..cdafb0a 100644 --- a/docs/qa/civiccore-longmont-ingest-proof-2026-05-21.md +++ b/docs/qa/townlight_core-longmont-ingest-proof-2026-05-21.md @@ -1,8 +1,8 @@ -# CivicCore Longmont Ingestion Proof - 2026-05-21 +# Townlight Core Longmont Ingestion Proof - 2026-05-21 -Purpose: prove the shared CivicCore ingestion pipeline parses a real municipal PDF, chunks it, embeds every chunk with the local Ollama embedding model, and persists rows into the CivicCore `documents` and `document_chunks` pgvector schema. +Purpose: prove the shared Townlight Core ingestion pipeline parses a real municipal PDF, chunks it, embeds every chunk with the local Ollama embedding model, and persists rows into the Townlight Core `documents` and `document_chunks` pgvector schema. -Command class: local proof script using `testcontainers.postgres.PostgresContainer("pgvector/pgvector:pg17")`, `civiccore.migrations.runner.upgrade_to_head()`, and `civiccore.ingest.ingest_file()`. +Command class: local proof script using `testcontainers.postgres.PostgresContainer("pgvector/pgvector:pg17")`, `townlight_core.migrations.runner.upgrade_to_head()`, and `townlight_core.ingest.ingest_file()`. Corpus: @@ -37,5 +37,5 @@ Acceptance facts: - Sentence-aware chunk rows persisted: `1789`. - Ollama `nomic-embed-text` vectors persisted: `1789`. - Vector dimensionality: `768`. -- Database schema: CivicCore baseline migration `documents` / `document_chunks` on pgvector PostgreSQL. +- Database schema: Townlight Core baseline migration `documents` / `document_chunks` on pgvector PostgreSQL. diff --git a/docs/release-recovery-status.md b/docs/release-recovery-status.md index 927229d..2c35c54 100644 --- a/docs/release-recovery-status.md +++ b/docs/release-recovery-status.md @@ -1,22 +1,22 @@ -# CivicCore Release Recovery Status +# Townlight Core Release Recovery Status Date: 2026-05-07 -Repo: `CivicSuite/civiccore` +Repo: `Townlight/townlight_core` ## v1.0.1 Recovery Patch `v1.0.1` is the recovery patch for the post-`v1.0` main branch. It includes the audit-finding fix and the provisional-status marking from the recovery range. -Security hardening: CivicCore auth errors no longer expose diagnostic role, +Security hardening: Townlight Core auth errors no longer expose diagnostic role, principal, caller-host, or trusted-proxy CIDR fields. The removed fields are `token_roles`, `principal`, `principal_roles`, `client_host`, and -`trusted_proxy_cidrs`. The affected files are `civiccore/auth/bearer.py` and -`civiccore/auth/trusted_headers.py`. Rationale is recorded in -`docs/audits/civiccore-audit-full-2026-05-07.md`. +`trusted_proxy_cidrs`. The affected files are `townlight_core/auth/bearer.py` and +`townlight_core/auth/trusted_headers.py`. Rationale is recorded in +`docs/audits/townlight_core-audit-full-2026-05-07.md`. Operator note: if your monitoring or downstream tests assert these field names -in CivicCore auth error responses, update them before bumping the pin. +in Townlight Core auth error responses, update them before bumping the pin. ## Current Verdict @@ -33,11 +33,11 @@ remains historical and should point operators to `v1.0.1`. | Security scan | Passing | Tracked-file secret scan found no matches outside ignored evidence/scratch surfaces. | | Docs-source consistency | Passing | Version and release posture are tested from source files. | | Mock-vs-production labeling | Passing for library scope | README and user manual distinguish shipped helpers from placeholders and unshipped platform behaviors. | -| Browser/user-flow QA | Passing | CivicCore is a library. Playwright checked the docs landing page at desktop and mobile widths, with no console/page errors, visible provisional copy, keyboard focus samples, and no horizontal overflow. | +| Browser/user-flow QA | Passing | Townlight Core is a library. Playwright checked the docs landing page at desktop and mobile widths, with no console/page errors, visible provisional copy, keyboard focus samples, and no horizontal overflow. | ## Sign-Off Boundary -CivicCore is a shared library, not an end-user municipal app. It cannot by -itself prove that a city can run the CivicSuite product family. Downstream +Townlight Core is a shared library, not an end-user municipal app. It cannot by +itself prove that a city can run the Townlight product family. Downstream modules must re-earn their own release status with module-specific runtime, UX, integration, security, and documentation gates. diff --git a/docs/rule-history.md b/docs/rule-history.md index f247500..0b0cef7 100644 --- a/docs/rule-history.md +++ b/docs/rule-history.md @@ -2,17 +2,17 @@ `exemption_rules` holds a consumer's *working* rules. It can be edited, disabled or renumbered, so it cannot prove which cited text produced a past suggestion. Core therefore -keeps a separate append-only history in `civiccore_rule_versions`, added by -`civiccore_0006_rule_history`. See [ADR-0006](adr/ADR-0006-rule-version-history.md). +keeps a separate append-only history in `townlight_core_rule_versions`, added by +`townlight_core_0006_rule_history`. See [ADR-0006](adr/ADR-0006-rule-version-history.md). -Apply Core migrations through `civiccore_0006_rule_history`. The migration is additive: no +Apply Core migrations through `townlight_core_0006_rule_history`. The migration is additive: no existing table, row or column is altered, so a consumer that never calls the history API keeps its current behaviour. ## Writing ```python -from civiccore.exemptions.history import record_rule_version +from townlight_core.exemptions.history import record_rule_version outcome = await record_rule_version( session, @@ -60,12 +60,12 @@ row that belongs to another jurisdiction. Retrieval never falls back to the work an edited working row cannot masquerade as a cited version. `current_rules(session, state_code, rule_ids=None)` returns only the latest version of each -rule as `civiccore.exemptions.Rule`, ordered by `(category, rule_id)`, ready for -`civiccore.exemptions.evaluate`. A superseded definition is never evaluated as current. +rule as `townlight_core.exemptions.Rule`, ordered by `(category, rule_id)`, ready for +`townlight_core.exemptions.evaluate`. A superseded definition is never evaluated as current. ## Database guarantees -Triggers refuse UPDATE and DELETE on `civiccore_rule_versions`, and refuse an insert that +Triggers refuse UPDATE and DELETE on `townlight_core_rule_versions`, and refuse an insert that binds an existing rule id to a second jurisdiction. Rollback of the migration is a no-op on purpose: deleting cited history would destroy provenance. Recover through backup/restore. diff --git a/docs/scaffold.md b/docs/scaffold.md index 807adc6..ac38c17 100644 --- a/docs/scaffold.md +++ b/docs/scaffold.md @@ -1,5 +1,5 @@ -# `civiccore.scaffold` +# `townlight_core.scaffold` The generator that turns one validated module id into a working Townlight module skeleton. ADR-0007 records the contract; ADR-0003 remains the historical deferral. @@ -8,8 +8,8 @@ ADR-0007 records the contract; ADR-0003 remains the historical deferral. | Path (inside the new project directory) | Purpose | | --- | --- | -| `pyproject.toml` | AGPL-3.0-only module package with a `civiccore>=` floor. | -| `src//manifest.json` | Validates through `civiccore.platform.ModuleManifest`. | +| `pyproject.toml` | AGPL-3.0-only module package with a `townlight_core>=` floor. | +| `src//manifest.json` | Validates through `townlight_core.platform.ModuleManifest`. | | `src//manifest.py` | `load_manifest()` — typed access, validated on load. | | `src//app.py` | Minimal FastAPI staff surface using Core bearer auth. | | `migrations/env.py` | Alembic env owning only the module schema; creates the schema before configuring the context. | @@ -20,8 +20,8 @@ ADR-0007 records the contract; ADR-0003 remains the historical deferral. ## CLI ``` -python -m civiccore.scaffold plan notes --name "Notes" --description "..." # JSON plan -python -m civiccore.scaffold generate notes --name "Notes" --description "..." --target ./modules +python -m townlight_core.scaffold plan notes --name "Notes" --description "..." # JSON plan +python -m townlight_core.scaffold generate notes --name "Notes" --description "..." --target ./modules ``` `generate` refuses an existing directory, an unsafe module id, or a non-directory target and @@ -39,7 +39,7 @@ token and no insecure fallback. `work/beta-foundations/scaffold-01/pg-acceptance/harness.py` starts one disposable, owned PostgreSQL 17 cluster, applies Core's real chain with -`civiccore.migrations.runner.upgrade_to_head` (head `civiccore_0006_rule_history`), then runs +`townlight_core.migrations.runner.upgrade_to_head` (head `townlight_core_0006_rule_history`), then runs the generated module's own chain from `migrations/`. It asserts the module stamps `civicnotes_0001_baseline`, creates only schema `civicnotes`, leaves every Core table and the Core revision untouched, is idempotent on re-run, survives a cluster stop/start, and diff --git a/pyproject.toml b/pyproject.toml index cceb796..f0c8f23 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,8 +3,8 @@ requires = ["setuptools>=77.0.3", "wheel"] build-backend = "setuptools.build_meta" [project] -name = "civiccore" -version = "1.3.0.dev1" +name = "townlight-core" +version = "1.3.0.dev2" description = "Townlight shared platform package - migrations, shared SQLAlchemy base, LLM abstraction, audit/provenance, document ingestion, ingest and connector contracts, connector sync primitives, connector delta planning, reusable mock-city proof contracts, connector security helpers, startup config validation helpers, schedule validation helpers, encrypted config primitives, notice helpers, onboarding profile helpers, search access helpers, small auth helpers, manifests, exports, city profile primitives, and Windows-local module/runtime contracts" readme = "README.md" requires-python = ">=3.11" @@ -12,7 +12,7 @@ license = "AGPL-3.0-only" license-files = ["LICENSE", "LICENSE-CODE", "LICENSE-DOCS"] authors = [ { name = "Scott Converse" }, - { name = "CivicSuite contributors" }, + { name = "Townlight contributors" }, ] keywords = [ "civic-tech", @@ -23,7 +23,7 @@ keywords = [ "self-hosted", "local-llm", "ollama", - "civicsuite", + "townlight", ] classifiers = [ "Development Status :: 4 - Beta", @@ -36,10 +36,10 @@ classifiers = [ "Programming Language :: Python :: 3.13", "Topic :: Software Development :: Libraries :: Application Frameworks", ] -# Dep pins below mirror civicrecords-ai/backend/pyproject.toml exactly for the -# subsystems CivicCore extracts (auth, audit, LLM, ingest, search, connectors, +# Dep pins below mirror townlight_records/backend/pyproject.toml exactly for the +# subsystems TownlightCore extracts (auth, audit, LLM, ingest, search, connectors, # notifications, onboarding, exemptions, verification, models, migrations, -# scaffold). civicrecords-ai pins requires-python = ">=3.12"; CivicCore widens +# scaffold). townlight_records pins requires-python = ">=3.12"; TownlightCore widens # to ">=3.11" because it is a shared library and must support modules that # may not have moved to 3.12 yet. dependencies = [ @@ -99,10 +99,10 @@ Issues = "https://github.com/townlight/core/issues" [tool.setuptools.packages.find] where = ["."] -include = ["civiccore*"] +include = ["townlight_core*"] [tool.setuptools.package-data] -civiccore = ["migrations/alembic.ini"] +townlight_core = ["migrations/alembic.ini"] [tool.pytest.ini_options] asyncio_mode = "auto" diff --git a/scripts/build-release-attestation.py b/scripts/build-release-attestation.py index c5127a0..5f1979d 100644 --- a/scripts/build-release-attestation.py +++ b/scripts/build-release-attestation.py @@ -3,7 +3,7 @@ import argparse from pathlib import Path -from civiccore.release_provenance import build_release_attestation, canonical_json_bytes +from townlight_core.release_provenance import build_release_attestation, canonical_json_bytes def main() -> int: diff --git a/scripts/check-tier1-ledger.py b/scripts/check-tier1-ledger.py index a8e68e6..fa84b33 100644 --- a/scripts/check-tier1-ledger.py +++ b/scripts/check-tier1-ledger.py @@ -44,8 +44,8 @@ def _entry_tags(entries: list[dict[str, Any]]) -> list[str]: def validate_ledger(ledger: dict[str, Any]) -> list[dict[str, Any]]: if ledger.get("schema_version") != 1: raise LedgerError("schema_version must be 1") - if ledger.get("repo") != "CivicSuite/civiccore": - raise LedgerError("repo must be CivicSuite/civiccore") + if ledger.get("repo") != "Townlight/townlight_core": + raise LedgerError("repo must be Townlight/townlight_core") if ledger.get("baseline_tag") != "v0.22.1": raise LedgerError("baseline_tag must be v0.22.1") @@ -136,9 +136,9 @@ def main(argv: list[str] | None = None) -> int: parser.add_argument( "--ledger", type=Path, - default=Path("docs/ops/civiccore-tier1-retrofit-ledger.json"), + default=Path("docs/ops/townlight_core-tier1-retrofit-ledger.json"), ) - parser.add_argument("--repo", default="CivicSuite/civiccore") + parser.add_argument("--repo", default="Townlight/townlight_core") parser.add_argument( "--live", action="store_true", diff --git a/scripts/cleanroom/civiccore-cleanroom-runner.sh b/scripts/cleanroom/townlight_core-cleanroom-runner.sh old mode 100755 new mode 100644 similarity index 85% rename from scripts/cleanroom/civiccore-cleanroom-runner.sh rename to scripts/cleanroom/townlight_core-cleanroom-runner.sh index f24bb5d..04d8eff --- a/scripts/cleanroom/civiccore-cleanroom-runner.sh +++ b/scripts/cleanroom/townlight_core-cleanroom-runner.sh @@ -5,9 +5,9 @@ MODE="${1:-online}" EVIDENCE_DIR="${CLEANROOM_EVIDENCE_DIR:-/evidence}" RUN_LABEL="${CLEANROOM_RUN_LABEL:-cleanroom}" RELEASE_TAG="${CLEANROOM_RELEASE_TAG:-v0.22.1}" -RELEASE_BASE_URL="https://github.com/CivicSuite/civiccore/releases/download/${RELEASE_TAG}" +RELEASE_BASE_URL="https://github.com/Townlight/townlight_core/releases/download/${RELEASE_TAG}" OIDC_ISSUER="https://token.actions.githubusercontent.com" -WORKFLOW_IDENTITY="https://github.com/CivicSuite/civiccore/.github/workflows/release.yml@refs/tags/${RELEASE_TAG}" +WORKFLOW_IDENTITY="https://github.com/Townlight/townlight_core/.github/workflows/release.yml@refs/tags/${RELEASE_TAG}" mkdir -p "${EVIDENCE_DIR}/logs" "${EVIDENCE_DIR}/release-assets" @@ -67,8 +67,8 @@ metadata.update( "updated_at_utc": datetime.now(UTC).isoformat().replace("+00:00", "Z"), "platform": platform.platform(), "python": platform.python_version(), - "target_commit": os.environ["CIVICCORE_COMMIT"], - "repo_url": os.environ.get("CIVICCORE_REPO_URL", ""), + "target_commit": os.environ["TOWNLIGHT_CORE_COMMIT"], + "repo_url": os.environ.get("TOWNLIGHT_CORE_REPO_URL", ""), } ) metadata_path.write_text(json.dumps(metadata, indent=2, sort_keys=True) + "\n", encoding="utf-8") @@ -77,8 +77,8 @@ PY download_release_assets() { local assets=( - "civiccore-0.22.1-py3-none-any.whl" - "civiccore-0.22.1.tar.gz" + "townlight_core-0.22.1-py3-none-any.whl" + "townlight_core-0.22.1.tar.gz" "SHA256SUMS.txt" "release-attestation.json" "release-attestation.json.bundle" @@ -104,7 +104,7 @@ online() { bash -lc "cd '${EVIDENCE_DIR}/release-assets' && cosign verify-blob release-attestation.json --bundle release-attestation.json.bundle --certificate-identity '${WORKFLOW_IDENTITY}' --certificate-oidc-issuer '${OIDC_ISSUER}'" run_step "live-release-provenance" \ python scripts/verify-release-provenance.py "${RELEASE_TAG}" \ - --repo CivicSuite/civiccore \ + --repo Townlight/townlight_core \ --attestation "${EVIDENCE_DIR}/release-assets/release-attestation.json" \ --bundle "${EVIDENCE_DIR}/release-assets/release-attestation.json.bundle" \ --artifacts-dir "${EVIDENCE_DIR}/release-assets" @@ -114,18 +114,18 @@ offline() { export MODE RUN_LABEL EVIDENCE_DIR write_run_metadata run_step "offline-runtime-smoke" python - <<'PY' -import civiccore +import townlight_core import tomllib from pathlib import Path project = tomllib.loads(Path("pyproject.toml").read_text(encoding="utf-8")) -assert civiccore.__version__ == project["project"]["version"] -assert callable(civiccore.validate_manifest) -assert callable(civiccore.import_meeting_payload) -assert callable(civiccore.plan_vendor_delta_request) -assert callable(civiccore.validate_cron_expression) -assert callable(civiccore.compute_onboarding_status) -assert callable(civiccore.verify_persisted_audit_chain) +assert townlight_core.__version__ == project["project"]["version"] +assert callable(townlight_core.validate_manifest) +assert callable(townlight_core.import_meeting_payload) +assert callable(townlight_core.plan_vendor_delta_request) +assert callable(townlight_core.validate_cron_expression) +assert callable(townlight_core.compute_onboarding_status) +assert callable(townlight_core.verify_persisted_audit_chain) print("offline runtime smoke OK") PY run_step "offline-release-provenance-fixtures" \ @@ -175,9 +175,9 @@ manifest = { "sprint_id": "CO-6", "result": "PASS", "target": { - "repo": "CivicSuite/civiccore", - "repo_url": os.environ.get("CIVICCORE_REPO_URL", ""), - "commit": os.environ["CIVICCORE_COMMIT"], + "repo": "Townlight/townlight_core", + "repo_url": os.environ.get("TOWNLIGHT_CORE_REPO_URL", ""), + "commit": os.environ["TOWNLIGHT_CORE_COMMIT"], }, "container": { "base_image": os.environ["CLEANROOM_BASE_IMAGE"], @@ -190,15 +190,15 @@ manifest = { }, "release": { "tag": "v0.22.1", - "workflow_identity": "https://github.com/CivicSuite/civiccore/.github/workflows/release.yml@refs/tags/v0.22.1", + "workflow_identity": "https://github.com/Townlight/townlight_core/.github/workflows/release.yml@refs/tags/v0.22.1", "oidc_issuer": "https://token.actions.githubusercontent.com", "assets": release_assets, }, "network": { "allowed_during_provisioning_and_verification": [ - "https://github.com/CivicSuite/civiccore.git", - "https://github.com/CivicSuite/civiccore/releases/download/v0.22.1/*", - "https://api.github.com/repos/CivicSuite/civiccore/*", + "https://github.com/Townlight/townlight_core.git", + "https://github.com/Townlight/townlight_core/releases/download/v0.22.1/*", + "https://api.github.com/repos/Townlight/townlight_core/*", "https://github.com/sigstore/cosign/releases/download/v3.0.6/cosign-linux-amd64", "https://pypi.org/*", "https://files.pythonhosted.org/*", diff --git a/scripts/run-civiccore-cleanroom.sh b/scripts/run-townlight_core-cleanroom.sh old mode 100755 new mode 100644 similarity index 88% rename from scripts/run-civiccore-cleanroom.sh rename to scripts/run-townlight_core-cleanroom.sh index caeb447..7d1bf8a --- a/scripts/run-civiccore-cleanroom.sh +++ b/scripts/run-townlight_core-cleanroom.sh @@ -7,13 +7,13 @@ cd "${REPO_ROOT}" TARGET_COMMIT="${1:-$(git rev-parse HEAD)}" TARGET_COMMIT="$(git rev-parse "${TARGET_COMMIT}^{commit}")" SHORT_SHA="${TARGET_COMMIT:0:12}" -EVIDENCE_ROOT="${2:-docs/evidence/co6-civiccore-cleanroom-${SHORT_SHA}}" +EVIDENCE_ROOT="${2:-docs/evidence/co6-townlight_core-cleanroom-${SHORT_SHA}}" RUN_COUNT="${CLEANROOM_RUN_COUNT:-2}" -IMAGE_TAG="civiccore-cleanroom:${SHORT_SHA}" -REPO_URL="${CIVICCORE_REPO_URL:-https://github.com/CivicSuite/civiccore.git}" +IMAGE_TAG="townlight_core-cleanroom:${SHORT_SHA}" +REPO_URL="${TOWNLIGHT_CORE_REPO_URL:-https://github.com/Townlight/townlight_core.git}" if ! command -v docker >/dev/null 2>&1; then - echo "Docker is required to run the CivicCore cleanroom harness." >&2 + echo "Docker is required to run the TownlightCore cleanroom harness." >&2 exit 1 fi @@ -64,9 +64,9 @@ echo "Evidence root: ${EVIDENCE_ROOT}" echo "Run count: ${RUN_COUNT}" DOCKER_BUILDKIT=1 docker build --no-cache --pull --platform linux/amd64 \ - --build-arg "CIVICCORE_REPO_URL=${REPO_URL}" \ - --build-arg "CIVICCORE_COMMIT=${TARGET_COMMIT}" \ - -f cleanroom/civiccore.Dockerfile \ + --build-arg "TOWNLIGHT_CORE_REPO_URL=${REPO_URL}" \ + --build-arg "TOWNLIGHT_CORE_COMMIT=${TARGET_COMMIT}" \ + -f cleanroom/townlight_core.Dockerfile \ -t "${IMAGE_TAG}" \ . @@ -83,21 +83,21 @@ for idx in $(seq 1 "${RUN_COUNT}"); do echo "Running online cleanroom phase: ${label}" MSYS_NO_PATHCONV=1 docker run --rm --platform linux/amd64 --network bridge \ -e "CLEANROOM_RUN_LABEL=${label}" \ - -e "CIVICCORE_COMMIT=${TARGET_COMMIT}" \ + -e "TOWNLIGHT_CORE_COMMIT=${TARGET_COMMIT}" \ -v "${evidence_mount}:/evidence" \ "${IMAGE_TAG}" online echo "Running offline cleanroom phase: ${label}" MSYS_NO_PATHCONV=1 docker run --rm --platform linux/amd64 --network none \ -e "CLEANROOM_RUN_LABEL=${label}" \ - -e "CIVICCORE_COMMIT=${TARGET_COMMIT}" \ + -e "TOWNLIGHT_CORE_COMMIT=${TARGET_COMMIT}" \ -v "${evidence_mount}:/evidence" \ "${IMAGE_TAG}" offline echo "Finalizing cleanroom evidence: ${label}" MSYS_NO_PATHCONV=1 docker run --rm --platform linux/amd64 --network none \ -e "CLEANROOM_RUN_LABEL=${label}" \ - -e "CIVICCORE_COMMIT=${TARGET_COMMIT}" \ + -e "TOWNLIGHT_CORE_COMMIT=${TARGET_COMMIT}" \ -v "${evidence_mount}:/evidence" \ "${IMAGE_TAG}" finalize done @@ -158,7 +158,7 @@ comparison = { ) summary = [ - "# CO-6 CivicCore Cleanroom Harness Evidence", + "# CO-6 TownlightCore Cleanroom Harness Evidence", "", f"Target commit: `{target_commit}`", f"Run count: {run_count}", diff --git a/scripts/verify-release-provenance.py b/scripts/verify-release-provenance.py index 7cc3f37..8f46b0b 100644 --- a/scripts/verify-release-provenance.py +++ b/scripts/verify-release-provenance.py @@ -5,7 +5,7 @@ sys.path.insert(0, str(Path(__file__).resolve().parents[1])) -from civiccore.release_provenance import main +from townlight_core.release_provenance import main if __name__ == "__main__": diff --git a/scripts/verify-release.sh b/scripts/verify-release.sh index 716f787..158738c 100644 --- a/scripts/verify-release.sh +++ b/scripts/verify-release.sh @@ -1,10 +1,10 @@ #!/usr/bin/env bash -# civiccore/scripts/verify-release.sh - civiccore release gate. +# townlight_core/scripts/verify-release.sh - townlight_core release gate. # -# Read-only verification of civiccore's pre-push readiness. Checks: +# Read-only verification of townlight_core's pre-push readiness. Checks: # 1. Test suite (pytest tests/) # 2. Lint (ruff check .) -# 3. Version lockstep between pyproject.toml and civiccore/__init__.py +# 3. Version lockstep between pyproject.toml and townlight_core/__init__.py # 4. Required Rule 9 doc artifacts present on disk # 5. Build artifacts (sdist + wheel via python -m build) # 6. Fresh virtualenv install from the built wheel, exact version check, @@ -66,7 +66,7 @@ dump_failure_diagnostics() { echo "" else echo "## docker compose" - echo "No compose file present; CivicCore release verification is package-only." + echo "No compose file present; TownlightCore release verification is package-only." echo "" fi echo "============================================" @@ -74,7 +74,7 @@ dump_failure_diagnostics() { } info "0. release verification environment" -RELEASE_VENV="$(mktemp -d "${TMPDIR:-/tmp}/civiccore-release-env-XXXXXX")" +RELEASE_VENV="$(mktemp -d "${TMPDIR:-/tmp}/townlight_core-release-env-XXXXXX")" if "${PYTHON_CMD[@]}" -m venv "$RELEASE_VENV"; then VENV_PYTHON="$RELEASE_VENV/bin/python" if [ ! -x "$VENV_PYTHON" ] && [ -x "$RELEASE_VENV/Scripts/python.exe" ]; then @@ -111,17 +111,17 @@ else fail "ruff reported issues" fi -# --- 3. version lockstep (pyproject.toml <-> civiccore/__init__.py) --------- +# --- 3. version lockstep (pyproject.toml <-> townlight_core/__init__.py) --------- info "3. version lockstep" PY_VER=$(grep -oE '^version[[:space:]]*=[[:space:]]*"[^"]+"' pyproject.toml 2>/dev/null \ | head -1 \ | sed -E 's/^version[[:space:]]*=[[:space:]]*"([^"]+)"/\1/' || true) -INIT_VER=$(grep -oE '__version__[[:space:]]*=[[:space:]]*"[^"]+"' civiccore/__init__.py 2>/dev/null \ +INIT_VER=$(grep -oE '__version__[[:space:]]*=[[:space:]]*"[^"]+"' townlight_core/__init__.py 2>/dev/null \ | head -1 \ | sed -E 's/.*"([^"]+)"/\1/' || true) printf ' pyproject.toml %s\n' "${PY_VER:-}" -printf ' civiccore/__init__.py %s\n' "${INIT_VER:-}" +printf ' townlight_core/__init__.py %s\n' "${INIT_VER:-}" if [ -n "$PY_VER" ] && [ -n "$INIT_VER" ] && [ "$PY_VER" = "$INIT_VER" ]; then pass "two surfaces agree on $PY_VER" @@ -172,13 +172,13 @@ from pathlib import Path def main() -> int: - wheels = sorted(glob.glob("dist/civiccore-*.whl")) + wheels = sorted(glob.glob("dist/townlight_core-*.whl")) if not wheels: print("missing built wheel in dist/", file=sys.stderr) return 1 wheel_path = Path(wheels[0]).resolve() - temp_dir = Path(tempfile.mkdtemp(prefix="civiccore-release-")) + temp_dir = Path(tempfile.mkdtemp(prefix="townlight_core-release-")) try: builder = venv.EnvBuilder(with_pip=True) @@ -206,42 +206,42 @@ def main() -> int: "from pathlib import Path; " "import re; " "from importlib.metadata import version; " - "import civiccore; " - "from civiccore.migrations.runner import upgrade_to_head; " + "import townlight_core; " + "from townlight_core.migrations.runner import upgrade_to_head; " "pyproject = Path('pyproject.toml').read_text(encoding='utf-8'); " "match = re.search(r'^version\\s*=\\s*\"([^\"]+)\"', pyproject, re.MULTILINE); " "assert match, 'pyproject.toml version missing'; " "expected_version = match.group(1); " - "assert version('civiccore') == expected_version; " - "assert civiccore.__version__ == expected_version; " + "assert version('townlight_core') == expected_version; " + "assert townlight_core.__version__ == expected_version; " "assert callable(upgrade_to_head); " - "assert callable(civiccore.validate_manifest); " - "assert callable(civiccore.ingest_file); " - "assert callable(civiccore.ingest_bytes); " - "assert callable(civiccore.register_handler); " - "assert civiccore.Document; " - "assert civiccore.DocumentChunk; " - "assert civiccore.DataSource; " - "assert callable(civiccore.import_meeting_payload); " - "assert callable(civiccore.plan_vendor_delta_request); " - "assert callable(civiccore.build_deadline_plan); " - "assert callable(civiccore.evaluate_notice_compliance); " - "assert callable(civiccore.validate_cron_expression); " - "assert callable(civiccore.compute_next_sync_at); " - "assert callable(civiccore.compute_onboarding_status); " - "assert callable(civiccore.next_profile_prompt); " - "assert civiccore.AuditHashChain; " - "assert civiccore.PersistedAuditLogEntry; " - "assert callable(civiccore.compute_persisted_audit_hash); " - "assert callable(civiccore.verify_persisted_audit_chain); " - "assert civiccore.SyncCircuitState; " - "assert civiccore.SyncRunResult; " - "assert civiccore.SyncSourceStatus; " - "assert callable(civiccore.apply_sync_run_result); " - "assert callable(civiccore.build_sync_source_status); " - "assert callable(civiccore.with_http_retry); " - "assert civiccore.CityProfile; " - "assert callable(civiccore.reciprocal_rank_fusion); " + "assert callable(townlight_core.validate_manifest); " + "assert callable(townlight_core.ingest_file); " + "assert callable(townlight_core.ingest_bytes); " + "assert callable(townlight_core.register_handler); " + "assert townlight_core.Document; " + "assert townlight_core.DocumentChunk; " + "assert townlight_core.DataSource; " + "assert callable(townlight_core.import_meeting_payload); " + "assert callable(townlight_core.plan_vendor_delta_request); " + "assert callable(townlight_core.build_deadline_plan); " + "assert callable(townlight_core.evaluate_notice_compliance); " + "assert callable(townlight_core.validate_cron_expression); " + "assert callable(townlight_core.compute_next_sync_at); " + "assert callable(townlight_core.compute_onboarding_status); " + "assert callable(townlight_core.next_profile_prompt); " + "assert townlight_core.AuditHashChain; " + "assert townlight_core.PersistedAuditLogEntry; " + "assert callable(townlight_core.compute_persisted_audit_hash); " + "assert callable(townlight_core.verify_persisted_audit_chain); " + "assert townlight_core.SyncCircuitState; " + "assert townlight_core.SyncRunResult; " + "assert townlight_core.SyncSourceStatus; " + "assert callable(townlight_core.apply_sync_run_result); " + "assert callable(townlight_core.build_sync_source_status); " + "assert callable(townlight_core.with_http_retry); " + "assert townlight_core.CityProfile; " + "assert callable(townlight_core.reciprocal_rank_fusion); " "print('fresh-venv import smoke OK')" ), ], diff --git a/tests/fixtures/release_provenance/00_known_good_sigstore_attestation.json b/tests/fixtures/release_provenance/00_known_good_sigstore_attestation.json index 643f8f8..29ce6de 100644 --- a/tests/fixtures/release_provenance/00_known_good_sigstore_attestation.json +++ b/tests/fixtures/release_provenance/00_known_good_sigstore_attestation.json @@ -18,7 +18,7 @@ "attestation": { "schema_version": 1, "subject": { - "repo": "CivicSuite/civiccore", + "repo": "Townlight/townlight_core", "tag": "vfixture-good", "tag_ref_type": "commit", "tag_ref_sha": "commit-good", @@ -26,25 +26,25 @@ "target_tree": "tree-good" }, "build": { - "workflow_identity": "https://github.com/CivicSuite/civiccore/.github/workflows/release.yml@refs/tags/vfixture-good", + "workflow_identity": "https://github.com/Townlight/townlight_core/.github/workflows/release.yml@refs/tags/vfixture-good", "workflow_path": ".github/workflows/release.yml", "workflow_run_id": "123456789", "oidc_issuer": "https://token.actions.githubusercontent.com" }, "artifacts": [ { - "name": "civiccore-0.22.0-py3-none-any.whl", + "name": "townlight_core-0.22.0-py3-none-any.whl", "sha256": "67c0d8f7de19e30c2d5891030a0b37cbfcdd240852b53055c0b28290ad52290b" } ], "evidence_bundles": [] }, "artifact_payloads": [ - {"name": "civiccore-0.22.0-py3-none-any.whl", "content": "wheel bytes"} + {"name": "townlight_core-0.22.0-py3-none-any.whl", "content": "wheel bytes"} ], "sigstore": { "verified": true, - "identity": "https://github.com/CivicSuite/civiccore/.github/workflows/release.yml@refs/tags/vfixture-good", + "identity": "https://github.com/Townlight/townlight_core/.github/workflows/release.yml@refs/tags/vfixture-good", "issuer": "https://token.actions.githubusercontent.com" } } diff --git a/tests/fixtures/release_provenance/10_missing_attestation_schema.json b/tests/fixtures/release_provenance/10_missing_attestation_schema.json index 0ae2de4..018d871 100644 --- a/tests/fixtures/release_provenance/10_missing_attestation_schema.json +++ b/tests/fixtures/release_provenance/10_missing_attestation_schema.json @@ -16,7 +16,7 @@ }, "attestation": { "subject": { - "repo": "CivicSuite/civiccore", + "repo": "Townlight/townlight_core", "tag": "vfixture-missing-schema", "tag_ref_type": "commit", "tag_ref_sha": "commit-good", @@ -24,17 +24,17 @@ "target_tree": "tree-good" }, "build": { - "workflow_identity": "https://github.com/CivicSuite/civiccore/.github/workflows/release.yml@refs/tags/vfixture-missing-schema", + "workflow_identity": "https://github.com/Townlight/townlight_core/.github/workflows/release.yml@refs/tags/vfixture-missing-schema", "workflow_path": ".github/workflows/release.yml", "workflow_run_id": "123456789", "oidc_issuer": "https://token.actions.githubusercontent.com" }, - "artifacts": [{"name": "civiccore-0.22.0.whl", "sha256": "67c0d8f7de19e30c2d5891030a0b37cbfcdd240852b53055c0b28290ad52290b"}] + "artifacts": [{"name": "townlight_core-0.22.0.whl", "sha256": "67c0d8f7de19e30c2d5891030a0b37cbfcdd240852b53055c0b28290ad52290b"}] }, - "artifact_payloads": [{"name": "civiccore-0.22.0.whl", "content": "wheel bytes"}], + "artifact_payloads": [{"name": "townlight_core-0.22.0.whl", "content": "wheel bytes"}], "sigstore": { "verified": true, - "identity": "https://github.com/CivicSuite/civiccore/.github/workflows/release.yml@refs/tags/vfixture-missing-schema", + "identity": "https://github.com/Townlight/townlight_core/.github/workflows/release.yml@refs/tags/vfixture-missing-schema", "issuer": "https://token.actions.githubusercontent.com" } } diff --git a/tests/fixtures/release_provenance/20_wrong_workflow_identity.json b/tests/fixtures/release_provenance/20_wrong_workflow_identity.json index 854c2c1..aa226e8 100644 --- a/tests/fixtures/release_provenance/20_wrong_workflow_identity.json +++ b/tests/fixtures/release_provenance/20_wrong_workflow_identity.json @@ -17,7 +17,7 @@ "attestation": { "schema_version": 1, "subject": { - "repo": "CivicSuite/civiccore", + "repo": "Townlight/townlight_core", "tag": "vfixture-wrong-identity", "tag_ref_type": "commit", "tag_ref_sha": "commit-good", @@ -25,17 +25,17 @@ "target_tree": "tree-good" }, "build": { - "workflow_identity": "https://github.com/CivicSuite/other-module/.github/workflows/release.yml@refs/tags/vfixture-wrong-identity", + "workflow_identity": "https://github.com/Townlight/other-module/.github/workflows/release.yml@refs/tags/vfixture-wrong-identity", "workflow_path": ".github/workflows/release.yml", "workflow_run_id": "123456789", "oidc_issuer": "https://token.actions.githubusercontent.com" }, - "artifacts": [{"name": "civiccore-0.22.0.whl", "sha256": "67c0d8f7de19e30c2d5891030a0b37cbfcdd240852b53055c0b28290ad52290b"}] + "artifacts": [{"name": "townlight_core-0.22.0.whl", "sha256": "67c0d8f7de19e30c2d5891030a0b37cbfcdd240852b53055c0b28290ad52290b"}] }, - "artifact_payloads": [{"name": "civiccore-0.22.0.whl", "content": "wheel bytes"}], + "artifact_payloads": [{"name": "townlight_core-0.22.0.whl", "content": "wheel bytes"}], "sigstore": { "verified": true, - "identity": "https://github.com/CivicSuite/other-module/.github/workflows/release.yml@refs/tags/vfixture-wrong-identity", + "identity": "https://github.com/Townlight/other-module/.github/workflows/release.yml@refs/tags/vfixture-wrong-identity", "issuer": "https://token.actions.githubusercontent.com" } } diff --git a/tests/fixtures/release_provenance/30_mismatched_artifact_hash.json b/tests/fixtures/release_provenance/30_mismatched_artifact_hash.json index e328d61..cb97d75 100644 --- a/tests/fixtures/release_provenance/30_mismatched_artifact_hash.json +++ b/tests/fixtures/release_provenance/30_mismatched_artifact_hash.json @@ -17,7 +17,7 @@ "attestation": { "schema_version": 1, "subject": { - "repo": "CivicSuite/civiccore", + "repo": "Townlight/townlight_core", "tag": "vfixture-bad-hash", "tag_ref_type": "commit", "tag_ref_sha": "commit-good", @@ -25,17 +25,17 @@ "target_tree": "tree-good" }, "build": { - "workflow_identity": "https://github.com/CivicSuite/civiccore/.github/workflows/release.yml@refs/tags/vfixture-bad-hash", + "workflow_identity": "https://github.com/Townlight/townlight_core/.github/workflows/release.yml@refs/tags/vfixture-bad-hash", "workflow_path": ".github/workflows/release.yml", "workflow_run_id": "123456789", "oidc_issuer": "https://token.actions.githubusercontent.com" }, - "artifacts": [{"name": "civiccore-0.22.0.whl", "sha256": "c90a090615d6c77dfdc45a02d9d18c7cebe71c0d2213efbc7dd50f7e9ea2dbd5"}] + "artifacts": [{"name": "townlight_core-0.22.0.whl", "sha256": "c90a090615d6c77dfdc45a02d9d18c7cebe71c0d2213efbc7dd50f7e9ea2dbd5"}] }, - "artifact_payloads": [{"name": "civiccore-0.22.0.whl", "content": "wheel bytes"}], + "artifact_payloads": [{"name": "townlight_core-0.22.0.whl", "content": "wheel bytes"}], "sigstore": { "verified": true, - "identity": "https://github.com/CivicSuite/civiccore/.github/workflows/release.yml@refs/tags/vfixture-bad-hash", + "identity": "https://github.com/Townlight/townlight_core/.github/workflows/release.yml@refs/tags/vfixture-bad-hash", "issuer": "https://token.actions.githubusercontent.com" } } diff --git a/tests/fixtures/release_provenance/40_unexpected_oidc_issuer.json b/tests/fixtures/release_provenance/40_unexpected_oidc_issuer.json index c6f9b06..359cc77 100644 --- a/tests/fixtures/release_provenance/40_unexpected_oidc_issuer.json +++ b/tests/fixtures/release_provenance/40_unexpected_oidc_issuer.json @@ -17,7 +17,7 @@ "attestation": { "schema_version": 1, "subject": { - "repo": "CivicSuite/civiccore", + "repo": "Townlight/townlight_core", "tag": "vfixture-wrong-issuer", "tag_ref_type": "commit", "tag_ref_sha": "commit-good", @@ -25,17 +25,17 @@ "target_tree": "tree-good" }, "build": { - "workflow_identity": "https://github.com/CivicSuite/civiccore/.github/workflows/release.yml@refs/tags/vfixture-wrong-issuer", + "workflow_identity": "https://github.com/Townlight/townlight_core/.github/workflows/release.yml@refs/tags/vfixture-wrong-issuer", "workflow_path": ".github/workflows/release.yml", "workflow_run_id": "123456789", "oidc_issuer": "https://issuer.example.invalid" }, - "artifacts": [{"name": "civiccore-0.22.0.whl", "sha256": "67c0d8f7de19e30c2d5891030a0b37cbfcdd240852b53055c0b28290ad52290b"}] + "artifacts": [{"name": "townlight_core-0.22.0.whl", "sha256": "67c0d8f7de19e30c2d5891030a0b37cbfcdd240852b53055c0b28290ad52290b"}] }, - "artifact_payloads": [{"name": "civiccore-0.22.0.whl", "content": "wheel bytes"}], + "artifact_payloads": [{"name": "townlight_core-0.22.0.whl", "content": "wheel bytes"}], "sigstore": { "verified": true, - "identity": "https://github.com/CivicSuite/civiccore/.github/workflows/release.yml@refs/tags/vfixture-wrong-issuer", + "identity": "https://github.com/Townlight/townlight_core/.github/workflows/release.yml@refs/tags/vfixture-wrong-issuer", "issuer": "https://issuer.example.invalid" } } diff --git a/tests/fixtures/release_provenance/50_transparency_log_unavailable.json b/tests/fixtures/release_provenance/50_transparency_log_unavailable.json index c66e328..b88278b 100644 --- a/tests/fixtures/release_provenance/50_transparency_log_unavailable.json +++ b/tests/fixtures/release_provenance/50_transparency_log_unavailable.json @@ -17,7 +17,7 @@ "attestation": { "schema_version": 1, "subject": { - "repo": "CivicSuite/civiccore", + "repo": "Townlight/townlight_core", "tag": "vfixture-rekor-offline", "tag_ref_type": "commit", "tag_ref_sha": "commit-good", @@ -25,17 +25,17 @@ "target_tree": "tree-good" }, "build": { - "workflow_identity": "https://github.com/CivicSuite/civiccore/.github/workflows/release.yml@refs/tags/vfixture-rekor-offline", + "workflow_identity": "https://github.com/Townlight/townlight_core/.github/workflows/release.yml@refs/tags/vfixture-rekor-offline", "workflow_path": ".github/workflows/release.yml", "workflow_run_id": "123456789", "oidc_issuer": "https://token.actions.githubusercontent.com" }, - "artifacts": [{"name": "civiccore-0.22.0.whl", "sha256": "67c0d8f7de19e30c2d5891030a0b37cbfcdd240852b53055c0b28290ad52290b"}] + "artifacts": [{"name": "townlight_core-0.22.0.whl", "sha256": "67c0d8f7de19e30c2d5891030a0b37cbfcdd240852b53055c0b28290ad52290b"}] }, - "artifact_payloads": [{"name": "civiccore-0.22.0.whl", "content": "wheel bytes"}], + "artifact_payloads": [{"name": "townlight_core-0.22.0.whl", "content": "wheel bytes"}], "sigstore": { "availability": "offline", - "identity": "https://github.com/CivicSuite/civiccore/.github/workflows/release.yml@refs/tags/vfixture-rekor-offline", + "identity": "https://github.com/Townlight/townlight_core/.github/workflows/release.yml@refs/tags/vfixture-rekor-offline", "issuer": "https://token.actions.githubusercontent.com" } } diff --git a/tests/fixtures/release_provenance/60_tag_target_mismatch.json b/tests/fixtures/release_provenance/60_tag_target_mismatch.json index 1dfb6a3..41b499d 100644 --- a/tests/fixtures/release_provenance/60_tag_target_mismatch.json +++ b/tests/fixtures/release_provenance/60_tag_target_mismatch.json @@ -17,7 +17,7 @@ "attestation": { "schema_version": 1, "subject": { - "repo": "CivicSuite/civiccore", + "repo": "Townlight/townlight_core", "tag": "vfixture-target-mismatch", "tag_ref_type": "commit", "tag_ref_sha": "commit-real", @@ -25,17 +25,17 @@ "target_tree": "tree-good" }, "build": { - "workflow_identity": "https://github.com/CivicSuite/civiccore/.github/workflows/release.yml@refs/tags/vfixture-target-mismatch", + "workflow_identity": "https://github.com/Townlight/townlight_core/.github/workflows/release.yml@refs/tags/vfixture-target-mismatch", "workflow_path": ".github/workflows/release.yml", "workflow_run_id": "123456789", "oidc_issuer": "https://token.actions.githubusercontent.com" }, - "artifacts": [{"name": "civiccore-0.22.0.whl", "sha256": "67c0d8f7de19e30c2d5891030a0b37cbfcdd240852b53055c0b28290ad52290b"}] + "artifacts": [{"name": "townlight_core-0.22.0.whl", "sha256": "67c0d8f7de19e30c2d5891030a0b37cbfcdd240852b53055c0b28290ad52290b"}] }, - "artifact_payloads": [{"name": "civiccore-0.22.0.whl", "content": "wheel bytes"}], + "artifact_payloads": [{"name": "townlight_core-0.22.0.whl", "content": "wheel bytes"}], "sigstore": { "verified": true, - "identity": "https://github.com/CivicSuite/civiccore/.github/workflows/release.yml@refs/tags/vfixture-target-mismatch", + "identity": "https://github.com/Townlight/townlight_core/.github/workflows/release.yml@refs/tags/vfixture-target-mismatch", "issuer": "https://token.actions.githubusercontent.com" } } diff --git a/tests/fixtures/release_provenance/70_workflow_rename_identity_drift.json b/tests/fixtures/release_provenance/70_workflow_rename_identity_drift.json index a8ab95b..72c0d3e 100644 --- a/tests/fixtures/release_provenance/70_workflow_rename_identity_drift.json +++ b/tests/fixtures/release_provenance/70_workflow_rename_identity_drift.json @@ -17,7 +17,7 @@ "attestation": { "schema_version": 1, "subject": { - "repo": "CivicSuite/civiccore", + "repo": "Townlight/townlight_core", "tag": "vfixture-renamed-workflow", "tag_ref_type": "commit", "tag_ref_sha": "commit-good", @@ -25,17 +25,17 @@ "target_tree": "tree-good" }, "build": { - "workflow_identity": "https://github.com/CivicSuite/civiccore/.github/workflows/release-renamed.yml@refs/tags/vfixture-renamed-workflow", + "workflow_identity": "https://github.com/Townlight/townlight_core/.github/workflows/release-renamed.yml@refs/tags/vfixture-renamed-workflow", "workflow_path": ".github/workflows/release-renamed.yml", "workflow_run_id": "123456789", "oidc_issuer": "https://token.actions.githubusercontent.com" }, - "artifacts": [{"name": "civiccore-0.22.0.whl", "sha256": "67c0d8f7de19e30c2d5891030a0b37cbfcdd240852b53055c0b28290ad52290b"}] + "artifacts": [{"name": "townlight_core-0.22.0.whl", "sha256": "67c0d8f7de19e30c2d5891030a0b37cbfcdd240852b53055c0b28290ad52290b"}] }, - "artifact_payloads": [{"name": "civiccore-0.22.0.whl", "content": "wheel bytes"}], + "artifact_payloads": [{"name": "townlight_core-0.22.0.whl", "content": "wheel bytes"}], "sigstore": { "verified": true, - "identity": "https://github.com/CivicSuite/civiccore/.github/workflows/release-renamed.yml@refs/tags/vfixture-renamed-workflow", + "identity": "https://github.com/Townlight/townlight_core/.github/workflows/release-renamed.yml@refs/tags/vfixture-renamed-workflow", "issuer": "https://token.actions.githubusercontent.com" } } diff --git a/tests/fixtures/release_provenance/80_trust_root_rotation.json b/tests/fixtures/release_provenance/80_trust_root_rotation.json index 8dea388..fc5f017 100644 --- a/tests/fixtures/release_provenance/80_trust_root_rotation.json +++ b/tests/fixtures/release_provenance/80_trust_root_rotation.json @@ -17,7 +17,7 @@ "attestation": { "schema_version": 1, "subject": { - "repo": "CivicSuite/civiccore", + "repo": "Townlight/townlight_core", "tag": "vfixture-root-rotation", "tag_ref_type": "commit", "tag_ref_sha": "commit-good", @@ -25,17 +25,17 @@ "target_tree": "tree-good" }, "build": { - "workflow_identity": "https://github.com/CivicSuite/civiccore/.github/workflows/release.yml@refs/tags/vfixture-root-rotation", + "workflow_identity": "https://github.com/Townlight/townlight_core/.github/workflows/release.yml@refs/tags/vfixture-root-rotation", "workflow_path": ".github/workflows/release.yml", "workflow_run_id": "123456789", "oidc_issuer": "https://token.actions.githubusercontent.com" }, - "artifacts": [{"name": "civiccore-0.22.0.whl", "sha256": "67c0d8f7de19e30c2d5891030a0b37cbfcdd240852b53055c0b28290ad52290b"}] + "artifacts": [{"name": "townlight_core-0.22.0.whl", "sha256": "67c0d8f7de19e30c2d5891030a0b37cbfcdd240852b53055c0b28290ad52290b"}] }, - "artifact_payloads": [{"name": "civiccore-0.22.0.whl", "content": "wheel bytes"}], + "artifact_payloads": [{"name": "townlight_core-0.22.0.whl", "content": "wheel bytes"}], "sigstore": { "trust_root_status": "rotated", - "identity": "https://github.com/CivicSuite/civiccore/.github/workflows/release.yml@refs/tags/vfixture-root-rotation", + "identity": "https://github.com/Townlight/townlight_core/.github/workflows/release.yml@refs/tags/vfixture-root-rotation", "issuer": "https://token.actions.githubusercontent.com" } } diff --git a/tests/test_audit_primitives.py b/tests/test_audit_primitives.py index e57dbff..cf4a08b 100644 --- a/tests/test_audit_primitives.py +++ b/tests/test_audit_primitives.py @@ -6,7 +6,7 @@ import pytest -from civiccore.audit import ( +from townlight_core.audit import ( AuditActor, AuditEvent, AuditHashChain, diff --git a/tests/test_auth_bearer.py b/tests/test_auth_bearer.py index 28a83b2..a562f71 100644 --- a/tests/test_auth_bearer.py +++ b/tests/test_auth_bearer.py @@ -4,7 +4,7 @@ from fastapi import HTTPException from fastapi.security import HTTPAuthorizationCredentials -from civiccore.auth import ( +from townlight_core.auth import ( AuthenticatedPrincipal, authorize_bearer_roles, enforce_trusted_proxy_source, @@ -135,9 +135,9 @@ def test_authorize_bearer_roles_returns_principal_for_allowed_token( def test_resolve_optional_bearer_roles_allows_anonymous_callers_without_config() -> None: principal = resolve_optional_bearer_roles( None, - service_name="CivicClerk", + service_name="TownlightMeetings", feature_name="archive search staff access", - token_roles_env_var="CIVICCLERK_AUTH_TOKEN_ROLES", + token_roles_env_var="TOWNLIGHT_MEETINGS_AUTH_TOKEN_ROLES", allowed_roles={"archive_reader"}, ) @@ -148,15 +148,15 @@ def test_resolve_optional_bearer_roles_returns_principal_for_configured_staff_to monkeypatch: pytest.MonkeyPatch, ) -> None: monkeypatch.setenv( - "CIVICCLERK_AUTH_TOKEN_ROLES", + "TOWNLIGHT_MEETINGS_AUTH_TOKEN_ROLES", '{"staff-token": ["archive_reader", "clerk_admin"]}', ) principal = resolve_optional_bearer_roles( HTTPAuthorizationCredentials(scheme="Bearer", credentials="staff-token"), - service_name="CivicClerk", + service_name="TownlightMeetings", feature_name="archive search staff access", - token_roles_env_var="CIVICCLERK_AUTH_TOKEN_ROLES", + token_roles_env_var="TOWNLIGHT_MEETINGS_AUTH_TOKEN_ROLES", allowed_roles={"archive_reader"}, ) @@ -168,16 +168,16 @@ def test_resolve_optional_bearer_roles_rejects_present_token_without_allowed_rol monkeypatch: pytest.MonkeyPatch, ) -> None: monkeypatch.setenv( - "CIVICCLERK_AUTH_TOKEN_ROLES", + "TOWNLIGHT_MEETINGS_AUTH_TOKEN_ROLES", '{"staff-token": ["meeting_editor"]}', ) with pytest.raises(HTTPException) as exc_info: resolve_optional_bearer_roles( HTTPAuthorizationCredentials(scheme="Bearer", credentials="staff-token"), - service_name="CivicClerk", + service_name="TownlightMeetings", feature_name="archive search staff access", - token_roles_env_var="CIVICCLERK_AUTH_TOKEN_ROLES", + token_roles_env_var="TOWNLIGHT_MEETINGS_AUTH_TOKEN_ROLES", allowed_roles={"archive_reader"}, ) @@ -198,7 +198,7 @@ def test_authorize_trusted_header_roles_requires_principal_header() -> None: with pytest.raises(HTTPException) as exc_info: authorize_trusted_header_roles( {"X-Civic-Roles": "clerk_admin"}, - service_name="CivicClerk", + service_name="TownlightMeetings", feature_name="staff workflow access", principal_header_name="X-Civic-Principal", roles_header_name="X-Civic-Roles", @@ -209,7 +209,7 @@ def test_authorize_trusted_header_roles_requires_principal_header() -> None: assert exc_info.value.status_code == 401 assert exc_info.value.detail["message"] == "Trusted identity header missing." assert "X-Civic-Principal" in exc_info.value.detail["fix"] - assert "CivicClerk" in exc_info.value.detail["fix"] + assert "TownlightMeetings" in exc_info.value.detail["fix"] assert "staff workflow access" in exc_info.value.detail["fix"] @@ -217,7 +217,7 @@ def test_authorize_trusted_header_roles_requires_role_header() -> None: with pytest.raises(HTTPException) as exc_info: authorize_trusted_header_roles( {"X-Civic-Principal": "clerk@example.gov"}, - service_name="CivicClerk", + service_name="TownlightMeetings", feature_name="staff workflow access", principal_header_name="X-Civic-Principal", roles_header_name="X-Civic-Roles", @@ -228,7 +228,7 @@ def test_authorize_trusted_header_roles_requires_role_header() -> None: assert exc_info.value.status_code == 401 assert exc_info.value.detail["message"] == "Trusted role header missing." assert "X-Civic-Roles" in exc_info.value.detail["fix"] - assert "CivicClerk" in exc_info.value.detail["fix"] + assert "TownlightMeetings" in exc_info.value.detail["fix"] assert "staff workflow access" in exc_info.value.detail["fix"] @@ -239,7 +239,7 @@ def test_authorize_trusted_header_roles_rejects_underprivileged_identity() -> No "X-Civic-Principal": "clerk@example.gov", "X-Civic-Roles": "records_viewer", }, - service_name="CivicClerk", + service_name="TownlightMeetings", feature_name="staff workflow access", principal_header_name="X-Civic-Principal", roles_header_name="X-Civic-Roles", @@ -252,7 +252,7 @@ def test_authorize_trusted_header_roles_rejects_underprivileged_identity() -> No assert exc_info.value.detail["required_roles"] == ["clerk_admin", "meeting_editor"] assert "principal" not in exc_info.value.detail assert "principal_roles" not in exc_info.value.detail - assert "CivicClerk" in exc_info.value.detail["fix"] + assert "TownlightMeetings" in exc_info.value.detail["fix"] assert "staff workflow access" in exc_info.value.detail["fix"] @@ -262,7 +262,7 @@ def test_authorize_trusted_header_roles_returns_principal() -> None: "X-Civic-Principal": "clerk@example.gov", "X-Civic-Roles": "meeting_editor, clerk_admin", }, - service_name="CivicClerk", + service_name="TownlightMeetings", feature_name="staff workflow access", principal_header_name="X-Civic-Principal", roles_header_name="X-Civic-Roles", @@ -281,7 +281,7 @@ def test_authorize_trusted_header_roles_returns_principal() -> None: def test_resolve_optional_trusted_header_roles_allows_anonymous_callers() -> None: principal = resolve_optional_trusted_header_roles( {}, - service_name="CivicClerk", + service_name="TownlightMeetings", feature_name="staff workflow access", principal_header_name="X-Civic-Principal", roles_header_name="X-Civic-Roles", @@ -298,7 +298,7 @@ def test_resolve_optional_trusted_header_roles_returns_principal_when_present() "X-Civic-Principal": "clerk@example.gov", "X-Civic-Roles": "clerk_admin", }, - service_name="CivicClerk", + service_name="TownlightMeetings", feature_name="staff workflow access", principal_header_name="X-Civic-Principal", roles_header_name="X-Civic-Roles", @@ -371,15 +371,15 @@ def test_enforce_trusted_proxy_source_requires_allowlist() -> None: with pytest.raises(HTTPException) as exc_info: enforce_trusted_proxy_source( "127.0.0.1", - service_name="CivicClerk", + service_name="TownlightMeetings", feature_name="staff workflow access", config=config, - trusted_proxy_env_var="CIVICCLERK_STAFF_SSO_TRUSTED_PROXIES", + trusted_proxy_env_var="TOWNLIGHT_MEETINGS_STAFF_SSO_TRUSTED_PROXIES", ) assert exc_info.value.status_code == 503 assert exc_info.value.detail["message"] == "Trusted-header proxy allowlist is missing." - assert "CIVICCLERK_STAFF_SSO_TRUSTED_PROXIES" in exc_info.value.detail["fix"] + assert "TOWNLIGHT_MEETINGS_STAFF_SSO_TRUSTED_PROXIES" in exc_info.value.detail["fix"] def test_enforce_trusted_proxy_source_rejects_invalid_allowlist() -> None: @@ -393,10 +393,10 @@ def test_enforce_trusted_proxy_source_rejects_invalid_allowlist() -> None: with pytest.raises(HTTPException) as exc_info: enforce_trusted_proxy_source( "127.0.0.1", - service_name="CivicClerk", + service_name="TownlightMeetings", feature_name="staff workflow access", config=config, - trusted_proxy_env_var="CIVICCLERK_STAFF_SSO_TRUSTED_PROXIES", + trusted_proxy_env_var="TOWNLIGHT_MEETINGS_STAFF_SSO_TRUSTED_PROXIES", ) assert exc_info.value.status_code == 503 @@ -415,10 +415,10 @@ def test_enforce_trusted_proxy_source_rejects_untrusted_host() -> None: with pytest.raises(HTTPException) as exc_info: enforce_trusted_proxy_source( "203.0.113.22", - service_name="CivicClerk", + service_name="TownlightMeetings", feature_name="staff workflow access", config=config, - trusted_proxy_env_var="CIVICCLERK_STAFF_SSO_TRUSTED_PROXIES", + trusted_proxy_env_var="TOWNLIGHT_MEETINGS_STAFF_SSO_TRUSTED_PROXIES", ) assert exc_info.value.status_code == 403 @@ -439,10 +439,10 @@ def test_enforce_trusted_proxy_source_accepts_allowed_host() -> None: enforce_trusted_proxy_source( "10.20.30.40", - service_name="CivicClerk", + service_name="TownlightMeetings", feature_name="staff workflow access", config=config, - trusted_proxy_env_var="CIVICCLERK_STAFF_SSO_TRUSTED_PROXIES", + trusted_proxy_env_var="TOWNLIGHT_MEETINGS_STAFF_SSO_TRUSTED_PROXIES", ) @@ -507,7 +507,7 @@ def fake_compare_digest(left: bytes, right: bytes) -> bool: return False monkeypatch.setenv("CIVIC_TEST_STAFF_API_KEY", "secret") - monkeypatch.setattr("civiccore.auth.staff_key.hmac.compare_digest", fake_compare_digest) + monkeypatch.setattr("townlight_core.auth.staff_key.hmac.compare_digest", fake_compare_digest) dependency = staff_key_gate("CIVIC_TEST_STAFF_API_KEY", "X-CivicTest-Staff-Key") with pytest.raises(HTTPException): diff --git a/tests/test_auth_suite_session.py b/tests/test_auth_suite_session.py index 815a8cf..8303249 100644 --- a/tests/test_auth_suite_session.py +++ b/tests/test_auth_suite_session.py @@ -1,4 +1,4 @@ -"""Contract tests for CivicCore-owned suite staff session tokens.""" +"""Contract tests for TownlightCore-owned suite staff session tokens.""" from __future__ import annotations @@ -6,8 +6,8 @@ import pytest -import civiccore.auth.suite_session as suite_session_module -from civiccore.auth.suite_session import ( +import townlight_core.auth.suite_session as suite_session_module +from townlight_core.auth.suite_session import ( SuiteSessionConfigError, SuiteSessionPrincipal, issue_suite_session_token, @@ -19,7 +19,7 @@ def test_suite_session_token_validates_role_claims_and_rejects_revocation( monkeypatch: pytest.MonkeyPatch, ) -> None: - monkeypatch.setenv("CIVICCORE_SUITE_SESSION_SECRET", "test-secret-with-enough-entropy") + monkeypatch.setenv("TOWNLIGHT_CORE_SUITE_SESSION_SECRET", "test-secret-with-enough-entropy") expires_at = datetime.now(UTC) + timedelta(minutes=15) token = issue_suite_session_token( @@ -49,9 +49,9 @@ def test_suite_session_token_validates_role_claims_and_rejects_revocation( def test_suite_session_secret_is_required_with_actionable_error( monkeypatch: pytest.MonkeyPatch, ) -> None: - monkeypatch.delenv("CIVICCORE_SUITE_SESSION_SECRET", raising=False) + monkeypatch.delenv("TOWNLIGHT_CORE_SUITE_SESSION_SECRET", raising=False) - with pytest.raises(SuiteSessionConfigError, match="CIVICCORE_SUITE_SESSION_SECRET"): + with pytest.raises(SuiteSessionConfigError, match="TOWNLIGHT_CORE_SUITE_SESSION_SECRET"): issue_suite_session_token( subject="admin@example.gov", roles=frozenset({"records_admin"}), @@ -63,9 +63,9 @@ def test_suite_session_revocation_file_survives_process_local_cache_reset( monkeypatch: pytest.MonkeyPatch, tmp_path, ) -> None: - monkeypatch.setenv("CIVICCORE_SUITE_SESSION_SECRET", "test-secret-with-enough-entropy") + monkeypatch.setenv("TOWNLIGHT_CORE_SUITE_SESSION_SECRET", "test-secret-with-enough-entropy") revocation_path = tmp_path / "suite-session-revocations.json" - monkeypatch.setenv("CIVICCORE_SUITE_SESSION_REVOCATION_FILE", str(revocation_path)) + monkeypatch.setenv("TOWNLIGHT_CORE_SUITE_SESSION_REVOCATION_FILE", str(revocation_path)) token = issue_suite_session_token( subject="admin@example.gov", roles=frozenset({"records_admin"}), diff --git a/tests/test_baseline_idempotency.py b/tests/test_baseline_idempotency.py index 1febfd4..dade428 100644 --- a/tests/test_baseline_idempotency.py +++ b/tests/test_baseline_idempotency.py @@ -1,4 +1,4 @@ -"""Idempotency test for civiccore_0001_baseline_v1. Blocks Phase 1 Part A PR merge per ADR-0003 §5.""" +"""Idempotency test for townlight_core_0001_baseline_v1. Blocks Phase 1 Part A PR merge per ADR-0003 §5.""" from __future__ import annotations @@ -18,12 +18,12 @@ ) PostgresContainer = testcontainers.PostgresContainer -from civiccore.migrations.runner import current_revision, upgrade_to_head # noqa: E402 -from civiccore.migrations.versions.civiccore_0001_baseline_v1 import ( # noqa: E402 +from townlight_core.migrations.runner import current_revision, upgrade_to_head # noqa: E402 +from townlight_core.migrations.versions.townlight_core_0001_baseline_v1 import ( # noqa: E402 _SHARED_TABLE_ORDER, ) -EXPECTED_HEAD = "civiccore_0009_job_artifacts" +EXPECTED_HEAD = "townlight_core_0009" def _docker_available() -> bool: @@ -46,7 +46,7 @@ def _docker_available() -> bool: def pg_container(): """Ephemeral Postgres 17 + pgvector container shared across this module's tests. - Uses the same ``pgvector/pgvector:pg17`` image as CivicRecords' docker-compose + Uses the same ``pgvector/pgvector:pg17`` image as TownlightRecords' docker-compose stack so the extension stanza in the baseline migration (``CREATE EXTENSION IF NOT EXISTS vector``) can succeed. Plain ``postgres:17`` lacks the pgvector control file and would fail the ``document_chunks`` table DDL. @@ -135,10 +135,10 @@ def test_baseline_runs_clean_on_empty_db(engine, pg_container): def test_baseline_is_idempotent(engine, pg_container): """Re-running the baseline against an already-populated DB is a no-op. - Proves the ``idempotent_*`` op wrappers (see ``civiccore.migrations.guards``) + Proves the ``idempotent_*`` op wrappers (see ``townlight_core.migrations.guards``) skip existing objects rather than destructively recreating them — which - is what makes the extracted civiccore baseline safe to ship alongside - already-deployed civicrecords databases (ADR-0003 §3). + is what makes the extracted townlight_core baseline safe to ship alongside + already-deployed townlight_records databases (ADR-0003 §3). """ with _database_url_env(pg_container): upgrade_to_head() diff --git a/tests/test_city_profile.py b/tests/test_city_profile.py index 0ae9c7f..a4c9f7f 100644 --- a/tests/test_city_profile.py +++ b/tests/test_city_profile.py @@ -5,7 +5,7 @@ import pytest from pydantic import ValidationError -from civiccore.city_profile import ( +from townlight_core.city_profile import ( CityProfile, DeploymentProfile, ModuleEnablement, @@ -35,7 +35,7 @@ def valid_payload() -> dict: {"name": "permits", "enabled": False, "settings": {"pilot": True}}, ], "default_llm_provider": "ollama", - "file_drop_roots": ["C:/civiccore/dropbox"], + "file_drop_roots": ["C:/townlight_core/dropbox"], "public_contact": { "email": "info@example.gov", "phone": "555-0100", @@ -50,7 +50,7 @@ def test_load_valid_json_profile(tmp_path): assert profile.city_name == "Sampleville" assert profile.timezone == "America/Denver" assert profile.departments[0].slug == "city-clerk" - assert profile.file_drop_roots[0].as_posix().endswith("civiccore/dropbox") + assert profile.file_drop_roots[0].as_posix().endswith("townlight_core/dropbox") assert profile.public_contact["email"] == "info@example.gov" diff --git a/tests/test_cleanroom_harness.py b/tests/test_cleanroom_harness.py index d5f6ecd..a6d4343 100644 --- a/tests/test_cleanroom_harness.py +++ b/tests/test_cleanroom_harness.py @@ -15,17 +15,17 @@ def read(path: str) -> str: def test_cleanroom_dockerfile_pins_base_image_and_cosign() -> None: - dockerfile = read("cleanroom/civiccore.Dockerfile") + dockerfile = read("cleanroom/townlight_core.Dockerfile") assert "python:3.13-slim-bookworm@sha256:bb73517d48bd32016e15eade0c009b2724ec3a025a9975b5cd9b251d0dcadb33" in dockerfile assert "ARG COSIGN_VERSION=v3.0.6" in dockerfile assert "ARG COSIGN_SHA256=c956e5dfcac53d52bcf058360d579472f0c1d2d9b69f55209e256fe7783f4c74" in dockerfile assert "git fetch --depth 1 origin" in dockerfile - assert 'test "$(git rev-parse HEAD)" = "${CIVICCORE_COMMIT}"' in dockerfile + assert 'test "$(git rev-parse HEAD)" = "${TOWNLIGHT_CORE_COMMIT}"' in dockerfile def test_cleanroom_runner_executes_required_verification_paths() -> None: - runner = read("scripts/cleanroom/civiccore-cleanroom-runner.sh") + runner = read("scripts/cleanroom/townlight_core-cleanroom-runner.sh") assert "bash scripts/verify-release.sh" in runner assert "python scripts/verify-release-provenance.py --fixtures-dir tests/fixtures/release_provenance" in runner @@ -37,7 +37,7 @@ def test_cleanroom_runner_executes_required_verification_paths() -> None: def test_cleanroom_orchestrator_uses_no_cache_two_runs_and_offline_network() -> None: - orchestrator = read("scripts/run-civiccore-cleanroom.sh") + orchestrator = read("scripts/run-townlight_core-cleanroom.sh") assert "docker build --no-cache --pull --platform linux/amd64" in orchestrator assert "RUN_COUNT=\"${CLEANROOM_RUN_COUNT:-2}\"" in orchestrator @@ -53,7 +53,7 @@ def test_cleanroom_ci_uploads_evidence_artifact() -> None: assert "TARGET_COMMIT" in workflow assert "github.event.pull_request.head.sha" in workflow assert "fetch-depth: 0" in workflow - assert "bash scripts/run-civiccore-cleanroom.sh" in workflow + assert "bash scripts/run-townlight_core-cleanroom.sh" in workflow assert "actions/upload-artifact" in workflow assert "CLEANROOM_RUN_COUNT: \"2\"" in workflow @@ -62,7 +62,7 @@ def test_cleanroom_ci_uploads_evidence_artifact() -> None: def test_offline_smoke_requires_candidate_version( tmp_path: Path, runtime_version: str ) -> None: - runner = read("scripts/cleanroom/civiccore-cleanroom-runner.sh") + runner = read("scripts/cleanroom/townlight_core-cleanroom-runner.sh") marker = 'run_step "offline-runtime-smoke" python - <<\'PY\'\n' smoke = runner.split(marker, 1)[1].split("\nPY", 1)[0] (tmp_path / "pyproject.toml").write_text( @@ -76,7 +76,7 @@ def test_offline_smoke_requires_candidate_version( "compute_onboarding_status", "verify_persisted_audit_chain", ) - (tmp_path / "civiccore.py").write_text( + (tmp_path / "townlight_core.py").write_text( f"__version__ = {runtime_version!r}\n" + "".join(f"def {name}(): pass\n" for name in exports), encoding="utf-8", diff --git a/tests/test_connector_delta.py b/tests/test_connector_delta.py index 06d8365..05d3742 100644 --- a/tests/test_connector_delta.py +++ b/tests/test_connector_delta.py @@ -2,7 +2,7 @@ from datetime import UTC, datetime -from civiccore.connectors import plan_vendor_delta_request +from townlight_core.connectors import plan_vendor_delta_request def test_delta_request_plans_connector_specific_cursor_query() -> None: diff --git a/tests/test_connector_imports.py b/tests/test_connector_imports.py index 0ab0f67..cbd4556 100644 --- a/tests/test_connector_imports.py +++ b/tests/test_connector_imports.py @@ -4,7 +4,7 @@ import pytest -from civiccore.connectors import ( +from townlight_core.connectors import ( ConnectorImportError, ImportedAgendaItem, SUPPORTED_CONNECTORS, diff --git a/tests/test_connector_manifest.py b/tests/test_connector_manifest.py index 6f10a5a..761dd92 100644 --- a/tests/test_connector_manifest.py +++ b/tests/test_connector_manifest.py @@ -4,7 +4,7 @@ import pytest -from civiccore.connectors import ( +from townlight_core.connectors import ( ExportManifest, ImportManifest, ManifestFile, @@ -24,9 +24,9 @@ def test_validate_csv_import_manifest_with_file_checksum(tmp_path) -> None: source.write_bytes(payload) manifest = ImportManifest( - module_name="civicrecords", + module_name="townlight_records", module_version="1.2.3", - civiccore_version="0.3.0", + townlight_core_version="0.3.0", purpose="csv_import", source_files=[ ManifestFile(path="imports/people.csv", byte_size=len(payload), sha256=_sha256(payload)) @@ -48,9 +48,9 @@ def test_validate_geojson_and_file_drop_import_purposes(tmp_path) -> None: (tmp_path / "permit.pdf").write_bytes(document) geojson_manifest = { - "module_name": "civiczone", + "module_name": "townlight_zoning", "module_version": "0.3.0", - "civiccore_version": "0.3.0", + "townlight_core_version": "0.3.0", "purpose": "geojson_import", "source_files": [ { @@ -62,9 +62,9 @@ def test_validate_geojson_and_file_drop_import_purposes(tmp_path) -> None: "limitations": ["Offline GeoJSON import only."], } file_drop_manifest = { - "module_name": "civicrecords", + "module_name": "townlight_records", "module_version": "0.3.0", - "civiccore_version": "0.3.0", + "townlight_core_version": "0.3.0", "purpose": "file_drop_import", "source_files": [ {"path": "permit.pdf", "byte_size": len(document), "sha256": _sha256(document)} @@ -82,9 +82,9 @@ def test_validate_static_export_manifest_with_generated_file(tmp_path) -> None: export.write_bytes(content) manifest = { - "module_name": "civicrecords", + "module_name": "townlight_records", "module_version": "0.3.0", - "civiccore_version": "0.3.0", + "townlight_core_version": "0.3.0", "purpose": "static_export_bundle", "generated_files": [ {"path": "cases.csv", "byte_size": len(content), "sha256": _sha256(content)} @@ -104,9 +104,9 @@ def test_manifest_detects_checksum_size_missing_and_version_mismatch(tmp_path) - file_path.write_bytes(data) manifest = { - "module_name": "civicrecords", + "module_name": "townlight_records", "module_version": "0.3.0", - "civiccore_version": "0.3.0", + "townlight_core_version": "0.3.0", "purpose": "csv_import", "source_files": [{"path": "data.csv", "byte_size": len(data), "sha256": _sha256(data)}], "limitations": ["Offline import only."], @@ -122,7 +122,7 @@ def test_manifest_detects_checksum_size_missing_and_version_mismatch(tmp_path) - validate_manifest(manifest, base_path=tmp_path) with pytest.raises(ManifestValidationError, match="Townlight Core version mismatch"): - validate_manifest(manifest, expected_civiccore_version="9.9.9") + validate_manifest(manifest, expected_townlight_core_version="9.9.9") def test_manifest_models_do_not_expose_live_connector_runtime_behavior() -> None: diff --git a/tests/test_connector_sync.py b/tests/test_connector_sync.py index 63bdbb8..8d45fd7 100644 --- a/tests/test_connector_sync.py +++ b/tests/test_connector_sync.py @@ -5,7 +5,7 @@ import httpx import pytest -from civiccore.connectors import ( +from townlight_core.connectors import ( SyncCircuitPolicy, SyncCircuitState, SyncRetryExhausted, diff --git a/tests/test_demo_town_contract.py b/tests/test_demo_town_contract.py index f905452..397ad03 100644 --- a/tests/test_demo_town_contract.py +++ b/tests/test_demo_town_contract.py @@ -7,7 +7,7 @@ import pytest -from civiccore.testing import ( +from townlight_core.testing import ( DEMO_TOWN_CONTRACT_SCHEMA_VERSION, DEMO_TOWN_DEFAULT_SEED, DEMO_TOWN_FIXTURE_ID, @@ -54,7 +54,7 @@ def test_demo_town_contract_is_versioned_and_explicitly_fictional() -> None: assert manifest["schema_version"] == DEMO_TOWN_CONTRACT_SCHEMA_VERSION == "1.0.0" assert manifest["fixture_id"] == DEMO_TOWN_FIXTURE_ID - assert manifest["fixture_version"] == DEMO_TOWN_FIXTURE_VERSION == "1.0.0" + assert manifest["fixture_version"] == DEMO_TOWN_FIXTURE_VERSION == "1.0.1" assert manifest["deterministic_seed"] == DEMO_TOWN_DEFAULT_SEED assert manifest["generation_mode"] == DEMO_TOWN_GENERATION_MODE == "static-canonical-v1" assert manifest["municipality"] == { @@ -91,7 +91,7 @@ def test_demo_town_fixture_and_artifact_hashes_are_deterministic() -> None: assert first["fixture_sha256"] == _canonical_sha256(fixture_without_hash) assert first["fixture_sha256"] == DEMO_TOWN_FIXTURE_SHA256_V1 assert DEMO_TOWN_FIXTURE_SHA256_V1 == ( - "a9c242a3f2618a69d7effb1d0d17d2df06f6744c8c351bba4065d315c94575b4" + "d9aaa79403cfca2711e8031439fbab8bf9f70a20b8afc293faef8edd683ffbd6" ) assert len(first["fixture_sha256"]) == 64 diff --git a/tests/test_department_authority.py b/tests/test_department_authority.py index fa06755..4eed7c8 100644 --- a/tests/test_department_authority.py +++ b/tests/test_department_authority.py @@ -14,8 +14,8 @@ import pytest -from civiccore.auth import AuthenticatedPrincipal -from civiccore.auth.department_scope import ( +from townlight_core.auth import AuthenticatedPrincipal +from townlight_core.auth.department_scope import ( TRUSTED_AUTH_METHODS, AuthorityProvenanceError, DepartmentAccessDenied, @@ -27,7 +27,7 @@ scope_model_context_chunks, scope_search_results, ) -from civiccore.llm.context import assemble_context +from townlight_core.llm.context import assemble_context SCOPE = "city-a" OTHER_SCOPE = "city-b" @@ -344,7 +344,7 @@ def test_receipt_is_bounded_and_does_not_leak_the_subject(): def test_grant_writes_refuse_a_malformed_scope(scope): import asyncio - from civiccore.auth.department_scope import active_department_grants, record_department_grant + from townlight_core.auth.department_scope import active_department_grants, record_department_grant async def write(): # ``session=None`` is never touched: the scope is validated before any query. diff --git a/tests/test_department_authority_adr.py b/tests/test_department_authority_adr.py index 3b01937..ffc7fca 100644 --- a/tests/test_department_authority_adr.py +++ b/tests/test_department_authority_adr.py @@ -9,7 +9,7 @@ from pathlib import Path -import civiccore.auth.department_scope as authority +import townlight_core.auth.department_scope as authority REPO_ROOT = Path(__file__).resolve().parents[1] @@ -23,7 +23,7 @@ def test_authority_adr_records_the_trust_boundary_and_non_claims() -> None: assert "Implemented in the private beta candidate" in current assert "not released" in current # The trust boundary is the point of the ADR and must stay stated. - assert "civiccore_department_grant_events" in current + assert "civiccore_department_grant_events" in current # Dated ADR's original identity. assert "privil" in current.lower() # the escalation shape it prevents assert "active_department_grants" in current assert "deny by default" in current.lower() @@ -62,7 +62,7 @@ def test_authority_module_documents_the_non_claims_it_must_uphold() -> None: def test_authority_contract_is_importable_from_the_auth_namespace() -> None: - import civiccore.auth as auth + import townlight_core.auth as auth for name in ( "DepartmentAuthority", diff --git a/tests/test_exemption_evaluation.py b/tests/test_exemption_evaluation.py index b63da12..95b7eb9 100644 --- a/tests/test_exemption_evaluation.py +++ b/tests/test_exemption_evaluation.py @@ -1,6 +1,6 @@ from uuid import uuid4 import pytest -from civiccore.exemptions import ( +from townlight_core.exemptions import ( Rule, RuleEvaluationError, evaluate, diff --git a/tests/test_export_bundle.py b/tests/test_export_bundle.py index 2b048cf..d8ce75b 100644 --- a/tests/test_export_bundle.py +++ b/tests/test_export_bundle.py @@ -4,8 +4,8 @@ import pytest -from civiccore.connectors.manifest import ManifestValidationError -from civiccore.exports import ( +from townlight_core.connectors.manifest import ManifestValidationError +from townlight_core.exports import ( BundleFile, ExportBundle, build_sha256sums, @@ -21,7 +21,7 @@ def _make_bundle(tmp_path) -> ExportBundle: (reports / "summary.json").write_text('{"total":1}\n', encoding="utf-8") return ExportBundle( - module_name="civicrecords", + module_name="townlight_records", module_version="0.3.0", files=[ BundleFile.from_path(tmp_path, "reports/cases.csv"), diff --git a/tests/test_github_workflows.py b/tests/test_github_workflows.py index a88ca05..067a19b 100644 --- a/tests/test_github_workflows.py +++ b/tests/test_github_workflows.py @@ -31,18 +31,18 @@ def test_release_workflow_uploads_explicit_downloaded_asset_files() -> None: assert release_tag["required"] is True assert release_tag["default"] == "v1.2.1" assert "v*" in tag_triggers - assert "civiccore-*-freeze" in tag_triggers + assert "townlight_core-*-freeze" in tag_triggers assert workflow["jobs"]["cleanroom-rehearsal"]["if"] == "github.event_name == 'workflow_dispatch'" assert release_cleanroom["needs"] == ["create-draft-release"] assert workflow["jobs"]["publish-release"]["needs"] == ["release-cleanroom-rehearsal"] assert download_step["uses"] == "actions/download-artifact@v8" - assert download_step["with"]["name"] == "civiccore-dist" + assert download_step["with"]["name"] == "townlight_core-dist" assert download_step["with"]["path"] == "release-assets/" - assert "civiccore-*-freeze) latest_flag=(--latest=false)" in create_release_script + assert "townlight_core-*-freeze) latest_flag=(--latest=false)" in create_release_script assert "Cleanroom rehearsal: PASSED in workflow run ${WORKFLOW_RUN_ID}" in create_release_script assert "Verified clean install of ${WHEEL_URL} from cold caches" in create_release_script - assert "docs/evidence/co8-civiccore-procurement-evidence-pack/index.md" in create_release_script - assert "docs/ops/co-9-civiccore-v1-closeout.md" in create_release_script + assert "docs/evidence/co8-townlight_core-procurement-evidence-pack/index.md" in create_release_script + assert "docs/ops/co-9-townlight_core-v1-closeout.md" in create_release_script assert "python scripts/verify-release-provenance.py ${TAG}" in create_release_script assert '"${latest_flag[@]}" \\' in create_release_script assert "--draft" in create_release_script @@ -53,10 +53,10 @@ def test_release_workflow_uploads_explicit_downloaded_asset_files() -> None: assert "gh release download" in release_cleanroom["steps"][3]["run"] assert "python -m pip install --no-cache-dir --force-reinstall" in release_cleanroom["steps"][4]["run"] assert "TESTING=1 python" in release_cleanroom["steps"][4]["run"] - assert "docker builder prune --all --force --filter \"label=civicsuite-cleanroom=1\"" in release_cleanroom["steps"][2]["run"] + assert "docker builder prune --all --force --filter \"label=townlight-cleanroom=1\"" in release_cleanroom["steps"][2]["run"] assert "system prune" not in release_cleanroom["steps"][2]["run"] assert "--draft=false" in publish_script - assert "civiccore-*-freeze) latest_flag=(--latest=false)" in publish_script + assert "townlight_core-*-freeze) latest_flag=(--latest=false)" in publish_script def test_ci_workflow_runs_full_release_verification_gate() -> None: diff --git a/tests/test_ingest_contracts.py b/tests/test_ingest_contracts.py index 844c248..6880094 100644 --- a/tests/test_ingest_contracts.py +++ b/tests/test_ingest_contracts.py @@ -2,7 +2,7 @@ from __future__ import annotations -from civiccore.ingest import ( +from townlight_core.ingest import ( CitedSentence, CitationValidationError, DiscoveredRecord, diff --git a/tests/test_ingest_pipeline.py b/tests/test_ingest_pipeline.py index 753832e..4860d1d 100644 --- a/tests/test_ingest_pipeline.py +++ b/tests/test_ingest_pipeline.py @@ -2,10 +2,10 @@ import pytest -from civiccore.ingest import embedder -from civiccore.ingest import ingest_bytes, register_handler -from civiccore.ingest.chunker import chunk_pages -from civiccore.ingest.parsers import detect_parser +from townlight_core.ingest import embedder +from townlight_core.ingest import ingest_bytes, register_handler +from townlight_core.ingest.chunker import chunk_pages +from townlight_core.ingest.parsers import detect_parser def test_shared_ingest_exports_pdf_parser_and_sentence_chunks() -> None: @@ -42,7 +42,7 @@ def parse(self, file_path: Path): # pragma: no cover - registry proof only register_handler(CustomParser()) - from civiccore.ingest.pipeline import _detect_handler + from townlight_core.ingest.pipeline import _detect_handler assert _detect_handler(Path("longmont.citycode")).__class__.__name__ == "CustomParser" @@ -64,7 +64,7 @@ class FakeDocument: async def fake_commit(): calls["committed"] = True - monkeypatch.setattr("civiccore.ingest.pipeline.ingest_file", fake_ingest_file) + monkeypatch.setattr("townlight_core.ingest.pipeline.ingest_file", fake_ingest_file) class FakeSession: commit = staticmethod(fake_commit) diff --git a/tests/test_job_artifacts.py b/tests/test_job_artifacts.py index 9c1bc26..964ab11 100644 --- a/tests/test_job_artifacts.py +++ b/tests/test_job_artifacts.py @@ -17,10 +17,10 @@ import pytest -import civiccore.tasks.artifacts as module -from civiccore.platform import LocalTaskEnvelope -from civiccore.platform.task_queue import StaleTaskClaim -from civiccore.tasks.artifacts import ( +import townlight_core.tasks.artifacts as module +from townlight_core.platform import LocalTaskEnvelope +from townlight_core.platform.task_queue import StaleTaskClaim +from townlight_core.tasks.artifacts import ( MAX_ARTIFACT_BYTES, REFUSAL_REASONS, ArtifactProposal, @@ -336,7 +336,7 @@ def test_unknown_refusal_reason_is_rejected() -> None: def test_artifact_namespace_is_importable_and_exported() -> None: - import civiccore.tasks as tasks + import townlight_core.tasks as tasks for name in ( "ArtifactProposal", diff --git a/tests/test_job_artifacts_adr.py b/tests/test_job_artifacts_adr.py index d8ad2df..1fa2b30 100644 --- a/tests/test_job_artifacts_adr.py +++ b/tests/test_job_artifacts_adr.py @@ -5,7 +5,7 @@ from pathlib import Path -import civiccore.tasks.artifacts as artifacts +import townlight_core.tasks.artifacts as artifacts REPO_ROOT = Path(__file__).resolve().parents[1] @@ -20,7 +20,7 @@ def test_artifact_adr_records_trust_boundary_and_non_claims() -> None: assert "not released" in current assert "claim_token" in current assert "StaleTaskClaim" in current - assert "civiccore_job_artifacts" in current + assert "civiccore_job_artifacts" in current # Dated ADR's original identity. assert "append-only" in current assert "restore-from-backup" in current assert "**no** transcription" in current @@ -73,7 +73,7 @@ def test_artifact_module_documents_the_non_claims_it_must_uphold() -> None: def test_artifact_contract_is_importable_from_the_tasks_namespace() -> None: - import civiccore.tasks as tasks + import townlight_core.tasks as tasks for name in ( "ArtifactProposal", @@ -94,11 +94,11 @@ def test_artifact_contract_is_importable_from_the_tasks_namespace() -> None: def test_queue_require_active_claim_is_exported_without_a_second_engine() -> None: - import civiccore.platform as platform + import townlight_core.platform as platform assert "require_active_claim" in platform.__all__ assert hasattr(platform, "require_active_claim") - source = (REPO_ROOT / "civiccore/platform/task_queue.py").read_text(encoding="utf-8") + source = (REPO_ROOT / "townlight_core/platform/task_queue.py").read_text(encoding="utf-8") # It must be a read-only fence over the existing ownership helper. assert "async def require_active_claim(" in source assert "row = await _owned_task(session, task_id, claim_token, now)" in source diff --git a/tests/test_llm_context.py b/tests/test_llm_context.py index 6717215..dd03d15 100644 --- a/tests/test_llm_context.py +++ b/tests/test_llm_context.py @@ -1,11 +1,11 @@ -"""Unit tests for civiccore.llm.context. +"""Unit tests for townlight_core.llm.context. Pure unit tests — no DB, no live providers, no skips. """ from __future__ import annotations -from civiccore.llm.context import ( +from townlight_core.llm.context import ( DEFAULT_CONTEXT_WINDOW, ContextBlock, TokenBudget, diff --git a/tests/test_llm_migration_0002.py b/tests/test_llm_migration_0002.py index dcc3ad4..105a391 100644 --- a/tests/test_llm_migration_0002.py +++ b/tests/test_llm_migration_0002.py @@ -1,4 +1,4 @@ -"""Tests for civiccore_0002_llm migration. +"""Tests for townlight_core_0002_llm migration. Validates: - New columns (template_name, consumer_app, is_override) exist after upgrade_to_head() @@ -23,15 +23,15 @@ ) PostgresContainer = testcontainers.PostgresContainer -import civiccore # noqa: E402 -from civiccore.migrations.runner import current_revision, upgrade_to_head # noqa: E402 -from civiccore.migrations.versions.civiccore_0001_baseline_v1 import ( # noqa: E402 +import townlight_core # noqa: E402 +from townlight_core.migrations.runner import current_revision, upgrade_to_head # noqa: E402 +from townlight_core.migrations.versions.townlight_core_0001_baseline_v1 import ( # noqa: E402 _SHARED_TABLE_ORDER, ) -EXPECTED_HEAD = "civiccore_0009_job_artifacts" +EXPECTED_HEAD = "townlight_core_0009" -_ALEMBIC_INI = Path(civiccore.__file__).parent / "migrations" / "alembic.ini" +_ALEMBIC_INI = Path(townlight_core.__file__).parent / "migrations" / "alembic.ini" def _docker_available() -> bool: @@ -119,7 +119,7 @@ def test_0002_prompt_templates_has_new_columns(engine, pg_container): """After upgrade_to_head(), prompt_templates has the Phase 2 override columns. Verifies: - - Current revision is the latest CivicCore head + - Current revision is the latest TownlightCore head - template_name column exists (renamed from name) - consumer_app column exists - is_override column exists @@ -160,11 +160,11 @@ def test_0002_prompt_templates_has_new_columns(engine, pg_container): def test_0002_upgrade_from_0001_baseline(pg_container): """Incremental upgrade from 0001 through 0002 transforms prompt_templates correctly. - Step 1: Apply only civiccore_0001_baseline_v1 — verify old schema shape (name column). + Step 1: Apply only townlight_core_0001_baseline_v1 — verify old schema shape (name column). Step 2: Apply upgrade_to_head() — verify 0002 shape plus any later head migrations. """ # Step 1: only 0001 applied - _upgrade_to_revision(pg_container, "civiccore_0001_baseline_v1") + _upgrade_to_revision(pg_container, "townlight_core_0001") url = pg_container.get_connection_url() eng = sa.create_engine(url, future=True) diff --git a/tests/test_llm_ollama_think.py b/tests/test_llm_ollama_think.py index 2e0b341..64010f8 100644 --- a/tests/test_llm_ollama_think.py +++ b/tests/test_llm_ollama_think.py @@ -12,7 +12,7 @@ import pytest import respx -from civiccore.llm.providers import OllamaConfig, OllamaProvider +from townlight_core.llm.providers import OllamaConfig, OllamaProvider @pytest.mark.asyncio @@ -41,7 +41,7 @@ async def test_think_level_string_is_sent(): def test_config_accepts_think_and_builds_provider(): - from civiccore.llm.factory import build_provider + from townlight_core.llm.factory import build_provider provider = build_provider("ollama", OllamaConfig(base_url="http://t", think=False)) assert isinstance(provider, OllamaProvider) diff --git a/tests/test_llm_providers.py b/tests/test_llm_providers.py index 0308f3f..f222cee 100644 --- a/tests/test_llm_providers.py +++ b/tests/test_llm_providers.py @@ -1,4 +1,4 @@ -"""Unit tests for civiccore.llm.providers. +"""Unit tests for townlight_core.llm.providers. No live HTTP, no real API keys. httpx-based providers are mocked with respx; optional-SDK providers (openai, anthropic) are mocked via unittest.mock. @@ -17,7 +17,7 @@ import pytest import respx -from civiccore.llm.providers import ( +from townlight_core.llm.providers import ( AnthropicProvider, LLMProvider, OllamaProvider, @@ -35,7 +35,7 @@ def test_three_builtin_providers_registered(): - """Importing civiccore.llm.providers must register all three built-ins.""" + """Importing townlight_core.llm.providers must register all three built-ins.""" assert {"ollama", "openai", "anthropic"}.issubset(set(list_providers())) @@ -74,11 +74,11 @@ def test_get_unknown_provider_raises(): def test_fourth_provider_extensibility(): - """Prove a fourth provider can be registered without editing civiccore source. + """Prove a fourth provider can be registered without editing townlight_core source. This test imports ONLY the public API (register_provider, list_providers, get_provider, LLMProvider) and demonstrates that a downstream consumer can - add their own provider with no civiccore source changes. + add their own provider with no townlight_core source changes. """ try: @@ -232,7 +232,7 @@ def test_openai_provider_raises_clear_error_without_sdk(monkeypatch): # fresh resolution path even if the SDK was already imported elsewhere. monkeypatch.delitem(sys.modules, "openai", raising=False) monkeypatch.setitem(sys.modules, "openai", None) - with pytest.raises(ImportError, match=r"civiccore\[openai\]"): + with pytest.raises(ImportError, match=r"townlight_core\[openai\]"): OpenAIProvider(api_key="dummy") @@ -243,7 +243,7 @@ def test_anthropic_provider_raises_clear_error_without_sdk(monkeypatch): monkeypatch.delitem(sys.modules, "anthropic", raising=False) monkeypatch.setitem(sys.modules, "anthropic", None) - with pytest.raises(ImportError, match=r"civiccore\[anthropic\]"): + with pytest.raises(ImportError, match=r"townlight_core\[anthropic\]"): AnthropicProvider(api_key="dummy") @@ -313,7 +313,7 @@ def test_supports_images_property(): def test_ollama_config_defaults(): """OllamaConfig builds with no fields supplied; sensible defaults.""" - from civiccore.llm.providers import OllamaConfig + from townlight_core.llm.providers import OllamaConfig cfg = OllamaConfig() assert cfg.base_url == "http://localhost:11434" assert cfg.default_model == "gemma4:e4b" @@ -321,7 +321,7 @@ def test_ollama_config_defaults(): def test_openai_config_requires_api_key(): """OpenAIConfig.api_key is required and must be non-empty.""" - from civiccore.llm.providers import OpenAIConfig + from townlight_core.llm.providers import OpenAIConfig from pydantic import ValidationError with pytest.raises(ValidationError): OpenAIConfig() # missing api_key @@ -331,7 +331,7 @@ def test_openai_config_requires_api_key(): def test_anthropic_config_requires_api_key_and_positive_max_tokens(): """AnthropicConfig validates api_key and max_tokens > 0.""" - from civiccore.llm.providers import AnthropicConfig + from townlight_core.llm.providers import AnthropicConfig from pydantic import ValidationError with pytest.raises(ValidationError): AnthropicConfig() # missing api_key @@ -342,8 +342,8 @@ def test_anthropic_config_requires_api_key_and_positive_max_tokens(): @pytest.mark.asyncio async def test_build_provider_validates_config_type(): """build_provider raises TypeError when given the wrong config schema.""" - from civiccore.llm.factory import build_provider - from civiccore.llm.providers import OpenAIConfig + from townlight_core.llm.factory import build_provider + from townlight_core.llm.providers import OpenAIConfig # Pass OpenAIConfig to ollama; should be rejected with pytest.raises(TypeError, match="ollama.*expects config type OllamaConfig"): build_provider("ollama", OpenAIConfig(api_key="k")) @@ -352,8 +352,8 @@ async def test_build_provider_validates_config_type(): @pytest.mark.asyncio async def test_build_provider_unknown_name_raises_key_error(): """build_provider raises KeyError naming available providers.""" - from civiccore.llm.factory import build_provider - from civiccore.llm.providers import OllamaConfig + from townlight_core.llm.factory import build_provider + from townlight_core.llm.providers import OllamaConfig with pytest.raises(KeyError, match="not registered"): build_provider("nonexistent_provider", OllamaConfig()) @@ -361,8 +361,8 @@ async def test_build_provider_unknown_name_raises_key_error(): @pytest.mark.asyncio async def test_build_provider_constructs_ollama_with_valid_config(): """build_provider with valid OllamaConfig returns a working provider instance.""" - from civiccore.llm.factory import build_provider - from civiccore.llm.providers import OllamaConfig, OllamaProvider + from townlight_core.llm.factory import build_provider + from townlight_core.llm.providers import OllamaConfig, OllamaProvider cfg = OllamaConfig(base_url="http://test:11434", default_model="custom") provider = build_provider("ollama", cfg) assert isinstance(provider, OllamaProvider) @@ -374,8 +374,8 @@ async def test_build_provider_constructs_ollama_with_valid_config(): @pytest.mark.asyncio async def test_build_provider_constructs_openai_with_valid_config(): """build_provider with valid OpenAIConfig returns OpenAIProvider.""" - from civiccore.llm.factory import build_provider - from civiccore.llm.providers import OpenAIConfig, OpenAIProvider + from townlight_core.llm.factory import build_provider + from townlight_core.llm.providers import OpenAIConfig, OpenAIProvider cfg = OpenAIConfig(api_key="dummy") provider = build_provider("openai", cfg) assert isinstance(provider, OpenAIProvider) @@ -385,8 +385,8 @@ async def test_build_provider_constructs_openai_with_valid_config(): @pytest.mark.asyncio async def test_build_provider_constructs_anthropic_with_valid_config(): """build_provider with valid AnthropicConfig returns AnthropicProvider.""" - from civiccore.llm.factory import build_provider - from civiccore.llm.providers import AnthropicConfig, AnthropicProvider + from townlight_core.llm.factory import build_provider + from townlight_core.llm.providers import AnthropicConfig, AnthropicProvider cfg = AnthropicConfig(api_key="dummy") provider = build_provider("anthropic", cfg) assert isinstance(provider, AnthropicProvider) diff --git a/tests/test_llm_public_api.py b/tests/test_llm_public_api.py index 7bc5093..990e310 100644 --- a/tests/test_llm_public_api.py +++ b/tests/test_llm_public_api.py @@ -1,22 +1,22 @@ -"""Smoke test: civiccore.llm public API is fully importable and complete. +"""Smoke test: townlight_core.llm public API is fully importable and complete. This test exists so that any future refactor that breaks a public symbol fails CI immediately. The list of expected public symbols is the contract -that downstream apps (records-ai, civicclerk) rely on. +that downstream apps (records-ai, townlight_meetings) rely on. """ from __future__ import annotations -def test_civiccore_llm_imports_cleanly(): - """Importing civiccore.llm must not error and must register built-in providers.""" - import civiccore.llm # noqa: F401 - from civiccore.llm.providers import PROVIDER_REGISTRY +def test_townlight_core_llm_imports_cleanly(): + """Importing townlight_core.llm must not error and must register built-in providers.""" + import townlight_core.llm # noqa: F401 + from townlight_core.llm.providers import PROVIDER_REGISTRY assert {"ollama", "openai", "anthropic"}.issubset(set(PROVIDER_REGISTRY.keys())) def test_public_api_surface_is_complete(): """All expected symbols are exposed at the package root.""" - import civiccore.llm as llm + import townlight_core.llm as llm expected = { # Providers "LLMProvider", "PROVIDER_REGISTRY", "register_provider", @@ -28,7 +28,7 @@ def test_public_api_surface_is_complete(): # Templates "PromptTemplate", "PromptTemplateCreate", "PromptTemplateRead", "RenderedPrompt", "render_template", "resolve_template", - "CIVICCORE_DEFAULT_APP", + "TOWNLIGHT_CORE_DEFAULT_APP", "PromptTemplateError", "PromptTemplateNotFoundError", "PromptTemplateRenderError", "OVERRIDE_REGISTRY", "register_template_override", @@ -49,7 +49,7 @@ def test_public_api_surface_is_complete(): "DEFAULT_MAX_ATTEMPTS", } missing = expected - set(dir(llm)) - assert not missing, f"Missing public symbols in civiccore.llm: {missing}" + assert not missing, f"Missing public symbols in townlight_core.llm: {missing}" def test_public_api_has_no_cost_tracking(): @@ -57,27 +57,27 @@ def test_public_api_has_no_cost_tracking(): Token budget is allowed (context-window math). Cost/dollar/spend is not. """ - import civiccore.llm as llm + import townlight_core.llm as llm forbidden_substrings = ("cost", "dollar", "spend", "billing", "budget_enforce") surface = " ".join(dir(llm)).lower() for sub in forbidden_substrings: # "budget" alone is fine (TokenBudget). Forbid the more loaded terms. assert sub not in surface, ( - f"Forbidden cost-tracking surface present in civiccore.llm: {sub}. " - "Per ADR-0004, no cost tracking in civiccore." + f"Forbidden cost-tracking surface present in townlight_core.llm: {sub}. " + "Per ADR-0004, no cost tracking in townlight_core." ) def test_public_api_no_live_provider_calls_at_import(): - """Importing civiccore.llm must not make any live HTTP/provider call. + """Importing townlight_core.llm must not make any live HTTP/provider call. This test is a smoke check that import time is purely registration — no network. (If this passed once, that's mostly proof; the test exists so any future code that adds an import-time call will be caught.) """ # If import-time made a real call, the import would slow drastically or - # fail without network. The previous test_civiccore_llm_imports_cleanly + # fail without network. The previous test_townlight_core_llm_imports_cleanly # would have flaked. This explicit test exists as a documentation hook. - import civiccore.llm # noqa: F401 + import townlight_core.llm # noqa: F401 # No assertion — successful import + the imports_cleanly test passing # is the assertion. diff --git a/tests/test_llm_registry_service.py b/tests/test_llm_registry_service.py index 8db4b76..77250cd 100644 --- a/tests/test_llm_registry_service.py +++ b/tests/test_llm_registry_service.py @@ -1,7 +1,7 @@ -"""Tests for civiccore.llm.registry.service and .router. +"""Tests for townlight_core.llm.registry.service and .router. Mirrors the testcontainer pattern from tests/test_llm_templates.py: -function-scoped Postgres container, schema upgraded to civiccore HEAD, +function-scoped Postgres container, schema upgraded to townlight_core HEAD, fresh AsyncSession per test for full isolation. Hard Rule 4a: no test.skip / xfail / inside-test importorskip. The Docker @@ -33,8 +33,8 @@ ) PostgresContainer = testcontainers.PostgresContainer -from civiccore.llm.context import DEFAULT_CONTEXT_WINDOW # noqa: E402 -from civiccore.llm.registry import ( # noqa: E402 +from townlight_core.llm.context import DEFAULT_CONTEXT_WINDOW # noqa: E402 +from townlight_core.llm.registry import ( # noqa: E402 MissingModelError, ModelRegistry, get_active_model, @@ -42,8 +42,8 @@ model_registry_router, require_active_model, ) -from civiccore.llm.registry.router import get_session # noqa: E402 -from civiccore.migrations.runner import upgrade_to_head # noqa: E402 +from townlight_core.llm.registry.router import get_session # noqa: E402 +from townlight_core.migrations.runner import upgrade_to_head # noqa: E402 # --------------------------------------------------------------------------- diff --git a/tests/test_llm_structured.py b/tests/test_llm_structured.py index 20fce95..310ee33 100644 --- a/tests/test_llm_structured.py +++ b/tests/test_llm_structured.py @@ -1,4 +1,4 @@ -"""Tests for civiccore.llm.structured.StructuredOutput. +"""Tests for townlight_core.llm.structured.StructuredOutput. All tests use a fake LLMProvider with canned responses - NO live provider calls, NO DB, NO network. @@ -10,8 +10,8 @@ import pytest from pydantic import BaseModel -from civiccore.llm.providers.base import LLMProvider -from civiccore.llm.structured import StructuredOutput, StructuredOutputFailure +from townlight_core.llm.providers.base import LLMProvider +from townlight_core.llm.structured import StructuredOutput, StructuredOutputFailure class _FakeProvider(LLMProvider): @@ -169,7 +169,7 @@ def test_structured_output_no_live_calls() -> None: this no-op test simply imports the helper module to confirm it loads without pulling in httpx-bound live clients at import time. """ - from civiccore.llm import structured as _structured # noqa: F401 + from townlight_core.llm import structured as _structured # noqa: F401 assert _structured.StructuredOutput is StructuredOutput assert _structured.StructuredOutputFailure is StructuredOutputFailure diff --git a/tests/test_llm_templates.py b/tests/test_llm_templates.py index e634f4d..47bb189 100644 --- a/tests/test_llm_templates.py +++ b/tests/test_llm_templates.py @@ -2,7 +2,7 @@ Engine tests are pure unit tests (no DB). Resolver tests use a fresh testcontainer Postgres per test (function scope) so each scenario starts from -an empty schema upgraded to civiccore HEAD — preventing cross-test bleed. +an empty schema upgraded to townlight_core HEAD — preventing cross-test bleed. Hard Rule 4a: no test.skip / xfail / inside-test importorskip. The Docker importorskip at module top is acceptable per the existing test_baseline_idempotency @@ -34,21 +34,21 @@ ) PostgresContainer = testcontainers.PostgresContainer -from civiccore.llm.templates.engine import RenderedPrompt, render_template # noqa: E402 -from civiccore.llm.templates.exceptions import ( # noqa: E402 +from townlight_core.llm.templates.engine import RenderedPrompt, render_template # noqa: E402 +from townlight_core.llm.templates.exceptions import ( # noqa: E402 PromptTemplateNotFoundError, PromptTemplateRenderError, ) -from civiccore.llm.templates.models import PromptTemplate # noqa: E402 -from civiccore.llm.templates.overrides import ( # noqa: E402 +from townlight_core.llm.templates.models import PromptTemplate # noqa: E402 +from townlight_core.llm.templates.overrides import ( # noqa: E402 register_template_override, unregister_template_override, ) -from civiccore.llm.templates.resolver import ( # noqa: E402 - CIVICCORE_DEFAULT_APP, +from townlight_core.llm.templates.resolver import ( # noqa: E402 + TOWNLIGHT_CORE_DEFAULT_APP, resolve_template, ) -from civiccore.migrations.runner import upgrade_to_head # noqa: E402 +from townlight_core.migrations.runner import upgrade_to_head # noqa: E402 # --------------------------------------------------------------------------- @@ -84,7 +84,7 @@ def _database_url_env(pg_container): def _make_template( *, template_name: str, - consumer_app: str = "civiccore", + consumer_app: str = "townlight_core", is_override: bool = False, version: int = 1, is_active: bool = True, @@ -126,7 +126,7 @@ def pg_container(): @pytest_asyncio.fixture(loop_scope="function") async def session(pg_container): - """AsyncSession against a fresh DB upgraded to civiccore HEAD.""" + """AsyncSession against a fresh DB upgraded to townlight_core HEAD.""" # 1. Upgrade schema via the runner (uses DATABASE_URL). with _database_url_env(pg_container): upgrade_to_head() @@ -158,7 +158,7 @@ def test_render_template_substitutes_system_and_user(): """$name and $msg substitute into both system_prompt and user_prompt_template.""" tmpl = _make_template( template_name="greet", - consumer_app="civiccore", + consumer_app="townlight_core", version=3, system_prompt="hi $name", user_prompt_template="say $msg", @@ -170,7 +170,7 @@ def test_render_template_substitutes_system_and_user(): assert result.system == "hi alice" assert result.user == "say hello" assert result.template_name == "greet" - assert result.consumer_app == "civiccore" + assert result.consumer_app == "townlight_core" assert result.version == 3 @@ -240,12 +240,12 @@ def test_render_template_does_not_collide_with_json_braces(): @pytest.mark.asyncio -async def test_resolver_returns_civiccore_default_when_only_default_exists(session): - """A civiccore default is returned when no app-specific override exists.""" +async def test_resolver_returns_townlight_core_default_when_only_default_exists(session): + """A townlight_core default is returned when no app-specific override exists.""" session.add( _make_template( template_name="t1", - consumer_app=CIVICCORE_DEFAULT_APP, + consumer_app=TOWNLIGHT_CORE_DEFAULT_APP, is_override=False, is_active=True, ) @@ -253,21 +253,21 @@ async def test_resolver_returns_civiccore_default_when_only_default_exists(sessi await session.commit() found = await resolve_template( - session, template_name="t1", consumer_app="civicrecords-ai" + session, template_name="t1", consumer_app="townlight_records" ) assert found.template_name == "t1" - assert found.consumer_app == CIVICCORE_DEFAULT_APP + assert found.consumer_app == TOWNLIGHT_CORE_DEFAULT_APP assert found.is_override is False @pytest.mark.asyncio -async def test_resolver_app_override_wins_over_civiccore_default(session): - """When an app override exists, it wins over the civiccore default.""" +async def test_resolver_app_override_wins_over_townlight_core_default(session): + """When an app override exists, it wins over the townlight_core default.""" session.add( _make_template( template_name="t2", - consumer_app=CIVICCORE_DEFAULT_APP, + consumer_app=TOWNLIGHT_CORE_DEFAULT_APP, is_override=False, system_prompt="DEFAULT system", ) @@ -275,7 +275,7 @@ async def test_resolver_app_override_wins_over_civiccore_default(session): session.add( _make_template( template_name="t2", - consumer_app="civicrecords-ai", + consumer_app="townlight_records", is_override=True, system_prompt="OVERRIDE system", ) @@ -283,37 +283,37 @@ async def test_resolver_app_override_wins_over_civiccore_default(session): await session.commit() found = await resolve_template( - session, template_name="t2", consumer_app="civicrecords-ai" + session, template_name="t2", consumer_app="townlight_records" ) - assert found.consumer_app == "civicrecords-ai" + assert found.consumer_app == "townlight_records" assert found.is_override is True assert found.system_prompt == "OVERRIDE system" @pytest.mark.asyncio -async def test_resolver_civiccore_app_skips_step1(session): - """When consumer_app == 'civiccore', step 1 (override lookup) is skipped. +async def test_resolver_townlight_core_app_skips_step1(session): + """When consumer_app == 'townlight_core', step 1 (override lookup) is skipped. - Even if a civiccore + is_override=True row exists (operator misconfiguration), - a consumer_app='civiccore' resolution returns the canonical default + Even if a townlight_core + is_override=True row exists (operator misconfiguration), + a consumer_app='townlight_core' resolution returns the canonical default (is_override=False) row. """ # Misplaced override row (same app as the default — operator slip). session.add( _make_template( template_name="t3", - consumer_app=CIVICCORE_DEFAULT_APP, + consumer_app=TOWNLIGHT_CORE_DEFAULT_APP, is_override=True, version=1, - system_prompt="WEIRD override-on-civiccore", + system_prompt="WEIRD override-on-townlight_core", ) ) # Canonical default. session.add( _make_template( template_name="t3", - consumer_app=CIVICCORE_DEFAULT_APP, + consumer_app=TOWNLIGHT_CORE_DEFAULT_APP, is_override=False, version=2, system_prompt="canonical default", @@ -322,7 +322,7 @@ async def test_resolver_civiccore_app_skips_step1(session): await session.commit() found = await resolve_template( - session, template_name="t3", consumer_app=CIVICCORE_DEFAULT_APP + session, template_name="t3", consumer_app=TOWNLIGHT_CORE_DEFAULT_APP ) assert found.is_override is False @@ -335,7 +335,7 @@ async def test_resolver_inactive_templates_ignored(session): session.add( _make_template( template_name="t4", - consumer_app=CIVICCORE_DEFAULT_APP, + consumer_app=TOWNLIGHT_CORE_DEFAULT_APP, is_active=False, ) ) @@ -343,7 +343,7 @@ async def test_resolver_inactive_templates_ignored(session): with pytest.raises(PromptTemplateNotFoundError): await resolve_template( - session, template_name="t4", consumer_app="civicrecords-ai" + session, template_name="t4", consumer_app="townlight_records" ) @@ -353,7 +353,7 @@ async def test_resolver_highest_version_wins(session): session.add( _make_template( template_name="t5", - consumer_app=CIVICCORE_DEFAULT_APP, + consumer_app=TOWNLIGHT_CORE_DEFAULT_APP, version=1, is_active=True, system_prompt="v1", @@ -362,7 +362,7 @@ async def test_resolver_highest_version_wins(session): session.add( _make_template( template_name="t5", - consumer_app=CIVICCORE_DEFAULT_APP, + consumer_app=TOWNLIGHT_CORE_DEFAULT_APP, version=2, is_active=True, system_prompt="v2", @@ -371,7 +371,7 @@ async def test_resolver_highest_version_wins(session): await session.commit() found = await resolve_template( - session, template_name="t5", consumer_app="civicrecords-ai" + session, template_name="t5", consumer_app="townlight_records" ) assert found.version == 2 @@ -384,7 +384,7 @@ async def test_resolver_inactive_higher_version_skipped_active_lower_returned(se session.add( _make_template( template_name="t6", - consumer_app=CIVICCORE_DEFAULT_APP, + consumer_app=TOWNLIGHT_CORE_DEFAULT_APP, version=1, is_active=True, system_prompt="v1-active", @@ -393,7 +393,7 @@ async def test_resolver_inactive_higher_version_skipped_active_lower_returned(se session.add( _make_template( template_name="t6", - consumer_app=CIVICCORE_DEFAULT_APP, + consumer_app=TOWNLIGHT_CORE_DEFAULT_APP, version=2, is_active=False, system_prompt="v2-inactive", @@ -402,7 +402,7 @@ async def test_resolver_inactive_higher_version_skipped_active_lower_returned(se await session.commit() found = await resolve_template( - session, template_name="t6", consumer_app="civicrecords-ai" + session, template_name="t6", consumer_app="townlight_records" ) assert found.version == 1 @@ -414,16 +414,16 @@ async def test_resolver_missing_template_raises_actionable_error(session): """Empty DB raises NotFound carrying both template_name and consumer_app.""" with pytest.raises(PromptTemplateNotFoundError) as excinfo: await resolve_template( - session, template_name="nope", consumer_app="civicrecords-ai" + session, template_name="nope", consumer_app="townlight_records" ) err = excinfo.value # Constructor exposes these attributes per the spec. assert err.template_name == "nope" - assert err.consumer_app == "civicrecords-ai" + assert err.consumer_app == "townlight_records" msg = str(err) assert "nope" in msg - assert "civicrecords-ai" in msg + assert "townlight_records" in msg def test_resolver_uses_template_name_not_old_name_column(): @@ -435,27 +435,27 @@ def test_resolver_uses_template_name_not_old_name_column(): @pytest.mark.asyncio async def test_resolver_uses_consumer_app_not_null_fallback(session): - """The civiccore default uses consumer_app='civiccore', NOT IS NULL. + """The townlight_core default uses consumer_app='townlight_core', NOT IS NULL. Per ADR-0004, the legacy IS NULL fallback is removed; the default tier - is keyed on the literal string 'civiccore'. + is keyed on the literal string 'townlight_core'. """ session.add( _make_template( template_name="t8", - consumer_app=CIVICCORE_DEFAULT_APP, # literal "civiccore" + consumer_app=TOWNLIGHT_CORE_DEFAULT_APP, # literal "townlight_core" is_override=False, is_active=True, ) ) await session.commit() - # Resolution from a different consumer_app finds the civiccore default. + # Resolution from a different consumer_app finds the townlight_core default. found = await resolve_template( - session, template_name="t8", consumer_app="civicrecords-ai" + session, template_name="t8", consumer_app="townlight_records" ) - assert found.consumer_app == CIVICCORE_DEFAULT_APP + assert found.consumer_app == TOWNLIGHT_CORE_DEFAULT_APP # Belt-and-suspenders: the column value is non-null. assert found.consumer_app is not None @@ -472,13 +472,13 @@ async def test_resolver_db_override_wins_over_code_override(session): # Register code override code_tmpl = _make_template( template_name="contested", - consumer_app="civicrecords-ai", + consumer_app="townlight_records", is_override=True, system_prompt="CODE OVERRIDE", user_prompt_template="from code", ) register_template_override( - consumer_app="civicrecords-ai", + consumer_app="townlight_records", template_name="contested", template=code_tmpl, ) @@ -486,7 +486,7 @@ async def test_resolver_db_override_wins_over_code_override(session): # Persist DB override (different prompt body) db_override = _make_template( template_name="contested", - consumer_app="civicrecords-ai", + consumer_app="townlight_records", is_override=True, is_active=True, system_prompt="DB OVERRIDE", @@ -498,76 +498,76 @@ async def test_resolver_db_override_wins_over_code_override(session): resolved = await resolve_template( session, template_name="contested", - consumer_app="civicrecords-ai", + consumer_app="townlight_records", ) assert resolved.system_prompt == "DB OVERRIDE" finally: unregister_template_override( - consumer_app="civicrecords-ai", template_name="contested" + consumer_app="townlight_records", template_name="contested" ) @pytest.mark.asyncio -async def test_resolver_code_override_wins_over_civiccore_default(session): - """No DB app override; code-level override beats civiccore default.""" +async def test_resolver_code_override_wins_over_townlight_core_default(session): + """No DB app override; code-level override beats townlight_core default.""" code_tmpl = _make_template( template_name="t1", - consumer_app="civicrecords-ai", + consumer_app="townlight_records", is_override=True, system_prompt="CODE OVERRIDE", user_prompt_template="x", ) register_template_override( - consumer_app="civicrecords-ai", + consumer_app="townlight_records", template_name="t1", template=code_tmpl, ) try: - # civiccore default in DB - civiccore_default = _make_template( + # townlight_core default in DB + townlight_core_default = _make_template( template_name="t1", - consumer_app="civiccore", + consumer_app="townlight_core", is_override=False, is_active=True, - system_prompt="CIVICCORE DEFAULT", + system_prompt="TOWNLIGHT_CORE DEFAULT", user_prompt_template="y", ) - session.add(civiccore_default) + session.add(townlight_core_default) await session.commit() resolved = await resolve_template( session, template_name="t1", - consumer_app="civicrecords-ai", + consumer_app="townlight_records", ) assert resolved.system_prompt == "CODE OVERRIDE" finally: unregister_template_override( - consumer_app="civicrecords-ai", template_name="t1" + consumer_app="townlight_records", template_name="t1" ) @pytest.mark.asyncio -async def test_resolver_civiccore_app_skips_code_override(session): - """consumer_app='civiccore' skips both step 1 (DB override) and step 2 - (code override). civiccore owns its own defaults.""" +async def test_resolver_townlight_core_app_skips_code_override(session): + """consumer_app='townlight_core' skips both step 1 (DB override) and step 2 + (code override). townlight_core owns its own defaults.""" code_tmpl = _make_template( template_name="t2", - consumer_app="civiccore", + consumer_app="townlight_core", system_prompt="CODE", user_prompt_template="x", ) - # Register a code override under civiccore (operator could theoretically - # do this; resolver must ignore it for consumer_app='civiccore' callers). + # Register a code override under townlight_core (operator could theoretically + # do this; resolver must ignore it for consumer_app='townlight_core' callers). register_template_override( - consumer_app="civiccore", + consumer_app="townlight_core", template_name="t2", template=code_tmpl, ) try: - # civiccore DB default + # townlight_core DB default db_default = _make_template( template_name="t2", - consumer_app="civiccore", + consumer_app="townlight_core", is_active=True, system_prompt="DB DEFAULT", user_prompt_template="y", @@ -575,13 +575,13 @@ async def test_resolver_civiccore_app_skips_code_override(session): session.add(db_default) await session.commit() resolved = await resolve_template( - session, template_name="t2", consumer_app="civiccore" + session, template_name="t2", consumer_app="townlight_core" ) - # Returns DB default; ignores any registered code override under civiccore + # Returns DB default; ignores any registered code override under townlight_core assert resolved.system_prompt == "DB DEFAULT" finally: unregister_template_override( - consumer_app="civiccore", template_name="t2" + consumer_app="townlight_core", template_name="t2" ) @@ -590,25 +590,25 @@ async def test_resolver_code_override_alone_is_resolvable(session): """No DB row at all; code override is the only source. Resolver returns it.""" code_tmpl = _make_template( template_name="solo", - consumer_app="civicrecords-ai", + consumer_app="townlight_records", is_override=True, system_prompt="ONLY IN CODE", user_prompt_template="x", ) register_template_override( - consumer_app="civicrecords-ai", + consumer_app="townlight_records", template_name="solo", template=code_tmpl, ) try: # Empty DB; only the code override exists. resolved = await resolve_template( - session, template_name="solo", consumer_app="civicrecords-ai" + session, template_name="solo", consumer_app="townlight_records" ) assert resolved.system_prompt == "ONLY IN CODE" finally: unregister_template_override( - consumer_app="civicrecords-ai", template_name="solo" + consumer_app="townlight_records", template_name="solo" ) @@ -623,7 +623,7 @@ async def test_resolver_then_render_e2e(session): session.add( _make_template( template_name="e2e", - consumer_app=CIVICCORE_DEFAULT_APP, + consumer_app=TOWNLIGHT_CORE_DEFAULT_APP, system_prompt="You are a $role.", user_prompt_template="Process this: $user_input", version=1, @@ -632,7 +632,7 @@ async def test_resolver_then_render_e2e(session): await session.commit() tmpl = await resolve_template( - session, template_name="e2e", consumer_app="civicrecords-ai" + session, template_name="e2e", consumer_app="townlight_records" ) rendered = render_template( tmpl, {"role": "summarizer", "user_input": "the meeting minutes"} @@ -641,5 +641,5 @@ async def test_resolver_then_render_e2e(session): assert rendered.system == "You are a summarizer." assert rendered.user == "Process this: the meeting minutes" assert rendered.template_name == "e2e" - assert rendered.consumer_app == CIVICCORE_DEFAULT_APP + assert rendered.consumer_app == TOWNLIGHT_CORE_DEFAULT_APP assert rendered.version == 1 diff --git a/tests/test_module_inventory.py b/tests/test_module_inventory.py index fc06253..cb761f4 100644 --- a/tests/test_module_inventory.py +++ b/tests/test_module_inventory.py @@ -12,8 +12,8 @@ import pytest -from civiccore.platform import ModuleManifest -from civiccore.platform.inventory import ( +from townlight_core.platform import ModuleManifest +from townlight_core.platform.inventory import ( InventoryConflictError, ModuleInventory, ModuleInventoryEntry, @@ -31,7 +31,7 @@ def manifest(name, *, version="1.0.0", **extra): name=name.title(), version=version, package_name=name, - civiccore_min_version="1.3.0", + townlight_core_min_version="1.3.0", **extra, ) @@ -44,7 +44,7 @@ def entry(item, *, enabled=True): def inventory(*entries, scope="city-a", revision=1, version="1.3.0"): return ModuleInventory( - scope_id=scope, revision=revision, civiccore_version=version, entries=list(entries) + scope_id=scope, revision=revision, townlight_core_version=version, entries=list(entries) ) @@ -139,7 +139,7 @@ def test_core_too_old_is_reported_as_upgrade_core_not_dependency(): item = inventory(entry(meeting), version="1.2.9") [recommendation] = module_recommendations(item) assert recommendation.action == "upgrade-core" - assert "CivicCore" in recommendation.operator_action + assert "TownlightCore" in recommendation.operator_action def test_profile_mismatch_is_reported_as_not_supported(): diff --git a/tests/test_module_inventory_adr.py b/tests/test_module_inventory_adr.py index 8ede5f6..d4038f4 100644 --- a/tests/test_module_inventory_adr.py +++ b/tests/test_module_inventory_adr.py @@ -10,7 +10,7 @@ from pathlib import Path -import civiccore.platform.inventory as inventory +import townlight_core.platform.inventory as inventory REPO_ROOT = Path(__file__).resolve().parents[1] @@ -26,7 +26,7 @@ def test_inventory_adr_records_contract_and_retains_historical_deferrals() -> No # The non-claims the contract must keep making. assert "No scanning, network access, package enumeration" in current assert "Advice separated from evidence" in current - assert "civiccore.catalog" in current + assert "civiccore.catalog" in current # Dated ADR's original identity. assert "build_module_registry" in current historical = (REPO_ROOT / "docs/adr/ADR-0001-defer-civiccore-catalog.md").read_text( @@ -46,14 +46,14 @@ def test_inventory_module_documents_the_non_claims_it_must_uphold() -> None: assert "never scans a machine" in docstring assert "exactly one module resolver" in docstring - assert "civiccore.platform.modules.build_module_registry" in docstring + assert "townlight_core.platform.modules.build_module_registry" in docstring assert "not installation evidence" in docstring assert "reference data about *vendor systems*" in docstring assert "caller-supplied" in docstring def test_inventory_contract_is_importable_from_the_platform_namespace() -> None: - import civiccore.platform as platform + import townlight_core.platform as platform for name in ( "ModuleInventory", diff --git a/tests/test_module_resolution.py b/tests/test_module_resolution.py index 37e708d..f6482e1 100644 --- a/tests/test_module_resolution.py +++ b/tests/test_module_resolution.py @@ -1,7 +1,7 @@ """Dependency admission must not enable a module whose prerequisites cannot run.""" import pytest -from civiccore.platform import ModuleManifest, build_module_registry +from townlight_core.platform import ModuleManifest, build_module_registry def module(name, **extra): @@ -10,7 +10,7 @@ def module(name, **extra): name=name, version="1.0.0", package_name=name, - civiccore_min_version="1.2.0", + townlight_core_min_version="1.2.0", **extra, ) @@ -18,7 +18,7 @@ def module(name, **extra): def resolve(*modules, version="1.3.0.dev1"): return { entry.module_id: entry - for entry in build_module_registry(list(modules), civiccore_version=version).entries + for entry in build_module_registry(list(modules), townlight_core_version=version).entries } diff --git a/tests/test_notifications_notice.py b/tests/test_notifications_notice.py index ccf7b63..d0d6f3b 100644 --- a/tests/test_notifications_notice.py +++ b/tests/test_notifications_notice.py @@ -2,7 +2,7 @@ from datetime import UTC, date, datetime -from civiccore.notifications import build_deadline_plan, evaluate_notice_compliance +from townlight_core.notifications import build_deadline_plan, evaluate_notice_compliance def test_build_deadline_plan_returns_publish_by_and_reminders() -> None: diff --git a/tests/test_onboarding_profile.py b/tests/test_onboarding_profile.py index 2ee1490..c060e93 100644 --- a/tests/test_onboarding_profile.py +++ b/tests/test_onboarding_profile.py @@ -1,6 +1,6 @@ from __future__ import annotations -from civiccore.onboarding import ( +from townlight_core.onboarding import ( DEFAULT_PROFILE_FIELDS, completed_profile_fields, compute_onboarding_status, diff --git a/tests/test_placeholder_adrs.py b/tests/test_placeholder_adrs.py index a31331d..130828a 100644 --- a/tests/test_placeholder_adrs.py +++ b/tests/test_placeholder_adrs.py @@ -2,19 +2,19 @@ from pathlib import Path -import civiccore.catalog -import civiccore.exemptions -import civiccore.scaffold +import townlight_core.catalog +import townlight_core.exemptions +import townlight_core.scaffold REPO_ROOT = Path(__file__).resolve().parents[1] HISTORICAL_DEFERRAL_ADRS = { - "civiccore.scaffold": REPO_ROOT / "docs/adr/ADR-0003-defer-civiccore-scaffold.md", + "townlight_core.scaffold": REPO_ROOT / "docs/adr/ADR-0003-defer-civiccore-scaffold.md", } RESUMPTION_ADRS = { - "civiccore.scaffold": REPO_ROOT / "docs/adr/ADR-0007-beta-module-scaffold.md", + "townlight_core.scaffold": REPO_ROOT / "docs/adr/ADR-0007-beta-module-scaffold.md", } @@ -22,11 +22,11 @@ def test_placeholder_namespaces_have_freeze_line_adrs() -> None: for namespace, path in HISTORICAL_DEFERRAL_ADRS.items(): text = path.read_text(encoding="utf-8") - assert namespace in text + assert namespace.replace("townlight_core", "civiccore") in text assert "Status: Accepted" in text assert "Explicit downstream consumption rule" in text assert "no module depends" in text - assert "versioned CivicCore release artifact" in text + assert "versioned CivicCore release artifact" in text # Exact historical decision. def test_placeholder_adr_index_lists_all_placeholder_namespaces() -> None: @@ -43,23 +43,23 @@ def test_scaffold_resumption_retains_historical_deferral_and_names_new_contract( historical = (REPO_ROOT / "docs/adr/ADR-0003-defer-civiccore-scaffold.md").read_text( encoding="utf-8" ) - current = RESUMPTION_ADRS["civiccore.scaffold"].read_text(encoding="utf-8") + current = RESUMPTION_ADRS["townlight_core.scaffold"].read_text(encoding="utf-8") assert "Status: Accepted" in historical assert "Defer" in historical assert "Supersedes: ADR-0003" in current assert "not released" in current assert "generate_module_project" in current - assert callable(civiccore.scaffold.generate_module_project) - assert callable(civiccore.scaffold.plan_module_project) - assert callable(civiccore.scaffold.main) + assert callable(townlight_core.scaffold.generate_module_project) + assert callable(townlight_core.scaffold.plan_module_project) + assert callable(townlight_core.scaffold.main) index = (REPO_ROOT / "docs/adr/index.md").read_text(encoding="utf-8") - assert RESUMPTION_ADRS["civiccore.scaffold"].name in index + assert RESUMPTION_ADRS["townlight_core.scaffold"].name in index def test_scaffold_package_still_withholds_downstream_dependency() -> None: - docstring = " ".join((civiccore.scaffold.__doc__ or "").split()) + docstring = " ".join((townlight_core.scaffold.__doc__ or "").split()) assert "ADR-0003-defer-civiccore-scaffold.md" in docstring assert "No downstream module may" in docstring @@ -74,5 +74,5 @@ def test_catalog_resumption_retains_historical_deferral_and_names_open_scope(): current = (REPO_ROOT / "docs/adr/ADR-0004-beta-shared-catalog.md").read_text(encoding="utf-8") assert "Status: Accepted" in historical assert "installed-module inventory" in current - assert callable(civiccore.catalog.import_catalog) - assert callable(civiccore.catalog.connectors_for) + assert callable(townlight_core.catalog.import_catalog) + assert callable(townlight_core.catalog.connectors_for) diff --git a/tests/test_platform_contracts.py b/tests/test_platform_contracts.py index fab10f6..7ada238 100644 --- a/tests/test_platform_contracts.py +++ b/tests/test_platform_contracts.py @@ -1,4 +1,4 @@ -"""Tests for CivicCore Windows-local platform contracts.""" +"""Tests for TownlightCore Windows-local platform contracts.""" from __future__ import annotations @@ -6,7 +6,7 @@ import pytest -from civiccore.platform import ( +from townlight_core.platform import ( BackupManifest, LocalRuntimeProfile, LocalTaskEnvelope, @@ -25,13 +25,13 @@ ) -def _module_manifest(module_id: str = "civicclerk", **overrides) -> ModuleManifest: +def _module_manifest(module_id: str = "townlight_meetings", **overrides) -> ModuleManifest: data = { "module_id": module_id, - "name": "CivicClerk", + "name": "TownlightMeetings", "version": "1.0.0", - "package_name": "civicclerk", - "civiccore_min_version": "1.2.0", + "package_name": "townlight_meetings", + "townlight_core_min_version": "1.2.0", "surfaces": ["staff", "admin"], "install_profiles": ["windows_local"], "permissions": [ @@ -69,15 +69,15 @@ def _module_manifest(module_id: str = "civicclerk", **overrides) -> ModuleManife "migrations": [ { "id": "initial-schema", - "description": "Create local CivicClerk tables.", - "owner_schema": "civicclerk", + "description": "Create local TownlightMeetings tables.", + "owner_schema": "townlight_meetings", } ], "backup_hooks": [ { "id": "module-data", "label": "Module data", - "includes": ["civicclerk/**"], + "includes": ["townlight_meetings/**"], } ], "model_requirements": [ @@ -124,28 +124,28 @@ def test_windows_manifest_rejects_docker_wsl_and_terminal_requirements() -> None def test_module_registry_blocks_missing_required_dependencies() -> None: manifest = _module_manifest( - dependencies=[{"module_id": "civicrecords-ai", "required": True}] + dependencies=[{"module_id": "townlight_records", "required": True}] ) registry = build_module_registry( [manifest], - civiccore_version="1.2.0", - selected_module_ids={"civicclerk"}, + townlight_core_version="1.2.0", + selected_module_ids={"townlight_meetings"}, ) entry = registry.entries[0] - assert registry.civiccore_locked is True + assert registry.townlight_core_locked is True assert entry.status == "blocked" assert entry.enabled is False - assert "civicrecords-ai" in (entry.reason or "") + assert "townlight_records" in (entry.reason or "") def test_module_registry_enables_valid_windows_local_module() -> None: manifest = _module_manifest() - registry = build_module_registry([manifest], civiccore_version="1.2.0") + registry = build_module_registry([manifest], townlight_core_version="1.2.0") - assert registry.enabled_module_ids == ["civicclerk"] + assert registry.enabled_module_ids == ["townlight_meetings"] assert registry.blocked_module_ids == [] assert registry.entries[0].manifest.routes[0].label == "Meetings & Notices" @@ -182,7 +182,7 @@ def test_local_task_retry_contract_has_no_external_runtime_assumption() -> None: now = datetime(2026, 6, 13, 12, 0, tzinfo=UTC) task = LocalTaskEnvelope( task_id="packet-export-1", - module_id="civicclerk", + module_id="townlight_meetings", task_type="packet_export", ) @@ -208,7 +208,7 @@ def test_local_task_exhaustion_is_blocking() -> None: now = datetime(2026, 6, 13, 12, 0, tzinfo=UTC) task = LocalTaskEnvelope( task_id="records-export-1", - module_id="civicrecords-ai", + module_id="townlight_records", task_type="records_export", attempt_count=1, ) @@ -228,8 +228,8 @@ def test_local_task_exhaustion_is_blocking() -> None: def test_backup_manifest_validates_hashes_and_restore_safety(tmp_path) -> None: data_root = tmp_path / "data" data_root.mkdir() - (data_root / "civicclerk").mkdir() - payload = data_root / "civicclerk" / "meetings.json" + (data_root / "townlight_meetings").mkdir() + payload = data_root / "townlight_meetings" / "meetings.json" payload.write_text('{"meeting":"Regular Council"}', encoding="utf-8") manifest = build_backup_manifest( @@ -237,8 +237,8 @@ def test_backup_manifest_validates_hashes_and_restore_safety(tmp_path) -> None: files=[payload], backup_id="backup-1", city_profile_id="sampleville", - civiccore_version="1.2.0", - module_id="civicclerk", + townlight_core_version="1.2.0", + module_id="townlight_meetings", ) assert isinstance(manifest, BackupManifest) @@ -254,16 +254,16 @@ def test_backup_manifest_validates_hashes_and_restore_safety(tmp_path) -> None: payload.write_text("tampered", encoding="utf-8") tampered = validate_backup_manifest(manifest, root=data_root) assert tampered.valid is False - assert tampered.hash_mismatches == ["civicclerk/meetings.json"] + assert tampered.hash_mismatches == ["townlight_meetings/meetings.json"] def test_restore_plan_blocks_overwrite_by_default(tmp_path) -> None: backup_root = tmp_path / "backup" restore_root = tmp_path / "restore" - (backup_root / "civiccode").mkdir(parents=True) - (restore_root / "civiccode").mkdir(parents=True) - source = backup_root / "civiccode" / "code.json" - target = restore_root / "civiccode" / "code.json" + (backup_root / "townlight_code").mkdir(parents=True) + (restore_root / "townlight_code").mkdir(parents=True) + source = backup_root / "townlight_code" / "code.json" + target = restore_root / "townlight_code" / "code.json" source.write_text('{"title":"Code"}', encoding="utf-8") target.write_text("existing", encoding="utf-8") @@ -272,8 +272,8 @@ def test_restore_plan_blocks_overwrite_by_default(tmp_path) -> None: files=[source], backup_id="backup-2", city_profile_id="sampleville", - civiccore_version="1.2.0", - module_id="civiccode", + townlight_core_version="1.2.0", + module_id="townlight_code", ) plan = plan_restore(manifest, backup_root=backup_root, restore_root=restore_root) @@ -282,7 +282,7 @@ def test_restore_plan_blocks_overwrite_by_default(tmp_path) -> None: def test_runtime_profile_and_action_result_are_local_first(tmp_path) -> None: - registry = build_module_registry([_module_manifest()], civiccore_version="1.2.0") + registry = build_module_registry([_module_manifest()], townlight_core_version="1.2.0") profile = LocalRuntimeProfile( profile_id="sampleville", @@ -296,9 +296,9 @@ def test_runtime_profile_and_action_result_are_local_first(tmp_path) -> None: action="first_run", status="succeeded", title="Setup complete", - message="CivicSuite is ready on this computer.", + message="Townlight is ready on this computer.", ) assert profile.local_only is True - assert profile.module_registry.enabled_module_ids == ["civicclerk"] + assert profile.module_registry.enabled_module_ids == ["townlight_meetings"] assert result.status == "succeeded" diff --git a/tests/test_platform_task_queue.py b/tests/test_platform_task_queue.py index 73072b8..cc18dd1 100644 --- a/tests/test_platform_task_queue.py +++ b/tests/test_platform_task_queue.py @@ -21,8 +21,8 @@ ) PostgresContainer = testcontainers.PostgresContainer -from civiccore.migrations.runner import upgrade_to_head # noqa: E402 -from civiccore.platform import ( # noqa: E402 +from townlight_core.migrations.runner import upgrade_to_head # noqa: E402 +from townlight_core.platform import ( # noqa: E402 LocalTask, LocalTaskEnvelope, TaskRetryPolicy, @@ -32,8 +32,8 @@ fail_local_task, run_one_local_task, ) -from civiccore.tasks import register_task_handler # noqa: E402 -from civiccore.tasks.worker import _run_worker # noqa: E402 +from townlight_core.tasks import register_task_handler # noqa: E402 +from townlight_core.tasks.worker import _run_worker # noqa: E402 def _docker_available() -> bool: @@ -98,7 +98,7 @@ async def session(session_factory): async def test_local_task_queue_enqueues_claims_and_completes(session) -> None: task = LocalTaskEnvelope( task_id="records-response-1", - module_id="civicrecords-ai", + module_id="townlight_records", task_type="records_response_export", payload={"request_id": "RR-1001"}, idempotency_key="RR-1001:response-export", @@ -124,7 +124,7 @@ async def test_local_task_queue_enqueues_claims_and_completes(session) -> None: async def test_local_task_queue_records_retry_state(session) -> None: task = LocalTaskEnvelope( task_id="records-search-1", - module_id="civicrecords-ai", + module_id="townlight_records", task_type="records_search_index", ) await enqueue_local_task(session, task) @@ -151,7 +151,7 @@ async def test_run_one_local_task_uses_registered_handler(session) -> None: session, LocalTaskEnvelope( task_id="records-review-1", - module_id="civicrecords-ai", + module_id="townlight_records", task_type="records_review_packet", ), ) @@ -197,7 +197,7 @@ async def handler(task: LocalTaskEnvelope) -> None: sess, LocalTaskEnvelope( task_id="records-worker-1", - module_id="civicrecords-ai", + module_id="townlight_records", task_type="records_worker_registry_probe", ), ) diff --git a/tests/test_provenance_contracts.py b/tests/test_provenance_contracts.py index e1c3160..51bf954 100644 --- a/tests/test_provenance_contracts.py +++ b/tests/test_provenance_contracts.py @@ -6,7 +6,7 @@ import pytest -from civiccore.provenance import ( +from townlight_core.provenance import ( CitationTarget, DocumentMetadata, ProvenanceBundle, diff --git a/tests/test_public_api_v03.py b/tests/test_public_api_v03.py index 707303f..883751b 100644 --- a/tests/test_public_api_v03.py +++ b/tests/test_public_api_v03.py @@ -1,10 +1,10 @@ -"""Smoke tests for the shipped CivicCore package-root surface.""" +"""Smoke tests for the shipped TownlightCore package-root surface.""" from __future__ import annotations def test_v03_public_api_symbols_import_from_package_root() -> None: - import civiccore + import townlight_core expected = { "AuditActor", @@ -141,16 +141,16 @@ def test_v03_public_api_symbols_import_from_package_root() -> None: "validate_windows_local_manifest", } - missing = expected - set(dir(civiccore)) + missing = expected - set(dir(townlight_core)) assert not missing, f"Missing shipped public symbols: {missing}" def test_v03_placeholder_modules_stay_out_of_root_surface() -> None: - import civiccore + import townlight_core not_yet_shipped = { "Auth", "ExemptionRuleEngine", } - assert not (not_yet_shipped & set(dir(civiccore))) + assert not (not_yet_shipped & set(dir(townlight_core))) diff --git a/tests/test_release_provenance.py b/tests/test_release_provenance.py index 62ec14d..f60af10 100644 --- a/tests/test_release_provenance.py +++ b/tests/test_release_provenance.py @@ -5,7 +5,7 @@ from pathlib import Path from typing import Any -from civiccore.release_provenance import ( +from townlight_core.release_provenance import ( GitHubProvenanceClient, build_release_attestation, canonical_json_bytes, @@ -44,11 +44,11 @@ def test_adversarial_release_provenance_fixtures_are_enforced() -> None: def test_release_attestation_builder_uses_exact_workflow_identity(tmp_path: Path) -> None: - artifact = tmp_path / "civiccore-0.22.1-py3-none-any.whl" + artifact = tmp_path / "townlight_core-0.22.1-py3-none-any.whl" artifact.write_text("wheel bytes", encoding="utf-8") attestation = build_release_attestation( - repo="CivicSuite/civiccore", + repo="Townlight/townlight_core", tag_name="v0.22.1", tag_ref_type="commit", tag_ref_sha="a" * 40, @@ -61,17 +61,17 @@ def test_release_attestation_builder_uses_exact_workflow_identity(tmp_path: Path assert attestation["schema_version"] == 1 assert ( attestation["build"]["workflow_identity"] - == "https://github.com/CivicSuite/civiccore/.github/workflows/release.yml@refs/tags/v0.22.1" + == "https://github.com/Townlight/townlight_core/.github/workflows/release.yml@refs/tags/v0.22.1" ) assert attestation["build"]["oidc_issuer"] == "https://token.actions.githubusercontent.com" assert attestation["artifacts"] == [ { - "name": "civiccore-0.22.1-py3-none-any.whl", + "name": "townlight_core-0.22.1-py3-none-any.whl", "sha256": "67c0d8f7de19e30c2d5891030a0b37cbfcdd240852b53055c0b28290ad52290b", } ] assert canonical_json_bytes(attestation).decode("utf-8").startswith( - '{"artifacts":[{"name":"civiccore-0.22.1-py3-none-any.whl"' + '{"artifacts":[{"name":"townlight_core-0.22.1-py3-none-any.whl"' ) @@ -99,10 +99,10 @@ def fake_urlopen(request: Any, timeout: int) -> FakeResponse: monkeypatch.setenv("GH_TOKEN", "token-for-test") monkeypatch.setattr("urllib.request.urlopen", fake_urlopen) - result = GitHubProvenanceClient().tag_ref("CivicSuite/civiccore", "v0.22.1") + result = GitHubProvenanceClient().tag_ref("Townlight/townlight_core", "v0.22.1") assert result["object"]["sha"] == "abc123" - assert captured["url"] == "https://api.github.com/repos/CivicSuite/civiccore/git/ref/tags/v0.22.1" + assert captured["url"] == "https://api.github.com/repos/Townlight/townlight_core/git/ref/tags/v0.22.1" assert captured["headers"]["Authorization"] == "Bearer token-for-test" - assert captured["headers"]["User-agent"] == "civiccore-release-provenance" + assert captured["headers"]["User-agent"] == "townlight_core-release-provenance" assert captured["timeout"] == 30 diff --git a/tests/test_rule_version_history.py b/tests/test_rule_version_history.py index dc7eb71..b25e5bf 100644 --- a/tests/test_rule_version_history.py +++ b/tests/test_rule_version_history.py @@ -13,8 +13,8 @@ import pytest from pydantic import ValidationError -from civiccore.exemptions import Rule, evaluate -from civiccore.exemptions.history import ( +from townlight_core.exemptions import Rule, evaluate +from townlight_core.exemptions.history import ( COVERAGE_DECLARATIONS, RuleHistoryError, RuleVersionInput, @@ -80,7 +80,7 @@ def test_rejects_unsupported_type_coverage_citation_and_pattern(changes): def test_incomplete_scan_error_is_not_converted_to_empty(): - from civiccore.exemptions import RuleEvaluationError + from townlight_core.exemptions import RuleEvaluationError with pytest.raises(ValidationError) as caught: RuleVersionInput.model_validate(payload(rule_type="regex", rule_definition="(a+)+$")) diff --git a/tests/test_scaffold.py b/tests/test_scaffold.py index d23696b..bd07425 100644 --- a/tests/test_scaffold.py +++ b/tests/test_scaffold.py @@ -1,5 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-only -"""Contract tests for ``civiccore.scaffold`` (ADR-0007). +"""Contract tests for ``townlight_core.scaffold`` (ADR-0007). These tests assert the properties the beta plan actually needs, not a framework: the generated project is a valid module by Core's own manifest contract, its code @@ -20,9 +20,9 @@ import pytest from pydantic import ValidationError -import civiccore.scaffold -from civiccore.platform import ModuleManifest, build_module_registry, validate_windows_local_manifest -from civiccore.scaffold import ( +import townlight_core.scaffold +from townlight_core.platform import ModuleManifest, build_module_registry, validate_windows_local_manifest +from townlight_core.scaffold import ( InvalidModuleSpecError, ModuleSpec, PathContainmentError, @@ -39,7 +39,7 @@ "name": "CivicNotes (synthetic)", "description": "Synthetic module used to prove the generator contract.", "version": "0.1.0", - "civiccore_min_version": "1.3.0.dev1", + "townlight_core_min_version": "1.3.0.dev1", "staff_roles": ("notes_editor",), "route_path": "/notes", } @@ -68,7 +68,7 @@ def test_spec_derives_every_identity_from_module_id() -> None: "civic notes", "civicnotes;rm -rf", "notes.exe", - "civiccore", + "townlight_core", "tests", "json", "import", @@ -82,7 +82,7 @@ def test_unsafe_or_reserved_module_ids_are_refused_not_sanitised(module_id: str) make_spec(module_id=module_id) with pytest.raises(InvalidModuleSpecError): - civiccore.scaffold.spec.assert_admissible_module_id(module_id) + townlight_core.scaffold.spec.assert_admissible_module_id(module_id) def test_plan_is_complete_and_pure(tmp_path: Path) -> None: @@ -124,12 +124,12 @@ def test_generated_manifest_is_valid_under_core_contracts() -> None: assert manifest.migrations[0].id == "civicnotes_0001_baseline" # Off by default; an operator selects it explicitly and then it resolves enabled. - default_registry = build_module_registry([payload], civiccore_version="1.3.0.dev1") + default_registry = build_module_registry([payload], townlight_core_version="1.3.0.dev1") assert default_registry.entries[0].status == "disabled" registry = build_module_registry( [payload], - civiccore_version="1.3.0.dev1", + townlight_core_version="1.3.0.dev1", selected_module_ids={"civicnotes"}, ) entry = registry.entries[0] @@ -151,7 +151,7 @@ def test_generated_sources_carry_agpl_spdx_and_no_secrets() -> None: pyproject = next(item.content for item in plan.files if item.relative_path == "pyproject.toml") assert 'license = "AGPL-3.0-only"' in pyproject - assert "civiccore>=" in pyproject + assert "townlight_core>=" in pyproject def test_generated_health_probe_is_the_only_unauthenticated_route() -> None: @@ -235,7 +235,7 @@ def test_generated_migration_owns_only_its_own_schema(tmp_path: Path) -> None: assert 'revision = "civicnotes_0001_baseline"' in baseline assert "down_revision = None" in baseline assert "CREATE SCHEMA IF NOT EXISTS civicnotes" in baseline - assert "civiccore" not in baseline.replace("civiccore.scaffold", "") + assert "townlight_core" not in baseline.replace("townlight_core.scaffold", "") assert "DROP TABLE" not in baseline.split("def downgrade")[0] assert "upgrade_to_head" in env_py # Alembic creates its version table in civicnotes before the baseline revision runs, @@ -291,7 +291,7 @@ def test_file_target_is_refused(tmp_path: Path) -> None: def test_planned_paths_are_contained_and_parent_traversal_is_refused(monkeypatch) -> None: - from civiccore.scaffold import project as project_module + from townlight_core.scaffold import project as project_module plan = plan_module_project(make_spec()) poisoned = type(plan)( @@ -333,7 +333,7 @@ def test_cli_reports_refusal_and_creates_project(tmp_path: Path) -> None: "-X", "utf8", "-m", - "civiccore.scaffold", + "townlight_core.scaffold", "generate", "civicnotes", "--name", @@ -362,7 +362,7 @@ def test_cli_reports_refusal_and_creates_project(tmp_path: Path) -> None: "-X", "utf8", "-m", - "civiccore.scaffold", + "townlight_core.scaffold", "generate", "../escape", "--name", diff --git a/tests/test_scheduling_cron.py b/tests/test_scheduling_cron.py index 5ce2053..ad430db 100644 --- a/tests/test_scheduling_cron.py +++ b/tests/test_scheduling_cron.py @@ -4,7 +4,7 @@ import pytest -from civiccore.scheduling import ( +from townlight_core.scheduling import ( UTC, compute_next_sync_at, min_interval_minutes, diff --git a/tests/test_search_helpers.py b/tests/test_search_helpers.py index 4b2541a..27d30ff 100644 --- a/tests/test_search_helpers.py +++ b/tests/test_search_helpers.py @@ -2,7 +2,7 @@ import uuid -from civiccore.search import ( +from townlight_core.search import ( access_level_allows, filter_records_by_access_level, normalize_access_value, diff --git a/tests/test_security_at_rest.py b/tests/test_security_at_rest.py index 8f80f1f..fff3d2d 100644 --- a/tests/test_security_at_rest.py +++ b/tests/test_security_at_rest.py @@ -3,7 +3,7 @@ import pytest from cryptography.fernet import Fernet -from civiccore.security import AtRestDecryptionError, decrypt_json, encrypt_json, is_encrypted +from townlight_core.security import AtRestDecryptionError, decrypt_json, encrypt_json, is_encrypted def test_encrypt_json_round_trips_dict_payload() -> None: diff --git a/tests/test_security_config_validation.py b/tests/test_security_config_validation.py index 89b7bbf..764ea2b 100644 --- a/tests/test_security_config_validation.py +++ b/tests/test_security_config_validation.py @@ -3,7 +3,7 @@ import pytest from cryptography.fernet import Fernet -from civiccore.security import ( +from townlight_core.security import ( ConfigValidationError, looks_like_placeholder, parse_csv_setting, diff --git a/tests/test_security_host_validation.py b/tests/test_security_host_validation.py index 84f15db..a865552 100644 --- a/tests/test_security_host_validation.py +++ b/tests/test_security_host_validation.py @@ -2,7 +2,7 @@ import pytest -from civiccore.security import ( +from townlight_core.security import ( BLOCK_REASON, extract_odbc_host, is_blocked_host, diff --git a/tests/test_smoke.py b/tests/test_smoke.py index db1eb16..a190da0 100644 --- a/tests/test_smoke.py +++ b/tests/test_smoke.py @@ -4,45 +4,45 @@ import tomllib -def test_import_civiccore() -> None: - import civiccore +def test_import_townlight_core() -> None: + import townlight_core - assert civiccore.__version__ == "1.3.0.dev1" - assert civiccore.roles_grant_access - assert civiccore.access_level_allows - assert civiccore.filter_records_by_access_level - assert civiccore.AuditHashChain - assert civiccore.PersistedAuditLogEntry - assert callable(civiccore.compute_persisted_audit_hash) - assert callable(civiccore.verify_persisted_audit_chain) - assert civiccore.SourceReference - assert civiccore.ExportManifest - assert civiccore.ExportBundle - assert civiccore.CityProfile - assert civiccore.reciprocal_rank_fusion - assert civiccore.import_meeting_payload - assert civiccore.DiscoveredRecord - assert civiccore.FetchedDocument - assert civiccore.SourceMaterial - assert civiccore.validate_cited_sentences - assert civiccore.build_deadline_plan - assert civiccore.evaluate_notice_compliance - assert civiccore.encrypt_json - assert civiccore.LocalTask - assert civiccore.enqueue_local_task - assert civiccore.claim_next_local_task - assert civiccore.run_one_local_task - assert civiccore.validate_url_host - assert civiccore.normalize_trusted_proxy_cidrs - assert civiccore.is_trusted_proxy_ip - assert civiccore.validate_cron_expression - assert civiccore.compute_next_sync_at + assert townlight_core.__version__ == "1.3.0.dev2" + assert townlight_core.roles_grant_access + assert townlight_core.access_level_allows + assert townlight_core.filter_records_by_access_level + assert townlight_core.AuditHashChain + assert townlight_core.PersistedAuditLogEntry + assert callable(townlight_core.compute_persisted_audit_hash) + assert callable(townlight_core.verify_persisted_audit_chain) + assert townlight_core.SourceReference + assert townlight_core.ExportManifest + assert townlight_core.ExportBundle + assert townlight_core.CityProfile + assert townlight_core.reciprocal_rank_fusion + assert townlight_core.import_meeting_payload + assert townlight_core.DiscoveredRecord + assert townlight_core.FetchedDocument + assert townlight_core.SourceMaterial + assert townlight_core.validate_cited_sentences + assert townlight_core.build_deadline_plan + assert townlight_core.evaluate_notice_compliance + assert townlight_core.encrypt_json + assert townlight_core.LocalTask + assert townlight_core.enqueue_local_task + assert townlight_core.claim_next_local_task + assert townlight_core.run_one_local_task + assert townlight_core.validate_url_host + assert townlight_core.normalize_trusted_proxy_cidrs + assert townlight_core.is_trusted_proxy_ip + assert townlight_core.validate_cron_expression + assert townlight_core.compute_next_sync_at def test_package_metadata_marks_v1_as_provisional_recovery_line() -> None: pyproject = tomllib.loads(Path("pyproject.toml").read_text(encoding="utf-8")) - assert pyproject["project"]["version"] == "1.3.0.dev1" + assert pyproject["project"]["version"] == "1.3.0.dev2" assert "Development Status :: 4 - Beta" in pyproject["project"]["classifiers"] assert "Development Status :: 5 - Production/Stable" not in pyproject["project"]["classifiers"] assert "Development Status :: 2 - Pre-Alpha" not in pyproject["project"]["classifiers"] diff --git a/tests/test_suite_session_negative_contract.py b/tests/test_suite_session_negative_contract.py index 8e83f09..48d41e8 100644 --- a/tests/test_suite_session_negative_contract.py +++ b/tests/test_suite_session_negative_contract.py @@ -1,4 +1,4 @@ -"""Negative contract tests for CivicCore-owned suite staff session tokens.""" +"""Negative contract tests for TownlightCore-owned suite staff session tokens.""" from __future__ import annotations @@ -10,12 +10,12 @@ def test_suite_session_rejects_expired_and_wrong_signature_tokens( monkeypatch: pytest.MonkeyPatch, ) -> None: - from civiccore.auth.suite_session import ( + from townlight_core.auth.suite_session import ( issue_suite_session_token, validate_suite_session_token, ) - monkeypatch.setenv("CIVICCORE_SUITE_SESSION_SECRET", "first-test-secret") + monkeypatch.setenv("TOWNLIGHT_CORE_SUITE_SESSION_SECRET", "first-test-secret") expired_token = issue_suite_session_token( subject="operator@example.gov", roles=frozenset({"records_admin"}), @@ -35,7 +35,7 @@ def test_suite_session_rejects_expired_and_wrong_signature_tokens( session_id="wrong-secret-session", expires_at=datetime.now(UTC) + timedelta(minutes=5), ) - monkeypatch.setenv("CIVICCORE_SUITE_SESSION_SECRET", "second-test-secret") + monkeypatch.setenv("TOWNLIGHT_CORE_SUITE_SESSION_SECRET", "second-test-secret") with pytest.raises(PermissionError, match="signature|invalid"): validate_suite_session_token( diff --git a/tests/test_testing_mock_city.py b/tests/test_testing_mock_city.py index 7ceeb9c..d3af709 100644 --- a/tests/test_testing_mock_city.py +++ b/tests/test_testing_mock_city.py @@ -2,7 +2,7 @@ import json -from civiccore.testing import ( +from townlight_core.testing import ( MOCK_CITY_NAME, assert_secret_free_report, mock_city_backup_retention_contract, diff --git a/tests/test_tier1_retrofit_ledger.py b/tests/test_tier1_retrofit_ledger.py index a929867..7365bd2 100644 --- a/tests/test_tier1_retrofit_ledger.py +++ b/tests/test_tier1_retrofit_ledger.py @@ -9,7 +9,7 @@ REPO_ROOT = Path(__file__).resolve().parents[1] -LEDGER = REPO_ROOT / "docs" / "ops" / "civiccore-tier1-retrofit-ledger.json" +LEDGER = REPO_ROOT / "docs" / "ops" / "townlight_core-tier1-retrofit-ledger.json" LEDGER_CHECK = REPO_ROOT / "scripts" / "check-tier1-ledger.py" @@ -61,8 +61,8 @@ def test_live_parity_allows_new_post_baseline_releases_with_attestation_assets() entries = _ledger()["entries"] live_releases = {entry["tag"]: set(entry["release_assets"]) for entry in entries} live_releases["v1.0"] = { - "civiccore-1.0.0-py3-none-any.whl", - "civiccore-1.0.0.tar.gz", + "townlight_core-1.0.0-py3-none-any.whl", + "townlight_core-1.0.0.tar.gz", "SHA256SUMS.txt", "release-attestation.json", "release-attestation.json.bundle", @@ -75,7 +75,7 @@ def test_live_parity_rejects_unledgered_releases_without_attestation_assets() -> module = _ledger_check_module() entries = _ledger()["entries"] live_releases = {entry["tag"]: set(entry["release_assets"]) for entry in entries} - live_releases["v0.22.2"] = {"civiccore-0.22.2-py3-none-any.whl"} + live_releases["v0.22.2"] = {"townlight_core-0.22.2-py3-none-any.whl"} try: module.validate_live_release_parity(entries, live_releases) diff --git a/tests/test_verification_browser_evidence.py b/tests/test_verification_browser_evidence.py index 08dc4f9..de2ab11 100644 --- a/tests/test_verification_browser_evidence.py +++ b/tests/test_verification_browser_evidence.py @@ -5,7 +5,7 @@ import pytest -from civiccore.verification import ( +from townlight_core.verification import ( BrowserReleaseEvidenceResult, normalized_text_sha256, validate_release_browser_evidence, diff --git a/civiccore-ui/README.md b/townlight_core-ui/README.md similarity index 91% rename from civiccore-ui/README.md rename to townlight_core-ui/README.md index feac16f..4a8c5a5 100644 --- a/civiccore-ui/README.md +++ b/townlight_core-ui/README.md @@ -1,6 +1,6 @@ - + -# civiccore-ui — the Townlight design system +# townlight_core-ui — the Townlight design system The shared, versioned UI layer every Townlight module builds on. Three layers, each the single source of truth for its concern: @@ -25,7 +25,7 @@ redefines a `:root` custom property that `tokens.css` already owns. ## Consumption (offline binaries cannot `@import` at runtime) Consumers — the Tauri/WebView2 desktop app, the umbrella prototype — **vendor a -generated copy** of each file, pinned to a `civiccore` version, with a CI +generated copy** of each file, pinned to a `townlight_core` version, with a CI `--check` drift gate that fails the build if a vendored copy drifts from the source here. Any JS/JSON mirror is generated, never hand-maintained. This is the same idiom as the `source_commit` pins and the generated topology block. See the diff --git a/civiccore-ui/components/components-reference.html b/townlight_core-ui/components/components-reference.html similarity index 99% rename from civiccore-ui/components/components-reference.html rename to townlight_core-ui/components/components-reference.html index ce86f46..f6bac56 100644 --- a/civiccore-ui/components/components-reference.html +++ b/townlight_core-ui/components/components-reference.html @@ -4,7 +4,7 @@ Townlight — Component Reference - diff --git a/civiccore-ui/components/components.css b/townlight_core-ui/components/components.css similarity index 97% rename from civiccore-ui/components/components.css rename to townlight_core-ui/components/components.css index 2e83c62..74562ad 100644 --- a/civiccore-ui/components/components.css +++ b/townlight_core-ui/components/components.css @@ -1,15 +1,15 @@ /* ============================================================================= - CivicSuite component primitives — CANONICAL COMPONENT LAYER + Townlight component primitives — CANONICAL COMPONENT LAYER ----------------------------------------------------------------------------- Buttons, badges, status ribbon, tables, forms, alerts, first-run setup steps, empty states, and the audit drawer. Extracted faithfully from the canonical - prototype (docs/design/ui-ux-prototype/styles.css in the CivicSuite umbrella + prototype (docs/design/ui-ux-prototype/styles.css in the Townlight umbrella repo) — same class names, same behavior — so this file becomes the single source for component STRUCTURE the way tokens.css is the source for VALUES. - CONSUMPTION: consumes civiccore-ui/tokens/tokens.css (all colors/type/density + CONSUMPTION: consumes townlight_core-ui/tokens/tokens.css (all colors/type/density come from those custom properties). Load tokens.css first, then this file. - Offline consumers vendor a generated copy pinned to a civiccore version, with + Offline consumers vendor a generated copy pinned to a townlight_core version, with a CI --check drift gate (same idiom as tokens.css). AA: one correction vs the prototype at extraction time — .badge.gold uses diff --git a/civiccore-ui/shell/shell.css b/townlight_core-ui/shell/shell.css similarity index 98% rename from civiccore-ui/shell/shell.css rename to townlight_core-ui/shell/shell.css index 0699bc1..10f6221 100644 --- a/civiccore-ui/shell/shell.css +++ b/townlight_core-ui/shell/shell.css @@ -1,13 +1,13 @@ /* ============================================================================= - CivicSuite desktop shell chrome — CANONICAL SHELL LAYER + Townlight desktop shell chrome — CANONICAL SHELL LAYER ----------------------------------------------------------------------------- The app frame the six workflow modules render inside: brand block, topbar, surface switcher (staff / resident / admin), primary nav, main workspace, page header, letterhead, and the global search overlay. Extracted faithfully from the canonical prototype (docs/design/ui-ux-prototype/styles.css). - CONSUMPTION: consumes civiccore-ui/tokens/tokens.css and pairs with - civiccore-ui/components/components.css. Load tokens.css, then components.css, + CONSUMPTION: consumes townlight_core-ui/tokens/tokens.css and pairs with + townlight_core-ui/components/components.css. Load tokens.css, then components.css, then this file. Offline consumers vendor a generated copy, drift-gated in CI. ========================================================================== */ diff --git a/civiccore-ui/tokens/tokens-reference.html b/townlight_core-ui/tokens/tokens-reference.html similarity index 97% rename from civiccore-ui/tokens/tokens-reference.html rename to townlight_core-ui/tokens/tokens-reference.html index 2fd22dc..d82e8b1 100644 --- a/civiccore-ui/tokens/tokens-reference.html +++ b/townlight_core-ui/tokens/tokens-reference.html @@ -4,7 +4,7 @@ Townlight — Design Tokens Reference - @@ -79,7 +79,7 @@
Townlight · Design System

Design Tokens Reference

-

The visual reference for civiccore-ui/tokens/tokens.css — the suite's single token source. Every value here is rendered live from the token file. Contrast ratios are WCAG 2.x against the noted surface; AA requires 4.5:1 for normal text, 3:1 for large text and UI boundaries.

+

The visual reference for townlight_core-ui/tokens/tokens.css — the suite's single token source. Every value here is rendered live from the token file. Contrast ratios are WCAG 2.x against the noted surface; AA requires 4.5:1 for normal text, 3:1 for large text and UI boundaries.

diff --git a/civiccore-ui/tokens/tokens.css b/townlight_core-ui/tokens/tokens.css similarity index 98% rename from civiccore-ui/tokens/tokens.css rename to townlight_core-ui/tokens/tokens.css index a61c660..6e62300 100644 --- a/civiccore-ui/tokens/tokens.css +++ b/townlight_core-ui/tokens/tokens.css @@ -1,5 +1,5 @@ /* ============================================================================= - CivicSuite design tokens — SINGLE SOURCE OF TRUTH + Townlight design tokens — SINGLE SOURCE OF TRUTH ----------------------------------------------------------------------------- Palette: light civic / navy / warm gold. "Modern public infrastructure." @@ -10,7 +10,7 @@ See docs/design/windows-desktop-design-control.md. CONSUMPTION (offline binaries cannot @import at runtime) - Consumers VENDOR a generated copy of this file, pinned to a civiccore + Consumers VENDOR a generated copy of this file, pinned to a townlight_core version, and a CI --check gate fails the build if the vendored copy drifts. - Desktop app (Tauri/WebView2): desktop/src/styles.css consumes a vendored copy. - Prototype (docs/design/ui-ux-prototype/styles.css) consumes a vendored copy. diff --git a/civiccore/__init__.py b/townlight_core/__init__.py similarity index 93% rename from civiccore/__init__.py rename to townlight_core/__init__.py index e52959d..aca3981 100644 --- a/civiccore/__init__.py +++ b/townlight_core/__init__.py @@ -16,9 +16,9 @@ from __future__ import annotations -__version__ = "1.3.0.dev1" +__version__ = "1.3.0.dev2" -from civiccore.audit import ( +from townlight_core.audit import ( AuditActor, AuditEvent, AuditHashChain, @@ -31,14 +31,14 @@ compute_persisted_audit_hash, verify_persisted_audit_chain, ) -from civiccore.city_profile import ( +from townlight_core.city_profile import ( CityProfile, DepartmentProfile, DeploymentProfile, ModuleEnablement, load_city_profile, ) -from civiccore.connectors import ( +from townlight_core.connectors import ( ConnectorImportError, ExportManifest, ImportedAgendaItem, @@ -67,14 +67,14 @@ validate_manifest, with_http_retry, ) -from civiccore.exports import ( +from townlight_core.exports import ( BundleFile, ExportBundle, build_sha256sums, validate_bundle, write_manifest, ) -from civiccore.ingest import ( +from townlight_core.ingest import ( CitedSentence, CitationValidationError, DataSource, @@ -95,7 +95,7 @@ register_handler, validate_cited_sentences, ) -from civiccore.notifications import ( +from townlight_core.notifications import ( DeadlinePlan, NoticeComplianceResult, NoticeComplianceWarning, @@ -103,7 +103,7 @@ build_deadline_plan, evaluate_notice_compliance, ) -from civiccore.onboarding import ( +from townlight_core.onboarding import ( DEFAULT_PROFILE_FIELDS, OnboardingField, OnboardingProgress, @@ -112,7 +112,7 @@ next_profile_prompt, parse_profile_answer, ) -from civiccore.platform import ( +from townlight_core.platform import ( WINDOWS_LOCAL_BLOCKED_RUNTIME_KINDS, BackupItem, BackupManifest, @@ -161,14 +161,14 @@ validate_backup_manifest, validate_windows_local_manifest, ) -from civiccore.provenance import ( +from townlight_core.provenance import ( CitationTarget, DocumentMetadata, ProvenanceBundle, SourceKind, SourceReference, ) -from civiccore.security import ( +from townlight_core.security import ( AtRestDecryptionError, ConfigValidationError, build_fernet, @@ -188,7 +188,7 @@ validate_secret_setting, validate_url_host, ) -from civiccore.search import ( +from townlight_core.search import ( access_level_allows, filter_records_by_access_level, normalize_access_value, @@ -199,13 +199,13 @@ roles_grant_access, search_text_matches_query, ) -from civiccore.scheduling import ( +from townlight_core.scheduling import ( UTC, compute_next_sync_at, min_interval_minutes, validate_cron_expression, ) -from civiccore.release_provenance import ( +from townlight_core.release_provenance import ( ATTESTATION_SCHEMA_VERSION, FixtureProvenanceClient, GitHubProvenanceClient, @@ -217,7 +217,7 @@ run_fixtures, verify_release_provenance, ) -from civiccore.verification import normalized_text_sha256, validate_release_browser_evidence +from townlight_core.verification import normalized_text_sha256, validate_release_browser_evidence __all__ = [ "__version__", diff --git a/civiccore/audit/__init__.py b/townlight_core/audit/__init__.py similarity index 100% rename from civiccore/audit/__init__.py rename to townlight_core/audit/__init__.py diff --git a/civiccore/audit/primitives.py b/townlight_core/audit/primitives.py similarity index 100% rename from civiccore/audit/primitives.py rename to townlight_core/audit/primitives.py diff --git a/civiccore/auth/__init__.py b/townlight_core/auth/__init__.py similarity index 83% rename from civiccore/auth/__init__.py rename to townlight_core/auth/__init__.py index 9c481b5..4771d69 100644 --- a/civiccore/auth/__init__.py +++ b/townlight_core/auth/__init__.py @@ -1,18 +1,18 @@ """Authentication helpers for Townlight FastAPI services. -``civiccore.auth`` verifies credentials (bearer tokens, trusted proxy headers, staff keys and -suite sessions). ``civiccore.auth.department_scope`` is the separate *authorization* contract: +``townlight_core.auth`` verifies credentials (bearer tokens, trusted proxy headers, staff keys and +suite sessions). ``townlight_core.auth.department_scope`` is the separate *authorization* contract: it consumes an already-authenticated principal and refuses by default unless a persisted, server-side department grant admits the request. """ -from civiccore.auth.bearer import ( +from townlight_core.auth.bearer import ( AuthenticatedPrincipal, authorize_bearer_roles, parse_token_role_map, resolve_optional_bearer_roles, ) -from civiccore.auth.department_scope import ( +from townlight_core.auth.department_scope import ( AuthorityProvenanceError, DepartmentAccessDenied, DepartmentAuthority, @@ -31,15 +31,15 @@ scope_search_results, TRUSTED_AUTH_METHODS, ) -from civiccore.auth.staff_key import staff_key_gate -from civiccore.auth.suite_session import ( +from townlight_core.auth.staff_key import staff_key_gate +from townlight_core.auth.suite_session import ( SuiteSessionConfigError, SuiteSessionPrincipal, issue_suite_session_token, revoke_suite_session, validate_suite_session_token, ) -from civiccore.auth.trusted_headers import ( +from townlight_core.auth.trusted_headers import ( authorize_trusted_header_roles, enforce_trusted_proxy_source, load_trusted_header_auth_config, diff --git a/civiccore/auth/bearer.py b/townlight_core/auth/bearer.py similarity index 100% rename from civiccore/auth/bearer.py rename to townlight_core/auth/bearer.py diff --git a/civiccore/auth/department_scope.py b/townlight_core/auth/department_scope.py similarity index 97% rename from civiccore/auth/department_scope.py rename to townlight_core/auth/department_scope.py index 208b2fd..562c3a4 100644 --- a/civiccore/auth/department_scope.py +++ b/townlight_core/auth/department_scope.py @@ -11,15 +11,15 @@ What this module is not ----------------------- It is not an identity provider and it does not authenticate anyone. Credential verification -stays in the shipped helpers (:mod:`civiccore.auth.bearer`, -:mod:`civiccore.auth.trusted_headers`, :mod:`civiccore.auth.staff_key`, -:mod:`civiccore.auth.suite_session`). This module consumes the *already authenticated* +stays in the shipped helpers (:mod:`townlight_core.auth.bearer`, +:mod:`townlight_core.auth.trusted_headers`, :mod:`townlight_core.auth.staff_key`, +:mod:`townlight_core.auth.suite_session`). This module consumes the *already authenticated* principal those helpers return. The trust boundary (read this before adding a caller) ---------------------------------------------------- The only admissible source of a department claim is the persisted, server-side grant ledger -``civiccore_department_grant_events`` read through :func:`active_department_grants` and keyed by +``townlight_core_department_grant_events`` read through :func:`active_department_grants` and keyed by ``(scope_id, subject, department_id)``. A department named in a request body, query string, cookie, HTTP header, environment variable, JWT custom claim or model output is **not** a grant: :func:`resolve_department_authority` has no parameter that accepts one, and @@ -60,7 +60,7 @@ from sqlalchemy import text from sqlalchemy.ext.asyncio import AsyncSession -from civiccore.search import normalize_access_values, roles_grant_access +from townlight_core.search import normalize_access_values, roles_grant_access __all__ = [ "DepartmentAuthorityError", @@ -84,7 +84,7 @@ "SCOPE_PATTERN", ] -GRANT_TABLE = "civiccore_department_grant_events" +GRANT_TABLE = "townlight_core_department_grant_events" #: Identity sources produced by a credential check inside the service or by a proxy that is #: verified separately (``enforce_trusted_proxy_source``). Anything else — including a raw @@ -465,7 +465,7 @@ async def _append_event( # Serialize per (scope, subject, department): sequence assignment must be total. await session.execute( text("SELECT pg_advisory_xact_lock(hashtextextended(:key, 0))"), - {"key": f"civiccore.department_authority:{scope_id}:{subject}:{department_id}"}, + {"key": f"townlight_core.department_authority:{scope_id}:{subject}:{department_id}"}, ) latest = ( ( @@ -696,7 +696,7 @@ def scope_model_context_chunks( """Return only chunk text the authority may send to a model. Chunks are ``(record, text)`` pairs. The returned list is the exact argument Core's existing - :func:`civiccore.llm.context.assemble_context` accepts as ``chunks``, so no second context + :func:`townlight_core.llm.context.assemble_context` accepts as ``chunks``, so no second context builder is introduced. """ diff --git a/civiccore/auth/staff_key.py b/townlight_core/auth/staff_key.py similarity index 97% rename from civiccore/auth/staff_key.py rename to townlight_core/auth/staff_key.py index 799c5fb..f9418ae 100644 --- a/civiccore/auth/staff_key.py +++ b/townlight_core/auth/staff_key.py @@ -9,7 +9,7 @@ from fastapi import Header, HTTPException -from civiccore.auth.bearer import AuthenticatedPrincipal +from townlight_core.auth.bearer import AuthenticatedPrincipal def _role_header_for_staff_key_header(header: str) -> str: diff --git a/civiccore/auth/suite_session.py b/townlight_core/auth/suite_session.py similarity index 98% rename from civiccore/auth/suite_session.py rename to townlight_core/auth/suite_session.py index 6e3b671..f39395f 100644 --- a/civiccore/auth/suite_session.py +++ b/townlight_core/auth/suite_session.py @@ -15,8 +15,8 @@ from typing import Any -_ENV_VAR = "CIVICCORE_SUITE_SESSION_SECRET" -_REVOCATION_FILE_ENV_VAR = "CIVICCORE_SUITE_SESSION_REVOCATION_FILE" +_ENV_VAR = "TOWNLIGHT_CORE_SUITE_SESSION_SECRET" +_REVOCATION_FILE_ENV_VAR = "TOWNLIGHT_CORE_SUITE_SESSION_REVOCATION_FILE" _DEFAULT_TOKEN_TTL = timedelta(minutes=15) _MIN_KEY_LENGTH = 16 _MAX_LOCAL_REVOCATIONS = 4096 diff --git a/civiccore/auth/trusted_headers.py b/townlight_core/auth/trusted_headers.py similarity index 98% rename from civiccore/auth/trusted_headers.py rename to townlight_core/auth/trusted_headers.py index 35255f3..3d8a52b 100644 --- a/civiccore/auth/trusted_headers.py +++ b/townlight_core/auth/trusted_headers.py @@ -9,8 +9,8 @@ from fastapi import HTTPException -from civiccore.auth.bearer import AuthenticatedPrincipal -from civiccore.security import is_trusted_proxy_ip, normalize_trusted_proxy_cidrs +from townlight_core.auth.bearer import AuthenticatedPrincipal +from townlight_core.security import is_trusted_proxy_ip, normalize_trusted_proxy_cidrs @dataclass(frozen=True) diff --git a/civiccore/catalog/__init__.py b/townlight_core/catalog/__init__.py similarity index 96% rename from civiccore/catalog/__init__.py rename to townlight_core/catalog/__init__.py index bfe734f..f181179 100644 --- a/civiccore/catalog/__init__.py +++ b/townlight_core/catalog/__init__.py @@ -98,7 +98,7 @@ async def import_catalog(session: AsyncSession, value: dict, *, actor_id: str) - prior = ( ( await session.execute( - text("SELECT source_sha256 FROM civiccore_catalog_imports WHERE version=:version"), + text("SELECT source_sha256 FROM townlight_core_catalog_imports WHERE version=:version"), {"version": bundle.catalog_version}, ) ) @@ -139,7 +139,7 @@ async def import_catalog(session: AsyncSession, value: dict, *, actor_id: str) - ) await session.execute( text( - "INSERT INTO civiccore_catalog_imports (version,source_sha256,entry_count,actor_id) VALUES (:version,:digest,:count,:actor)" + "INSERT INTO townlight_core_catalog_imports (version,source_sha256,entry_count,actor_id) VALUES (:version,:digest,:count,:actor)" ), { "version": bundle.catalog_version, diff --git a/civiccore/city_profile/__init__.py b/townlight_core/city_profile/__init__.py similarity index 100% rename from civiccore/city_profile/__init__.py rename to townlight_core/city_profile/__init__.py diff --git a/civiccore/city_profile/models.py b/townlight_core/city_profile/models.py similarity index 100% rename from civiccore/city_profile/models.py rename to townlight_core/city_profile/models.py diff --git a/civiccore/connectors/__init__.py b/townlight_core/connectors/__init__.py similarity index 88% rename from civiccore/connectors/__init__.py rename to townlight_core/connectors/__init__.py index 9d1305a..2ecb88b 100644 --- a/civiccore/connectors/__init__.py +++ b/townlight_core/connectors/__init__.py @@ -1,25 +1,25 @@ """Shared offline connector primitives for current Townlight consumers.""" -from civiccore.connectors.imports import ( +from townlight_core.connectors.imports import ( ConnectorImportError, ImportedAgendaItem, ImportedMeeting, SUPPORTED_CONNECTORS, import_meeting_payload, ) -from civiccore.connectors.delta import ( +from townlight_core.connectors.delta import ( DELTA_QUERY_PARAMS, VendorDeltaRequestPlan, plan_vendor_delta_request, ) -from civiccore.connectors.manifest import ( +from townlight_core.connectors.manifest import ( ExportManifest, ImportManifest, ManifestFile, ManifestValidationError, validate_manifest, ) -from civiccore.connectors.sync import ( +from townlight_core.connectors.sync import ( SyncCircuitPolicy, SyncCircuitState, SyncHealthStatus, diff --git a/civiccore/connectors/delta.py b/townlight_core/connectors/delta.py similarity index 100% rename from civiccore/connectors/delta.py rename to townlight_core/connectors/delta.py diff --git a/civiccore/connectors/imports.py b/townlight_core/connectors/imports.py similarity index 100% rename from civiccore/connectors/imports.py rename to townlight_core/connectors/imports.py diff --git a/civiccore/connectors/manifest.py b/townlight_core/connectors/manifest.py similarity index 94% rename from civiccore/connectors/manifest.py rename to townlight_core/connectors/manifest.py index 59b1810..32b17d5 100644 --- a/civiccore/connectors/manifest.py +++ b/townlight_core/connectors/manifest.py @@ -80,7 +80,7 @@ class _ManifestBase(BaseModel): manifest_version: str = "1.0" module_name: str module_version: str - civiccore_version: str + townlight_core_version: str purpose: ManifestPurpose source_files: list[ManifestFile] = Field(default_factory=list) generated_files: list[ManifestFile] = Field(default_factory=list) @@ -88,7 +88,7 @@ class _ManifestBase(BaseModel): model_config = ConfigDict(extra="forbid") - @field_validator("manifest_version", "module_name", "module_version", "civiccore_version") + @field_validator("manifest_version", "module_name", "module_version", "townlight_core_version") @classmethod def _validate_required_text(cls, value: str) -> str: return _clean_string(value, "required text field") @@ -190,7 +190,7 @@ def validate_manifest( manifest: str | Path | dict[str, Any] | ImportManifest | ExportManifest, *, base_path: str | Path | None = None, - expected_civiccore_version: str | None = None, + expected_townlight_core_version: str | None = None, ) -> ImportManifest | ExportManifest: """Validate a manifest payload and, when requested, its files on disk. @@ -198,7 +198,7 @@ def validate_manifest( manifest: Manifest model, mapping, JSON string path, or JSON Path. base_path: Optional directory used to verify file existence, byte sizes, and SHA-256 checksums. - expected_civiccore_version: Optional exact Townlight Core version to require. + expected_townlight_core_version: Optional exact Townlight Core version to require. Raises: ManifestValidationError: If schema validation or file verification fails. @@ -211,12 +211,12 @@ def validate_manifest( except ValidationError as exc: raise ManifestValidationError(str(exc)) from exc - if expected_civiccore_version is not None and ( - validated.civiccore_version != expected_civiccore_version + if expected_townlight_core_version is not None and ( + validated.townlight_core_version != expected_townlight_core_version ): raise ManifestValidationError( "Manifest Townlight Core version mismatch: " - f"expected {expected_civiccore_version}, got {validated.civiccore_version}" + f"expected {expected_townlight_core_version}, got {validated.townlight_core_version}" ) if base_path is not None: diff --git a/civiccore/connectors/sync.py b/townlight_core/connectors/sync.py similarity index 99% rename from civiccore/connectors/sync.py rename to townlight_core/connectors/sync.py index 934f4c0..5a7de93 100644 --- a/civiccore/connectors/sync.py +++ b/townlight_core/connectors/sync.py @@ -16,7 +16,7 @@ from typing import Literal, TypeVar import httpx -from civiccore.scheduling import compute_next_sync_at +from townlight_core.scheduling import compute_next_sync_at logger = logging.getLogger(__name__) diff --git a/townlight_core/db/__init__.py b/townlight_core/db/__init__.py new file mode 100644 index 0000000..867d9f1 --- /dev/null +++ b/townlight_core/db/__init__.py @@ -0,0 +1,18 @@ +""" +Shared SQLAlchemy declarative base for all townlight_core ORM models. + +All ORM models in townlight_core (and downstream consumers such as townlight_records) +should inherit from this ``Base`` class so that metadata is shared across the +same declarative registry. In Phase 2 Step 5, townlight_records will migrate its +own models to import and inherit from this Base rather than maintaining a +separate one. +""" + +from sqlalchemy.orm import DeclarativeBase + + +class Base(DeclarativeBase): + """Shared declarative base for all townlight_core ORM models.""" + + +__all__ = ["Base"] diff --git a/civiccore/exemptions/__init__.py b/townlight_core/exemptions/__init__.py similarity index 98% rename from civiccore/exemptions/__init__.py rename to townlight_core/exemptions/__init__.py index 329f9ba..163b3fe 100644 --- a/civiccore/exemptions/__init__.py +++ b/townlight_core/exemptions/__init__.py @@ -4,7 +4,7 @@ The caller owns authorization, rule selection and review. Jurisdiction completeness and legal correctness are not inferred from a match. -Citation and version retention live in :mod:`civiccore.exemptions.history`, which +Citation and version retention live in :mod:`townlight_core.exemptions.history`, which appends immutable cited rule versions and returns ``Rule`` objects for exactly the persisted version via ``RuleVersion.as_rule()``. That module adds history around this single evaluator; it is not a second rule engine and it never declares a diff --git a/civiccore/exemptions/history.py b/townlight_core/exemptions/history.py similarity index 97% rename from civiccore/exemptions/history.py rename to townlight_core/exemptions/history.py index 5d9e84c..1606eaa 100644 --- a/civiccore/exemptions/history.py +++ b/townlight_core/exemptions/history.py @@ -16,11 +16,11 @@ Relationship to the evaluator ----------------------------- -There is exactly one rule evaluation path: :func:`civiccore.exemptions.evaluate`. +There is exactly one rule evaluation path: :func:`townlight_core.exemptions.evaluate`. This module adds version history *around* it; :meth:`RuleVersion.as_rule` returns -the existing frozen :class:`civiccore.exemptions.Rule` so persisted history feeds +the existing frozen :class:`townlight_core.exemptions.Rule` so persisted history feeds that evaluator instead of a second, competing rule engine. Pattern admission at -write time reuses :func:`civiccore.exemptions.validate_rule_pattern`, which runs +write time reuses :func:`townlight_core.exemptions.validate_rule_pattern`, which runs the same shared scanner, so an invalid or catastrophic expression is refused before it can be stored as "reviewed". @@ -69,7 +69,7 @@ "TABLE", ] -TABLE = "civiccore_rule_versions" +TABLE = "townlight_core_rule_versions" COVERAGE_DECLARATIONS = ("synthetic-fixture", "tenant-supplied") @@ -255,7 +255,7 @@ async def record_rule_version( # they are writing the next version. await session.execute( text("SELECT pg_advisory_xact_lock(hashtextextended(:key, 0))"), - {"key": f"civiccore.rule_versions:{item.state_code}:{item.rule_id}"}, + {"key": f"townlight_core.rule_versions:{item.state_code}:{item.rule_id}"}, ) other_states = await _state_codes_for(session, item.rule_id) - {item.state_code} diff --git a/civiccore/exemptions/patterns.py b/townlight_core/exemptions/patterns.py similarity index 100% rename from civiccore/exemptions/patterns.py rename to townlight_core/exemptions/patterns.py diff --git a/civiccore/exports/__init__.py b/townlight_core/exports/__init__.py similarity index 86% rename from civiccore/exports/__init__.py rename to townlight_core/exports/__init__.py index 7d06f7c..db037b6 100644 --- a/civiccore/exports/__init__.py +++ b/townlight_core/exports/__init__.py @@ -1,6 +1,6 @@ """Offline static export bundle helpers for Townlight Core.""" -from civiccore.exports.bundle import ( +from townlight_core.exports.bundle import ( BundleFile, ExportBundle, build_sha256sums, diff --git a/civiccore/exports/bundle.py b/townlight_core/exports/bundle.py similarity index 96% rename from civiccore/exports/bundle.py rename to townlight_core/exports/bundle.py index 0582a5f..3d04261 100644 --- a/civiccore/exports/bundle.py +++ b/townlight_core/exports/bundle.py @@ -7,8 +7,8 @@ from pydantic import BaseModel, ConfigDict, Field, model_validator -from civiccore import __version__ as CIVICCORE_VERSION -from civiccore.connectors.manifest import ( +from townlight_core import __version__ as TOWNLIGHT_CORE_VERSION +from townlight_core.connectors.manifest import ( ExportManifest, ManifestFile, ManifestValidationError, @@ -56,7 +56,7 @@ class ExportBundle(BaseModel): module_name: str module_version: str - civiccore_version: str = CIVICCORE_VERSION + townlight_core_version: str = TOWNLIGHT_CORE_VERSION purpose: str = "static_export_bundle" files: list[BundleFile] = Field(default_factory=list) limitations: list[str] = Field(default_factory=list) @@ -77,7 +77,7 @@ def to_manifest(self) -> ExportManifest: return ExportManifest( module_name=self.module_name, module_version=self.module_version, - civiccore_version=self.civiccore_version, + townlight_core_version=self.townlight_core_version, purpose="static_export_bundle", source_files=[], generated_files=[ManifestFile.model_validate(file.model_dump()) for file in self.files], diff --git a/civiccore/ingest/__init__.py b/townlight_core/ingest/__init__.py similarity index 89% rename from civiccore/ingest/__init__.py rename to townlight_core/ingest/__init__.py index 173865c..0469baf 100644 --- a/civiccore/ingest/__init__.py +++ b/townlight_core/ingest/__init__.py @@ -5,7 +5,7 @@ module workflows that parse source files into sentence-aware vector chunks. """ -from civiccore.ingest.contracts import ( +from townlight_core.ingest.contracts import ( CitedSentence, CitationValidationError, DiscoveredRecord, @@ -15,14 +15,14 @@ SourceMaterial, validate_cited_sentences, ) -from civiccore.ingest.models import ( +from townlight_core.ingest.models import ( DataSource, Document, DocumentChunk, IngestionStatus, SourceType, ) -from civiccore.ingest.pipeline import ( +from townlight_core.ingest.pipeline import ( compute_file_hash, ingest_bytes, ingest_directory, diff --git a/civiccore/ingest/chunker.py b/townlight_core/ingest/chunker.py similarity index 100% rename from civiccore/ingest/chunker.py rename to townlight_core/ingest/chunker.py diff --git a/civiccore/ingest/contracts.py b/townlight_core/ingest/contracts.py similarity index 100% rename from civiccore/ingest/contracts.py rename to townlight_core/ingest/contracts.py diff --git a/civiccore/ingest/embedder.py b/townlight_core/ingest/embedder.py similarity index 96% rename from civiccore/ingest/embedder.py rename to townlight_core/ingest/embedder.py index 4164ea1..fad81ab 100644 --- a/civiccore/ingest/embedder.py +++ b/townlight_core/ingest/embedder.py @@ -4,7 +4,7 @@ import os -from civiccore.llm.providers import OllamaProvider +from townlight_core.llm.providers import OllamaProvider _providers: dict[str, OllamaProvider] = {} diff --git a/civiccore/ingest/llm_extractor.py b/townlight_core/ingest/llm_extractor.py similarity index 98% rename from civiccore/ingest/llm_extractor.py rename to townlight_core/ingest/llm_extractor.py index b13b55f..5f66784 100644 --- a/civiccore/ingest/llm_extractor.py +++ b/townlight_core/ingest/llm_extractor.py @@ -3,7 +3,7 @@ import os from pathlib import Path -from civiccore.llm.providers import OllamaProvider +from townlight_core.llm.providers import OllamaProvider logger = logging.getLogger(__name__) diff --git a/civiccore/ingest/models.py b/townlight_core/ingest/models.py similarity index 99% rename from civiccore/ingest/models.py rename to townlight_core/ingest/models.py index 4335163..15b9a66 100644 --- a/civiccore/ingest/models.py +++ b/townlight_core/ingest/models.py @@ -12,7 +12,7 @@ from sqlalchemy.dialects.postgresql import JSONB, UUID from sqlalchemy.orm import Mapped, mapped_column -from civiccore.db import Base +from townlight_core.db import Base class SourceType(str, enum.Enum): @@ -45,7 +45,7 @@ class DataSource(Base): ) connection_config: Mapped[dict[str, Any]] = mapped_column(JSONB, default=dict) is_active: Mapped[bool] = mapped_column(Boolean, default=True) - # The baseline migration owns the DB-level FK to users(id). CivicCore has no + # The baseline migration owns the DB-level FK to users(id). TownlightCore has no # User ORM model in this metadata registry, so an ORM ForeignKey would break # standalone ingestion sessions with NoReferencedTableError. created_by: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True)) diff --git a/civiccore/ingest/parsers/__init__.py b/townlight_core/ingest/parsers/__init__.py similarity index 54% rename from civiccore/ingest/parsers/__init__.py rename to townlight_core/ingest/parsers/__init__.py index f67c912..91f878f 100644 --- a/civiccore/ingest/parsers/__init__.py +++ b/townlight_core/ingest/parsers/__init__.py @@ -1,12 +1,12 @@ from pathlib import Path -from civiccore.ingest.parsers.base import BaseParser, ParseResult -from civiccore.ingest.parsers.csv_parser import CsvParser -from civiccore.ingest.parsers.docx import DocxParser -from civiccore.ingest.parsers.email import EmailParser -from civiccore.ingest.parsers.html import HtmlParser -from civiccore.ingest.parsers.pdf import PdfParser -from civiccore.ingest.parsers.text import TextParser -from civiccore.ingest.parsers.xlsx import XlsxParser +from townlight_core.ingest.parsers.base import BaseParser, ParseResult +from townlight_core.ingest.parsers.csv_parser import CsvParser +from townlight_core.ingest.parsers.docx import DocxParser +from townlight_core.ingest.parsers.email import EmailParser +from townlight_core.ingest.parsers.html import HtmlParser +from townlight_core.ingest.parsers.pdf import PdfParser +from townlight_core.ingest.parsers.text import TextParser +from townlight_core.ingest.parsers.xlsx import XlsxParser _PARSERS: list[BaseParser] = [PdfParser(), DocxParser(), XlsxParser(), CsvParser(), EmailParser(), HtmlParser(), TextParser()] IMAGE_EXTENSIONS = {".jpg", ".jpeg", ".png", ".tiff", ".tif", ".bmp"} diff --git a/civiccore/ingest/parsers/base.py b/townlight_core/ingest/parsers/base.py similarity index 100% rename from civiccore/ingest/parsers/base.py rename to townlight_core/ingest/parsers/base.py diff --git a/civiccore/ingest/parsers/csv_parser.py b/townlight_core/ingest/parsers/csv_parser.py similarity index 89% rename from civiccore/ingest/parsers/csv_parser.py rename to townlight_core/ingest/parsers/csv_parser.py index 3342f41..48edffe 100644 --- a/civiccore/ingest/parsers/csv_parser.py +++ b/townlight_core/ingest/parsers/csv_parser.py @@ -1,6 +1,6 @@ import csv from pathlib import Path -from civiccore.ingest.parsers.base import BaseParser, ParsedPage, ParseResult +from townlight_core.ingest.parsers.base import BaseParser, ParsedPage, ParseResult class CsvParser(BaseParser): supported_extensions = [".csv", ".tsv"] diff --git a/civiccore/ingest/parsers/docx.py b/townlight_core/ingest/parsers/docx.py similarity index 97% rename from civiccore/ingest/parsers/docx.py rename to townlight_core/ingest/parsers/docx.py index 0800e7e..82e9dcc 100644 --- a/civiccore/ingest/parsers/docx.py +++ b/townlight_core/ingest/parsers/docx.py @@ -5,7 +5,7 @@ from docx import Document as DocxDocument -from civiccore.ingest.parsers.base import BaseParser, ParsedPage, ParseResult +from townlight_core.ingest.parsers.base import BaseParser, ParsedPage, ParseResult logger = logging.getLogger(__name__) diff --git a/civiccore/ingest/parsers/email.py b/townlight_core/ingest/parsers/email.py similarity index 93% rename from civiccore/ingest/parsers/email.py rename to townlight_core/ingest/parsers/email.py index c118a29..781b799 100644 --- a/civiccore/ingest/parsers/email.py +++ b/townlight_core/ingest/parsers/email.py @@ -1,7 +1,7 @@ import email from email import policy from pathlib import Path -from civiccore.ingest.parsers.base import BaseParser, ParsedPage, ParseResult +from townlight_core.ingest.parsers.base import BaseParser, ParsedPage, ParseResult class EmailParser(BaseParser): supported_extensions = [".eml"] diff --git a/civiccore/ingest/parsers/html.py b/townlight_core/ingest/parsers/html.py similarity index 89% rename from civiccore/ingest/parsers/html.py rename to townlight_core/ingest/parsers/html.py index 7bcca42..6659819 100644 --- a/civiccore/ingest/parsers/html.py +++ b/townlight_core/ingest/parsers/html.py @@ -1,6 +1,6 @@ from pathlib import Path from bs4 import BeautifulSoup -from civiccore.ingest.parsers.base import BaseParser, ParsedPage, ParseResult +from townlight_core.ingest.parsers.base import BaseParser, ParsedPage, ParseResult class HtmlParser(BaseParser): supported_extensions = [".html", ".htm"] diff --git a/civiccore/ingest/parsers/pdf.py b/townlight_core/ingest/parsers/pdf.py similarity index 90% rename from civiccore/ingest/parsers/pdf.py rename to townlight_core/ingest/parsers/pdf.py index 2421b94..17872ff 100644 --- a/civiccore/ingest/parsers/pdf.py +++ b/townlight_core/ingest/parsers/pdf.py @@ -1,6 +1,6 @@ from pathlib import Path import pdfplumber -from civiccore.ingest.parsers.base import BaseParser, ParsedPage, ParseResult +from townlight_core.ingest.parsers.base import BaseParser, ParsedPage, ParseResult class PdfParser(BaseParser): supported_extensions = [".pdf"] diff --git a/civiccore/ingest/parsers/text.py b/townlight_core/ingest/parsers/text.py similarity index 85% rename from civiccore/ingest/parsers/text.py rename to townlight_core/ingest/parsers/text.py index 88d074d..a210abd 100644 --- a/civiccore/ingest/parsers/text.py +++ b/townlight_core/ingest/parsers/text.py @@ -1,5 +1,5 @@ from pathlib import Path -from civiccore.ingest.parsers.base import BaseParser, ParsedPage, ParseResult +from townlight_core.ingest.parsers.base import BaseParser, ParsedPage, ParseResult class TextParser(BaseParser): supported_extensions = [".txt", ".md", ".log", ".cfg", ".ini", ".json", ".xml", ".yaml", ".yml"] diff --git a/civiccore/ingest/parsers/xlsx.py b/townlight_core/ingest/parsers/xlsx.py similarity index 97% rename from civiccore/ingest/parsers/xlsx.py rename to townlight_core/ingest/parsers/xlsx.py index 9b9d377..413525e 100644 --- a/civiccore/ingest/parsers/xlsx.py +++ b/townlight_core/ingest/parsers/xlsx.py @@ -5,7 +5,7 @@ from openpyxl import load_workbook -from civiccore.ingest.parsers.base import BaseParser, ParsedPage, ParseResult +from townlight_core.ingest.parsers.base import BaseParser, ParsedPage, ParseResult logger = logging.getLogger(__name__) diff --git a/civiccore/ingest/pipeline.py b/townlight_core/ingest/pipeline.py similarity index 96% rename from civiccore/ingest/pipeline.py rename to townlight_core/ingest/pipeline.py index 103397f..644b561 100644 --- a/civiccore/ingest/pipeline.py +++ b/townlight_core/ingest/pipeline.py @@ -9,11 +9,11 @@ from sqlalchemy import select, delete from sqlalchemy.ext.asyncio import AsyncSession -from civiccore.ingest.chunker import chunk_pages -from civiccore.ingest.embedder import embed_batch -from civiccore.ingest.parsers import detect_parser, is_image_file -from civiccore.ingest.llm_extractor import extract_text_from_image, extract_text_from_scanned_pdf -from civiccore.ingest.models import Document, DocumentChunk, IngestionStatus +from townlight_core.ingest.chunker import chunk_pages +from townlight_core.ingest.embedder import embed_batch +from townlight_core.ingest.parsers import detect_parser, is_image_file +from townlight_core.ingest.llm_extractor import extract_text_from_image, extract_text_from_scanned_pdf +from townlight_core.ingest.models import Document, DocumentChunk, IngestionStatus class IngestHandler(Protocol): @@ -61,7 +61,7 @@ async def ingest_file( chunk_overlap: int = 50, embed_model: str = "nomic-embed-text", ) -> Document: - from civiccore.ingest.models import DataSource + from townlight_core.ingest.models import DataSource file_path = Path(file_path) file_hash = await asyncio.to_thread(compute_file_hash, file_path) @@ -337,7 +337,7 @@ async def ingest_directory( chunk_overlap: int = 50, embed_model: str = "nomic-embed-text", ) -> dict: - from civiccore.ingest.parsers import _PARSERS, IMAGE_EXTENSIONS + from townlight_core.ingest.parsers import _PARSERS, IMAGE_EXTENSIONS supported_extensions = set() for p in _PARSERS: diff --git a/civiccore/llm/__init__.py b/townlight_core/llm/__init__.py similarity index 86% rename from civiccore/llm/__init__.py rename to townlight_core/llm/__init__.py index fd01bf3..7e8d55e 100644 --- a/civiccore/llm/__init__.py +++ b/townlight_core/llm/__init__.py @@ -1,9 +1,9 @@ """Townlight Core LLM abstraction. -Public API entry point for downstream apps (records-ai, civicclerk). Exposes: +Public API entry point for downstream apps (records-ai, townlight_meetings). Exposes: - Provider abstraction (LLMProvider ABC, registry, built-in Ollama/OpenAI/Anthropic). -- Prompt template ORM, rendering, and 3-step override resolution (DB override → code-level override → civiccore default). +- Prompt template ORM, rendering, and 3-step override resolution (DB override → code-level override → townlight_core default). - Model registry ORM, Pydantic schemas, async service, and FastAPI admin router. - Token-budgeted context assembly and prompt-injection defense. - Structured-output helper (Pydantic-validated, retry-on-malformed). @@ -17,7 +17,7 @@ from __future__ import annotations # Providers (Step 3b) -from civiccore.llm.providers import ( +from townlight_core.llm.providers import ( PROVIDER_REGISTRY, AnthropicConfig, AnthropicProvider, @@ -32,11 +32,11 @@ ) # Provider factory (Step 3 audit fix — PROVIDER-CONFIG-001) -from civiccore.llm.factory import CONFIG_SCHEMAS, build_provider +from townlight_core.llm.factory import CONFIG_SCHEMAS, build_provider # Templates (Step 3a + 3c) -from civiccore.llm.templates import ( - CIVICCORE_DEFAULT_APP, +from townlight_core.llm.templates import ( + TOWNLIGHT_CORE_DEFAULT_APP, OVERRIDE_REGISTRY, PromptTemplate, PromptTemplateCreate, @@ -52,7 +52,7 @@ ) # Registry (Step 3a + 3d) -from civiccore.llm.registry import ( +from townlight_core.llm.registry import ( MissingModelError, ModelRegistry, ModelRegistryCreate, @@ -66,7 +66,7 @@ ) # Context utilities (Step 3d) -from civiccore.llm.context import ( +from townlight_core.llm.context import ( DEFAULT_CONTEXT_WINDOW, ContextBlock, TokenBudget, @@ -78,7 +78,7 @@ ) # Structured output (Step 3d) -from civiccore.llm.structured import ( +from townlight_core.llm.structured import ( DEFAULT_MAX_ATTEMPTS, StructuredOutput, StructuredOutputFailure, @@ -107,7 +107,7 @@ "RenderedPrompt", "render_template", "resolve_template", - "CIVICCORE_DEFAULT_APP", + "TOWNLIGHT_CORE_DEFAULT_APP", "PromptTemplateError", "PromptTemplateNotFoundError", "PromptTemplateRenderError", diff --git a/civiccore/llm/context.py b/townlight_core/llm/context.py similarity index 97% rename from civiccore/llm/context.py rename to townlight_core/llm/context.py index e229d19..a07bc44 100644 --- a/civiccore/llm/context.py +++ b/townlight_core/llm/context.py @@ -1,13 +1,13 @@ -"""Context manager for civiccore LLM services. +"""Context manager for townlight_core LLM services. -Civiccore port of records-ai's ``backend/app/llm/context_manager.py``. +Townlight Core context handling shared with Townlight Records. Covers token-budget math, prompt-injection defense, and prompt assembly -for any provider plugged into civiccore. +for any provider plugged into townlight_core. Adaptation notes (vs. records-ai): - ``get_active_model_context_window()`` is intentionally NOT ported here. Per ADR-0004, that lookup is a registry-service concern and lives in - ``civiccore/llm/registry/service.py``. This module stays free of DB + ``townlight_core/llm/registry/service.py``. This module stays free of DB imports and is safe to use in pure unit-test contexts. - ``count_tokens(text, model)`` is a thin, provider-aware wrapper around the chars/4 heuristic. A future v0.3.0 candidate is provider-specific diff --git a/civiccore/llm/factory.py b/townlight_core/llm/factory.py similarity index 93% rename from civiccore/llm/factory.py rename to townlight_core/llm/factory.py index 5094614..bc45818 100644 --- a/civiccore/llm/factory.py +++ b/townlight_core/llm/factory.py @@ -12,13 +12,13 @@ from pydantic import BaseModel -from civiccore.llm.providers.base import LLMProvider -from civiccore.llm.providers.config import ( +from townlight_core.llm.providers.base import LLMProvider +from townlight_core.llm.providers.config import ( AnthropicConfig, OllamaConfig, OpenAIConfig, ) -from civiccore.llm.providers.registry import PROVIDER_REGISTRY +from townlight_core.llm.providers.registry import PROVIDER_REGISTRY # Mapping of provider name -> expected Pydantic config schema. # Third-party providers registered via @register_provider can extend this map diff --git a/civiccore/llm/providers/__init__.py b/townlight_core/llm/providers/__init__.py similarity index 62% rename from civiccore/llm/providers/__init__.py rename to townlight_core/llm/providers/__init__.py index b6e70fa..4e568b5 100644 --- a/civiccore/llm/providers/__init__.py +++ b/townlight_core/llm/providers/__init__.py @@ -2,12 +2,12 @@ Importing this package triggers registration of three built-in providers: ollama, openai, anthropic. Consumers may register additional providers via -`@register_provider` without modifying civiccore source. +`@register_provider` without modifying townlight_core source. """ from __future__ import annotations -from civiccore.llm.providers.base import LLMProvider -from civiccore.llm.providers.registry import ( +from townlight_core.llm.providers.base import LLMProvider +from townlight_core.llm.providers.registry import ( PROVIDER_REGISTRY, get_provider, list_providers, @@ -16,11 +16,11 @@ # Trigger decorator-based registration of built-in providers. # Concrete classes are also re-exported below for explicit imports. -from civiccore.llm.providers.ollama import OllamaProvider # noqa: F401, E402 -from civiccore.llm.providers.openai import OpenAIProvider # noqa: F401, E402 -from civiccore.llm.providers.anthropic import AnthropicProvider # noqa: F401, E402 +from townlight_core.llm.providers.ollama import OllamaProvider # noqa: F401, E402 +from townlight_core.llm.providers.openai import OpenAIProvider # noqa: F401, E402 +from townlight_core.llm.providers.anthropic import AnthropicProvider # noqa: F401, E402 -from civiccore.llm.providers.config import ( +from townlight_core.llm.providers.config import ( AnthropicConfig, OllamaConfig, OpenAIConfig, diff --git a/civiccore/llm/providers/anthropic.py b/townlight_core/llm/providers/anthropic.py similarity index 90% rename from civiccore/llm/providers/anthropic.py rename to townlight_core/llm/providers/anthropic.py index cbebdf2..9119678 100644 --- a/civiccore/llm/providers/anthropic.py +++ b/townlight_core/llm/providers/anthropic.py @@ -1,8 +1,8 @@ -"""Anthropic provider for civiccore.llm. +"""Anthropic provider for townlight_core.llm. Concrete LLMProvider implementation backed by the official ``anthropic`` SDK, -which ships as an OPTIONAL extra (``pip install civiccore[anthropic]``). The -SDK is imported lazily inside ``__init__`` so that civiccore continues to +which ships as an OPTIONAL extra (``pip install townlight_core[anthropic]``). The +SDK is imported lazily inside ``__init__`` so that townlight_core continues to import cleanly when the extra is not installed; if a caller instantiates ``AnthropicProvider`` without the SDK present, a clear ``ImportError`` is raised directing them to install the extra. @@ -18,15 +18,15 @@ from __future__ import annotations -from civiccore.llm.providers.base import LLMProvider -from civiccore.llm.providers.registry import register_provider +from townlight_core.llm.providers.base import LLMProvider +from townlight_core.llm.providers.registry import register_provider @register_provider("anthropic") class AnthropicProvider(LLMProvider): """Anthropic API provider using the official anthropic SDK. - Requires the optional extra: pip install civiccore[anthropic]. + Requires the optional extra: pip install townlight_core[anthropic]. Default model: claude-haiku-4-5 (latest small/fast model). Embeddings are NOT supported — Anthropic does not ship a native embedding @@ -49,7 +49,7 @@ def __init__( except ImportError as e: raise ImportError( "anthropic SDK is required for AnthropicProvider. Install it: pip install anthropic " - "(or pip install 'civiccore[anthropic]' once civiccore is published to PyPI)." + "(or pip install 'townlight_core[anthropic]' once townlight_core is published to PyPI)." ) from e self._client = AsyncAnthropic(api_key=api_key) self.default_model = default_model diff --git a/civiccore/llm/providers/base.py b/townlight_core/llm/providers/base.py similarity index 93% rename from civiccore/llm/providers/base.py rename to townlight_core/llm/providers/base.py index 7b5f873..0acd884 100644 --- a/civiccore/llm/providers/base.py +++ b/townlight_core/llm/providers/base.py @@ -2,7 +2,7 @@ This module defines :class:`LLMProvider`, the abstract base class that every concrete LLM backend in Townlight must implement. The surface here is -deliberately narrow and was extracted in Phase 2 of the civiccore split from +deliberately narrow and was extracted in Phase 2 of the townlight_core split from the records-ai status quo: * :meth:`LLMProvider.generate` mirrors the call shape used by @@ -36,8 +36,8 @@ class LLMProvider(ABC): """Abstract base class for an LLM backend. Concrete implementations live alongside this module (e.g. - ``civiccore.llm.providers.anthropic``) and register themselves with the - decorator registry in :mod:`civiccore.llm.providers.registry`. + ``townlight_core.llm.providers.anthropic``) and register themselves with the + decorator registry in :mod:`townlight_core.llm.providers.registry`. """ @abstractmethod diff --git a/civiccore/llm/providers/config.py b/townlight_core/llm/providers/config.py similarity index 95% rename from civiccore/llm/providers/config.py rename to townlight_core/llm/providers/config.py index 03d4203..29426b1 100644 --- a/civiccore/llm/providers/config.py +++ b/townlight_core/llm/providers/config.py @@ -1,7 +1,7 @@ """Pydantic config schemas for built-in LLM providers (per ADR-0004 §6). Each schema declares the fields the provider needs and validates them at -startup (via `civiccore.llm.factory.build_provider`) rather than at first +startup (via `townlight_core.llm.factory.build_provider`) rather than at first generate() call. Misconfiguration surfaces immediately. """ from __future__ import annotations diff --git a/civiccore/llm/providers/ollama.py b/townlight_core/llm/providers/ollama.py similarity index 95% rename from civiccore/llm/providers/ollama.py rename to townlight_core/llm/providers/ollama.py index 1f925ba..0659213 100644 --- a/civiccore/llm/providers/ollama.py +++ b/townlight_core/llm/providers/ollama.py @@ -1,6 +1,6 @@ """Ollama local LLM runtime provider. -Uses httpx (already a civiccore dependency — no extra packages required) to +Uses httpx (already a townlight_core dependency — no extra packages required) to talk to a local Ollama daemon over its HTTP API. Default generation model is ``gemma4:e4b``, which matches the current @@ -16,8 +16,8 @@ import httpx -from civiccore.llm.providers.base import LLMProvider -from civiccore.llm.providers.registry import register_provider +from townlight_core.llm.providers.base import LLMProvider +from townlight_core.llm.providers.registry import register_provider @register_provider("ollama") diff --git a/civiccore/llm/providers/openai.py b/townlight_core/llm/providers/openai.py similarity index 89% rename from civiccore/llm/providers/openai.py rename to townlight_core/llm/providers/openai.py index 555fcfe..98bcd9f 100644 --- a/civiccore/llm/providers/openai.py +++ b/townlight_core/llm/providers/openai.py @@ -1,12 +1,12 @@ -"""OpenAI LLM provider for civiccore. +"""OpenAI LLM provider for townlight_core. This module implements :class:`OpenAIProvider`, a concrete -:class:`~civiccore.llm.providers.base.LLMProvider` backed by the official +:class:`~townlight_core.llm.providers.base.LLMProvider` backed by the official ``openai`` Python SDK. The ``openai`` SDK is an **optional extra**. Install with:: - pip install 'civiccore[openai]' + pip install 'townlight_core[openai]' The SDK import is performed lazily inside ``__init__`` so that this module (and therefore the provider registry decorator) can be imported cleanly even @@ -22,15 +22,15 @@ from __future__ import annotations -from civiccore.llm.providers.base import LLMProvider -from civiccore.llm.providers.registry import register_provider +from townlight_core.llm.providers.base import LLMProvider +from townlight_core.llm.providers.registry import register_provider @register_provider("openai") class OpenAIProvider(LLMProvider): """OpenAI API provider using the official openai SDK. - Requires the optional extra: ``pip install 'civiccore[openai]'``. + Requires the optional extra: ``pip install 'townlight_core[openai]'``. Default chat model: ``gpt-4o-mini``. Default embed model: ``text-embedding-3-small``. """ @@ -47,7 +47,7 @@ def __init__( except ImportError as e: raise ImportError( "openai SDK is required for OpenAIProvider. Install it: pip install openai " - "(or pip install 'civiccore[openai]' once civiccore is published to PyPI)." + "(or pip install 'townlight_core[openai]' once townlight_core is published to PyPI)." ) from e self._client = AsyncOpenAI(api_key=api_key) self.default_model = default_model diff --git a/civiccore/llm/providers/registry.py b/townlight_core/llm/providers/registry.py similarity index 95% rename from civiccore/llm/providers/registry.py rename to townlight_core/llm/providers/registry.py index f5fbcb4..9a877c1 100644 --- a/civiccore/llm/providers/registry.py +++ b/townlight_core/llm/providers/registry.py @@ -1,6 +1,6 @@ """In-process decorator registry for LLM providers. -Per ADR-0004 §6, civiccore uses a simple in-process decorator registry rather +Per ADR-0004 §6, townlight_core uses a simple in-process decorator registry rather than setuptools entry-points to discover :class:`LLMProvider` implementations. At one-process FastAPI scale (the records-ai deployment shape today), the entry-points machinery adds packaging-time and import-time overhead with no @@ -28,7 +28,7 @@ from typing import Callable -from civiccore.llm.providers.base import LLMProvider +from townlight_core.llm.providers.base import LLMProvider __all__ = [ "PROVIDER_REGISTRY", diff --git a/civiccore/llm/registry/__init__.py b/townlight_core/llm/registry/__init__.py similarity index 80% rename from civiccore/llm/registry/__init__.py rename to townlight_core/llm/registry/__init__.py index a0fb772..3368f1b 100644 --- a/civiccore/llm/registry/__init__.py +++ b/townlight_core/llm/registry/__init__.py @@ -1,5 +1,5 @@ """ -civiccore.llm.registry — ORM model, Pydantic schemas, service, and router. +townlight_core.llm.registry — ORM model, Pydantic schemas, service, and router. Public exports: @@ -15,14 +15,14 @@ - ``MissingModelError`` — Raised when a required active model is absent. """ -from civiccore.llm.registry.models import ModelRegistry -from civiccore.llm.registry.router import router as model_registry_router -from civiccore.llm.registry.schemas import ( +from townlight_core.llm.registry.models import ModelRegistry +from townlight_core.llm.registry.router import router as model_registry_router +from townlight_core.llm.registry.schemas import ( ModelRegistryCreate, ModelRegistryRead, ModelRegistryUpdate, ) -from civiccore.llm.registry.service import ( +from townlight_core.llm.registry.service import ( MissingModelError, ModelRegistryServiceError, get_active_model, diff --git a/civiccore/llm/registry/models.py b/townlight_core/llm/registry/models.py similarity index 98% rename from civiccore/llm/registry/models.py rename to townlight_core/llm/registry/models.py index f051233..a6342e6 100644 --- a/civiccore/llm/registry/models.py +++ b/townlight_core/llm/registry/models.py @@ -23,7 +23,7 @@ from sqlalchemy.dialects.postgresql import TIMESTAMP from sqlalchemy.orm import Mapped, mapped_column -from civiccore.db import Base +from townlight_core.db import Base class ModelRegistry(Base): diff --git a/civiccore/llm/registry/router.py b/townlight_core/llm/registry/router.py similarity index 94% rename from civiccore/llm/registry/router.py rename to townlight_core/llm/registry/router.py index 304bb06..b0519f8 100644 --- a/civiccore/llm/registry/router.py +++ b/townlight_core/llm/registry/router.py @@ -13,8 +13,8 @@ from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession -from civiccore.llm.registry.models import ModelRegistry -from civiccore.llm.registry.schemas import ( +from townlight_core.llm.registry.models import ModelRegistry +from townlight_core.llm.registry.schemas import ( ModelRegistryCreate, ModelRegistryRead, ModelRegistryUpdate, @@ -28,7 +28,7 @@ def _unconfigured_session_dependency() -> AsyncSession: ``app.dependency_overrides[get_session] = my_session_provider``. """ raise RuntimeError( - "civiccore.llm.registry.router.get_session has not been overridden. " + "townlight_core.llm.registry.router.get_session has not been overridden. " "Mount the router on your FastAPI app with a session dependency: " "`app.dependency_overrides[get_session] = your_session_provider`." ) diff --git a/civiccore/llm/registry/schemas.py b/townlight_core/llm/registry/schemas.py similarity index 100% rename from civiccore/llm/registry/schemas.py rename to townlight_core/llm/registry/schemas.py diff --git a/civiccore/llm/registry/service.py b/townlight_core/llm/registry/service.py similarity index 87% rename from civiccore/llm/registry/service.py rename to townlight_core/llm/registry/service.py index aea3872..ab32284 100644 --- a/civiccore/llm/registry/service.py +++ b/townlight_core/llm/registry/service.py @@ -1,8 +1,8 @@ -"""Service layer for the civiccore LLM model registry. +"""Service layer for the townlight_core LLM model registry. Library-friendly: callers pass an AsyncSession explicitly (no hardcoded -session_maker). Used by downstream apps (records-ai, civicclerk) and by -internal civiccore code that needs the active model's metadata. +session_maker). Used by downstream apps (records-ai, townlight_meetings) and by +internal townlight_core code that needs the active model's metadata. """ from __future__ import annotations @@ -11,8 +11,8 @@ from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession -from civiccore.llm.context import DEFAULT_CONTEXT_WINDOW -from civiccore.llm.registry.models import ModelRegistry +from townlight_core.llm.context import DEFAULT_CONTEXT_WINDOW +from townlight_core.llm.registry.models import ModelRegistry logger = logging.getLogger(__name__) diff --git a/civiccore/llm/structured.py b/townlight_core/llm/structured.py similarity index 98% rename from civiccore/llm/structured.py rename to townlight_core/llm/structured.py index 0dba6ff..433201d 100644 --- a/civiccore/llm/structured.py +++ b/townlight_core/llm/structured.py @@ -15,7 +15,7 @@ from pydantic import BaseModel, ValidationError -from civiccore.llm.providers.base import LLMProvider +from townlight_core.llm.providers.base import LLMProvider logger = logging.getLogger(__name__) diff --git a/civiccore/llm/templates/__init__.py b/townlight_core/llm/templates/__init__.py similarity index 59% rename from civiccore/llm/templates/__init__.py rename to townlight_core/llm/templates/__init__.py index e965241..c79a0fe 100644 --- a/civiccore/llm/templates/__init__.py +++ b/townlight_core/llm/templates/__init__.py @@ -5,26 +5,26 @@ """ from __future__ import annotations -# Side-effect import: ensure ModelRegistry is registered with civiccore.db.Base.metadata +# Side-effect import: ensure ModelRegistry is registered with townlight_core.db.Base.metadata # so SQLAlchemy can resolve PromptTemplate.model_id's FK("model_registry.id") at # mapper configuration time. Without this, querying PromptTemplate from a session -# where only civiccore.llm.templates was imported raises NoReferencedTableError. -from civiccore.llm.registry.models import ModelRegistry # noqa: F401 +# where only townlight_core.llm.templates was imported raises NoReferencedTableError. +from townlight_core.llm.registry.models import ModelRegistry # noqa: F401 -from civiccore.llm.templates.engine import RenderedPrompt, render_template -from civiccore.llm.templates.exceptions import ( +from townlight_core.llm.templates.engine import RenderedPrompt, render_template +from townlight_core.llm.templates.exceptions import ( PromptTemplateError, PromptTemplateNotFoundError, PromptTemplateRenderError, ) -from civiccore.llm.templates.models import PromptTemplate -from civiccore.llm.templates.overrides import ( +from townlight_core.llm.templates.models import PromptTemplate +from townlight_core.llm.templates.overrides import ( OVERRIDE_REGISTRY, register_template_override, unregister_template_override, ) -from civiccore.llm.templates.resolver import CIVICCORE_DEFAULT_APP, resolve_template -from civiccore.llm.templates.schemas import ( +from townlight_core.llm.templates.resolver import TOWNLIGHT_CORE_DEFAULT_APP, resolve_template +from townlight_core.llm.templates.schemas import ( PromptTemplateCreate, PromptTemplateRead, ) @@ -39,7 +39,7 @@ "RenderedPrompt", "render_template", "resolve_template", - "CIVICCORE_DEFAULT_APP", + "TOWNLIGHT_CORE_DEFAULT_APP", "PromptTemplateError", "PromptTemplateNotFoundError", "PromptTemplateRenderError", diff --git a/civiccore/llm/templates/engine.py b/townlight_core/llm/templates/engine.py similarity index 92% rename from civiccore/llm/templates/engine.py rename to townlight_core/llm/templates/engine.py index b4cc914..b90a902 100644 --- a/civiccore/llm/templates/engine.py +++ b/townlight_core/llm/templates/engine.py @@ -1,6 +1,6 @@ """Prompt template rendering using stdlib string.Template (PEP 292). -Per ADR-0004, civiccore uses string.Template (NOT Jinja2 or str.format) because: +Per ADR-0004, townlight_core uses string.Template (NOT Jinja2 or str.format) because: - $name / ${name} syntax does not collide with literal JSON braces in prompts that show JSON examples to the LLM. - Stdlib only — no dep cost. @@ -12,8 +12,8 @@ import string from dataclasses import dataclass -from civiccore.llm.templates.exceptions import PromptTemplateRenderError -from civiccore.llm.templates.models import PromptTemplate +from townlight_core.llm.templates.exceptions import PromptTemplateRenderError +from townlight_core.llm.templates.models import PromptTemplate @dataclass(frozen=True) diff --git a/civiccore/llm/templates/exceptions.py b/townlight_core/llm/templates/exceptions.py similarity index 92% rename from civiccore/llm/templates/exceptions.py rename to townlight_core/llm/templates/exceptions.py index b681ba1..61cc7b8 100644 --- a/civiccore/llm/templates/exceptions.py +++ b/townlight_core/llm/templates/exceptions.py @@ -11,7 +11,7 @@ class PromptTemplateNotFoundError(PromptTemplateError): The error message must direct the caller to either (a) seed the template in the prompt_templates table for the requesting consumer_app, or (b) - create a civiccore default. Both fields are exposed as attributes for + create a townlight_core default. Both fields are exposed as attributes for programmatic inspection. """ @@ -23,7 +23,7 @@ def __init__(self, *, template_name: str, consumer_app: str) -> None: f"template_name={template_name!r}, consumer_app={consumer_app!r}. " f"Insert an active row into prompt_templates with either " f"consumer_app={consumer_app!r} (app override, is_override=true) or " - f"consumer_app='civiccore' (civiccore default, is_override=false)." + f"consumer_app='townlight_core' (townlight_core default, is_override=false)." ) diff --git a/civiccore/llm/templates/models.py b/townlight_core/llm/templates/models.py similarity index 91% rename from civiccore/llm/templates/models.py rename to townlight_core/llm/templates/models.py index 08ac545..3dd45ec 100644 --- a/civiccore/llm/templates/models.py +++ b/townlight_core/llm/templates/models.py @@ -4,7 +4,7 @@ Maps exactly to the Phase 2 schema: - id UUID PK (Python-side default uuid4) - template_name VARCHAR(200) NOT NULL - - consumer_app VARCHAR(100) NOT NULL DEFAULT 'civiccore' + - consumer_app VARCHAR(100) NOT NULL DEFAULT 'townlight_core' - is_override BOOLEAN NOT NULL DEFAULT false - purpose VARCHAR(50) NOT NULL - system_prompt TEXT NOT NULL @@ -31,7 +31,7 @@ from sqlalchemy.orm import Mapped, mapped_column from sqlalchemy.sql import func -from civiccore.db import Base +from townlight_core.db import Base class PromptTemplate(Base): @@ -55,7 +55,7 @@ class PromptTemplate(Base): ) template_name: Mapped[str] = mapped_column(String(200), nullable=False) consumer_app: Mapped[str] = mapped_column( - String(100), nullable=False, server_default="civiccore" + String(100), nullable=False, server_default="townlight_core" ) is_override: Mapped[bool] = mapped_column( Boolean, nullable=False, server_default="false" @@ -77,8 +77,8 @@ class PromptTemplate(Base): ) # NOTE: DB-level FK to users(id) ON DELETE SET NULL is created by the # 0001 baseline migration. The ORM-level ForeignKey reference is omitted - # because civiccore has no User ORM model — users.id lives in records-ai - # and is not part of civiccore.db.Base.metadata. Including the ORM-level + # because townlight_core has no User ORM model — users.id lives in records-ai + # and is not part of townlight_core.db.Base.metadata. Including the ORM-level # ForeignKey here causes NoReferencedTableError at mapper config time. # The DB constraint is unaffected. created_by: Mapped[uuid.UUID | None] = mapped_column( diff --git a/civiccore/llm/templates/overrides.py b/townlight_core/llm/templates/overrides.py similarity index 79% rename from civiccore/llm/templates/overrides.py rename to townlight_core/llm/templates/overrides.py index 9ae71a5..c75f5ac 100644 --- a/civiccore/llm/templates/overrides.py +++ b/townlight_core/llm/templates/overrides.py @@ -1,19 +1,19 @@ """Code-level template overrides per ADR-0004 §7. -Consumer apps (records-ai, civicclerk) can register Python-shipped default +Consumer apps (records-ai, townlight_meetings) can register Python-shipped default overrides at module import time via @register_template_override. These take -precedence over civiccore defaults but are subordinate to operator-installed +precedence over townlight_core defaults but are subordinate to operator-installed DB overrides (so production hot-fixes still win). Resolution order (per ADR-0004 §7): 1. App DB override (consumer_app, is_override=true, is_active, highest version) 2. App code-level override (this module's OVERRIDE_REGISTRY) -3. Townlight Core DB default (consumer_app="civiccore", is_override=false, is_active, highest version) +3. Townlight Core DB default (consumer_app="townlight_core", is_override=false, is_active, highest version) 4. PromptTemplateNotFoundError """ from __future__ import annotations -from civiccore.llm.templates.models import PromptTemplate +from townlight_core.llm.templates.models import PromptTemplate # Keyed by (consumer_app, template_name); value is a fully-formed PromptTemplate # instance (not a Pydantic schema — the resolver returns ORM rows uniformly). @@ -35,8 +35,8 @@ def register_template_override( on re-import in tests). Args: - consumer_app: Namespace key (e.g., "civicrecords-ai", "civicclerk"). - Should not be "civiccore" — civiccore defaults belong in the DB. + consumer_app: Namespace key (e.g., "townlight_records", "townlight_meetings"). + Should not be "townlight_core" — townlight_core defaults belong in the DB. template_name: Logical template name (e.g., "exemption_review.system"). template: Fully-formed PromptTemplate instance. The caller is responsible for setting `template_name`, `consumer_app`, diff --git a/civiccore/llm/templates/resolver.py b/townlight_core/llm/templates/resolver.py similarity index 70% rename from civiccore/llm/templates/resolver.py rename to townlight_core/llm/templates/resolver.py index 0bd7fba..e0bdbdc 100644 --- a/civiccore/llm/templates/resolver.py +++ b/townlight_core/llm/templates/resolver.py @@ -9,17 +9,17 @@ Step 2 — App code-level override: Look up (consumer_app, template_name) in OVERRIDE_REGISTRY (in-memory map populated at import time via @register_template_override). Code overrides - beat civiccore defaults so that consumer apps can ship Python-level - defaults that supersede civiccore's defaults when no DB override exists. + beat townlight_core defaults so that consumer apps can ship Python-level + defaults that supersede townlight_core's defaults when no DB override exists. Step 3 — Townlight Core DB default: - Fall back to consumer_app='civiccore', template_name=, + Fall back to consumer_app='townlight_core', template_name=, is_override=false, is_active=true. Highest version wins. Step 4 — Missing: Raise PromptTemplateNotFoundError. No silent default. -When consumer_app == 'civiccore', steps 1 AND 2 are skipped — civiccore can't +When consumer_app == 'townlight_core', steps 1 AND 2 are skipped — townlight_core can't override its own template; it owns the default. """ from __future__ import annotations @@ -27,11 +27,11 @@ from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession -from civiccore.llm.templates.exceptions import PromptTemplateNotFoundError -from civiccore.llm.templates.models import PromptTemplate -from civiccore.llm.templates.overrides import OVERRIDE_REGISTRY +from townlight_core.llm.templates.exceptions import PromptTemplateNotFoundError +from townlight_core.llm.templates.models import PromptTemplate +from townlight_core.llm.templates.overrides import OVERRIDE_REGISTRY -CIVICCORE_DEFAULT_APP = "civiccore" +TOWNLIGHT_CORE_DEFAULT_APP = "townlight_core" async def resolve_template( @@ -45,19 +45,19 @@ async def resolve_template( Args: session: Active SQLAlchemy AsyncSession. template_name: Logical template name (e.g., "exemption_review.system"). - consumer_app: Requesting application namespace (e.g., "civicrecords-ai"). - When set to "civiccore", steps 1 and 2 are skipped (no self-override). + consumer_app: Requesting application namespace (e.g., "townlight_records"). + When set to "townlight_core", steps 1 and 2 are skipped (no self-override). Returns: The resolved PromptTemplate ORM row (or in-memory instance for code overrides). Raises: PromptTemplateNotFoundError: When no DB app override, code override, or - civiccore default is found. The error names both fields and tells + townlight_core default is found. The error names both fields and tells the caller how to add the missing template. """ - # Step 1: App-specific DB override (skip if requester is civiccore itself) - if consumer_app != CIVICCORE_DEFAULT_APP: + # Step 1: App-specific DB override (skip if requester is townlight_core itself) + if consumer_app != TOWNLIGHT_CORE_DEFAULT_APP: stmt = ( select(PromptTemplate) .where( @@ -75,16 +75,16 @@ async def resolve_template( return row # Step 2: App code-level override (in-memory registry). - # Skipped for consumer_app='civiccore' along with step 1. + # Skipped for consumer_app='townlight_core' along with step 1. code_override = OVERRIDE_REGISTRY.get((consumer_app, template_name)) if code_override is not None: return code_override - # Step 3: CivicCore default + # Step 3: TownlightCore default stmt = ( select(PromptTemplate) .where( - PromptTemplate.consumer_app == CIVICCORE_DEFAULT_APP, + PromptTemplate.consumer_app == TOWNLIGHT_CORE_DEFAULT_APP, PromptTemplate.template_name == template_name, PromptTemplate.is_override.is_(False), PromptTemplate.is_active.is_(True), @@ -104,4 +104,4 @@ async def resolve_template( ) -__all__ = ["resolve_template", "CIVICCORE_DEFAULT_APP"] +__all__ = ["resolve_template", "TOWNLIGHT_CORE_DEFAULT_APP"] diff --git a/civiccore/llm/templates/schemas.py b/townlight_core/llm/templates/schemas.py similarity index 97% rename from civiccore/llm/templates/schemas.py rename to townlight_core/llm/templates/schemas.py index 8c31f43..65d3da8 100644 --- a/civiccore/llm/templates/schemas.py +++ b/townlight_core/llm/templates/schemas.py @@ -20,7 +20,7 @@ class PromptTemplateCreate(BaseModel): user_prompt_template: str # Optional with defaults - consumer_app: str = "civiccore" + consumer_app: str = "townlight_core" is_override: bool = False token_budget: dict | None = None model_id: int | None = None diff --git a/townlight_core/migrations/__init__.py b/townlight_core/migrations/__init__.py new file mode 100644 index 0000000..06b4d72 --- /dev/null +++ b/townlight_core/migrations/__init__.py @@ -0,0 +1 @@ +"""TownlightCore: Alembic migrations for shared tables. Run by every consuming module's migration runner BEFORE that module's own migrations. See env.py for the migration-ordering contract from TownlightCore Extraction Spec section 14.""" diff --git a/townlight_core/migrations/alembic.ini b/townlight_core/migrations/alembic.ini new file mode 100644 index 0000000..c00aaa6 --- /dev/null +++ b/townlight_core/migrations/alembic.ini @@ -0,0 +1,3 @@ +[alembic] +script_location = %(here)s +version_table = alembic_version_townlight_core diff --git a/civiccore/migrations/env.py b/townlight_core/migrations/env.py similarity index 91% rename from civiccore/migrations/env.py rename to townlight_core/migrations/env.py index 5ca1415..d257887 100644 --- a/civiccore/migrations/env.py +++ b/townlight_core/migrations/env.py @@ -1,4 +1,4 @@ -"""Alembic env for civiccore. Reads the connection from Config.attributes['connection'] when invoked by runner.py (the normal path). Falls back to DATABASE_URL env var when invoked standalone.""" +"""Alembic env for townlight_core. Reads the connection from Config.attributes['connection'] when invoked by runner.py (the normal path). Falls back to DATABASE_URL env var when invoked standalone.""" from __future__ import annotations @@ -18,7 +18,7 @@ # No logging sections configured; skip Python logging setup. pass -VERSION_TABLE = "alembic_version_civiccore" +VERSION_TABLE = "alembic_version_townlight_core" target_metadata = None # v0.1 baseline is raw-SQL; no ORM metadata yet. diff --git a/civiccore/migrations/guards.py b/townlight_core/migrations/guards.py similarity index 93% rename from civiccore/migrations/guards.py rename to townlight_core/migrations/guards.py index f124de6..b74dfa7 100644 --- a/civiccore/migrations/guards.py +++ b/townlight_core/migrations/guards.py @@ -1,4 +1,4 @@ -"""Idempotent Alembic operation helpers. These wrap alembic.op.* calls with 'skip if already exists' semantics so civiccore's baseline migration and records' 14 guarded migrations can all be re-run against a database that already contains the shared schema.""" +"""Idempotent Alembic operation helpers. These wrap alembic.op.* calls with 'skip if already exists' semantics so townlight_core's baseline migration and records' 14 guarded migrations can all be re-run against a database that already contains the shared schema.""" from __future__ import annotations @@ -17,7 +17,7 @@ def _inspector() -> Inspector: def idempotent_create_table(name: str, *columns: Any, **kwargs: Any) -> None: """op.create_table that no-ops if the table already exists. - Used by civiccore's baseline migration and by guarded records migrations that + Used by townlight_core's baseline migration and by guarded records migrations that create shared tables (e.g. `users`, `data_sources`). If the table is already present in the database, the create is skipped; otherwise it proceeds normally. """ @@ -31,7 +31,7 @@ def idempotent_add_column(table: str, column: Any, **kwargs: Any) -> None: """op.add_column that no-ops if the column already exists. If the target table itself does not exist, returns silently — the upstream - migration (or civiccore baseline) is responsible for creating it. If the + migration (or townlight_core baseline) is responsible for creating it. If the table exists and the column is already present, skip. Otherwise add it. """ inspector = _inspector() @@ -109,7 +109,7 @@ def idempotent_create_index( """op.create_index that no-ops if an index with this name already exists on the table. Used by guarded records migrations whose ``op.create_index`` calls target shared - tables that civiccore's baseline migration already populated with indexes + tables that townlight_core's baseline migration already populated with indexes (per pg_dump-derived DDL). If the named index is already present, skip the create; otherwise create it normally. """ @@ -191,7 +191,7 @@ def idempotent_drop_constraint( delegates directly to op.drop_constraint — caller is responsible for guarding those cases. - Used by civiccore_0002_llm to idempotently drop the old + Used by townlight_core_0002_llm to idempotently drop the old prompt_templates_name_key UNIQUE constraint before adding the replacement composite unique constraint. """ diff --git a/civiccore/migrations/runner.py b/townlight_core/migrations/runner.py similarity index 71% rename from civiccore/migrations/runner.py rename to townlight_core/migrations/runner.py index b811a91..3dbf08e 100644 --- a/civiccore/migrations/runner.py +++ b/townlight_core/migrations/runner.py @@ -1,4 +1,4 @@ -"""Programmatic entry point for civiccore migrations. Consumed by records' env.py (Phase 1 Part B) so records' alembic upgrade automatically brings civiccore up to head first.""" +"""Programmatic entry point for townlight_core migrations. Consumed by records' env.py (Phase 1 Part B) so records' alembic upgrade automatically brings townlight_core up to head first.""" from __future__ import annotations @@ -17,7 +17,7 @@ def upgrade_to_head(connection: "Connection | None" = None) -> None: - """Upgrade civiccore's migration chain to head. + """Upgrade townlight_core's migration chain to head. **Always opens its own synchronous SQLAlchemy connection from the DATABASE_URL environment variable**, ignoring any ``connection`` passed @@ -27,18 +27,18 @@ def upgrade_to_head(connection: "Connection | None" = None) -> None: Why: ``alembic.command.upgrade`` installs a process-global context proxy via ``alembic.context._install_proxy``. When invoked from inside another - active env.py (e.g., civicrecords' env.py wiring), exiting civiccore's + active env.py (e.g., townlight_records' env.py wiring), exiting townlight_core's EnvironmentContext destroys the caller's proxy state, causing ``AttributeError: 'NoneType' object has no attribute 'configure'`` when the caller's env.py continues. Opening a separate connection keeps - civiccore's alembic invocation cleanly isolated. + townlight_core's alembic invocation cleanly isolated. - Trade-off: civiccore commits independently of the caller's transaction. + Trade-off: townlight_core commits independently of the caller's transaction. The baseline is idempotent, so a partial-state restart produces the same end-state — acceptable per ADR-0003 §"Three deployment scenarios". Requires ``DATABASE_URL`` env var to be set. The URL may use any psycopg2 - or asyncpg dialect; civiccore normalizes to ``postgresql+psycopg2`` for + or asyncpg dialect; townlight_core normalizes to ``postgresql+psycopg2`` for its own sync alembic invocation. """ import os @@ -47,12 +47,12 @@ def upgrade_to_head(connection: "Connection | None" = None) -> None: url = os.environ.get("DATABASE_URL") if url is None: raise RuntimeError( - "civiccore.migrations.runner.upgrade_to_head requires " - "DATABASE_URL to be set; civiccore opens its own connection " + "townlight_core.migrations.runner.upgrade_to_head requires " + "DATABASE_URL to be set; townlight_core opens its own connection " "to avoid nesting inside the caller's alembic context." ) - # Normalize to sync psycopg2 driver — civiccore alembic is sync-only + # Normalize to sync psycopg2 driver — townlight_core alembic is sync-only sync_url = ( url.replace("postgresql+asyncpg", "postgresql+psycopg2") .replace("postgres+asyncpg", "postgresql+psycopg2") @@ -73,13 +73,13 @@ def upgrade_to_head(connection: "Connection | None" = None) -> None: def current_revision(connection: "Connection") -> str | None: - """Return civiccore's current Alembic revision on this connection, or None if unstamped. + """Return townlight_core's current Alembic revision on this connection, or None if unstamped. - Reads from the `alembic_version_civiccore` version table so it does not + Reads from the `alembic_version_townlight_core` version table so it does not collide with records' own `alembic_version` table in the same database. """ ctx = MigrationContext.configure( connection, - opts={"version_table": "alembic_version_civiccore"}, + opts={"version_table": "alembic_version_townlight_core"}, ) return ctx.get_current_revision() diff --git a/civiccore/migrations/versions/.gitkeep b/townlight_core/migrations/versions/.gitkeep similarity index 100% rename from civiccore/migrations/versions/.gitkeep rename to townlight_core/migrations/versions/.gitkeep diff --git a/civiccore/migrations/versions/__init__.py b/townlight_core/migrations/versions/__init__.py similarity index 83% rename from civiccore/migrations/versions/__init__.py rename to townlight_core/migrations/versions/__init__.py index 42d0b6d..6b7905a 100644 --- a/civiccore/migrations/versions/__init__.py +++ b/townlight_core/migrations/versions/__init__.py @@ -1,4 +1,4 @@ -"""Alembic migration versions for civiccore. +"""Alembic migration versions for townlight_core. Alembic discovers migration files by scanning this directory — the __init__.py is present only so the test suite can import version-module diff --git a/civiccore/migrations/versions/civiccore_0001_baseline_v1.py b/townlight_core/migrations/versions/townlight_core_0001_baseline_v1.py similarity index 97% rename from civiccore/migrations/versions/civiccore_0001_baseline_v1.py rename to townlight_core/migrations/versions/townlight_core_0001_baseline_v1.py index 0a13349..8c7578f 100644 --- a/civiccore/migrations/versions/civiccore_0001_baseline_v1.py +++ b/townlight_core/migrations/versions/townlight_core_0001_baseline_v1.py @@ -1,14 +1,14 @@ -"""CivicCore baseline v1 — shared schema extracted from CivicRecords HEAD 019. +"""TownlightCore baseline v1 — shared schema extracted from TownlightRecords HEAD 019. -This baseline captures the 16 shared tables that constitute the CivicCore +This baseline captures the 16 shared tables that constitute the TownlightCore kernel. It is the single source of truth for kernel schema going forward; -downstream applications (e.g., CivicRecords) should rebase onto this baseline +downstream applications (e.g., TownlightRecords) should rebase onto this baseline and stop re-declaring shared tables in their own migrations. Provenance: - Dumped from CivicRecords alembic HEAD ``019_encrypt_connection_config`` + Dumped from TownlightRecords alembic HEAD ``019_encrypt_connection_config`` via ``pg_dump --schema-only --no-owner --no-privileges --no-comments`` - against ``civicrecords_test`` on PostgreSQL 17.9. + against ``townlight_records_test`` on PostgreSQL 17.9. Dependencies captured (SHARED -> SHARED only): users.department_id -> departments.id @@ -35,7 +35,7 @@ Downgrade: No-op by design. A baseline migration defines the floor of supported - schema; reversing it would drop tables that both civiccore and + schema; reversing it would drop tables that both townlight_core and downstream apps depend on. Use point-in-time restore or drop the database instead. """ @@ -44,12 +44,12 @@ from alembic import op -from civiccore.migrations.guards import has_table +from townlight_core.migrations.guards import has_table # Alembic identifiers -------------------------------------------------------- -revision = "civiccore_0001_baseline_v1" +revision = "townlight_core_0001" down_revision = None branch_labels = None depends_on = None @@ -88,7 +88,7 @@ # - CREATE INDEX # - ALTER TABLE ... ADD CONSTRAINT ... FOREIGN KEY (only shared->shared) # -# Executed verbatim via ``op.execute`` so the DDL matches CivicRecords HEAD 019 +# Executed verbatim via ``op.execute`` so the DDL matches TownlightRecords HEAD 019 # byte-for-byte where practical. _TABLE_DDL: dict[str, str] = { @@ -543,7 +543,7 @@ def _split_statements(ddl: str) -> list[str]: def upgrade() -> None: - """Idempotently bring the database up to the civiccore baseline. + """Idempotently bring the database up to the townlight_core baseline. Runs in three phases: 1. Ensure required extensions exist (``vector`` for pgvector). diff --git a/civiccore/migrations/versions/civiccore_0002_llm.py b/townlight_core/migrations/versions/townlight_core_0002_llm.py similarity index 79% rename from civiccore/migrations/versions/civiccore_0002_llm.py rename to townlight_core/migrations/versions/townlight_core_0002_llm.py index 3cec5b2..e03aa8c 100644 --- a/civiccore/migrations/versions/civiccore_0002_llm.py +++ b/townlight_core/migrations/versions/townlight_core_0002_llm.py @@ -1,9 +1,9 @@ -"""CivicCore migration 0002 — Phase 2 LLM extraction: prompt_templates schema evolution. +"""TownlightCore migration 0002 — Phase 2 LLM extraction: prompt_templates schema evolution. Context — Phase 2 LLM extraction: - CivicCore v0.1.0 (baseline 0001) already contains both LLM-related tables: + TownlightCore v0.1.0 (baseline 0001) already contains both LLM-related tables: - * ``model_registry`` — fully Phase-2-ready as extracted from CivicRecords HEAD 019. + * ``model_registry`` — fully Phase-2-ready as extracted from TownlightRecords HEAD 019. No columns need to be added or altered; this migration leaves it untouched. * ``prompt_templates`` — present in the baseline but needs schema evolution to @@ -11,8 +11,8 @@ evolution in-place (ALTER, not CREATE). Why ALTER not CREATE: - Both tables were captured verbatim from CivicRecords HEAD 019 by the baseline - migration (civiccore_0001_baseline_v1). They therefore already exist in any + Both tables were captured verbatim from TownlightRecords HEAD 019 by the baseline + migration (townlight_core_0001_baseline_v1). They therefore already exist in any database that has run 0001. This migration extends ``prompt_templates``; it does not recreate it. Running against a fresh database after 0001 is the normal path; running against a database already at a partially-evolved state is also safe @@ -24,13 +24,13 @@ calls this ``template_name`` to distinguish it from other "name"-style columns in the database. - 2. Add ``consumer_app VARCHAR(100) NOT NULL DEFAULT 'civiccore'``. + 2. Add ``consumer_app VARCHAR(100) NOT NULL DEFAULT 'townlight_core'``. Identifies which consuming application owns a template row. Defaults to - 'civiccore' for the shared kernel. Records-AI side migration bacfills rows - that belong to 'civicrecords-ai' (Step 5 of the Phase 2 sprint). + 'townlight_core' for the shared kernel. Records-AI side migration bacfills rows + that belong to 'townlight_records' (Step 5 of the Phase 2 sprint). 3. Add ``is_override BOOLEAN NOT NULL DEFAULT false``. - Flag indicating whether a row is a consumer-app override of a civiccore + Flag indicating whether a row is a consumer-app override of a townlight_core canonical template rather than a canonical template itself. 4. Drop old unique constraint ``prompt_templates_name_key``. @@ -49,12 +49,12 @@ Data migration note: Existing ``prompt_templates`` rows will default ``consumer_app`` to - 'civiccore' and ``is_override`` to False. The CivicRecords-side migration - handles backfilling rows that logically belong to 'civicrecords-ai' + 'townlight_core' and ``is_override`` to False. The TownlightRecords-side migration + handles backfilling rows that logically belong to 'townlight_records' (Phase 2 sprint Step 5). No data migration is performed in this file. Idempotency guarantees: - Every step uses a guard helper from ``civiccore.migrations.guards``: + Every step uses a guard helper from ``townlight_core.migrations.guards``: * idempotent_alter_column — no-op if the old column name is absent * idempotent_add_column — no-op if the column already exists * idempotent_drop_constraint — no-op if the constraint is absent @@ -65,7 +65,7 @@ Downgrade: No-op by design — same reasoning as 0001. The renamed column and new - columns are already referenced by downstream civicrecords-ai migrations. + columns are already referenced by downstream townlight_records migrations. Use point-in-time restore or drop/recreate the database instead. """ @@ -73,7 +73,7 @@ import sqlalchemy as sa -from civiccore.migrations.guards import ( +from townlight_core.migrations.guards import ( idempotent_add_column, idempotent_alter_column, idempotent_create_unique_constraint, @@ -83,8 +83,8 @@ # Alembic identifiers -------------------------------------------------------- -revision = "civiccore_0002_llm" -down_revision = "civiccore_0001_baseline_v1" +revision = "townlight_core_0002" +down_revision = "townlight_core_0001" branch_labels = None depends_on = None @@ -110,10 +110,10 @@ def upgrade() -> None: existing_type=sa.String(200), ) - # 2. Add consumer_app VARCHAR(100) NOT NULL DEFAULT 'civiccore' + # 2. Add consumer_app VARCHAR(100) NOT NULL DEFAULT 'townlight_core' idempotent_add_column( "prompt_templates", - sa.Column("consumer_app", sa.String(100), nullable=False, server_default="civiccore"), + sa.Column("consumer_app", sa.String(100), nullable=False, server_default="townlight_core"), ) # 3. Add is_override BOOLEAN NOT NULL DEFAULT false @@ -141,7 +141,7 @@ def downgrade() -> None: """No-op. The renamed column (template_name) and new columns (consumer_app, - is_override) are already referenced by downstream civicrecords-ai + is_override) are already referenced by downstream townlight_records migrations. Reversing this migration would break those dependencies. Use database-level restore instead. """ diff --git a/civiccore/migrations/versions/civiccore_0003_local_task_queue.py b/townlight_core/migrations/versions/townlight_core_0003_local_task_queue.py similarity index 68% rename from civiccore/migrations/versions/civiccore_0003_local_task_queue.py rename to townlight_core/migrations/versions/townlight_core_0003_local_task_queue.py index fdec2b6..2cb377c 100644 --- a/civiccore/migrations/versions/civiccore_0003_local_task_queue.py +++ b/townlight_core/migrations/versions/townlight_core_0003_local_task_queue.py @@ -1,22 +1,22 @@ -"""CivicCore migration 0003 - local task queue.""" +"""TownlightCore migration 0003 - local task queue.""" from __future__ import annotations import sqlalchemy as sa from sqlalchemy.dialects import postgresql -from civiccore.migrations.guards import idempotent_create_index, idempotent_create_table +from townlight_core.migrations.guards import idempotent_create_index, idempotent_create_table -revision = "civiccore_0003_local_task_queue" -down_revision = "civiccore_0002_llm" +revision = "townlight_core_0003" +down_revision = "townlight_core_0002" branch_labels = None depends_on = None def upgrade() -> None: idempotent_create_table( - "civiccore_local_tasks", + "townlight_core_local_tasks", sa.Column("task_id", sa.String(128), primary_key=True), sa.Column("module_id", sa.String(64), nullable=False), sa.Column("task_type", sa.String(100), nullable=False), @@ -34,9 +34,9 @@ def upgrade() -> None: sa.Column("idempotency_key", sa.String(255), nullable=True, unique=True), sa.Column("audit_subject_id", sa.String(255), nullable=True), ) - idempotent_create_index("ix_civiccore_local_tasks_module", "civiccore_local_tasks", ["module_id"]) - idempotent_create_index("ix_civiccore_local_tasks_status", "civiccore_local_tasks", ["status"]) - idempotent_create_index("ix_civiccore_local_tasks_type", "civiccore_local_tasks", ["task_type"]) + idempotent_create_index("ix_townlight_core_local_tasks_module", "townlight_core_local_tasks", ["module_id"]) + idempotent_create_index("ix_townlight_core_local_tasks_status", "townlight_core_local_tasks", ["status"]) + idempotent_create_index("ix_townlight_core_local_tasks_type", "townlight_core_local_tasks", ["task_type"]) def downgrade() -> None: diff --git a/civiccore/migrations/versions/civiccore_0004_catalog.py b/townlight_core/migrations/versions/townlight_core_0004_catalog.py similarity index 78% rename from civiccore/migrations/versions/civiccore_0004_catalog.py rename to townlight_core/migrations/versions/townlight_core_0004_catalog.py index 5c00fa3..6449626 100644 --- a/civiccore/migrations/versions/civiccore_0004_catalog.py +++ b/townlight_core/migrations/versions/townlight_core_0004_catalog.py @@ -3,14 +3,14 @@ from alembic import op -revision = "civiccore_0004_catalog" -down_revision = "civiccore_0003_local_task_queue" +revision = "townlight_core_0004" +down_revision = "townlight_core_0003" branch_labels = None depends_on = None def upgrade(): - op.execute("""CREATE TABLE IF NOT EXISTS civiccore_catalog_imports ( + op.execute("""CREATE TABLE IF NOT EXISTS townlight_core_catalog_imports ( version varchar(20) PRIMARY KEY, source_sha256 varchar(64) NOT NULL, entry_count integer NOT NULL CHECK (entry_count >= 0), diff --git a/townlight_core/migrations/versions/townlight_core_0005_job_leases.py b/townlight_core/migrations/versions/townlight_core_0005_job_leases.py new file mode 100644 index 0000000..d0a6bb8 --- /dev/null +++ b/townlight_core/migrations/versions/townlight_core_0005_job_leases.py @@ -0,0 +1,26 @@ +# SPDX-License-Identifier: AGPL-3.0-only +"""Fenced worker leases on the existing shared queue; no second job store.""" + +from alembic import op + +revision = "townlight_core_0005" +down_revision = "townlight_core_0004" +branch_labels = None +depends_on = None + + +def upgrade(): + op.execute("ALTER TABLE townlight_core_local_tasks ADD COLUMN IF NOT EXISTS claim_token varchar(64)") + op.execute( + "ALTER TABLE townlight_core_local_tasks ADD COLUMN IF NOT EXISTS lease_expires_at timestamptz" + ) + op.execute( + "ALTER TABLE townlight_core_local_tasks ADD COLUMN IF NOT EXISTS cancelled_by varchar(128)" + ) + op.execute( + "CREATE INDEX IF NOT EXISTS ix_townlight_core_local_tasks_lease ON townlight_core_local_tasks (status,lease_expires_at)" + ) + + +def downgrade(): + pass # Preserve jobs and cancellation history; restore a coherent backup. diff --git a/civiccore/migrations/versions/civiccore_0006_rule_history.py b/townlight_core/migrations/versions/townlight_core_0006_rule_history.py similarity index 62% rename from civiccore/migrations/versions/civiccore_0006_rule_history.py rename to townlight_core/migrations/versions/townlight_core_0006_rule_history.py index c338470..9754721 100644 --- a/civiccore/migrations/versions/civiccore_0006_rule_history.py +++ b/townlight_core/migrations/versions/townlight_core_0006_rule_history.py @@ -10,15 +10,15 @@ from alembic import op -revision = "civiccore_0006_rule_history" -down_revision = "civiccore_0005_job_leases" +revision = "townlight_core_0006" +down_revision = "townlight_core_0005" branch_labels = None depends_on = None def upgrade() -> None: op.execute( - """CREATE TABLE IF NOT EXISTS civiccore_rule_versions ( + """CREATE TABLE IF NOT EXISTS townlight_core_rule_versions ( rule_id uuid NOT NULL, state_code varchar(2) NOT NULL, version integer NOT NULL CHECK (version >= 1), @@ -34,41 +34,41 @@ def upgrade() -> None: content_sha256 char(64) NOT NULL, recorded_by varchar(128) NOT NULL CHECK (length(btrim(recorded_by)) > 0), recorded_at timestamptz NOT NULL DEFAULT now(), - CONSTRAINT civiccore_rule_versions_pkey PRIMARY KEY (rule_id, version), - CONSTRAINT civiccore_rule_versions_jurisdiction_key UNIQUE (rule_id, state_code, version), - CONSTRAINT civiccore_rule_versions_state_code_ck + CONSTRAINT townlight_core_rule_versions_pkey PRIMARY KEY (rule_id, version), + CONSTRAINT townlight_core_rule_versions_jurisdiction_key UNIQUE (rule_id, state_code, version), + CONSTRAINT townlight_core_rule_versions_state_code_ck CHECK (state_code = upper(state_code) AND length(state_code) = 2) )""" ) # Deterministic current-version and per-jurisdiction listing. op.execute( - "CREATE INDEX IF NOT EXISTS ix_civiccore_rule_versions_state_category " - "ON civiccore_rule_versions (state_code, category, version DESC)" + "CREATE INDEX IF NOT EXISTS ix_townlight_core_rule_versions_state_category " + "ON townlight_core_rule_versions (state_code, category, version DESC)" ) op.execute( - """CREATE OR REPLACE FUNCTION civiccore_rule_versions_append_only() + """CREATE OR REPLACE FUNCTION townlight_core_rule_versions_append_only() RETURNS trigger LANGUAGE plpgsql AS $$ BEGIN - RAISE EXCEPTION 'civiccore rule version history is append-only' + RAISE EXCEPTION 'townlight_core rule version history is append-only' USING ERRCODE = 'restrict_violation'; END; $$""" ) op.execute( - "DROP TRIGGER IF EXISTS trg_civiccore_rule_versions_append_only ON civiccore_rule_versions" + "DROP TRIGGER IF EXISTS trg_townlight_core_rule_versions_append_only ON townlight_core_rule_versions" ) op.execute( - """CREATE TRIGGER trg_civiccore_rule_versions_append_only - BEFORE UPDATE OR DELETE ON civiccore_rule_versions - FOR EACH ROW EXECUTE FUNCTION civiccore_rule_versions_append_only()""" + """CREATE TRIGGER trg_townlight_core_rule_versions_append_only + BEFORE UPDATE OR DELETE ON townlight_core_rule_versions + FOR EACH ROW EXECUTE FUNCTION townlight_core_rule_versions_append_only()""" ) # A rule id belongs to exactly one jurisdiction; a later insert cannot migrate it. op.execute( - """CREATE OR REPLACE FUNCTION civiccore_rule_versions_single_jurisdiction() + """CREATE OR REPLACE FUNCTION townlight_core_rule_versions_single_jurisdiction() RETURNS trigger LANGUAGE plpgsql AS $$ BEGIN IF EXISTS ( - SELECT 1 FROM civiccore_rule_versions + SELECT 1 FROM townlight_core_rule_versions WHERE rule_id = NEW.rule_id AND state_code <> NEW.state_code ) THEN RAISE EXCEPTION 'rule % already belongs to another jurisdiction', NEW.rule_id @@ -79,13 +79,13 @@ def upgrade() -> None: $$""" ) op.execute( - "DROP TRIGGER IF EXISTS trg_civiccore_rule_versions_jurisdiction " - "ON civiccore_rule_versions" + "DROP TRIGGER IF EXISTS trg_townlight_core_rule_versions_jurisdiction " + "ON townlight_core_rule_versions" ) op.execute( - """CREATE TRIGGER trg_civiccore_rule_versions_jurisdiction - BEFORE INSERT ON civiccore_rule_versions - FOR EACH ROW EXECUTE FUNCTION civiccore_rule_versions_single_jurisdiction()""" + """CREATE TRIGGER trg_townlight_core_rule_versions_jurisdiction + BEFORE INSERT ON townlight_core_rule_versions + FOR EACH ROW EXECUTE FUNCTION townlight_core_rule_versions_single_jurisdiction()""" ) diff --git a/civiccore/migrations/versions/civiccore_0007_module_inventory.py b/townlight_core/migrations/versions/townlight_core_0007_module_inventory.py similarity index 68% rename from civiccore/migrations/versions/civiccore_0007_module_inventory.py rename to townlight_core/migrations/versions/townlight_core_0007_module_inventory.py index 4eeb22f..8943365 100644 --- a/civiccore/migrations/versions/civiccore_0007_module_inventory.py +++ b/townlight_core/migrations/versions/townlight_core_0007_module_inventory.py @@ -10,60 +10,60 @@ from alembic import op -revision = "civiccore_0007_module_inventory" -down_revision = "civiccore_0006_rule_history" +revision = "townlight_core_0007" +down_revision = "townlight_core_0006" branch_labels = None depends_on = None def upgrade() -> None: op.execute( - """CREATE TABLE IF NOT EXISTS civiccore_module_inventory ( + """CREATE TABLE IF NOT EXISTS townlight_core_module_inventory ( scope_id varchar(64) NOT NULL CHECK (length(btrim(scope_id)) > 0), revision integer NOT NULL CHECK (revision >= 1), profile varchar(20) NOT NULL CHECK (profile IN ('windows_local','server','developer')), - civiccore_version varchar(40) NOT NULL CHECK (length(btrim(civiccore_version)) > 0), + townlight_core_version varchar(40) NOT NULL CHECK (length(btrim(townlight_core_version)) > 0), content_sha256 char(64) NOT NULL, recorded_by varchar(128) NOT NULL CHECK (length(btrim(recorded_by)) > 0), recorded_at timestamptz NOT NULL DEFAULT now(), - CONSTRAINT civiccore_module_inventory_pkey PRIMARY KEY (scope_id, revision) + CONSTRAINT townlight_core_module_inventory_pkey PRIMARY KEY (scope_id, revision) )""" ) op.execute( - """CREATE TABLE IF NOT EXISTS civiccore_module_inventory_entries ( + """CREATE TABLE IF NOT EXISTS townlight_core_module_inventory_entries ( scope_id varchar(64) NOT NULL, revision integer NOT NULL CHECK (revision >= 1), module_id varchar(64) NOT NULL CHECK (length(btrim(module_id)) > 0), version varchar(40) NOT NULL CHECK (length(btrim(version)) > 0), enabled boolean NOT NULL, manifest jsonb NOT NULL, - CONSTRAINT civiccore_module_inventory_entries_pkey + CONSTRAINT townlight_core_module_inventory_entries_pkey PRIMARY KEY (scope_id, revision, module_id), - CONSTRAINT civiccore_module_inventory_entries_scope_fk + CONSTRAINT townlight_core_module_inventory_entries_scope_fk FOREIGN KEY (scope_id, revision) - REFERENCES civiccore_module_inventory (scope_id, revision) + REFERENCES townlight_core_module_inventory (scope_id, revision) )""" ) # Deterministic scope listing without a sequential scan of every revision. op.execute( - "CREATE INDEX IF NOT EXISTS ix_civiccore_module_inventory_scope " - "ON civiccore_module_inventory (scope_id, revision DESC)" + "CREATE INDEX IF NOT EXISTS ix_townlight_core_module_inventory_scope " + "ON townlight_core_module_inventory (scope_id, revision DESC)" ) op.execute( - """CREATE OR REPLACE FUNCTION civiccore_module_inventory_append_only() + """CREATE OR REPLACE FUNCTION townlight_core_module_inventory_append_only() RETURNS trigger LANGUAGE plpgsql AS $$ BEGIN - RAISE EXCEPTION 'civiccore module inventory is append-only' + RAISE EXCEPTION 'townlight_core module inventory is append-only' USING ERRCODE = 'restrict_violation'; END; $$""" ) - for table in ("civiccore_module_inventory", "civiccore_module_inventory_entries"): + for table in ("townlight_core_module_inventory", "townlight_core_module_inventory_entries"): op.execute(f"DROP TRIGGER IF EXISTS trg_{table}_append_only ON {table}") op.execute( f"""CREATE TRIGGER trg_{table}_append_only BEFORE UPDATE OR DELETE ON {table} - FOR EACH ROW EXECUTE FUNCTION civiccore_module_inventory_append_only()""" + FOR EACH ROW EXECUTE FUNCTION townlight_core_module_inventory_append_only()""" ) # Scope isolation comes from the composite primary key and the (scope_id, revision) # foreign key: a revision's entries cannot be read or joined across scopes, while the same diff --git a/civiccore/migrations/versions/civiccore_0008_department_authority.py b/townlight_core/migrations/versions/townlight_core_0008_department_authority.py similarity index 68% rename from civiccore/migrations/versions/civiccore_0008_department_authority.py rename to townlight_core/migrations/versions/townlight_core_0008_department_authority.py index bac2d54..28ca86e 100644 --- a/civiccore/migrations/versions/civiccore_0008_department_authority.py +++ b/townlight_core/migrations/versions/townlight_core_0008_department_authority.py @@ -11,15 +11,15 @@ from alembic import op -revision = "civiccore_0008_authority" -down_revision = "civiccore_0007_module_inventory" +revision = "townlight_core_0008" +down_revision = "townlight_core_0007" branch_labels = None depends_on = None def upgrade() -> None: op.execute( - """CREATE TABLE IF NOT EXISTS civiccore_department_grant_events ( + """CREATE TABLE IF NOT EXISTS townlight_core_department_grant_events ( scope_id varchar(64) NOT NULL CHECK (length(btrim(scope_id)) > 0), subject varchar(320) NOT NULL CHECK (length(btrim(subject)) > 0), department_id uuid NOT NULL, @@ -29,9 +29,9 @@ def upgrade() -> None: recorded_by varchar(128) NOT NULL CHECK (length(btrim(recorded_by)) > 0), recorded_at timestamptz NOT NULL DEFAULT now(), content_sha256 char(64) NOT NULL, - CONSTRAINT civiccore_department_grant_events_pkey + CONSTRAINT townlight_core_department_grant_events_pkey PRIMARY KEY (scope_id, subject, department_id, sequence), - CONSTRAINT civiccore_department_grant_roles_shape + CONSTRAINT townlight_core_department_grant_roles_shape CHECK ((action = 'grant' AND cardinality(roles) >= 1) OR (action = 'revoke' AND cardinality(roles) = 0)) )""" @@ -39,30 +39,30 @@ def upgrade() -> None: # The active-state read path is one DISTINCT ON per (scope, subject): this index serves it # without scanning every retained event of the whole ledger. op.execute( - "CREATE INDEX IF NOT EXISTS ix_civiccore_department_grant_active " - "ON civiccore_department_grant_events (scope_id, subject, department_id, sequence DESC)" + "CREATE INDEX IF NOT EXISTS ix_townlight_core_department_grant_active " + "ON townlight_core_department_grant_events (scope_id, subject, department_id, sequence DESC)" ) op.execute( - "CREATE INDEX IF NOT EXISTS ix_civiccore_department_grant_department " - "ON civiccore_department_grant_events (scope_id, department_id)" + "CREATE INDEX IF NOT EXISTS ix_townlight_core_department_grant_department " + "ON townlight_core_department_grant_events (scope_id, department_id)" ) op.execute( - """CREATE OR REPLACE FUNCTION civiccore_department_grant_append_only() + """CREATE OR REPLACE FUNCTION townlight_core_department_grant_append_only() RETURNS trigger LANGUAGE plpgsql AS $$ BEGIN - RAISE EXCEPTION 'civiccore department grants are append-only' + RAISE EXCEPTION 'townlight_core department grants are append-only' USING ERRCODE = 'restrict_violation'; END; $$""" ) op.execute( - "DROP TRIGGER IF EXISTS trg_civiccore_department_grant_append_only " - "ON civiccore_department_grant_events" + "DROP TRIGGER IF EXISTS trg_townlight_core_department_grant_append_only " + "ON townlight_core_department_grant_events" ) op.execute( - """CREATE TRIGGER trg_civiccore_department_grant_append_only - BEFORE UPDATE OR DELETE ON civiccore_department_grant_events - FOR EACH ROW EXECUTE FUNCTION civiccore_department_grant_append_only()""" + """CREATE TRIGGER trg_townlight_core_department_grant_append_only + BEFORE UPDATE OR DELETE ON townlight_core_department_grant_events + FOR EACH ROW EXECUTE FUNCTION townlight_core_department_grant_append_only()""" ) # Scope isolation is structural: every row carries its scope, and the composite primary key # makes a (scope, subject, department, sequence) identity unambiguous. A grant in one scope diff --git a/civiccore/migrations/versions/civiccore_0009_job_artifacts.py b/townlight_core/migrations/versions/townlight_core_0009_job_artifacts.py similarity index 73% rename from civiccore/migrations/versions/civiccore_0009_job_artifacts.py rename to townlight_core/migrations/versions/townlight_core_0009_job_artifacts.py index 874dd5f..8e7d2bb 100644 --- a/civiccore/migrations/versions/civiccore_0009_job_artifacts.py +++ b/townlight_core/migrations/versions/townlight_core_0009_job_artifacts.py @@ -11,15 +11,15 @@ from alembic import op -revision = "civiccore_0009_job_artifacts" -down_revision = "civiccore_0008_authority" +revision = "townlight_core_0009" +down_revision = "townlight_core_0008" branch_labels = None depends_on = None def upgrade() -> None: op.execute( - """CREATE TABLE IF NOT EXISTS civiccore_job_artifacts ( + """CREATE TABLE IF NOT EXISTS townlight_core_job_artifacts ( artifact_id varchar(64) PRIMARY KEY CHECK (length(artifact_id) = 32), task_id varchar(128) NOT NULL CHECK (length(btrim(task_id)) > 0), module_id varchar(64) NOT NULL CHECK (length(btrim(module_id)) > 0), @@ -36,32 +36,32 @@ def upgrade() -> None: source_label varchar(200) NOT NULL CHECK (length(btrim(source_label)) > 0), recorded_by varchar(128) NOT NULL CHECK (length(btrim(recorded_by)) > 0), recorded_at timestamptz NOT NULL DEFAULT now(), - CONSTRAINT civiccore_job_artifacts_task_name_unique UNIQUE (task_id, artifact_name) + CONSTRAINT townlight_core_job_artifacts_task_name_unique UNIQUE (task_id, artifact_name) )""" ) # One claimed job cannot record the same relative path twice, and the queue's job # identity stays the fast lookup for a consumer assembling a job's receipts. op.execute( - "CREATE INDEX IF NOT EXISTS ix_civiccore_job_artifacts_task " - "ON civiccore_job_artifacts (task_id, recorded_at)" + "CREATE INDEX IF NOT EXISTS ix_townlight_core_job_artifacts_task " + "ON townlight_core_job_artifacts (task_id, recorded_at)" ) op.execute( - """CREATE OR REPLACE FUNCTION civiccore_job_artifacts_append_only() + """CREATE OR REPLACE FUNCTION townlight_core_job_artifacts_append_only() RETURNS trigger LANGUAGE plpgsql AS $$ BEGIN - RAISE EXCEPTION 'civiccore job artifact receipts are append-only' + RAISE EXCEPTION 'townlight_core job artifact receipts are append-only' USING ERRCODE = 'restrict_violation'; END; $$""" ) op.execute( - "DROP TRIGGER IF EXISTS trg_civiccore_job_artifacts_append_only " - "ON civiccore_job_artifacts" + "DROP TRIGGER IF EXISTS trg_townlight_core_job_artifacts_append_only " + "ON townlight_core_job_artifacts" ) op.execute( - """CREATE TRIGGER trg_civiccore_job_artifacts_append_only - BEFORE UPDATE OR DELETE ON civiccore_job_artifacts - FOR EACH ROW EXECUTE FUNCTION civiccore_job_artifacts_append_only()""" + """CREATE TRIGGER trg_townlight_core_job_artifacts_append_only + BEFORE UPDATE OR DELETE ON townlight_core_job_artifacts + FOR EACH ROW EXECUTE FUNCTION townlight_core_job_artifacts_append_only()""" ) diff --git a/civiccore/models/__init__.py b/townlight_core/models/__init__.py similarity index 53% rename from civiccore/models/__init__.py rename to townlight_core/models/__init__.py index 22b46a5..d342508 100644 --- a/civiccore/models/__init__.py +++ b/townlight_core/models/__init__.py @@ -1,7 +1,7 @@ """Townlight Core shared SQLAlchemy ORM model exports.""" -from civiccore.ingest.models import DataSource, Document, DocumentChunk, IngestionStatus, SourceType -from civiccore.platform.task_queue import LocalTask +from townlight_core.ingest.models import DataSource, Document, DocumentChunk, IngestionStatus, SourceType +from townlight_core.platform.task_queue import LocalTask __all__ = [ "DataSource", diff --git a/civiccore/notifications/__init__.py b/townlight_core/notifications/__init__.py similarity index 89% rename from civiccore/notifications/__init__.py rename to townlight_core/notifications/__init__.py index eac4f12..a2fb75a 100644 --- a/civiccore/notifications/__init__.py +++ b/townlight_core/notifications/__init__.py @@ -1,6 +1,6 @@ """Shared notice and notification helpers for Townlight modules.""" -from civiccore.notifications.notice import ( +from townlight_core.notifications.notice import ( DeadlinePlan, NoticeComplianceResult, NoticeComplianceWarning, diff --git a/civiccore/notifications/notice.py b/townlight_core/notifications/notice.py similarity index 100% rename from civiccore/notifications/notice.py rename to townlight_core/notifications/notice.py diff --git a/civiccore/onboarding/__init__.py b/townlight_core/onboarding/__init__.py similarity index 90% rename from civiccore/onboarding/__init__.py rename to townlight_core/onboarding/__init__.py index f77831a..1c09abb 100644 --- a/civiccore/onboarding/__init__.py +++ b/townlight_core/onboarding/__init__.py @@ -1,6 +1,6 @@ """Shared onboarding interview/profile helpers for Townlight modules.""" -from civiccore.onboarding.profile import ( +from townlight_core.onboarding.profile import ( DEFAULT_PROFILE_FIELDS, OnboardingField, OnboardingProgress, diff --git a/civiccore/onboarding/profile.py b/townlight_core/onboarding/profile.py similarity index 100% rename from civiccore/onboarding/profile.py rename to townlight_core/onboarding/profile.py diff --git a/civiccore/platform/__init__.py b/townlight_core/platform/__init__.py similarity index 89% rename from civiccore/platform/__init__.py rename to townlight_core/platform/__init__.py index 164d3c1..21c358b 100644 --- a/civiccore/platform/__init__.py +++ b/townlight_core/platform/__init__.py @@ -2,7 +2,7 @@ from __future__ import annotations -from civiccore.platform.backup import ( +from townlight_core.platform.backup import ( BackupItem, BackupManifest, BackupRestoreAction, @@ -12,13 +12,13 @@ plan_restore, validate_backup_manifest, ) -from civiccore.platform.health import ( +from townlight_core.platform.health import ( PlatformHealthCheck, PlatformHealthStatus, PlatformHealthSummary, summarize_platform_health, ) -from civiccore.platform.inventory import ( +from townlight_core.platform.inventory import ( InventoryConflictError, InventoryOutcome, ModuleInventory, @@ -34,7 +34,7 @@ record_inventory, require_installed, ) -from civiccore.platform.modules import ( +from townlight_core.platform.modules import ( WINDOWS_LOCAL_BLOCKED_RUNTIME_KINDS, ModuleBackupHook, ModuleDependency, @@ -51,8 +51,8 @@ build_module_registry, validate_windows_local_manifest, ) -from civiccore.platform.runtime import LocalRuntimeProfile, RuntimeActionResult -from civiccore.platform.task_queue import ( +from townlight_core.platform.runtime import LocalRuntimeProfile, RuntimeActionResult +from townlight_core.platform.task_queue import ( LocalTask, TaskHandler, claim_next_local_task, @@ -65,7 +65,7 @@ run_one_local_task, task_row_to_envelope, ) -from civiccore.platform.tasks import ( +from townlight_core.platform.tasks import ( LocalTaskEnvelope, LocalTaskResult, TaskQueueSummary, diff --git a/civiccore/platform/backup.py b/townlight_core/platform/backup.py similarity index 96% rename from civiccore/platform/backup.py rename to townlight_core/platform/backup.py index 1ac9ab1..b3c2946 100644 --- a/civiccore/platform/backup.py +++ b/townlight_core/platform/backup.py @@ -17,7 +17,7 @@ class BackupItem(BaseModel): model_config = ConfigDict(extra="forbid") - module_id: str = Field(pattern=r"^[a-z][a-z0-9-]{1,63}$") + module_id: str = Field(pattern=r"^[a-z][a-z0-9_-]{1,63}$") relative_path: str = Field(min_length=1) size_bytes: int = Field(ge=0) sha256: str = Field(pattern=r"^[a-f0-9]{64}$") @@ -32,7 +32,7 @@ class BackupManifest(BaseModel): schema_version: str = "1.0" backup_id: str = Field(min_length=1) city_profile_id: str = Field(min_length=1) - civiccore_version: str = Field(min_length=1) + townlight_core_version: str = Field(min_length=1) created_at: datetime = Field(default_factory=lambda: datetime.now(UTC)) modules: list[str] = Field(default_factory=list) items: list[BackupItem] @@ -75,7 +75,7 @@ def build_backup_manifest( files: list[Path], backup_id: str, city_profile_id: str, - civiccore_version: str, + townlight_core_version: str, module_id: str, ) -> BackupManifest: """Build a checksum manifest for files under a local data root.""" @@ -100,7 +100,7 @@ def build_backup_manifest( return BackupManifest( backup_id=backup_id, city_profile_id=city_profile_id, - civiccore_version=civiccore_version, + townlight_core_version=townlight_core_version, modules=sorted({module_id for _item in items}), items=sorted(items, key=lambda item: item.relative_path), ) diff --git a/civiccore/platform/health.py b/townlight_core/platform/health.py similarity index 95% rename from civiccore/platform/health.py rename to townlight_core/platform/health.py index e36dc9d..e2fa0db 100644 --- a/civiccore/platform/health.py +++ b/townlight_core/platform/health.py @@ -56,8 +56,8 @@ def summarize_platform_health(checks: list[PlatformHealthCheck]) -> PlatformHeal return PlatformHealthSummary( status="needs_setup", checks=[], - next_action="Run first-run setup so CivicSuite can verify the local services.", - staff_message="CivicSuite has not completed setup yet.", + next_action="Run first-run setup so Townlight can verify the local services.", + staff_message="Townlight has not completed setup yet.", admin_message="No platform health checks have reported.", blocked_components=[], degraded_components=[], diff --git a/civiccore/platform/inventory.py b/townlight_core/platform/inventory.py similarity index 94% rename from civiccore/platform/inventory.py rename to townlight_core/platform/inventory.py index d7fd11b..abc9ae6 100644 --- a/civiccore/platform/inventory.py +++ b/townlight_core/platform/inventory.py @@ -10,14 +10,14 @@ Relationship to the existing contracts -------------------------------------- -There is exactly one module resolver: :func:`civiccore.platform.modules.build_module_registry`. -This module validates through the shipped :class:`~civiccore.platform.modules.ModuleManifest`, +There is exactly one module resolver: :func:`townlight_core.platform.modules.build_module_registry`. +This module validates through the shipped :class:`~townlight_core.platform.modules.ModuleManifest`, persists a declared inventory, and asks that resolver what the declared set actually admits. No second resolver, dependency walker or cycle detector exists here. Relationship to the shared municipal systems catalog ---------------------------------------------------- -``civiccore.catalog`` holds reference data about *vendor systems* (domains, vendors, protocol +``townlight_core.catalog`` holds reference data about *vendor systems* (domains, vendors, protocol templates). That is not this: an installed-module inventory lists *Townlight module packages* a scope declares installed. The two never share rows, and a catalog entry never implies a module installation, just as a module entry never implies a vendor connection. @@ -50,7 +50,7 @@ from sqlalchemy import text from sqlalchemy.ext.asyncio import AsyncSession -from civiccore.platform.modules import ( +from townlight_core.platform.modules import ( InstallProfile, ModuleManifest, ModuleRegistryState, @@ -76,8 +76,8 @@ "ENTRY_TABLE", ] -HEAD_TABLE = "civiccore_module_inventory" -ENTRY_TABLE = "civiccore_module_inventory_entries" +HEAD_TABLE = "townlight_core_module_inventory" +ENTRY_TABLE = "townlight_core_module_inventory_entries" SCOPE_PATTERN = re.compile(r"^[a-z][a-z0-9._-]{1,63}$") @@ -144,7 +144,7 @@ class ModuleInventory(BaseModel): scope_id: str = Field(min_length=2, max_length=64) revision: int = Field(ge=1) profile: InstallProfile = "windows_local" - civiccore_version: str = Field(min_length=1) + townlight_core_version: str = Field(min_length=1) entries: list[ModuleInventoryEntry] = Field(default_factory=list) @field_validator("scope_id") @@ -183,7 +183,7 @@ def fingerprint(self) -> str: { "scope_id": self.scope_id, "profile": self.profile, - "civiccore_version": self.civiccore_version, + "townlight_core_version": self.townlight_core_version, "entries": payload, }, sort_keys=True, @@ -211,7 +211,7 @@ class InventoryOutcome(BaseModel): fingerprint: str -_COLUMNS = "scope_id,revision,profile,civiccore_version,content_sha256" +_COLUMNS = "scope_id,revision,profile,townlight_core_version,content_sha256" def _entry_rows(entries: list[ModuleInventoryEntry]) -> list[dict[str, Any]]: @@ -276,7 +276,7 @@ async def _load( scope_id=header["scope_id"], revision=header["revision"], profile=header["profile"], - civiccore_version=header["civiccore_version"], + townlight_core_version=header["townlight_core_version"], entries=[ ModuleInventoryEntry( module_id=row["module_id"], @@ -315,7 +315,7 @@ async def record_inventory( # Serialize per scope so two writers cannot both believe they hold the next revision. await session.execute( text("SELECT pg_advisory_xact_lock(hashtextextended(:key, 0))"), - {"key": f"civiccore.module_inventory:{item.scope_id}"}, + {"key": f"townlight_core.module_inventory:{item.scope_id}"}, ) current = ( @@ -359,14 +359,14 @@ async def record_inventory( await session.execute( text( - f"INSERT INTO {HEAD_TABLE} (scope_id,revision,profile,civiccore_version," + f"INSERT INTO {HEAD_TABLE} (scope_id,revision,profile,townlight_core_version," "content_sha256,recorded_by) VALUES (:scope,:rev,:profile,:core,:digest,:actor)" ), { "scope": item.scope_id, "rev": item.revision, "profile": item.profile, - "core": item.civiccore_version, + "core": item.townlight_core_version, "digest": fingerprint, "actor": recorded_by.strip(), }, @@ -432,13 +432,13 @@ def _actions_for_reason(reason: str | None) -> RecommendationAction: def _registry( manifests: list[ModuleManifest], *, - civiccore_version: str, + townlight_core_version: str, selected: set[str], profile: InstallProfile, ) -> ModuleRegistryState: return build_module_registry( list(manifests), - civiccore_version=civiccore_version, + townlight_core_version=townlight_core_version, selected_module_ids=selected, profile=profile, ) @@ -476,7 +476,7 @@ def resolve(selected: set[str]) -> dict[str, object]: entry.module_id: entry for entry in _registry( manifests, - civiccore_version=inventory.civiccore_version, + townlight_core_version=inventory.townlight_core_version, selected=selected, profile=inventory.profile, ).entries @@ -548,7 +548,7 @@ def _operator_copy(name: str, action: RecommendationAction, reason: str) -> str: if action == "enable": return f"{name} is installed but switched off. Enabling it is optional: {reason}" if action == "upgrade-core": - return f"{name} needs a newer CivicCore before it can run: {reason}" + return f"{name} needs a newer TownlightCore before it can run: {reason}" if action == "not-supported": return f"{name} does not support this install profile: {reason}" return f"{name} cannot start with the modules declared here: {reason}" diff --git a/civiccore/platform/modules.py b/townlight_core/platform/modules.py similarity index 95% rename from civiccore/platform/modules.py rename to townlight_core/platform/modules.py index 349179e..dd6159c 100644 --- a/civiccore/platform/modules.py +++ b/townlight_core/platform/modules.py @@ -19,7 +19,7 @@ "background-worker", ] RuntimeRequirementKind = Literal[ - "civiccore", + "townlight_core", "postgres", "pgvector", "python", @@ -38,7 +38,7 @@ ] ModuleRegistryStatus = Literal["enabled", "disabled", "blocked"] -MODULE_ID_PATTERN = r"^[a-z][a-z0-9-]{1,63}$" +MODULE_ID_PATTERN = r"^[a-z][a-z0-9_-]{1,63}$" SLUG_PATTERN = r"^[a-z][a-z0-9_-]{1,63}$" WINDOWS_LOCAL_BLOCKED_RUNTIME_KINDS = frozenset({"docker", "wsl", "linux_shell", "terminal"}) @@ -169,7 +169,7 @@ class ModuleManifest(BaseModel): name: str = Field(min_length=1) version: str = Field(min_length=1) package_name: str = Field(min_length=1) - civiccore_min_version: str = Field(min_length=1) + townlight_core_min_version: str = Field(min_length=1) enabled_by_default: bool = True surfaces: list[ModuleSurface] = Field(default_factory=lambda: ["staff"]) install_profiles: list[InstallProfile] = Field(default_factory=lambda: ["windows_local"]) @@ -248,8 +248,8 @@ class ModuleRegistryState(BaseModel): model_config = ConfigDict(extra="forbid") profile: InstallProfile = "windows_local" - civiccore_version: str = Field(min_length=1) - civiccore_locked: bool = True + townlight_core_version: str = Field(min_length=1) + townlight_core_locked: bool = True entries: list[ModuleRegistryEntry] @property @@ -278,7 +278,7 @@ def validate_windows_local_manifest(manifest: ModuleManifest | dict[str, Any]) - def build_module_registry( manifests: list[ModuleManifest | dict[str, Any]], *, - civiccore_version: str, + townlight_core_version: str, selected_module_ids: set[str] | None = None, profile: InstallProfile = "windows_local", ) -> ModuleRegistryState: @@ -301,10 +301,10 @@ def build_module_registry( if unknown: raise ValueError(f"selected modules are not installed: {sorted(unknown)}") - core_version = Version(civiccore_version) + core_version = Version(townlight_core_version) for manifest in parsed: Version(manifest.version) - Version(manifest.civiccore_min_version) + Version(manifest.townlight_core_min_version) for dependency in manifest.dependencies: if dependency.min_version: Version(dependency.min_version) @@ -323,8 +323,8 @@ def resolve(module_id: str) -> ModuleRegistryEntry: status: ModuleRegistryStatus = "enabled" if enabled else "disabled" if profile not in manifest.install_profiles: reason = f"{manifest.name} is not available for the {profile} profile." - elif enabled and core_version < Version(manifest.civiccore_min_version): - reason = f"Requires Core {manifest.civiccore_min_version} or newer." + elif enabled and core_version < Version(manifest.townlight_core_min_version): + reason = f"Requires Core {manifest.townlight_core_min_version} or newer." elif enabled: visiting.add(module_id) try: @@ -365,8 +365,8 @@ def resolve(module_id: str) -> ModuleRegistryEntry: return ModuleRegistryState( profile=profile, - civiccore_version=civiccore_version, - civiccore_locked=True, + townlight_core_version=townlight_core_version, + townlight_core_locked=True, entries=sorted(entries, key=lambda entry: entry.module_id), ) diff --git a/civiccore/platform/runtime.py b/townlight_core/platform/runtime.py similarity index 96% rename from civiccore/platform/runtime.py rename to townlight_core/platform/runtime.py index 24d7dfd..705ac42 100644 --- a/civiccore/platform/runtime.py +++ b/townlight_core/platform/runtime.py @@ -8,7 +8,7 @@ from pydantic import BaseModel, ConfigDict, Field, field_validator -from civiccore.platform.modules import ModuleRegistryState +from townlight_core.platform.modules import ModuleRegistryState RuntimeAction = Literal[ "install", diff --git a/civiccore/platform/task_queue.py b/townlight_core/platform/task_queue.py similarity index 98% rename from civiccore/platform/task_queue.py rename to townlight_core/platform/task_queue.py index 21b3141..2b659df 100644 --- a/civiccore/platform/task_queue.py +++ b/townlight_core/platform/task_queue.py @@ -14,8 +14,8 @@ from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.orm import Mapped, mapped_column -from civiccore.db import Base -from civiccore.platform.tasks import ( +from townlight_core.db import Base +from townlight_core.platform.tasks import ( LocalTaskEnvelope, TaskRetryPolicy, record_task_attempt, @@ -27,7 +27,7 @@ class LocalTask(Base): """Durable local task row used by the Windows local runtime.""" - __tablename__ = "civiccore_local_tasks" + __tablename__ = "townlight_core_local_tasks" task_id: Mapped[str] = mapped_column(String(128), primary_key=True) module_id: Mapped[str] = mapped_column(String(64), index=True) diff --git a/civiccore/platform/tasks.py b/townlight_core/platform/tasks.py similarity index 98% rename from civiccore/platform/tasks.py rename to townlight_core/platform/tasks.py index d9d794f..b5d84b5 100644 --- a/civiccore/platform/tasks.py +++ b/townlight_core/platform/tasks.py @@ -27,7 +27,7 @@ class LocalTaskEnvelope(BaseModel): model_config = ConfigDict(extra="forbid") task_id: str = Field(min_length=1) - module_id: str = Field(pattern=r"^[a-z][a-z0-9-]{1,63}$") + module_id: str = Field(pattern=r"^[a-z][a-z0-9_-]{1,63}$") task_type: str = Field(min_length=1) status: TaskStatus = "queued" payload: dict[str, Any] = Field(default_factory=dict) diff --git a/civiccore/provenance/__init__.py b/townlight_core/provenance/__init__.py similarity index 100% rename from civiccore/provenance/__init__.py rename to townlight_core/provenance/__init__.py diff --git a/civiccore/provenance/contracts.py b/townlight_core/provenance/contracts.py similarity index 100% rename from civiccore/provenance/contracts.py rename to townlight_core/provenance/contracts.py diff --git a/civiccore/release_provenance.py b/townlight_core/release_provenance.py similarity index 99% rename from civiccore/release_provenance.py rename to townlight_core/release_provenance.py index 73e1736..db13139 100644 --- a/civiccore/release_provenance.py +++ b/townlight_core/release_provenance.py @@ -56,7 +56,7 @@ def _gh_api(self, path: str) -> dict[str, Any]: url = f"https://api.github.com/{path}" headers = { "Accept": "application/vnd.github+json", - "User-Agent": "civiccore-release-provenance", + "User-Agent": "townlight_core-release-provenance", "X-GitHub-Api-Version": "2022-11-28", } token = os.environ.get("GH_TOKEN") or os.environ.get("GITHUB_TOKEN") @@ -538,7 +538,7 @@ def main(argv: list[str] | None = None) -> int: parser.add_argument("tag_name", nargs="?", help="Release tag to verify, for example v0.22.0.") parser.add_argument( "--repo", - default="CivicSuite/civiccore", + default="Townlight/townlight_core", help="GitHub repository in OWNER/REPO form.", ) parser.add_argument( diff --git a/civiccore/scaffold/__init__.py b/townlight_core/scaffold/__init__.py similarity index 90% rename from civiccore/scaffold/__init__.py rename to townlight_core/scaffold/__init__.py index b805e91..da2e51f 100644 --- a/civiccore/scaffold/__init__.py +++ b/townlight_core/scaffold/__init__.py @@ -14,8 +14,8 @@ from __future__ import annotations -from civiccore.scaffold.cli import main as main -from civiccore.scaffold.project import ( +from townlight_core.scaffold.cli import main as main +from townlight_core.scaffold.project import ( GENERATOR_VERSION, GenerationResult, PlannedFile, @@ -23,7 +23,7 @@ generate_module_project, plan_module_project, ) -from civiccore.scaffold.spec import ( +from townlight_core.scaffold.spec import ( InvalidModuleSpecError, ModuleSpec, PathContainmentError, diff --git a/civiccore/scaffold/__main__.py b/townlight_core/scaffold/__main__.py similarity index 59% rename from civiccore/scaffold/__main__.py rename to townlight_core/scaffold/__main__.py index f019eaa..65a512a 100644 --- a/civiccore/scaffold/__main__.py +++ b/townlight_core/scaffold/__main__.py @@ -1,9 +1,9 @@ # SPDX-License-Identifier: AGPL-3.0-only -"""``python -m civiccore.scaffold`` → ``civiccore.scaffold.cli.main``.""" +"""``python -m townlight_core.scaffold`` → ``townlight_core.scaffold.cli.main``.""" from __future__ import annotations -from civiccore.scaffold.cli import main +from townlight_core.scaffold.cli import main if __name__ == "__main__": # pragma: no cover - exercised through subprocess smoke raise SystemExit(main()) diff --git a/civiccore/scaffold/cli.py b/townlight_core/scaffold/cli.py similarity index 91% rename from civiccore/scaffold/cli.py rename to townlight_core/scaffold/cli.py index 63254a1..122e5dd 100644 --- a/civiccore/scaffold/cli.py +++ b/townlight_core/scaffold/cli.py @@ -1,7 +1,7 @@ # SPDX-License-Identifier: AGPL-3.0-only """Command-line entry point for generating one Townlight module project. -``python -m civiccore.scaffold generate ...`` writes a complete module skeleton +``python -m townlight_core.scaffold generate ...`` writes a complete module skeleton (manifest, package, staff app, own migrations, contract tests, docs). It never overwrites, never installs, never runs a network call, and never emits a credential: the generated app fails closed until the operator sets its token map. @@ -17,12 +17,12 @@ from pydantic import ValidationError -from civiccore.scaffold.project import ( +from townlight_core.scaffold.project import ( ProjectPlan, generate_module_project, plan_module_project, ) -from civiccore.scaffold.spec import ( +from townlight_core.scaffold.spec import ( ModuleSpec, ScaffoldError, ScaffoldOptions, @@ -34,7 +34,7 @@ def build_parser() -> argparse.ArgumentParser: parser = argparse.ArgumentParser( - prog="python -m civiccore.scaffold", + prog="python -m townlight_core.scaffold", description="Generate one Townlight module project (no install, no network).", ) subcommands = parser.add_subparsers(dest="command", required=True) @@ -45,9 +45,9 @@ def build_parser() -> argparse.ArgumentParser: generate.add_argument("--description", required=True, help="One-line module description.") generate.add_argument("--version", default="0.1.0", help="Module version (PEP 440).") generate.add_argument( - "--civiccore-min-version", + "--townlight_core-min-version", default="1.3.0.dev1", - help="Minimum CivicCore version the module declares.", + help="Minimum TownlightCore version the module declares.", ) generate.add_argument("--permission-key", default=None, help="Permission key (slug).") generate.add_argument( @@ -71,7 +71,7 @@ def build_parser() -> argparse.ArgumentParser: plan.add_argument("--name", required=True) plan.add_argument("--description", required=True) plan.add_argument("--version", default="0.1.0") - plan.add_argument("--civiccore-min-version", default="1.3.0.dev1") + plan.add_argument("--townlight_core-min-version", default="1.3.0.dev1") plan.add_argument("--permission-key", default=None) plan.add_argument("--staff-role", action="append", default=None) plan.add_argument("--route-path", default=None) @@ -84,7 +84,7 @@ def _spec_from_args(args: argparse.Namespace) -> ModuleSpec: "name": args.name, "description": args.description, "version": args.version, - "civiccore_min_version": args.civiccore_min_version, + "townlight_core_min_version": args.townlight_core_min_version, } if args.permission_key: payload["permission_key"] = args.permission_key diff --git a/civiccore/scaffold/project.py b/townlight_core/scaffold/project.py similarity index 94% rename from civiccore/scaffold/project.py rename to townlight_core/scaffold/project.py index 87fbf22..da18a32 100644 --- a/civiccore/scaffold/project.py +++ b/townlight_core/scaffold/project.py @@ -16,7 +16,7 @@ from dataclasses import dataclass, field from pathlib import Path, PurePosixPath, PureWindowsPath -from civiccore.scaffold.spec import ( +from townlight_core.scaffold.spec import ( InvalidModuleSpecError, ModuleSpec, PathContainmentError, @@ -64,7 +64,7 @@ class GenerationResult: def _manifest_payload(spec: ModuleSpec) -> dict[str, object]: """The exact manifest the generated project ships as data. - Shaped to validate through the shipped ``civiccore.platform.ModuleManifest`` + Shaped to validate through the shipped ``townlight_core.platform.ModuleManifest`` and its Windows-local profile check; the generator asserts that before it returns a plan, so a template drift cannot silently produce an invalid module. @@ -75,11 +75,11 @@ def _manifest_payload(spec: ModuleSpec) -> dict[str, object]: "name": spec.name, "version": spec.version, "package_name": spec.package_name, - "civiccore_min_version": spec.civiccore_min_version, + "townlight_core_min_version": spec.townlight_core_min_version, "enabled_by_default": False, "surfaces": ["staff"], "install_profiles": ["windows_local", "developer"], - "dependencies": [{"module_id": "civiccore", "required": False}], + "dependencies": [{"module_id": "townlight_core", "required": False}], "routes": [ { "id": "home", @@ -113,7 +113,7 @@ def _manifest_payload(spec: ModuleSpec) -> dict[str, object]: "runtime_requirements": [], "settings_schema_version": None, "metadata": { - "generated_by": f"civiccore.scaffold {GENERATOR_VERSION}", + "generated_by": f"townlight_core.scaffold {GENERATOR_VERSION}", "license": "AGPL-3.0-only", }, } @@ -131,7 +131,7 @@ def _manifest_payload(spec: ModuleSpec) -> dict[str, object]: requires-python = ">=3.11" license = "AGPL-3.0-only" dependencies = [ - "civiccore>={civiccore_min_version}", + "townlight_core>={townlight_core_min_version}", ] [project.optional-dependencies] @@ -146,14 +146,14 @@ def _manifest_payload(spec: ModuleSpec) -> dict[str, object]: """ _INIT = '''{spdx} -"""{name} — a Townlight module generated by ``civiccore.scaffold``. +"""{name} — a Townlight module generated by ``townlight_core.scaffold``. The module owns its business permissions, tables and workflow. Core owns the shared platform contracts this module imports; the module does not reach into Core's internals, and Core does not know this module exists until its manifest is registered. -Generated from CivicCore {generator_version}. SPDX: AGPL-3.0-only. +Generated from TownlightCore {generator_version}. SPDX: AGPL-3.0-only. """ from __future__ import annotations @@ -172,7 +172,7 @@ def _manifest_payload(spec: ModuleSpec) -> dict[str, object]: import json from importlib import resources -from civiccore.platform.modules import ModuleManifest, validate_windows_local_manifest +from townlight_core.platform.modules import ModuleManifest, validate_windows_local_manifest MANIFEST_RESOURCE = "manifest.json" @@ -199,7 +199,7 @@ def load_manifest() -> ModuleManifest: from fastapi import Depends, FastAPI from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer -from civiccore.auth import AuthenticatedPrincipal, authorize_bearer_roles +from townlight_core.auth import AuthenticatedPrincipal, authorize_bearer_roles from {package_name}.manifest import load_manifest @@ -255,7 +255,7 @@ def home( """Alembic environment for the {name} module schema. The generated project deliberately does not own Core's migration chain: Core is -applied by ``civiccore.migrations.runner.upgrade_to_head`` as a separate, +applied by ``townlight_core.migrations.runner.upgrade_to_head`` as a separate, version-pinned step. This chain only creates the module's own schema, so a module migration cannot alter or drop Core tables. """ @@ -410,7 +410,7 @@ def test_staff_route_admits_configured_role(monkeypatch: pytest.MonkeyPatch) -> _DOCS = """ # {name} -Generated by `civiccore.scaffold` {generator_version} from CivicCore source. This is a +Generated by `townlight_core.scaffold` {generator_version} from TownlightCore source. This is a minimal working module, not a finished product. | Item | Value | @@ -443,21 +443,21 @@ def test_staff_route_admits_configured_role(monkeypatch: pytest.MonkeyPatch) -> ## Database -Run Core's migrations first (`civiccore.migrations.runner.upgrade_to_head`), then +Run Core's migrations first (`townlight_core.migrations.runner.upgrade_to_head`), then this module's own chain from `migrations/` with `DATABASE_URL` set. The module owns schema `{package_name}` only; Core tables are never touched. ## License -Source: AGPL-3.0-only. Documentation in this project: AGPL-3.0-only. CivicCore's -historical CC BY 4.0 documentation and third-party notices remain with CivicCore; +Source: AGPL-3.0-only. Documentation in this project: AGPL-3.0-only. TownlightCore's +historical CC BY 4.0 documentation and third-party notices remain with TownlightCore; nothing here relicenses them. """ _README = """ # {name} -A Townlight module skeleton generated by `civiccore.scaffold` {generator_version}. +A Townlight module skeleton generated by `townlight_core.scaffold` {generator_version}. See [docs/module.md](docs/module.md) for the contract, auth and migration rules. * License: AGPL-3.0-only. @@ -489,7 +489,7 @@ def plan_module_project(spec: ModuleSpec) -> ProjectPlan: "name": spec.name, "description": spec.description, "version": spec.version, - "civiccore_min_version": spec.civiccore_min_version, + "townlight_core_min_version": spec.townlight_core_min_version, "permission": spec.permission, "route": spec.route, "token_roles_env_var": spec.token_roles_env_var, @@ -547,7 +547,7 @@ def plan_module_project(spec: ModuleSpec) -> ProjectPlan: def _assert_manifest_valid(spec: ModuleSpec) -> None: - from civiccore.platform.modules import ModuleManifest, validate_windows_local_manifest + from townlight_core.platform.modules import ModuleManifest, validate_windows_local_manifest manifest = validate_windows_local_manifest(ModuleManifest.model_validate(_manifest_payload(spec))) if manifest.module_id != spec.module_id: # pragma: no cover - defensive diff --git a/civiccore/scaffold/spec.py b/townlight_core/scaffold/spec.py similarity index 95% rename from civiccore/scaffold/spec.py rename to townlight_core/scaffold/spec.py index 10d7128..b94d51d 100644 --- a/civiccore/scaffold/spec.py +++ b/townlight_core/scaffold/spec.py @@ -18,7 +18,7 @@ from packaging.version import InvalidVersion, Version from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator -from civiccore.platform.modules import MODULE_ID_PATTERN, SLUG_PATTERN +from townlight_core.platform.modules import MODULE_ID_PATTERN, SLUG_PATTERN ROUTE_PATH_PATTERN = r"^/[a-z0-9/_:-]*$" @@ -26,8 +26,8 @@ #: names, or with the reserved module ids Core already ships around. RESERVED_MODULE_IDS = frozenset( { - "civiccore", - "civicsuite", + "townlight_core", + "townlight", "tests", "test", "docs", @@ -76,7 +76,7 @@ class ModuleSpec(BaseModel): name: str = Field(min_length=1, max_length=120) description: str = Field(min_length=12, max_length=500) version: str = "0.1.0" - civiccore_min_version: str = "1.3.0.dev1" + townlight_core_min_version: str = "1.3.0.dev1" permission_key: str | None = Field(default=None, pattern=SLUG_PATTERN) staff_roles: tuple[str, ...] = ("staff",) route_path: str | None = Field(default=None, pattern=ROUTE_PATH_PATTERN) @@ -103,7 +103,7 @@ def validate_derived_identity(self) -> ModuleSpec: assert_admissible_module_id(self.module_id) for label, raw in ( ("version", self.version), - ("civiccore_min_version", self.civiccore_min_version), + ("townlight_core_min_version", self.townlight_core_min_version), ): try: Version(raw) @@ -150,7 +150,7 @@ def assert_admissible_module_id(module_id: str) -> str: ) package_name = module_id.replace("-", "_") if module_id in RESERVED_MODULE_IDS or package_name in RESERVED_MODULE_IDS: - raise InvalidModuleSpecError(f"module_id {module_id!r} is reserved by CivicCore") + raise InvalidModuleSpecError(f"module_id {module_id!r} is reserved by TownlightCore") if keyword.iskeyword(package_name): raise InvalidModuleSpecError(f"module_id {module_id!r} derives a Python keyword") if package_name in sys.stdlib_module_names: diff --git a/civiccore/scheduling/__init__.py b/townlight_core/scheduling/__init__.py similarity index 86% rename from civiccore/scheduling/__init__.py rename to townlight_core/scheduling/__init__.py index c921294..05d9dd7 100644 --- a/civiccore/scheduling/__init__.py +++ b/townlight_core/scheduling/__init__.py @@ -1,6 +1,6 @@ """Shared schedule validation helpers for Townlight background jobs.""" -from civiccore.scheduling.cron import ( +from townlight_core.scheduling.cron import ( UTC, compute_next_sync_at, min_interval_minutes, diff --git a/civiccore/scheduling/cron.py b/townlight_core/scheduling/cron.py similarity index 100% rename from civiccore/scheduling/cron.py rename to townlight_core/scheduling/cron.py diff --git a/civiccore/search/__init__.py b/townlight_core/search/__init__.py similarity index 100% rename from civiccore/search/__init__.py rename to townlight_core/search/__init__.py diff --git a/civiccore/security/__init__.py b/townlight_core/security/__init__.py similarity index 90% rename from civiccore/security/__init__.py rename to townlight_core/security/__init__.py index 6e5d83e..2d77777 100644 --- a/civiccore/security/__init__.py +++ b/townlight_core/security/__init__.py @@ -1,6 +1,6 @@ """Shared security primitives extracted for Townlight modules.""" -from civiccore.security.at_rest import ( +from townlight_core.security.at_rest import ( AtRestDecryptionError, ENVELOPE_VERSION, build_fernet, @@ -8,7 +8,7 @@ encrypt_json, is_encrypted, ) -from civiccore.security.host_validation import ( +from townlight_core.security.host_validation import ( BLOCK_REASON, BLOCKED_HOSTNAMES, BLOCKED_NETWORKS, @@ -21,7 +21,7 @@ validate_odbc_connection_string, validate_url_host, ) -from civiccore.security.config_validation import ( +from townlight_core.security.config_validation import ( ConfigValidationError, DEFAULT_INSECURE_FERNET_KEY_VALUES, DEFAULT_INSECURE_PASSWORD_VALUES, diff --git a/civiccore/security/at_rest.py b/townlight_core/security/at_rest.py similarity index 100% rename from civiccore/security/at_rest.py rename to townlight_core/security/at_rest.py diff --git a/civiccore/security/config_validation.py b/townlight_core/security/config_validation.py similarity index 100% rename from civiccore/security/config_validation.py rename to townlight_core/security/config_validation.py diff --git a/civiccore/security/host_validation.py b/townlight_core/security/host_validation.py similarity index 100% rename from civiccore/security/host_validation.py rename to townlight_core/security/host_validation.py diff --git a/civiccore/tasks/__init__.py b/townlight_core/tasks/__init__.py similarity index 84% rename from civiccore/tasks/__init__.py rename to townlight_core/tasks/__init__.py index 65e268a..bf5c11c 100644 --- a/civiccore/tasks/__init__.py +++ b/townlight_core/tasks/__init__.py @@ -2,7 +2,7 @@ from __future__ import annotations -from civiccore.tasks.artifacts import ( +from townlight_core.tasks.artifacts import ( ArtifactProposal, ArtifactRefused, ArtifactStore, @@ -16,7 +16,7 @@ resolve_inside_root, verify_artifact_file, ) -from civiccore.tasks.registry import get_task_handlers, register_task_handler +from townlight_core.tasks.registry import get_task_handlers, register_task_handler __all__ = [ "ArtifactProposal", diff --git a/civiccore/tasks/artifacts.py b/townlight_core/tasks/artifacts.py similarity index 97% rename from civiccore/tasks/artifacts.py rename to townlight_core/tasks/artifacts.py index 76ecf6d..7683748 100644 --- a/civiccore/tasks/artifacts.py +++ b/townlight_core/tasks/artifacts.py @@ -8,7 +8,7 @@ are copied from the *claimed envelope* the worker received, never from a request body, filename, environment variable or model output. * The claim must still be current when the acceptance record is written: the write path - calls :func:`civiccore.platform.task_queue.require_active_claim`, which locks the task + calls :func:`townlight_core.platform.task_queue.require_active_claim`, which locks the task row and refuses a cancelled, expired or superseded claim (``StaleTaskClaim``). A stale worker therefore cannot publish an artifact, and it cannot overwrite the new owner's state. @@ -24,8 +24,8 @@ refused. This module is an adapter, not a second job engine: it reuses the shipped -``civiccore_local_tasks`` claim/lease contract and adds exactly one append-only acceptance -table (``civiccore_job_artifacts``). It performs no transcription, OCR, transcoding, +``townlight_core_local_tasks`` claim/lease contract and adds exactly one append-only acceptance +table (``townlight_core_job_artifacts``). It performs no transcription, OCR, transcoding, embedding or provider call, and it claims none. A handler owns its own native subprocess containment; this adapter only refuses to make an unowned or unverified file durable. @@ -50,8 +50,8 @@ from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.orm import Mapped, mapped_column -from civiccore.db import Base -from civiccore.platform.task_queue import LocalTaskEnvelope, require_active_claim +from townlight_core.db import Base +from townlight_core.platform.task_queue import LocalTaskEnvelope, require_active_claim #: Hard cap on one accepted artifact. Derivatives and documents only; a handler that needs #: to keep a larger original must record its own storage receipt instead of using this path. @@ -96,7 +96,7 @@ def __init__(self, reason: str, detail: str = "") -> None: class JobArtifact(Base): """Append-only acceptance record for one artifact produced by one claimed job.""" - __tablename__ = "civiccore_job_artifacts" + __tablename__ = "townlight_core_job_artifacts" artifact_id: Mapped[str] = mapped_column(String(64), primary_key=True) task_id: Mapped[str] = mapped_column(String(128), index=True) diff --git a/civiccore/tasks/leased.py b/townlight_core/tasks/leased.py similarity index 96% rename from civiccore/tasks/leased.py rename to townlight_core/tasks/leased.py index b1e5c93..45244af 100644 --- a/civiccore/tasks/leased.py +++ b/townlight_core/tasks/leased.py @@ -9,14 +9,14 @@ import asyncio import contextlib import inspect -from civiccore.platform.task_queue import ( +from townlight_core.platform.task_queue import ( claim_next_local_task, complete_local_task, fail_local_task, renew_local_task, StaleTaskClaim, ) -from civiccore.platform.tasks import TaskRetryPolicy +from townlight_core.platform.tasks import TaskRetryPolicy async def run_leased_task( diff --git a/civiccore/tasks/registry.py b/townlight_core/tasks/registry.py similarity index 92% rename from civiccore/tasks/registry.py rename to townlight_core/tasks/registry.py index 6b21b7f..d7ff91b 100644 --- a/civiccore/tasks/registry.py +++ b/townlight_core/tasks/registry.py @@ -4,7 +4,7 @@ from collections.abc import Callable -from civiccore.platform.task_queue import TaskHandler +from townlight_core.platform.task_queue import TaskHandler _HANDLERS: dict[str, TaskHandler] = {} diff --git a/civiccore/tasks/worker.py b/townlight_core/tasks/worker.py similarity index 88% rename from civiccore/tasks/worker.py rename to townlight_core/tasks/worker.py index 864a64b..05739a9 100644 --- a/civiccore/tasks/worker.py +++ b/townlight_core/tasks/worker.py @@ -10,9 +10,9 @@ from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine -from civiccore.tasks.leased import run_leased_task -from civiccore.platform.tasks import TaskRetryPolicy -from civiccore.tasks.registry import get_task_handlers +from townlight_core.tasks.leased import run_leased_task +from townlight_core.platform.tasks import TaskRetryPolicy +from townlight_core.tasks.registry import get_task_handlers def _async_database_url(url: str) -> str: @@ -33,8 +33,8 @@ def _load_handler_modules(raw_modules: str | None) -> None: async def _run_worker(args: argparse.Namespace) -> int: database_url = os.environ.get("DATABASE_URL") if not database_url: - raise RuntimeError("DATABASE_URL is required for civiccore.tasks.worker") - _load_handler_modules(os.environ.get("CIVICCORE_TASK_HANDLER_MODULES")) + raise RuntimeError("DATABASE_URL is required for townlight_core.tasks.worker") + _load_handler_modules(os.environ.get("TOWNLIGHT_CORE_TASK_HANDLER_MODULES")) handlers = get_task_handlers() engine = create_async_engine(_async_database_url(database_url)) diff --git a/civiccore/testing/__init__.py b/townlight_core/testing/__init__.py similarity index 97% rename from civiccore/testing/__init__.py rename to townlight_core/testing/__init__.py index 904db40..8c6c0c4 100644 --- a/civiccore/testing/__init__.py +++ b/townlight_core/testing/__init__.py @@ -1,6 +1,6 @@ """Reusable test contracts for Townlight modules.""" -from civiccore.testing.mock_city import ( +from townlight_core.testing.mock_city import ( DEMO_TOWN_CONTRACT_SCHEMA_VERSION, DEMO_TOWN_DEFAULT_SEED, DEMO_TOWN_FIXTURE_ID, diff --git a/civiccore/testing/mock_city.py b/townlight_core/testing/mock_city.py similarity index 98% rename from civiccore/testing/mock_city.py rename to townlight_core/testing/mock_city.py index 7ecfc71..f2d1b47 100644 --- a/civiccore/testing/mock_city.py +++ b/townlight_core/testing/mock_city.py @@ -13,8 +13,8 @@ import jwt from cryptography.hazmat.primitives.asymmetric import rsa -from civiccore.connectors.delta import plan_vendor_delta_request -from civiccore.connectors.imports import SUPPORTED_CONNECTORS, import_meeting_payload +from townlight_core.connectors.delta import plan_vendor_delta_request +from townlight_core.connectors.imports import SUPPORTED_CONNECTORS, import_meeting_payload MOCK_CITY_NAME = "City of Brookfield" MOCK_CITY_CHANGED_SINCE = datetime(2026, 5, 1, 12, 0, tzinfo=UTC) @@ -26,7 +26,7 @@ } DEMO_TOWN_CONTRACT_SCHEMA_VERSION = "1.0.0" -DEMO_TOWN_FIXTURE_VERSION = "1.0.0" +DEMO_TOWN_FIXTURE_VERSION = "1.0.1" DEMO_TOWN_FIXTURE_ID = "redstone-valley-records-demo" DEMO_TOWN_NAME = "Town of Redstone Valley (Fictional)" # The v1 generator is intentionally static, not pseudo-random. This value is a @@ -37,7 +37,7 @@ DEMO_TOWN_WATERMARK = "SYNTHETIC DEMONSTRATION DATA - NOT A REAL MUNICIPAL RECORD" DEMO_TOWN_PROVENANCE_MODES = ("fully-synthetic",) DEMO_TOWN_GENERATION_MODE = "static-canonical-v1" -DEMO_TOWN_FIXTURE_SHA256_V1 = "a9c242a3f2618a69d7effb1d0d17d2df06f6744c8c351bba4065d315c94575b4" +DEMO_TOWN_FIXTURE_SHA256_V1 = "d9aaa79403cfca2711e8031439fbab8bf9f70a20b8afc293faef8edd683ffbd6" DEMO_TOWN_WORKFLOW_STATUSES = ( "received", "assigned", @@ -282,7 +282,7 @@ def public_dict(self) -> dict[str, Any]: "deterministic_seed": self.deterministic_seed, "generation_mode": DEMO_TOWN_GENERATION_MODE, "generated_at": self.generated_at, - "generator": "civiccore.testing.mock_city", + "generator": "townlight_core.testing.mock_city", "municipality": dict(self.municipality), "synthetic": True, "watermark": DEMO_TOWN_WATERMARK, @@ -533,7 +533,7 @@ def validate_demo_town_fixture(fixture: dict[str, Any]) -> tuple[str, ...]: "deterministic_seed": DEMO_TOWN_DEFAULT_SEED, "generation_mode": DEMO_TOWN_GENERATION_MODE, "generated_at": DEMO_TOWN_GENERATED_AT, - "generator": "civiccore.testing.mock_city", + "generator": "townlight_core.testing.mock_city", "synthetic": True, "watermark": DEMO_TOWN_WATERMARK, "network_calls": False, @@ -910,7 +910,7 @@ def mock_city_vendor_contracts() -> list[MockCityVendorContract]: }, notes=( "Public marketing confirms Granicus meeting-management products, but customer API details are account-gated. " - "This fixture tests CivicSuite's normalized contract until city credentials provide a concrete endpoint." + "This fixture tests Townlight's normalized contract until city credentials provide a concrete endpoint." ), ), MockCityVendorContract( @@ -959,19 +959,19 @@ def mock_city_idp_contract() -> MockCityIdpContract: provider="Brookfield Entra ID", interface_status="mock-municipal-idp", issuer="https://login.mock-city.example.gov/brookfield/v2.0", - audience="api://civicsuite-staff", + audience="api://townlight-staff", authorization_url="https://login.mock-city.example.gov/brookfield/oauth2/v2.0/authorize", token_url="https://login.mock-city.example.gov/brookfield/oauth2/v2.0/token", jwks_path="/brookfield/discovery/v2.0/keys", role_claims=("roles", "groups"), algorithms=("RS256",), - client_id="civicsuite-staff-dashboard", + client_id="townlight-staff-dashboard", redirect_uri="https://module.mock-city.example.gov/staff/oidc/callback", staff_subject="brookfield-clerk-001", staff_email="clerk@brookfield.example.gov", staff_roles=("clerk_admin", "meeting_editor"), notes=( - "Models the authorization-code + PKCE and JWKS/token contract CivicSuite modules " + "Models the authorization-code + PKCE and JWKS/token contract Townlight modules " "must satisfy before replacing mock evidence with a real municipal tenant." ), ) @@ -1002,13 +1002,13 @@ def mock_city_backup_retention_contract() -> MockCityBackupRetentionContract: ), retention_years=7, restore_test_interval_days=30, - off_host_storage="mock://brookfield-secure-vault/civicsuite", + off_host_storage="mock://brookfield-secure-vault/townlight", encryption_at_rest_required=True, immutable_retention_required=True, legal_hold_supported=True, approval_artifact="mock-brookfield-backup-retention-policy-2026-05", notes=( - "Models the policy evidence CivicSuite modules must provide before replacing " + "Models the policy evidence Townlight modules must provide before replacing " "mock proof with a city-approved retention schedule and off-host storage runbook." ), ) diff --git a/civiccore/verification/__init__.py b/townlight_core/verification/__init__.py similarity index 86% rename from civiccore/verification/__init__.py rename to townlight_core/verification/__init__.py index 468f431..32ebb81 100644 --- a/civiccore/verification/__init__.py +++ b/townlight_core/verification/__init__.py @@ -1,6 +1,6 @@ """Verification helpers for Townlight release and runtime evidence.""" -from civiccore.verification.browser_evidence import ( +from townlight_core.verification.browser_evidence import ( DEFAULT_MIN_SCREENSHOT_BYTES, BrowserReleaseEvidenceResult, normalized_text_sha256, diff --git a/civiccore/verification/browser_evidence.py b/townlight_core/verification/browser_evidence.py similarity index 100% rename from civiccore/verification/browser_evidence.py rename to townlight_core/verification/browser_evidence.py From cb374b2a582ebd8811c6191c856982e3399c48ff Mon Sep 17 00:00:00 2001 From: Scott Converse Date: Mon, 2 Nov 2026 18:09:55 -0700 Subject: [PATCH 2/7] Preserve original Core release and ingestion evidence Restore nine dated reports and ledger records from the unchanged source baseline; repair historical links and current rehearsal default. The historical-ledger and workflow checks pass (10), and lint passes. Reuse the unchanged Core product tests, wheel build and clean-install evidence from the preceding candidate commit. Codex correction; no history rewrite or publication. --- .github/workflows/release.yml | 6 +- docs/ops/README.md | 18 ++ ...n => civiccore-tier1-retrofit-ledger.json} | 156 +++++++++--------- ....md => civiccore-tier1-retrofit-ledger.md} | 8 +- docs/ops/co-4-cross-module-retrofit-report.md | 6 +- docs/ops/co-7-freeze-readiness.md | 20 +-- docs/ops/co-9-audit-full-release-gate.md | 66 ++++---- ...seout.md => co-9-civiccore-v1-closeout.md} | 32 ++-- docs/ops/historical-provenance.md | 32 ++-- docs/ops/release-signing.md | 2 +- ...ccore-longmont-ingest-proof-2026-05-21.md} | 8 +- docs/release-recovery-status.md | 20 +-- scripts/check-tier1-ledger.py | 9 +- tests/test_github_workflows.py | 6 +- tests/test_tier1_retrofit_ledger.py | 2 +- 15 files changed, 205 insertions(+), 186 deletions(-) create mode 100644 docs/ops/README.md rename docs/ops/{townlight_core-tier1-retrofit-ledger.json => civiccore-tier1-retrofit-ledger.json} (79%) rename docs/ops/{townlight_core-tier1-retrofit-ledger.md => civiccore-tier1-retrofit-ledger.md} (95%) rename docs/ops/{co-9-townlight_core-v1-closeout.md => co-9-civiccore-v1-closeout.md} (59%) rename docs/qa/{townlight_core-longmont-ingest-proof-2026-05-21.md => civiccore-longmont-ingest-proof-2026-05-21.md} (74%) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 218bab9..d55bd30 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,7 +10,7 @@ on: release_tag: description: "Published release tag to rehearse from cold caches" required: true - default: "v1.2.1" + default: "v1.3.0.dev2" permissions: contents: write @@ -234,9 +234,9 @@ jobs: Release provenance: - The Git tag is a release pointer; the trust artifact is release-attestation.json plus release-attestation.json.bundle. - Pre-flight provenance fixtures and live attestation verification ran before publication in workflow run ${WORKFLOW_RUN_ID}. - - Procurement evidence pack: https://github.com/${REPO}/blob/${GITHUB_SHA}/docs/evidence/co8-townlight_core-procurement-evidence-pack/index.md + - Historical procurement evidence pack: https://github.com/${REPO}/blob/${GITHUB_SHA}/docs/evidence/co8-civiccore-procurement-evidence-pack/index.md - Historical provenance policy: https://github.com/${REPO}/blob/${GITHUB_SHA}/docs/ops/historical-provenance.md - - CO-9 closeout report, when present for the release tag: https://github.com/${REPO}/blob/${GITHUB_SHA}/docs/ops/co-9-townlight_core-v1-closeout.md + - Historical CO-9 closeout report: https://github.com/${REPO}/blob/${GITHUB_SHA}/docs/ops/co-9-civiccore-v1-closeout.md - Verify with: ```bash diff --git a/docs/ops/README.md b/docs/ops/README.md new file mode 100644 index 0000000..56f6dc4 --- /dev/null +++ b/docs/ops/README.md @@ -0,0 +1,18 @@ +# Core operations documentation and historical evidence + +The current candidate is `townlight-core` 1.3.0.dev2 with principal import +`townlight_core`. Its README, user manual and governing `AGENTS.md` describe +current source and fresh-install boundaries. Signed Windows installed acceptance +for the coordinated naming, Access and Notice candidate remains pending. + +The CO-3 ledger, CO-4 report, CO-7 freeze readiness and CO-9 release/audit reports +are historical records for their identified releases. Their original filenames, +organization/package identities, commands, URLs and receipt hashes are preserved. +The historical provenance policy and release recovery status likewise describe +their dated release lines. They do not certify this renamed candidate or provide +current installation commands. The dated municipal ingestion proof under +`../qa/` remains an original proof for its own inputs. + +Historical records are exempt from the current naming exception registry; that +exemption does not authorize old current package/import names or product titles. +Do not relabel a historical artifact to satisfy a current dependency or gate. diff --git a/docs/ops/townlight_core-tier1-retrofit-ledger.json b/docs/ops/civiccore-tier1-retrofit-ledger.json similarity index 79% rename from docs/ops/townlight_core-tier1-retrofit-ledger.json rename to docs/ops/civiccore-tier1-retrofit-ledger.json index 53174b7..3376f8a 100644 --- a/docs/ops/townlight_core-tier1-retrofit-ledger.json +++ b/docs/ops/civiccore-tier1-retrofit-ledger.json @@ -1,6 +1,6 @@ { "schema_version": 1, - "repo": "Townlight/townlight_core", + "repo": "CivicSuite/civiccore", "sprint_id": "CO-3", "baseline_tag": "v0.22.1", "checked_at": "2026-05-05T00:00:00-06:00", @@ -8,7 +8,7 @@ "command": "gh release list --limit 200", "release_count": 25, "latest_release": "v0.22.1", - "latest_release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.22.1" + "latest_release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.22.1" }, "policy": { "baseline_rule": "Use v0.22.1 or a later Sigstore-attested release as the provenance baseline.", @@ -19,32 +19,32 @@ { "tag": "v0.22.1", "published_at": "2026-05-05T16:23:36Z", - "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.22.1", + "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.22.1", "tag_ref_type": "lightweight_tag", "tag_ref_sha": "46c99854adbce6dc8a056ae5215278bb1eba9a19", "target_commit": "46c99854adbce6dc8a056ae5215278bb1eba9a19", "release_assets": [ - "townlight_core-0.22.1-py3-none-any.whl", - "townlight_core-0.22.1.tar.gz", + "civiccore-0.22.1-py3-none-any.whl", + "civiccore-0.22.1.tar.gz", "SHA256SUMS.txt", "release-attestation.json", "release-attestation.json.bundle" ], "ledger_status": "attested_baseline", "attestation_status": "sigstore_verified", - "rationale": "First TownlightCore release produced after the Sigstore release-provenance gate. The release workflow signed and verified release-attestation.json before publication, and the direct cosign verification command returned Verified OK.", + "rationale": "First CivicCore release produced after the Sigstore release-provenance gate. The release workflow signed and verified release-attestation.json before publication, and the direct cosign verification command returned Verified OK.", "downstream_rule": "Use this tag, or a later attested tag, when procurement-grade release provenance is required." }, { "tag": "v0.22.0", "published_at": "2026-05-03T06:39:51Z", - "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.22.0", + "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.22.0", "tag_ref_type": "lightweight_tag", "tag_ref_sha": "483a224aaf2ae08868bd4cd4caf842bfda97db94", "target_commit": "483a224aaf2ae08868bd4cd4caf842bfda97db94", "release_assets": [ - "townlight_core-0.22.0-py3-none-any.whl", - "townlight_core-0.22.0.tar.gz", + "civiccore-0.22.0-py3-none-any.whl", + "civiccore-0.22.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -55,13 +55,13 @@ { "tag": "v0.21.0", "published_at": "2026-05-02T17:00:33Z", - "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.21.0", + "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.21.0", "tag_ref_type": "annotated_tag_object", "tag_ref_sha": "a701834c125dbdcefab35994c1ce04a3dafd36dd", "target_commit": "4a1eb718ee9565a9a1911da9eff71a5c9f0b3e3e", "release_assets": [ - "townlight_core-0.21.0-py3-none-any.whl", - "townlight_core-0.21.0.tar.gz", + "civiccore-0.21.0-py3-none-any.whl", + "civiccore-0.21.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -72,13 +72,13 @@ { "tag": "v0.20.0", "published_at": "2026-05-02T15:06:14Z", - "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.20.0", + "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.20.0", "tag_ref_type": "lightweight_tag", "tag_ref_sha": "ad66681132c28bf17c48681c82943d153897b099", "target_commit": "ad66681132c28bf17c48681c82943d153897b099", "release_assets": [ - "townlight_core-0.20.0-py3-none-any.whl", - "townlight_core-0.20.0.tar.gz", + "civiccore-0.20.0-py3-none-any.whl", + "civiccore-0.20.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -89,13 +89,13 @@ { "tag": "v0.19.0", "published_at": "2026-05-02T10:26:56Z", - "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.19.0", + "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.19.0", "tag_ref_type": "annotated_tag_object", "tag_ref_sha": "8d187ce9da4ffbbf9a5cb0a2a9cedf3181e3f030", "target_commit": "7ae2acbe01568b8f1397975286754179f9836a52", "release_assets": [ - "townlight_core-0.19.0-py3-none-any.whl", - "townlight_core-0.19.0.tar.gz", + "civiccore-0.19.0-py3-none-any.whl", + "civiccore-0.19.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -106,13 +106,13 @@ { "tag": "v0.18.1", "published_at": "2026-05-02T06:37:09Z", - "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.18.1", + "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.18.1", "tag_ref_type": "lightweight_tag", "tag_ref_sha": "fd068e72767901a9541185fe782071ec2ffddc3b", "target_commit": "fd068e72767901a9541185fe782071ec2ffddc3b", "release_assets": [ - "townlight_core-0.18.1-py3-none-any.whl", - "townlight_core-0.18.1.tar.gz", + "civiccore-0.18.1-py3-none-any.whl", + "civiccore-0.18.1.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -123,13 +123,13 @@ { "tag": "v0.18.0", "published_at": "2026-05-02T06:25:30Z", - "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.18.0", + "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.18.0", "tag_ref_type": "lightweight_tag", "tag_ref_sha": "0785e34b65470803299273acef8f033570071b41", "target_commit": "0785e34b65470803299273acef8f033570071b41", "release_assets": [ - "townlight_core-0.18.0-py3-none-any.whl", - "townlight_core-0.18.0.tar.gz", + "civiccore-0.18.0-py3-none-any.whl", + "civiccore-0.18.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -140,13 +140,13 @@ { "tag": "v0.17.0", "published_at": "2026-05-01T23:40:12Z", - "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.17.0", + "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.17.0", "tag_ref_type": "annotated_tag_object", "tag_ref_sha": "d8cd894a5e41583bda40cdb19960a60ea64e3205", "target_commit": "e9dca05ad2b45c6b19cf97fb829cb7c8e1946343", "release_assets": [ - "townlight_core-0.17.0-py3-none-any.whl", - "townlight_core-0.17.0.tar.gz", + "civiccore-0.17.0-py3-none-any.whl", + "civiccore-0.17.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -157,13 +157,13 @@ { "tag": "v0.16.0", "published_at": "2026-04-30T05:23:09Z", - "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.16.0", + "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.16.0", "tag_ref_type": "lightweight_tag", "tag_ref_sha": "a8d287e40d2c9ded183f0d3e35c6c5fb4d89137c", "target_commit": "a8d287e40d2c9ded183f0d3e35c6c5fb4d89137c", "release_assets": [ - "townlight_core-0.16.0-py3-none-any.whl", - "townlight_core-0.16.0.tar.gz", + "civiccore-0.16.0-py3-none-any.whl", + "civiccore-0.16.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -174,13 +174,13 @@ { "tag": "v0.15.0", "published_at": "2026-04-30T03:51:46Z", - "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.15.0", + "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.15.0", "tag_ref_type": "lightweight_tag", "tag_ref_sha": "27702e2fe3ddb659a224f9c57f86b960da1792a7", "target_commit": "27702e2fe3ddb659a224f9c57f86b960da1792a7", "release_assets": [ - "townlight_core-0.15.0-py3-none-any.whl", - "townlight_core-0.15.0.tar.gz", + "civiccore-0.15.0-py3-none-any.whl", + "civiccore-0.15.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -191,13 +191,13 @@ { "tag": "v0.14.1", "published_at": "2026-04-30T03:16:15Z", - "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.14.1", + "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.14.1", "tag_ref_type": "annotated_tag_object", "tag_ref_sha": "22c31133f0932cd3f579d7e5862f928f44e6f686", "target_commit": "36080f75c372c62e27e0407ec3f6cbb2dbbd4012", "release_assets": [ - "townlight_core-0.14.1-py3-none-any.whl", - "townlight_core-0.14.1.tar.gz", + "civiccore-0.14.1-py3-none-any.whl", + "civiccore-0.14.1.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -208,13 +208,13 @@ { "tag": "v0.14.0", "published_at": "2026-04-30T02:42:46Z", - "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.14.0", + "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.14.0", "tag_ref_type": "annotated_tag_object", "tag_ref_sha": "bf9136c0af6f46786c5cfca2487b7e0e5bf0b26b", "target_commit": "09bfe262f91b897799c49a0c7708feabfa067239", "release_assets": [ - "townlight_core-0.14.0-py3-none-any.whl", - "townlight_core-0.14.0.tar.gz", + "civiccore-0.14.0-py3-none-any.whl", + "civiccore-0.14.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -225,13 +225,13 @@ { "tag": "v0.13.0", "published_at": "2026-04-29T23:45:49Z", - "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.13.0", + "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.13.0", "tag_ref_type": "annotated_tag_object", "tag_ref_sha": "27fbbc872b81be6d4b2930313e56dcee66d974b1", "target_commit": "5657806c9b583a2426b5cd028726fd5fda77963e", "release_assets": [ - "townlight_core-0.13.0-py3-none-any.whl", - "townlight_core-0.13.0.tar.gz", + "civiccore-0.13.0-py3-none-any.whl", + "civiccore-0.13.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -242,13 +242,13 @@ { "tag": "v0.12.0", "published_at": "2026-04-29T22:36:17Z", - "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.12.0", + "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.12.0", "tag_ref_type": "lightweight_tag", "tag_ref_sha": "d2f24b28ba05cc0b3c601babf389cea2713c11d0", "target_commit": "d2f24b28ba05cc0b3c601babf389cea2713c11d0", "release_assets": [ - "townlight_core-0.12.0-py3-none-any.whl", - "townlight_core-0.12.0.tar.gz", + "civiccore-0.12.0-py3-none-any.whl", + "civiccore-0.12.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -259,13 +259,13 @@ { "tag": "v0.11.0", "published_at": "2026-04-29T21:09:30Z", - "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.11.0", + "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.11.0", "tag_ref_type": "lightweight_tag", "tag_ref_sha": "b21001b1cebd7de01ac8011d4ec342ab99d9bf86", "target_commit": "b21001b1cebd7de01ac8011d4ec342ab99d9bf86", "release_assets": [ - "townlight_core-0.11.0-py3-none-any.whl", - "townlight_core-0.11.0.tar.gz" + "civiccore-0.11.0-py3-none-any.whl", + "civiccore-0.11.0.tar.gz" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", "attestation_status": "none_pre_gate", @@ -275,13 +275,13 @@ { "tag": "v0.10.0", "published_at": "2026-04-29T20:08:51Z", - "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.10.0", + "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.10.0", "tag_ref_type": "annotated_tag_object", "tag_ref_sha": "9bfcf754fce7e8298ffc6423358938bba68aa8c1", "target_commit": "8db660e546f002352b3df5f2519bb2a92d3282e7", "release_assets": [ - "townlight_core-0.10.0-py3-none-any.whl", - "townlight_core-0.10.0.tar.gz" + "civiccore-0.10.0-py3-none-any.whl", + "civiccore-0.10.0.tar.gz" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", "attestation_status": "none_pre_gate", @@ -291,13 +291,13 @@ { "tag": "v0.9.0", "published_at": "2026-04-29T18:32:51Z", - "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.9.0", + "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.9.0", "tag_ref_type": "annotated_tag_object", "tag_ref_sha": "52ca2c866d5e3f665c890b6aab13a34262f2c317", "target_commit": "8010e9fd9b5ab599f579c257f24f3c1ae3cea3e2", "release_assets": [ - "townlight_core-0.9.0-py3-none-any.whl", - "townlight_core-0.9.0.tar.gz", + "civiccore-0.9.0-py3-none-any.whl", + "civiccore-0.9.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -308,13 +308,13 @@ { "tag": "v0.8.0", "published_at": "2026-04-29T17:48:23Z", - "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.8.0", + "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.8.0", "tag_ref_type": "annotated_tag_object", "tag_ref_sha": "d4336082b20d2df3467b76d987feee54f2ec802e", "target_commit": "b7cfaeb9d9490ff0c68aad255df6f69da912d6be", "release_assets": [ - "townlight_core-0.8.0-py3-none-any.whl", - "townlight_core-0.8.0.tar.gz", + "civiccore-0.8.0-py3-none-any.whl", + "civiccore-0.8.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -325,13 +325,13 @@ { "tag": "v0.7.0", "published_at": "2026-04-29T16:43:12Z", - "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.7.0", + "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.7.0", "tag_ref_type": "annotated_tag_object", "tag_ref_sha": "3dc905a865d397551384d35d1fa7dc0978e6d964", "target_commit": "943da60abd6ef4e906b63eecbf7dcbc8de77550d", "release_assets": [ - "townlight_core-0.7.0-py3-none-any.whl", - "townlight_core-0.7.0.tar.gz", + "civiccore-0.7.0-py3-none-any.whl", + "civiccore-0.7.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -342,13 +342,13 @@ { "tag": "v0.6.0", "published_at": "2026-04-29T16:07:58Z", - "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.6.0", + "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.6.0", "tag_ref_type": "annotated_tag_object", "tag_ref_sha": "64c1f62f9c4224f987853864bd598a70f78806c0", "target_commit": "95890075c7886e66c9711e0e8e84517a705e3530", "release_assets": [ - "townlight_core-0.6.0-py3-none-any.whl", - "townlight_core-0.6.0.tar.gz", + "civiccore-0.6.0-py3-none-any.whl", + "civiccore-0.6.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -359,13 +359,13 @@ { "tag": "v0.5.0", "published_at": "2026-04-29T15:23:28Z", - "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.5.0", + "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.5.0", "tag_ref_type": "lightweight_tag", "tag_ref_sha": "bcb9b7852ba200302371bec3f425726230c435b3", "target_commit": "bcb9b7852ba200302371bec3f425726230c435b3", "release_assets": [ - "townlight_core-0.5.0-py3-none-any.whl", - "townlight_core-0.5.0.tar.gz", + "civiccore-0.5.0-py3-none-any.whl", + "civiccore-0.5.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -376,13 +376,13 @@ { "tag": "v0.4.0", "published_at": "2026-04-29T04:38:47Z", - "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.4.0", + "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.4.0", "tag_ref_type": "annotated_tag_object", "tag_ref_sha": "8c3eedc411570bba67c11ee750bfb2c168999026", "target_commit": "fab33a41f1c4c3ef3684dee1069f7069d31ac115", "release_assets": [ - "townlight_core-0.4.0-py3-none-any.whl", - "townlight_core-0.4.0.tar.gz", + "civiccore-0.4.0-py3-none-any.whl", + "civiccore-0.4.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -393,13 +393,13 @@ { "tag": "v0.3.0", "published_at": "2026-04-28T06:28:20Z", - "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.3.0", + "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.3.0", "tag_ref_type": "lightweight_tag", "tag_ref_sha": "7b3fbbf79b6c71513fac399658fe47195722b5e5", "target_commit": "7b3fbbf79b6c71513fac399658fe47195722b5e5", "release_assets": [ - "townlight_core-0.3.0-py3-none-any.whl", - "townlight_core-0.3.0.tar.gz", + "civiccore-0.3.0-py3-none-any.whl", + "civiccore-0.3.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -410,13 +410,13 @@ { "tag": "v0.2.0", "published_at": "2026-04-25T18:11:21Z", - "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.2.0", + "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.2.0", "tag_ref_type": "annotated_tag_object", "tag_ref_sha": "11ba8a6fa0c3c85f76d049eb76356e4eb6b5bfa8", "target_commit": "a8246ed34405d97be1e20adabd7dc8536e1246eb", "release_assets": [ - "townlight_core-0.2.0-py3-none-any.whl", - "townlight_core-0.2.0.tar.gz", + "civiccore-0.2.0-py3-none-any.whl", + "civiccore-0.2.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", @@ -427,13 +427,13 @@ { "tag": "v0.1.0", "published_at": "2026-04-24T23:30:45Z", - "release_url": "https://github.com/Townlight/townlight_core/releases/tag/v0.1.0", + "release_url": "https://github.com/CivicSuite/civiccore/releases/tag/v0.1.0", "tag_ref_type": "annotated_tag_object", "tag_ref_sha": "feaefd2366d30ceead5a324e15c475a503b3be34", "target_commit": "9ac20f0274fbe6fc9730bdc509d5e6d4cedf6231", "release_assets": [ - "townlight_core-0.1.0-py3-none-any.whl", - "townlight_core-0.1.0.tar.gz", + "civiccore-0.1.0-py3-none-any.whl", + "civiccore-0.1.0.tar.gz", "SHA256SUMS.txt" ], "ledger_status": "pre_gate_no_attestation_do_not_promote", diff --git a/docs/ops/townlight_core-tier1-retrofit-ledger.md b/docs/ops/civiccore-tier1-retrofit-ledger.md similarity index 95% rename from docs/ops/townlight_core-tier1-retrofit-ledger.md rename to docs/ops/civiccore-tier1-retrofit-ledger.md index 0c3101b..85aaf8b 100644 --- a/docs/ops/townlight_core-tier1-retrofit-ledger.md +++ b/docs/ops/civiccore-tier1-retrofit-ledger.md @@ -1,4 +1,4 @@ - + # Townlight Core Tier 1 Retrofit Ledger @@ -22,7 +22,7 @@ repo-controlled ledger plus documentation truth update. matrix permits it. Structured source of truth: -[`docs/ops/townlight_core-tier1-retrofit-ledger.json`](townlight_core-tier1-retrofit-ledger.json). +[`docs/ops/civiccore-tier1-retrofit-ledger.json`](civiccore-tier1-retrofit-ledger.json). Verification: @@ -42,11 +42,11 @@ but the live check permits them only when the GitHub release exposes both - Live releases scanned: 25 - Latest release: `v0.22.1` - Baseline release: - [`v0.22.1`](https://github.com/Townlight/townlight_core/releases/tag/v0.22.1) + [`v0.22.1`](https://github.com/CivicSuite/civiccore/releases/tag/v0.22.1) - Baseline target commit: `46c99854adbce6dc8a056ae5215278bb1eba9a19` - Baseline Sigstore identity: - `https://github.com/Townlight/townlight_core/.github/workflows/release.yml@refs/tags/v0.22.1` + `https://github.com/CivicSuite/civiccore/.github/workflows/release.yml@refs/tags/v0.22.1` ## Entries diff --git a/docs/ops/co-4-cross-module-retrofit-report.md b/docs/ops/co-4-cross-module-retrofit-report.md index 4bfc71e..6f512f9 100644 --- a/docs/ops/co-4-cross-module-retrofit-report.md +++ b/docs/ops/co-4-cross-module-retrofit-report.md @@ -28,9 +28,9 @@ in that product repository. | Repository | PR | Base | Merge commit | Scope | | --- | --- | --- | --- | --- | -| `townlight/sunshine` | [#67](https://github.com/Townlight/townlight_records/pull/67) | `master` | `3b1f38c3d88050c1cf299cf8254eedf65f58a52a` | Ledgered `v1.4.10`, updated current Townlight Core dependency/docs to `v0.22.1`, added browser QA evidence, and copied ledger evidence into the backend image so CI verifies it. | -| `townlight/meetings` | [#142](https://github.com/Townlight/townlight_meetings/pull/142) | `main` | `b068233e87608931ff9165fad435a10fbade24a8` | Ledgered `v0.1.20`, updated current Townlight Core dependency/docs/workflows/rehearsal health checks to `v0.22.1`, and refreshed browser QA evidence. | -| `townlight/ordinances` | [#47](https://github.com/Townlight/townlight_code/pull/47) | `main` | `4450931de51c1173adcff91d47e5373382670d89` | Ledgered `v0.1.17` and `v0.1.18`, updated current Townlight Core dependency/docs/workflows to `v0.22.1`, and added browser QA evidence. | +| `townlight/sunshine` | [#67](https://github.com/CivicSuite/civicrecords-ai/pull/67) | `master` | `3b1f38c3d88050c1cf299cf8254eedf65f58a52a` | Ledgered `v1.4.10`, updated current Townlight Core dependency/docs to `v0.22.1`, added browser QA evidence, and copied ledger evidence into the backend image so CI verifies it. | +| `townlight/meetings` | [#142](https://github.com/CivicSuite/civicclerk/pull/142) | `main` | `b068233e87608931ff9165fad435a10fbade24a8` | Ledgered `v0.1.20`, updated current Townlight Core dependency/docs/workflows/rehearsal health checks to `v0.22.1`, and refreshed browser QA evidence. | +| `townlight/ordinances` | [#47](https://github.com/CivicSuite/civiccode/pull/47) | `main` | `4450931de51c1173adcff91d47e5373382670d89` | Ledgered `v0.1.17` and `v0.1.18`, updated current Townlight Core dependency/docs/workflows to `v0.22.1`, and added browser QA evidence. | ## Evidence diff --git a/docs/ops/co-7-freeze-readiness.md b/docs/ops/co-7-freeze-readiness.md index 8ba9878..c8119df 100644 --- a/docs/ops/co-7-freeze-readiness.md +++ b/docs/ops/co-7-freeze-readiness.md @@ -1,4 +1,4 @@ - + # CO-7 Townlight Core Freeze Readiness @@ -27,7 +27,7 @@ CO-7 reconciles the shipped Townlight Core surface against Townlight unified spe section 6 and the Townlight Core README. The shipped freeze candidate includes: - migrations and shared SQLAlchemy `Base` -- `townlight_core.llm` provider, template, registry, context, and structured-output helpers +- `civiccore.llm` provider, template, registry, context, and structured-output helpers - audit, persisted audit-log verification, provenance, manifest, and export-bundle primitives - city profile models and onboarding profile interview helpers - auth helpers for bearer roles and trusted-header proxy boundaries @@ -45,9 +45,9 @@ Townlight PR so those shipped surfaces no longer appear as silent drift. The three README-listed placeholder namespaces now have Townlight Core ADRs: -- `docs/adr/ADR-0001-defer-townlight_core-catalog.md` -- `docs/adr/ADR-0002-defer-townlight_core-exemptions.md` -- `docs/adr/ADR-0003-defer-townlight_core-scaffold.md` +- `docs/adr/ADR-0001-defer-civiccore-catalog.md` +- `docs/adr/ADR-0002-defer-civiccore-exemptions.md` +- `docs/adr/ADR-0003-defer-civiccore-scaffold.md` Each ADR names the deferral rationale, target phase, and downstream consumption rule: no module depends on the placeholder namespace until it ships in a @@ -58,12 +58,12 @@ versioned Townlight Core release artifact. Local command: ```powershell -git -C grep -n -E 'townlight_core\.(catalog|exemptions|scaffold)|from townlight_core import (catalog|exemptions|scaffold)|import townlight_core\.(catalog|exemptions|scaffold)' -- . +git -C grep -n -E 'civiccore\.(catalog|exemptions|scaffold)|from civiccore import (catalog|exemptions|scaffold)|import civiccore\.(catalog|exemptions|scaffold)' -- . ``` Result: no production-code reliance found across the compatibility-matrix module set. Townlight Meetings and Townlight Code contain test-only references to -`townlight_core.exemptions` and `townlight_core.catalog` inside guard tests that assert +`civiccore.exemptions` and `civiccore.catalog` inside guard tests that assert module schemas do not foreign-key into unreleased Townlight Core placeholder targets. A production-code-only sweep excluding tests returned clean for every module in @@ -74,7 +74,7 @@ the compatibility matrix. Local checks completed on 2026-05-05 before any freeze tag publication: - `python -m pytest tests/test_placeholder_adrs.py -q`: 3 passed. -- `python -m ruff check tests/test_placeholder_adrs.py townlight_core/catalog/__init__.py townlight_core/exemptions/__init__.py townlight_core/scaffold/__init__.py`: passed. +- `python -m ruff check tests/test_placeholder_adrs.py civiccore/catalog/__init__.py civiccore/exemptions/__init__.py civiccore/scaffold/__init__.py`: passed. - `python -m pytest --collect-only -q`: 260 tests collected. - `bash scripts/verify-release.sh`: passed, including 260 tests, Ruff, docs checks, build artifacts, and fresh virtualenv import/version smoke. @@ -88,9 +88,9 @@ Local checks completed on 2026-05-05 before any freeze tag publication: `bash scripts/verify-docs.sh` passed. - Companion Townlight suite-state verification: `python scripts/verify-suite-state.py --remote-only` passed for all 26 repos - and confirmed `townlight_core 0.22.1`. + and confirmed `civiccore 0.22.1`. - Companion Townlight browser QA: - `docs/browser-qa-co7-townlight_core-freeze-lockstep-summary.md` passed with + `docs/browser-qa-co7-civiccore-freeze-lockstep-summary.md` passed with desktop 1280x900 and mobile 390x844 screenshots, zero browser console messages, zero page errors, no horizontal overflow, keyboard focus proof, contrast proof, and copy review. diff --git a/docs/ops/co-9-audit-full-release-gate.md b/docs/ops/co-9-audit-full-release-gate.md index d8456ba..b154d3b 100644 --- a/docs/ops/co-9-audit-full-release-gate.md +++ b/docs/ops/co-9-audit-full-release-gate.md @@ -2,14 +2,14 @@ Date: 2026-05-05. -Repo: `Townlight/townlight_core`. +Repo: `CivicSuite/civiccore`. Audit mode: release-gate. Auditor: Codex, no subagents. Post-publication addendum: the `v1.0` GitHub release is now published at -[`townlight_core v1.0`](https://github.com/Townlight/townlight_core/releases/tag/v1.0). +[`civiccore v1.0`](https://github.com/CivicSuite/civiccore/releases/tag/v1.0). The live tag target is `a699814c6b97ff3ef13ecd9f04b5f4a2d76f7438`, release workflow run `25408733597` completed successfully, and the release page carries the wheel, sdist, `SHA256SUMS.txt`, `release-attestation.json`, and @@ -19,7 +19,7 @@ former PR/main-CI and release-publication gaps. ## 1. Executive Audit -Scope: Townlight Core local release-prep checkout for CO-9 v1.0, plus live GitHub +Scope: CivicCore local release-prep checkout for CO-9 v1.0, plus live GitHub remote state. Post-publication addendum scope includes the merged `main` source tree and live `v1.0` GitHub release. @@ -29,7 +29,7 @@ Local-vs-live parity: checked before release-prep edits. Local `main`, merged `main` commit and `v1.0` target `a699814c6b97ff3ef13ecd9f04b5f4a2d76f7438`. -Overall verdict: PASS for Townlight Core `v1.0` publication posture. No open +Overall verdict: PASS for CivicCore `v1.0` publication posture. No open Blocker or Critical findings remain. PR CI, main CI, release workflow, publication, and post-publication release-asset checks are now complete. @@ -57,24 +57,24 @@ paths, and now publishes notes with evidence-pack and provenance commands. | Lane | Status | Evidence summary | Blocker | |---|---|---|---| -| Remote parity | Checked | `origin` is `https://github.com/Townlight/townlight_core.git`; pre-edit local main matched `origin/main` at `a1c52c9`. | None | +| Remote parity | Checked | `origin` is `https://github.com/CivicSuite/civiccore.git`; pre-edit local main matched `origin/main` at `a1c52c9`. | None | | Local-vs-live commit truth | Checked | Post-publication local `main`, `origin/main`, and `v1.0^{}` match `a699814c6b97ff3ef13ecd9f04b5f4a2d76f7438`. | None | | CI/workflow presence | Checked | Four workflows present; workflow YAML parse test passes. | None | -| Windows install path | Checked | `bash scripts/verify-release.sh` built and installed `townlight_core-1.0.0` in a fresh venv. | None | +| Windows install path | Checked | `bash scripts/verify-release.sh` built and installed `civiccore-1.0.0` in a fresh venv. | None | | Linux or Unix install path | Checked | Git Bash path passed locally; GitHub Linux CI and release workflow completed successfully for `v1.0`. | None | | Platform parity verdict | Checked | Local Windows verification and GitHub Linux CI/release verification are green for `v1.0`. | None | -| First boot | Checked | Library import smoke checks `townlight_core.__version__ == "1.0.0"` and public helpers. | None | +| First boot | Checked | Library import smoke checks `civiccore.__version__ == "1.0.0"` and public helpers. | None | | Required post-install steps | Checked | Docs describe wheel install plus SHA256/Sigstore verification; no app bootstrap required. | None | | Migrations | Checked | Baseline idempotency tests and migration tests collected and passed in release verifier. | None | -| Seed/bootstrap requirements | Not applicable | Townlight Core is a library with no seed data path. | None | +| Seed/bootstrap requirements | Not applicable | CivicCore is a library with no seed data path. | None | | Runtime dependency and model requirements | Checked | LLM provider tests are mocked; no live model pull at import. | None | -| First-boot dependency truth | Checked | README/manual identify Townlight Core as a library, not an end-user app. | None | +| First-boot dependency truth | Checked | README/manual identify CivicCore as a library, not an end-user app. | None | | Secrets and credential handling | Checked | Remote URL carries no embedded token; security config validation tests pass. | None | | Auth and session handling | Checked | Bearer/trusted-header auth tests passed. | None | | Authorization and role boundaries | Checked | Role parsing, trusted proxy source checks, and optional auth helpers are tested. | None | | Response-schema sensitive-data exposure | Checked | Public API tests and security tests cover exposed helper surface; no app responses ship. | None | | Audit and compliance logging | Checked | Audit chain and persisted audit hash tests pass. | None | -| External and admin surfaces | Checked | Townlight Core exposes library/admin router primitives only; no standalone public service. | None | +| External and admin surfaces | Checked | CivicCore exposes library/admin router primitives only; no standalone public service. | None | | Connector implementation completeness | Checked | Docs now distinguish shipped local/import/sync primitives from unshipped vendor adapters. | None | | Connector docs truth | Checked | README/manual/docs index scoped vendor-specific adapters as unshipped. | None | | Background jobs and schedulers | Checked | Scheduling helpers ship; scheduler runtime/task queue remain module-owned. | None | @@ -85,7 +85,7 @@ paths, and now publishes notes with evidence-pack and provenance commands. | Partial states | Not applicable | Static local HTML renders all sections. | None | | Accessibility cues | Checked | Keyboard focus sample and contrast ratios recorded in browser QA. | None | | Docs truthfulness | Checked | Version/install copy moved to v1.0; ingest docs drift fixed. | None | -| Version consistency | Checked | `pyproject.toml`, `townlight_core.__version__`, smoke test, docs, and SBOM align on `1.0.0`/`v1.0`. | None | +| Version consistency | Checked | `pyproject.toml`, `civiccore.__version__`, smoke test, docs, and SBOM align on `1.0.0`/`v1.0`. | None | | Release artifact consistency | Checked | Workflow expected assets are wheel, sdist, SHA256SUMS, attestation JSON, and bundle. | None | | Test realism | Checked | 273 tests collected in the post-publication quality pause; release verifier runs full test suite, ruff, build, fresh install. | None | | Runtime, build, and test verification | Checked | `VERIFY-RELEASE: PASSED`. | None | @@ -96,11 +96,11 @@ paths, and now publishes notes with evidence-pack and provenance commands. | Claim | Source | Verdict | Evidence | |---|---|---|---| -| Townlight Core is a shared platform library, not an end-user app. | README, manual, docs index | True | No app boot path; import smoke only. | +| CivicCore is a shared platform library, not an end-user app. | README, manual, docs index | True | No app boot path; import smoke only. | | v1.0 is the downstream productization release. | README, docs index, closeout | True | Package version `1.0.0`; install URL uses `v1.0`. | | v0.22.1 remains the first attested baseline. | Historical policy, ledger | True | Baseline tag and ledger unchanged. | -| Freeze tag is `townlight_core-m1-freeze`. | CO-7 evidence, release list | True | Live release and live Tier 1 check verify attestation assets. | -| Final v1.0 SBOM is present. | CO-8 evidence pack | True | `sbom-v1.0-pip-inspect.json`; test verifies `townlight_core` `1.0.0`. | +| Freeze tag is `civiccore-m1-freeze`. | CO-7 evidence, release list | True | Live release and live Tier 1 check verify attestation assets. | +| Final v1.0 SBOM is present. | CO-8 evidence pack | True | `sbom-v1.0-pip-inspect.json`; test verifies `civiccore` `1.0.0`. | | Release workflow publishes exact asset paths. | `.github/workflows/release.yml` | True | Workflow test asserts no wildcard `release-assets/*` upload. | | Release notes include auditor commands. | `.github/workflows/release.yml` | True | Test asserts evidence-pack and provenance command text. | | Docs landing page install path is current. | `docs/index.html` | True | Browser QA copy checks passed. | @@ -132,7 +132,7 @@ Can defer if consciously accepted: ## 5. Next-Sprint Watchlist -Architecture: Keep downstream modules pinned to `townlight_core-m1-freeze` until +Architecture: Keep downstream modules pinned to `civiccore-m1-freeze` until their compatibility matrices move deliberately. Security and compliance debt: Preserve release bundles and trust-root context @@ -141,13 +141,13 @@ for offline procurement review. UX debt: Future docs pages should avoid long status paragraphs if the static landing page becomes more app-like. -Docs debt: Townlight Meetings must reference the freeze tag and CO-8/CO-9 evidence pack +Docs debt: CivicClerk must reference the freeze tag and CO-8/CO-9 evidence pack when its productization lane starts. Install and bootstrap debt: Downstream modules need cleanroom harnesses pinned -to the freeze tag, not moving Townlight Core main. +to the freeze tag, not moving CivicCore main. -Test debt: Add downstream compatibility tests as soon as Townlight Meetings begins. +Test debt: Add downstream compatibility tests as soon as CivicClerk begins. Operational and release debt: Keep post-publication release verification linked from the release record for every future release. @@ -163,7 +163,7 @@ separates preflight, build/attest/verify, and publication jobs. Findings: none open. Verification gaps: None for the shipped `v1.0` source tree; downstream -module compatibility remains tracked outside this Townlight Core audit. +module compatibility remains tracked outside this CivicCore audit. ## 7. Security And Authorization Deep Dive @@ -175,7 +175,7 @@ commit, and target tree. The remote URL contains no credential-bearing token. Findings: none open. -Verification gaps: None for Townlight Core `v1.0`; the Sigstore bundle is published +Verification gaps: None for CivicCore `v1.0`; the Sigstore bundle is published with the GitHub release. ## 8. UI/UX Deep Dive @@ -196,11 +196,11 @@ Verdict: PASS. Strengths: The docs now distinguish the downstream productization release (`v1.0`) from the first attested baseline (`v0.22.1`) and the freeze-line tag -(`townlight_core-m1-freeze`). This avoids overstating historical releases. +(`civiccore-m1-freeze`). This avoids overstating historical releases. Findings: none open. -Verification gaps: None for Townlight Core `v1.0`; Townlight Meetings gating moved to its +Verification gaps: None for CivicCore `v1.0`; CivicClerk gating moved to its own productization lane after the release went live. ## 10. Documentation Deep Dive @@ -209,7 +209,7 @@ Verdict: PASS. Strengths: README, text README, user manual, docs index, changelog, evidence pack, closeout report, release workflow notes, and Tier 1 ledger docs were -updated together. The docs drift that described `townlight_core.ingest` as entirely +updated together. The docs drift that described `civiccore.ingest` as entirely unshipped was corrected. Findings: none open. @@ -222,8 +222,8 @@ verification commands. Verdict: PASS. -Strengths: Townlight Core has no seed/bootstrap path. The install path is a GitHub -release wheel; verifier built `townlight_core-1.0.0`, installed it into a fresh venv, +Strengths: CivicCore has no seed/bootstrap path. The install path is a GitHub +release wheel; verifier built `civiccore-1.0.0`, installed it into a fresh venv, and imported public helpers. Findings: none open. @@ -235,7 +235,7 @@ available through the GitHub release URL. Verdict: PASS. -Strengths: `pyproject.toml`, `townlight_core/__init__.py`, smoke tests, README, +Strengths: `pyproject.toml`, `civiccore/__init__.py`, smoke tests, README, README.txt, manuals, docs landing page, changelog, and final SBOM agree on package version `1.0.0` and release tag `v1.0`. Historical `v0.22.1` references remain as baseline history, not current install copy. @@ -256,7 +256,7 @@ workflow note content, smoke version, and live ledger parity rules. Findings: none open. Verification gaps: Mutation/adversarial downstream compatibility remains for -Townlight Meetings and Townlight Code lanes, not CO-9 Townlight Core release prep. +CivicClerk and CivicCode lanes, not CO-9 CivicCore release prep. ## 14. Runtime QA Deep Dive @@ -266,18 +266,18 @@ Verdict: PASS for local runtime QA. - `python -m pytest tests/test_tier1_retrofit_ledger.py tests/test_co8_procurement_evidence_pack.py tests/test_github_workflows.py tests/test_smoke.py -q` -> 16 passed, 1 warning. - `python -m ruff check ...` -> all checks passed. -- `python scripts/check-tier1-ledger.py --live` -> 25 historical tags ledgered; post-baseline `townlight_core-m1-freeze` attestation assets verified live. +- `python scripts/check-tier1-ledger.py --live` -> 25 historical tags ledgered; post-baseline `civiccore-m1-freeze` attestation assets verified live. - `python -m pytest --collect-only -q` -> 273 tests collected. - Browser QA summary -> PASS. - `bash scripts/verify-release.sh` -> full test suite passed, ruff passed, version lockstep `1.0.0`, build passed, fresh venv install/import smoke passed, `VERIFY-RELEASE: PASSED`. [DEV-REPORTED] -- CO-7 downstream temporary harnesses: Townlight Meetings 553 passed; Townlight Code 162 passed. +- CO-7 downstream temporary harnesses: CivicClerk 553 passed; CivicCode 162 passed. Findings: none open. -Verification gaps: None for Townlight Core `v1.0` release publication; downstream +Verification gaps: None for CivicCore `v1.0` release publication; downstream module compatibility remains separate. ## 15. Cross-Cutting Synthesis @@ -294,9 +294,9 @@ published `v1.0` release and its attestation assets. | Gap | Why it remains | Exact closing check | Blocks sign-off? | |---|---|---|---| -| Downstream module compatibility | Townlight Core `v1.0` is published, but each module still owns its compatibility matrix and pin movement. | Run each downstream module's release gate after changing its Townlight Core pin. | Limits downstream sign-off only. | -| Offline procurement reproduction | Local audit checked live metadata and local release verification; full offline cosign/SHA reproduction depends on the reviewer's environment. | Download release assets in a clean environment and run the release-note verification commands. | Confidence limit, not a Townlight Core source blocker. | +| Downstream module compatibility | CivicCore `v1.0` is published, but each module still owns its compatibility matrix and pin movement. | Run each downstream module's release gate after changing its CivicCore pin. | Limits downstream sign-off only. | +| Offline procurement reproduction | Local audit checked live metadata and local release verification; full offline cosign/SHA reproduction depends on the reviewer's environment. | Download release assets in a clean environment and run the release-note verification commands. | Confidence limit, not a CivicCore source blocker. | Sign-off limit: this report began as a release-prep audit and now includes a -post-publication addendum. It signs off Townlight Core `v1.0` publication posture, +post-publication addendum. It signs off CivicCore `v1.0` publication posture, while downstream module compatibility remains outside this report. diff --git a/docs/ops/co-9-townlight_core-v1-closeout.md b/docs/ops/co-9-civiccore-v1-closeout.md similarity index 59% rename from docs/ops/co-9-townlight_core-v1-closeout.md rename to docs/ops/co-9-civiccore-v1-closeout.md index 218e207..95b6a3e 100644 --- a/docs/ops/co-9-townlight_core-v1-closeout.md +++ b/docs/ops/co-9-civiccore-v1-closeout.md @@ -1,4 +1,4 @@ - + # CO-9 Townlight Core v1.0 Closeout Report @@ -19,7 +19,7 @@ The release-class operation is covered by explicit chat authorization for: | Sprint | Authorized operation | Scope | |---|---|---| | CO-2c | Cut Townlight Core `v0.22.1` | First Sigstore-attested baseline release. | -| CO-7 | Cut `townlight_core-m1-freeze` | Freeze-line release for downstream module pins. | +| CO-7 | Cut `civiccore-m1-freeze` | Freeze-line release for downstream module pins. | | CO-9 | Cut Townlight Core `v1.0` | Downstream productization release. | The CO-9 release payload is: @@ -29,11 +29,11 @@ The CO-9 release payload is: | Sprint ID | CO-9 | | Repo | `townlight/core` | | Target SHA | The GitHub-merged CO-9 release-prep commit on `main` | -| Tag / release name | `v1.0` / `townlight_core v1.0` | +| Tag / release name | `v1.0` / `civiccore v1.0` | | Package version | `1.0.0` | -| Release assets | `townlight_core-1.0.0-py3-none-any.whl`, `townlight_core-1.0.0.tar.gz`, `SHA256SUMS.txt`, `release-attestation.json`, `release-attestation.json.bundle` | -| Auditor verification command | `python scripts/verify-release-provenance.py v1.0 --repo Townlight/townlight_core --attestation release-attestation.json --bundle release-attestation.json.bundle --artifacts-dir .` | -| Expected Sigstore identity | `https://github.com/Townlight/townlight_core/.github/workflows/release.yml@refs/tags/v1.0` | +| Release assets | `civiccore-1.0.0-py3-none-any.whl`, `civiccore-1.0.0.tar.gz`, `SHA256SUMS.txt`, `release-attestation.json`, `release-attestation.json.bundle` | +| Auditor verification command | `python scripts/verify-release-provenance.py v1.0 --repo CivicSuite/civiccore --attestation release-attestation.json --bundle release-attestation.json.bundle --artifacts-dir .` | +| Expected Sigstore identity | `https://github.com/CivicSuite/civiccore/.github/workflows/release.yml@refs/tags/v1.0` | | Expected Sigstore issuer | `https://token.actions.githubusercontent.com` | | Failure plan | If tag creation succeeds but release publication fails, stop release work, file a failure report, and do not delete, move, edit, or republish any public artifact without fresh release-class authorization. | @@ -41,16 +41,16 @@ The CO-9 release payload is: | Release | Role | Verification surface | |---|---|---| -| [`v0.22.1`](https://github.com/Townlight/townlight_core/releases/tag/v0.22.1) | First Sigstore-attested baseline release. | `release-attestation.json`, `release-attestation.json.bundle`, `SHA256SUMS.txt`, historical-provenance policy. | -| [`townlight_core-m1-freeze`](https://github.com/Townlight/townlight_core/releases/tag/townlight_core-m1-freeze) | CO-7 downstream freeze-line release. | Freeze workflow run `25405991283`, target commit `3c4c34ccd153eeae705a57139f6713c356328b6d`, target tree `1e92d8b900b3d0134c4e8bc5b9133becff7822e6`. | -| [`v1.0`](https://github.com/Townlight/townlight_core/releases/tag/v1.0) | CO-9 downstream productization release. | Release workflow, final SBOM, release attestation, SHA256SUMS, and post-publication provenance verification. | +| [`v0.22.1`](https://github.com/CivicSuite/civiccore/releases/tag/v0.22.1) | First Sigstore-attested baseline release. | `release-attestation.json`, `release-attestation.json.bundle`, `SHA256SUMS.txt`, historical-provenance policy. | +| [`civiccore-m1-freeze`](https://github.com/CivicSuite/civiccore/releases/tag/civiccore-m1-freeze) | CO-7 downstream freeze-line release. | Freeze workflow run `25405991283`, target commit `3c4c34ccd153eeae705a57139f6713c356328b6d`, target tree `1e92d8b900b3d0134c4e8bc5b9133becff7822e6`. | +| [`v1.0`](https://github.com/CivicSuite/civiccore/releases/tag/v1.0) | CO-9 downstream productization release. | Release workflow, final SBOM, release attestation, SHA256SUMS, and post-publication provenance verification. | ## Retrofit Decisions | Decision | Record | |---|---| | Historical release tags are preserved, not rewritten. | [`historical-provenance.md`](historical-provenance.md). | -| `v0.22.1` is the first attested baseline; older releases remain historical. | [`townlight_core-tier1-retrofit-ledger.md`](townlight_core-tier1-retrofit-ledger.md). | +| `v0.22.1` is the first attested baseline; older releases remain historical. | [`civiccore-tier1-retrofit-ledger.md`](civiccore-tier1-retrofit-ledger.md). | | Cross-module historical retrofit findings are repo-controlled evidence, not desktop-only notes. | [`co-4-cross-module-retrofit-report.md`](co-4-cross-module-retrofit-report.md). | | Future release trust is Sigstore attestation plus artifact hashes, not the GitHub "Verified" badge alone. | [`release-signing.md`](release-signing.md). | @@ -58,22 +58,22 @@ The CO-9 release payload is: | Surface | Resolution | |---|---| -| Placeholder namespaces `townlight_core.catalog`, `townlight_core.exemptions`, and `townlight_core.scaffold`. | ADR-deferred with downstream no-dependency rule in [`../adr/index.md`](../adr/index.md). | +| Placeholder namespaces `civiccore.catalog`, `civiccore.exemptions`, and `civiccore.scaffold`. | ADR-deferred with downstream no-dependency rule in [`../adr/index.md`](../adr/index.md). | | Historical release provenance drift. | Disclosed and governed by [`historical-provenance.md`](historical-provenance.md). | -| Downstream module freeze dependency. | `townlight_core-m1-freeze` is the freeze-line tag; Townlight Meetings and Townlight Code productization lanes pin to the freeze, not moving `main`. | +| Downstream module freeze dependency. | `civiccore-m1-freeze` is the freeze-line tag; Townlight Meetings and Townlight Code productization lanes pin to the freeze, not moving `main`. | | Procurement evidence gap. | CO-8 evidence pack plus CO-9 final SBOM. | ## Evidence Anchors | Evidence | Location | |---|---| -| CO-8 procurement pack | [`../evidence/co8-townlight_core-procurement-evidence-pack/index.md`](../evidence/co8-townlight_core-procurement-evidence-pack/index.md) | -| Final v1.0 SBOM | [`../evidence/co8-townlight_core-procurement-evidence-pack/sbom-v1.0-pip-inspect.json`](../evidence/co8-townlight_core-procurement-evidence-pack/sbom-v1.0-pip-inspect.json) | +| CO-8 procurement pack | [`../evidence/co8-civiccore-procurement-evidence-pack/index.md`](../evidence/co8-civiccore-procurement-evidence-pack/index.md) | +| Final v1.0 SBOM | [`../evidence/co8-civiccore-procurement-evidence-pack/sbom-v1.0-pip-inspect.json`](../evidence/co8-civiccore-procurement-evidence-pack/sbom-v1.0-pip-inspect.json) | | Cleanroom harness | [`cleanroom-harness.md`](cleanroom-harness.md) | | CO-9 audit-full release gate | [`co-9-audit-full-release-gate.md`](co-9-audit-full-release-gate.md) | | Release signing runbook | [`release-signing.md`](release-signing.md) | | Historical provenance policy | [`historical-provenance.md`](historical-provenance.md) | -| Tier 1 retrofit ledger | [`townlight_core-tier1-retrofit-ledger.md`](townlight_core-tier1-retrofit-ledger.md) | +| Tier 1 retrofit ledger | [`civiccore-tier1-retrofit-ledger.md`](civiccore-tier1-retrofit-ledger.md) | ## Verification Gate @@ -92,7 +92,7 @@ The tag push then runs the release workflow, which rebuilds artifacts, creates `SHA256SUMS.txt`, signs `release-attestation.json`, verifies provenance before publication, and publishes the GitHub release. - + ## Townlight Meetings Unblock Rule diff --git a/docs/ops/historical-provenance.md b/docs/ops/historical-provenance.md index 4c7dae9..e28dad6 100644 --- a/docs/ops/historical-provenance.md +++ b/docs/ops/historical-provenance.md @@ -1,22 +1,22 @@ # Historical Provenance Disclosure Policy -Status: operative Townlight policy, effective 2026-05-05. +Status: operative CivicSuite policy, effective 2026-05-05. -Baseline: `townlight_core v0.22.1`, released 2026-05-05 at 16:23:36Z, is the +Baseline: `civiccore v0.22.1`, released 2026-05-05 at 16:23:36Z, is the baseline release under the attested provenance model. The live release and trust artifacts are: -- Release: [`v0.22.1`](https://github.com/Townlight/townlight_core/releases/tag/v0.22.1) +- Release: [`v0.22.1`](https://github.com/CivicSuite/civiccore/releases/tag/v0.22.1) - Attestation: - [`release-attestation.json`](https://github.com/Townlight/townlight_core/releases/download/v0.22.1/release-attestation.json) + [`release-attestation.json`](https://github.com/CivicSuite/civiccore/releases/download/v0.22.1/release-attestation.json) - Cosign bundle: - [`release-attestation.json.bundle`](https://github.com/Townlight/townlight_core/releases/download/v0.22.1/release-attestation.json.bundle) + [`release-attestation.json.bundle`](https://github.com/CivicSuite/civiccore/releases/download/v0.22.1/release-attestation.json.bundle) - Checksums: - [`SHA256SUMS.txt`](https://github.com/Townlight/townlight_core/releases/download/v0.22.1/SHA256SUMS.txt) + [`SHA256SUMS.txt`](https://github.com/CivicSuite/civiccore/releases/download/v0.22.1/SHA256SUMS.txt) ## Summary -Townlight strengthened its release provenance model during the synthetic +CivicSuite strengthened its release provenance model during the synthetic development phase. The prior model relied on GitHub-native release pages and tag references. A backfill scan found that historical releases were either lightweight tags or unsigned annotated tag objects. GitHub's release UI can show @@ -28,7 +28,7 @@ The new model treats tags as release pointers and makes a Sigstore-signed must include the attestation, cosign bundle, artifact checksums, evidence bundle hashes, and an exact per-repo/per-tag verification command. -This model shift was driven by the Townlight synthetic-phase adversarial audit +This model shift was driven by the CivicSuite synthetic-phase adversarial audit contract. The external auditor flagged that the release-page "Verified" signal was misleading for release provenance, the development team built a fixture-driven gate, the gate surfaced an organization-wide historical baseline @@ -40,8 +40,8 @@ rewriting release history. The 2026-05-05 policy promotion is anchored to the following evidence: - The live `v0.22.1` release attestation URL listed above. -- Townlight Core's Tier 1 retrofit ledger: - [`docs/ops/townlight_core-tier1-retrofit-ledger.md`](townlight_core-tier1-retrofit-ledger.md) +- CivicCore's Tier 1 retrofit ledger: + [`docs/ops/civiccore-tier1-retrofit-ledger.md`](civiccore-tier1-retrofit-ledger.md) - The cross-module retrofit closeout report: [`docs/ops/co-4-cross-module-retrofit-report.md`](co-4-cross-module-retrofit-report.md) - Release verification command and result: `bash scripts/verify-release.sh`, @@ -54,7 +54,7 @@ The 2026-05-05 policy promotion is anchored to the following evidence: - Historical releases before 2026-05-05 were produced under a weaker GitHub-native provenance model. -- The backfill scan covered Townlight release tags across the organization as +- The backfill scan covered CivicSuite release tags across the organization as of 2026-05-04 and found 119 historical releases failing the strengthened gate: 83 lightweight tags and 36 unsigned annotated tag objects. - Those releases are not retroactively deleted or rewritten. @@ -81,12 +81,12 @@ Worked example for the first attested Townlight Core baseline release: ```bash cosign verify-blob release-attestation.json \ --bundle release-attestation.json.bundle \ - --certificate-identity "https://github.com/Townlight/townlight_core/.github/workflows/release.yml@refs/tags/v0.22.1" \ + --certificate-identity "https://github.com/CivicSuite/civiccore/.github/workflows/release.yml@refs/tags/v0.22.1" \ --certificate-oidc-issuer https://token.actions.githubusercontent.com sha256sum -c SHA256SUMS.txt python scripts/verify-release-provenance.py v0.22.1 \ - --repo Townlight/townlight_core \ + --repo CivicSuite/civiccore \ --attestation release-attestation.json \ --bundle release-attestation.json.bundle \ --artifacts-dir . @@ -95,15 +95,15 @@ python scripts/verify-release-provenance.py v0.22.1 \ ## Canonical Sources - Live attested baseline release: - [`v0.22.1`](https://github.com/Townlight/townlight_core/releases/tag/v0.22.1) + [`v0.22.1`](https://github.com/CivicSuite/civiccore/releases/tag/v0.22.1) - Gate implementation: - [`townlight_core/release_provenance.py`](../../townlight_core/release_provenance.py) + [`civiccore/release_provenance.py`](../../civiccore/release_provenance.py) - Thin CLI wrapper: [`scripts/verify-release-provenance.py`](../../scripts/verify-release-provenance.py) - Versioned attestation schema: [`docs/ops/release-attestation.schema.json`](release-attestation.schema.json) - Townlight Core Tier 1 retrofit ledger: - [`docs/ops/townlight_core-tier1-retrofit-ledger.md`](townlight_core-tier1-retrofit-ledger.md) + [`docs/ops/civiccore-tier1-retrofit-ledger.md`](civiccore-tier1-retrofit-ledger.md) - CO-4 cross-module retrofit report: [`docs/ops/co-4-cross-module-retrofit-report.md`](co-4-cross-module-retrofit-report.md) - Adversarial fixture suite: diff --git a/docs/ops/release-signing.md b/docs/ops/release-signing.md index a40fd20..f49bced 100644 --- a/docs/ops/release-signing.md +++ b/docs/ops/release-signing.md @@ -162,7 +162,7 @@ FAIL: Live release verification requires --attestation and --bundle under the Si This release is ledgered as pre-gate, no attestation, do not promote as baseline in -[`docs/ops/townlight_core-tier1-retrofit-ledger.md`](townlight_core-tier1-retrofit-ledger.md). +[`docs/ops/civiccore-tier1-retrofit-ledger.md`](civiccore-tier1-retrofit-ledger.md). Do not add attestation assets, edit release notes, delete, or recreate it without explicit chat authorization for that specific release. diff --git a/docs/qa/townlight_core-longmont-ingest-proof-2026-05-21.md b/docs/qa/civiccore-longmont-ingest-proof-2026-05-21.md similarity index 74% rename from docs/qa/townlight_core-longmont-ingest-proof-2026-05-21.md rename to docs/qa/civiccore-longmont-ingest-proof-2026-05-21.md index cdafb0a..dca8faa 100644 --- a/docs/qa/townlight_core-longmont-ingest-proof-2026-05-21.md +++ b/docs/qa/civiccore-longmont-ingest-proof-2026-05-21.md @@ -1,8 +1,8 @@ -# Townlight Core Longmont Ingestion Proof - 2026-05-21 +# CivicCore Longmont Ingestion Proof - 2026-05-21 -Purpose: prove the shared Townlight Core ingestion pipeline parses a real municipal PDF, chunks it, embeds every chunk with the local Ollama embedding model, and persists rows into the Townlight Core `documents` and `document_chunks` pgvector schema. +Purpose: prove the shared CivicCore ingestion pipeline parses a real municipal PDF, chunks it, embeds every chunk with the local Ollama embedding model, and persists rows into the CivicCore `documents` and `document_chunks` pgvector schema. -Command class: local proof script using `testcontainers.postgres.PostgresContainer("pgvector/pgvector:pg17")`, `townlight_core.migrations.runner.upgrade_to_head()`, and `townlight_core.ingest.ingest_file()`. +Command class: local proof script using `testcontainers.postgres.PostgresContainer("pgvector/pgvector:pg17")`, `civiccore.migrations.runner.upgrade_to_head()`, and `civiccore.ingest.ingest_file()`. Corpus: @@ -37,5 +37,5 @@ Acceptance facts: - Sentence-aware chunk rows persisted: `1789`. - Ollama `nomic-embed-text` vectors persisted: `1789`. - Vector dimensionality: `768`. -- Database schema: Townlight Core baseline migration `documents` / `document_chunks` on pgvector PostgreSQL. +- Database schema: CivicCore baseline migration `documents` / `document_chunks` on pgvector PostgreSQL. diff --git a/docs/release-recovery-status.md b/docs/release-recovery-status.md index 2c35c54..927229d 100644 --- a/docs/release-recovery-status.md +++ b/docs/release-recovery-status.md @@ -1,22 +1,22 @@ -# Townlight Core Release Recovery Status +# CivicCore Release Recovery Status Date: 2026-05-07 -Repo: `Townlight/townlight_core` +Repo: `CivicSuite/civiccore` ## v1.0.1 Recovery Patch `v1.0.1` is the recovery patch for the post-`v1.0` main branch. It includes the audit-finding fix and the provisional-status marking from the recovery range. -Security hardening: Townlight Core auth errors no longer expose diagnostic role, +Security hardening: CivicCore auth errors no longer expose diagnostic role, principal, caller-host, or trusted-proxy CIDR fields. The removed fields are `token_roles`, `principal`, `principal_roles`, `client_host`, and -`trusted_proxy_cidrs`. The affected files are `townlight_core/auth/bearer.py` and -`townlight_core/auth/trusted_headers.py`. Rationale is recorded in -`docs/audits/townlight_core-audit-full-2026-05-07.md`. +`trusted_proxy_cidrs`. The affected files are `civiccore/auth/bearer.py` and +`civiccore/auth/trusted_headers.py`. Rationale is recorded in +`docs/audits/civiccore-audit-full-2026-05-07.md`. Operator note: if your monitoring or downstream tests assert these field names -in Townlight Core auth error responses, update them before bumping the pin. +in CivicCore auth error responses, update them before bumping the pin. ## Current Verdict @@ -33,11 +33,11 @@ remains historical and should point operators to `v1.0.1`. | Security scan | Passing | Tracked-file secret scan found no matches outside ignored evidence/scratch surfaces. | | Docs-source consistency | Passing | Version and release posture are tested from source files. | | Mock-vs-production labeling | Passing for library scope | README and user manual distinguish shipped helpers from placeholders and unshipped platform behaviors. | -| Browser/user-flow QA | Passing | Townlight Core is a library. Playwright checked the docs landing page at desktop and mobile widths, with no console/page errors, visible provisional copy, keyboard focus samples, and no horizontal overflow. | +| Browser/user-flow QA | Passing | CivicCore is a library. Playwright checked the docs landing page at desktop and mobile widths, with no console/page errors, visible provisional copy, keyboard focus samples, and no horizontal overflow. | ## Sign-Off Boundary -Townlight Core is a shared library, not an end-user municipal app. It cannot by -itself prove that a city can run the Townlight product family. Downstream +CivicCore is a shared library, not an end-user municipal app. It cannot by +itself prove that a city can run the CivicSuite product family. Downstream modules must re-earn their own release status with module-specific runtime, UX, integration, security, and documentation gates. diff --git a/scripts/check-tier1-ledger.py b/scripts/check-tier1-ledger.py index fa84b33..45e919e 100644 --- a/scripts/check-tier1-ledger.py +++ b/scripts/check-tier1-ledger.py @@ -44,8 +44,9 @@ def _entry_tags(entries: list[dict[str, Any]]) -> list[str]: def validate_ledger(ledger: dict[str, Any]) -> list[dict[str, Any]]: if ledger.get("schema_version") != 1: raise LedgerError("schema_version must be 1") - if ledger.get("repo") != "Townlight/townlight_core": - raise LedgerError("repo must be Townlight/townlight_core") + # This immutable historical ledger retains its original organization/name. + if ledger.get("repo") != "CivicSuite/civiccore": + raise LedgerError("historical ledger identity does not match its original repository") if ledger.get("baseline_tag") != "v0.22.1": raise LedgerError("baseline_tag must be v0.22.1") @@ -136,9 +137,9 @@ def main(argv: list[str] | None = None) -> int: parser.add_argument( "--ledger", type=Path, - default=Path("docs/ops/townlight_core-tier1-retrofit-ledger.json"), + default=Path("docs/ops/civiccore-tier1-retrofit-ledger.json"), ) - parser.add_argument("--repo", default="Townlight/townlight_core") + parser.add_argument("--repo", default="townlight/core") parser.add_argument( "--live", action="store_true", diff --git a/tests/test_github_workflows.py b/tests/test_github_workflows.py index 067a19b..8921970 100644 --- a/tests/test_github_workflows.py +++ b/tests/test_github_workflows.py @@ -29,7 +29,7 @@ def test_release_workflow_uploads_explicit_downloaded_asset_files() -> None: publish_script = workflow["jobs"]["publish-release"]["steps"][0]["run"] assert release_tag["required"] is True - assert release_tag["default"] == "v1.2.1" + assert release_tag["default"] == "v1.3.0.dev2" assert "v*" in tag_triggers assert "townlight_core-*-freeze" in tag_triggers assert workflow["jobs"]["cleanroom-rehearsal"]["if"] == "github.event_name == 'workflow_dispatch'" @@ -41,8 +41,8 @@ def test_release_workflow_uploads_explicit_downloaded_asset_files() -> None: assert "townlight_core-*-freeze) latest_flag=(--latest=false)" in create_release_script assert "Cleanroom rehearsal: PASSED in workflow run ${WORKFLOW_RUN_ID}" in create_release_script assert "Verified clean install of ${WHEEL_URL} from cold caches" in create_release_script - assert "docs/evidence/co8-townlight_core-procurement-evidence-pack/index.md" in create_release_script - assert "docs/ops/co-9-townlight_core-v1-closeout.md" in create_release_script + assert "docs/evidence/co8-civiccore-procurement-evidence-pack/index.md" in create_release_script + assert "docs/ops/co-9-civiccore-v1-closeout.md" in create_release_script assert "python scripts/verify-release-provenance.py ${TAG}" in create_release_script assert '"${latest_flag[@]}" \\' in create_release_script assert "--draft" in create_release_script diff --git a/tests/test_tier1_retrofit_ledger.py b/tests/test_tier1_retrofit_ledger.py index 7365bd2..4fccddc 100644 --- a/tests/test_tier1_retrofit_ledger.py +++ b/tests/test_tier1_retrofit_ledger.py @@ -9,7 +9,7 @@ REPO_ROOT = Path(__file__).resolve().parents[1] -LEDGER = REPO_ROOT / "docs" / "ops" / "townlight_core-tier1-retrofit-ledger.json" +LEDGER = REPO_ROOT / "docs" / "ops" / "civiccore-tier1-retrofit-ledger.json" LEDGER_CHECK = REPO_ROOT / "scripts" / "check-tier1-ledger.py" From fe4006cb3ba25a6f715747b01b6669e5ab3cc42f Mon Sep 17 00:00:00 2001 From: Scott Converse Date: Mon, 2 Nov 2026 21:11:25 -0700 Subject: [PATCH 3/7] Refresh current candidate API and source reference; preserve prior inventory --- docs/beta-1/api/access-openapi.json | 11594 +++++ docs/beta-1/api/access.html | 12073 +++++ docs/beta-1/api/code-openapi.json | 12264 +++++ docs/beta-1/api/code.html | 12739 +++++ docs/beta-1/api/core-openapi.json | 11092 ++++- docs/beta-1/api/core.html | 14657 +++++- docs/beta-1/api/inspections-openapi.json | 11811 +++++ docs/beta-1/api/inspections.html | 12288 +++++ docs/beta-1/api/meetings-openapi.json | 12880 ++++++ docs/beta-1/api/meetings.html | 13338 ++++++ docs/beta-1/api/notice-openapi.json | 11619 +++++ docs/beta-1/api/notice.html | 12100 +++++ docs/beta-1/api/permitting-openapi.json | 11763 +++++ docs/beta-1/api/permitting.html | 12243 +++++ docs/beta-1/api/planning-openapi.json | 12613 +++++ docs/beta-1/api/planning.html | 13078 ++++++ docs/beta-1/api/records-openapi.json | 19234 ++++++++ docs/beta-1/api/records.html | 19623 ++++++++ docs/beta-1/api/station-openapi.json | 11180 +++++ docs/beta-1/api/station.html | 11667 +++++ docs/beta-1/api/suite-openapi.json | 27254 +++++++++++ docs/beta-1/api/suite.html | 27524 +++++++++++ docs/beta-1/api/zoning-openapi.json | 11822 +++++ docs/beta-1/api/zoning.html | 12297 +++++ docs/beta-1/reference/index.html | 99 +- docs/beta-1/reference/source-inventory.json | 38449 +++++++--------- .../pre-naming-2026-11/source-inventory.json | 38440 +++++++++++++++ 27 files changed, 392407 insertions(+), 23334 deletions(-) create mode 100644 docs/beta-1/api/access-openapi.json create mode 100644 docs/beta-1/api/access.html create mode 100644 docs/beta-1/api/code-openapi.json create mode 100644 docs/beta-1/api/code.html create mode 100644 docs/beta-1/api/inspections-openapi.json create mode 100644 docs/beta-1/api/inspections.html create mode 100644 docs/beta-1/api/meetings-openapi.json create mode 100644 docs/beta-1/api/meetings.html create mode 100644 docs/beta-1/api/notice-openapi.json create mode 100644 docs/beta-1/api/notice.html create mode 100644 docs/beta-1/api/permitting-openapi.json create mode 100644 docs/beta-1/api/permitting.html create mode 100644 docs/beta-1/api/planning-openapi.json create mode 100644 docs/beta-1/api/planning.html create mode 100644 docs/beta-1/api/records-openapi.json create mode 100644 docs/beta-1/api/records.html create mode 100644 docs/beta-1/api/station-openapi.json create mode 100644 docs/beta-1/api/station.html create mode 100644 docs/beta-1/api/suite-openapi.json create mode 100644 docs/beta-1/api/suite.html create mode 100644 docs/beta-1/api/zoning-openapi.json create mode 100644 docs/beta-1/api/zoning.html create mode 100644 docs/history/pre-naming-2026-11/source-inventory.json diff --git a/docs/beta-1/api/access-openapi.json b/docs/beta-1/api/access-openapi.json new file mode 100644 index 0000000..a365256 --- /dev/null +++ b/docs/beta-1/api/access-openapi.json @@ -0,0 +1,11594 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "Townlight Records", + "description": "Prepared source schema for the actual native composition; installed acceptance remains pending. Exported without lifespan, migrations or database/network access.", + "version": "1.8.0.dev2" + }, + "paths": { + "/desktop/v1/access/state": { + "get": { + "tags": [ + "native-access" + ], + "summary": "Access State", + "operationId": "access_state_desktop_v1_access_state_get", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/access/review-context": { + "post": { + "tags": [ + "native-access" + ], + "summary": "Review Context", + "operationId": "review_context_desktop_v1_access_review_context_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReviewInput" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/access/reviews": { + "post": { + "tags": [ + "native-access" + ], + "summary": "Save Review", + "operationId": "save_review_desktop_v1_access_reviews_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SaveReview" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/access/reviews/{review_id}/delete": { + "post": { + "tags": [ + "native-access" + ], + "summary": "Delete Review", + "operationId": "delete_review_desktop_v1_access_reviews__review_id__delete_post", + "parameters": [ + { + "name": "review_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Review Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/access/tools": { + "post": { + "tags": [ + "native-access" + ], + "summary": "Tool", + "operationId": "tool_desktop_v1_access_tools_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "oneOf": [ + { + "$ref": "#/components/schemas/FormPlan" + }, + { + "$ref": "#/components/schemas/PublishingPlan" + }, + { + "$ref": "#/components/schemas/AdaPlan" + }, + { + "$ref": "#/components/schemas/TaggedPlan" + } + ], + "discriminator": { + "propertyName": "action", + "mapping": { + "form-plan": "#/components/schemas/FormPlan", + "publishing-workflow": "#/components/schemas/PublishingPlan", + "ada-title-ii": "#/components/schemas/AdaPlan", + "tagged-pdf": "#/components/schemas/TaggedPlan" + } + }, + "title": "Data" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/access/rewrite-context": { + "post": { + "tags": [ + "native-access" + ], + "summary": "Rewrite Context", + "operationId": "rewrite_context_desktop_v1_access_rewrite_context_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RewriteInput" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/access/rewrite-result": { + "post": { + "tags": [ + "native-access" + ], + "summary": "Rewrite Result", + "operationId": "rewrite_result_desktop_v1_access_rewrite_result_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RewriteResult" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/access/reviews/{review_id}/export": { + "post": { + "tags": [ + "native-access" + ], + "summary": "Prepare Export", + "operationId": "prepare_export_desktop_v1_access_reviews__review_id__export_post", + "parameters": [ + { + "name": "review_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Review Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/access/drafts/{draft_id}/export": { + "post": { + "tags": [ + "native-access" + ], + "summary": "Export Draft", + "operationId": "export_draft_desktop_v1_access_drafts__draft_id__export_post", + "parameters": [ + { + "name": "draft_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Draft Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/access/exports/{artifact_id}/complete": { + "post": { + "tags": [ + "native-access" + ], + "summary": "Complete Export", + "operationId": "complete_export_desktop_v1_access_exports__artifact_id__complete_post", + "parameters": [ + { + "name": "artifact_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Artifact Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExportReceipt" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "ActionItemInput": { + "properties": { + "description": { + "type": "string", + "minLength": 1, + "title": "Description" + }, + "assigned_to": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "source_motion_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Source Motion Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "description" + ], + "title": "ActionItemInput" + }, + "AdaPlan": { + "properties": { + "action": { + "type": "string", + "const": "ada-title-ii", + "title": "Action" + }, + "serviceArea": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Servicearea" + }, + "hasCoordinatorReview": { + "type": "boolean", + "title": "Hascoordinatorreview", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "serviceArea" + ], + "title": "AdaPlan" + }, + "AdminUserCreateRequest": { + "properties": { + "email": { + "type": "string", + "title": "Email" + }, + "password": { + "type": "string", + "title": "Password" + }, + "full_name": { + "type": "string", + "title": "Full Name", + "default": "" + }, + "role": { + "type": "string", + "title": "Role", + "default": "staff" + } + }, + "type": "object", + "required": [ + "email", + "password" + ], + "title": "AdminUserCreateRequest" + }, + "AdminUserCreateResponse": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "email": { + "type": "string", + "title": "Email" + }, + "full_name": { + "type": "string", + "title": "Full Name" + }, + "role": { + "type": "string", + "title": "Role" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + } + }, + "type": "object", + "required": [ + "id", + "email", + "full_name", + "role", + "is_active" + ], + "title": "AdminUserCreateResponse" + }, + "AgendaAssignment": { + "properties": { + "meeting_id": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "meeting_id" + ], + "title": "AgendaAssignment" + }, + "AgendaInput": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "department_name": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Department Name" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "department_name" + ], + "title": "AgendaInput" + }, + "AgendaReviewInput": { + "properties": { + "to_status": { + "type": "string", + "enum": [ + "DRAFTED", + "SUBMITTED", + "DEPT_APPROVED", + "LEGAL_REVIEWED", + "CLERK_ACCEPTED", + "ON_AGENDA", + "IN_PACKET", + "POSTED", + "HEARD", + "DISPOSED", + "ARCHIVED" + ], + "title": "To Status" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "to_status" + ], + "title": "AgendaReviewInput" + }, + "AmendmentInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "policy": { + "$ref": "#/components/schemas/PolicySelection" + }, + "proposal": { + "type": "string", + "maxLength": 20000, + "minLength": 1, + "title": "Proposal" + }, + "responsible_staff": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Responsible Staff" + }, + "status": { + "type": "string", + "enum": [ + "draft", + "review", + "adopted", + "withdrawn" + ], + "title": "Status", + "default": "draft" + }, + "review_note": { + "type": "string", + "maxLength": 5000, + "title": "Review Note", + "default": "" + }, + "adoption_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Adoption Revision" + }, + "note": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "policy", + "proposal", + "responsible_staff", + "note" + ], + "title": "AmendmentInput" + }, + "AnalysisObservation": { + "properties": { + "source": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "title": "Source" + }, + "filename": { + "type": "string", + "maxLength": 160, + "title": "Filename", + "default": "" + }, + "media_type": { + "type": "string", + "maxLength": 80, + "title": "Media Type", + "default": "" + }, + "text": { + "type": "string", + "maxLength": 4000, + "minLength": 1, + "title": "Text" + }, + "adapter": { + "type": "string", + "maxLength": 120, + "title": "Adapter", + "default": "" + }, + "citation_source_ids": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 30, + "title": "Citation Source Ids" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source", + "text" + ], + "title": "AnalysisObservation", + "description": "One draft observation, named with the adapter that actually produced it." + }, + "AnalysisRecord": { + "properties": { + "observations": { + "items": { + "$ref": "#/components/schemas/AnalysisObservation" + }, + "type": "array", + "maxItems": 30, + "title": "Observations" + }, + "cited_sections": { + "items": { + "$ref": "#/components/schemas/CitedSection" + }, + "type": "array", + "maxItems": 30, + "title": "Cited Sections" + }, + "unavailable": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 30, + "title": "Unavailable" + }, + "runtime": { + "additionalProperties": true, + "type": "object", + "title": "Runtime" + }, + "review_required": { + "type": "boolean", + "title": "Review Required", + "default": true + } + }, + "additionalProperties": false, + "type": "object", + "title": "AnalysisRecord", + "description": "The adapter output that accompanies a saved inspection draft." + }, + "ApprovalCommand": { + "properties": { + "action": { + "type": "string", + "const": "approve-records-response", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ApprovalPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "ApprovalCommand" + }, + "ApprovalPayload": { + "properties": { + "approvalNote": { + "type": "string", + "title": "Approvalnote", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "title": "ApprovalPayload" + }, + "ArchiveInput": { + "properties": { + "visibility": { + "type": "string", + "enum": [ + "public", + "closed_session" + ], + "title": "Visibility" + }, + "packet_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Packet Id" + }, + "minutes_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Minutes Id" + }, + "plain_language_summary": { + "type": "string", + "title": "Plain Language Summary", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "visibility" + ], + "title": "ArchiveInput" + }, + "ArtifactPlan": { + "properties": { + "artifact_id": { + "type": "string", + "title": "Artifact Id" + }, + "file_name": { + "type": "string", + "title": "File Name" + }, + "content": { + "type": "string", + "title": "Content" + }, + "sha256": { + "type": "string", + "title": "Sha256" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "artifact_id", + "file_name", + "content", + "sha256", + "created_at_unix_seconds" + ], + "title": "ArtifactPlan" + }, + "AssignCommand": { + "properties": { + "action": { + "type": "string", + "const": "assign-records-request", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/AssignmentPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "AssignCommand" + }, + "AssignmentPayload": { + "properties": { + "assignedTo": { + "type": "string", + "minLength": 1, + "title": "Assignedto" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "assignedTo" + ], + "title": "AssignmentPayload" + }, + "AttachDocument": { + "properties": { + "title": { + "type": "string", + "minLength": 1, + "title": "Title" + }, + "citation": { + "type": "string", + "title": "Citation", + "default": "" + }, + "file": { + "$ref": "#/components/schemas/ManagedFileReceipt" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "file" + ], + "title": "AttachDocument" + }, + "AttachReleaseCopy": { + "properties": { + "status": { + "type": "string", + "enum": [ + "release-ready copy", + "redacted copy" + ], + "title": "Status" + }, + "note": { + "type": "string", + "title": "Note", + "default": "" + }, + "added_by": { + "type": "string", + "title": "Added By", + "default": "" + }, + "file": { + "$ref": "#/components/schemas/ManagedFileReceipt" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "status", + "file" + ], + "title": "AttachReleaseCopy" + }, + "AuditChainVerification": { + "properties": { + "is_valid": { + "type": "boolean", + "title": "Is Valid" + }, + "entries_checked": { + "type": "integer", + "title": "Entries Checked" + }, + "error_message": { + "type": "string", + "title": "Error Message" + } + }, + "type": "object", + "required": [ + "is_valid", + "entries_checked", + "error_message" + ], + "title": "AuditChainVerification" + }, + "AuditLogRead": { + "properties": { + "id": { + "type": "integer", + "title": "Id" + }, + "prev_hash": { + "type": "string", + "title": "Prev Hash" + }, + "entry_hash": { + "type": "string", + "title": "Entry Hash" + }, + "timestamp": { + "type": "string", + "format": "date-time", + "title": "Timestamp" + }, + "user_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "User Id" + }, + "action": { + "type": "string", + "title": "Action" + }, + "resource_type": { + "type": "string", + "title": "Resource Type" + }, + "resource_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Resource Id" + }, + "details": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Details" + }, + "ai_generated": { + "type": "boolean", + "title": "Ai Generated" + } + }, + "type": "object", + "required": [ + "id", + "prev_hash", + "entry_hash", + "timestamp", + "user_id", + "action", + "resource_type", + "resource_id", + "details", + "ai_generated" + ], + "title": "AuditLogRead" + }, + "AuditView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "module_id": { + "type": "string", + "title": "Module Id" + }, + "action": { + "type": "string", + "title": "Action" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + }, + "previous_hash": { + "type": "string", + "title": "Previous Hash" + }, + "entry_hash": { + "type": "string", + "title": "Entry Hash" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "module_id", + "action", + "summary", + "created_at_unix_seconds", + "previous_hash", + "entry_hash" + ], + "title": "AuditView" + }, + "BearerResponse": { + "properties": { + "access_token": { + "type": "string", + "title": "Access Token" + }, + "token_type": { + "type": "string", + "title": "Token Type" + } + }, + "type": "object", + "required": [ + "access_token", + "token_type" + ], + "title": "BearerResponse" + }, + "Body_auth_jwt_login_auth_jwt_login_post": { + "properties": { + "grant_type": { + "anyOf": [ + { + "type": "string", + "pattern": "^password$" + }, + { + "type": "null" + } + ], + "title": "Grant Type" + }, + "username": { + "type": "string", + "title": "Username" + }, + "password": { + "type": "string", + "format": "password", + "title": "Password" + }, + "scope": { + "type": "string", + "title": "Scope", + "default": "" + }, + "client_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Client Id" + }, + "client_secret": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "format": "password", + "title": "Client Secret" + } + }, + "type": "object", + "required": [ + "username", + "password" + ], + "title": "Body_auth_jwt_login_auth_jwt_login_post" + }, + "Body_upload_file_datasources_upload_post": { + "properties": { + "file": { + "type": "string", + "contentMediaType": "application/octet-stream", + "title": "File" + } + }, + "type": "object", + "required": [ + "file" + ], + "title": "Body_upload_file_datasources_upload_post" + }, + "CalculateDeadlineCommand": { + "properties": { + "action": { + "type": "string", + "const": "calculate-records-deadline", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/CalculateDeadlinePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "CalculateDeadlineCommand" + }, + "CalculateDeadlinePayload": { + "properties": { + "deadlineReceivedDate": { + "type": "string", + "title": "Deadlinereceiveddate" + }, + "deadlineRuleName": { + "type": "string", + "minLength": 1, + "title": "Deadlinerulename" + }, + "deadlineDayCount": { + "type": "string", + "title": "Deadlinedaycount" + }, + "deadlineDayType": { + "type": "string", + "title": "Deadlinedaytype" + }, + "deadlineBasis": { + "type": "string", + "minLength": 1, + "title": "Deadlinebasis" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "deadlineReceivedDate", + "deadlineRuleName", + "deadlineDayCount", + "deadlineDayType", + "deadlineBasis" + ], + "title": "CalculateDeadlinePayload" + }, + "ChapterCreate": { + "properties": { + "chapter_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Chapter Id" + }, + "title_id": { + "type": "string", + "minLength": 1, + "title": "Title Id" + }, + "chapter_number": { + "type": "string", + "minLength": 1, + "title": "Chapter Number" + }, + "chapter_name": { + "type": "string", + "minLength": 1, + "title": "Chapter Name" + }, + "sort_order": { + "type": "integer", + "title": "Sort Order", + "default": 0 + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title_id", + "chapter_number", + "chapter_name" + ], + "title": "ChapterCreate", + "description": "Request body for creating a code chapter." + }, + "CitedSection": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "citation": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Citation" + }, + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "version": { + "type": "string", + "maxLength": 80, + "title": "Version", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "citation" + ], + "title": "CitedSection", + "description": "One resolved public Code section; never a caller-supplied quotation." + }, + "CityProfileCreate": { + "properties": { + "city_name": { + "type": "string", + "title": "City Name" + }, + "state": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State" + }, + "county": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "County" + }, + "population_band": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Population Band" + }, + "email_platform": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Email Platform" + }, + "has_dedicated_it": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Has Dedicated It" + }, + "monthly_request_volume": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Monthly Request Volume" + }, + "profile_data": { + "additionalProperties": true, + "type": "object", + "title": "Profile Data", + "default": {} + }, + "gap_map": { + "additionalProperties": true, + "type": "object", + "title": "Gap Map", + "default": {} + } + }, + "type": "object", + "required": [ + "city_name" + ], + "title": "CityProfileCreate" + }, + "CityProfileRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "city_name": { + "type": "string", + "title": "City Name" + }, + "state": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State" + }, + "county": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "County" + }, + "population_band": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Population Band" + }, + "email_platform": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Email Platform" + }, + "has_dedicated_it": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Has Dedicated It" + }, + "monthly_request_volume": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Monthly Request Volume" + }, + "onboarding_status": { + "type": "string", + "title": "Onboarding Status" + }, + "profile_data": { + "additionalProperties": true, + "type": "object", + "title": "Profile Data" + }, + "gap_map": { + "additionalProperties": true, + "type": "object", + "title": "Gap Map" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "city_name", + "state", + "county", + "population_band", + "email_platform", + "has_dedicated_it", + "monthly_request_volume", + "onboarding_status", + "profile_data", + "gap_map", + "created_at", + "updated_at" + ], + "title": "CityProfileRead" + }, + "CityProfileUpdate": { + "properties": { + "city_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "City Name" + }, + "state": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State" + }, + "county": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "County" + }, + "population_band": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Population Band" + }, + "email_platform": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Email Platform" + }, + "has_dedicated_it": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Has Dedicated It" + }, + "monthly_request_volume": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Monthly Request Volume" + }, + "onboarding_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Onboarding Status" + }, + "profile_data": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Profile Data" + }, + "gap_map": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Gap Map" + } + }, + "type": "object", + "title": "CityProfileUpdate" + }, + "ClarificationCommand": { + "properties": { + "action": { + "type": "string", + "const": "request-records-clarification", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ClarificationPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "ClarificationCommand" + }, + "ClarificationPayload": { + "properties": { + "clarificationNote": { + "type": "string", + "minLength": 1, + "title": "Clarificationnote" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "clarificationNote" + ], + "title": "ClarificationPayload" + }, + "Closeout": { + "properties": { + "decision_id": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Decision Id" + }, + "version_id": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Version Id" + }, + "source_id": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Source Id" + }, + "version_label": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Version Label" + }, + "body": { + "type": "string", + "maxLength": 1000000, + "minLength": 1, + "title": "Body" + }, + "effective_start": { + "type": "string", + "format": "date", + "title": "Effective Start" + }, + "effective_end": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective End" + }, + "is_current": { + "type": "boolean", + "title": "Is Current" + }, + "reconciliation_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reconciliation Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "decision_id", + "version_id", + "source_id", + "version_label", + "body", + "effective_start", + "is_current" + ], + "title": "Closeout" + }, + "CodeContext": { + "properties": { + "section_number": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Section Number" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "section_number" + ], + "title": "CodeContext" + }, + "CodeLink": { + "properties": { + "provider": { + "type": "string", + "const": "code", + "title": "Provider", + "default": "code" + }, + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "CodeLink" + }, + "CodeSearch": { + "properties": { + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "CodeSearch" + }, + "CodeSourceSelection": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "CodeSourceSelection" + }, + "CompleteArtifact": { + "properties": { + "export_path": { + "type": "string", + "minLength": 1, + "title": "Export Path" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "export_path" + ], + "title": "CompleteArtifact" + }, + "ConnectionSearch": { + "properties": { + "provider": { + "type": "string", + "enum": [ + "meetings", + "zoning" + ], + "title": "Provider" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "query" + ], + "title": "ConnectionSearch" + }, + "CoverageGapResponse": { + "properties": { + "jurisdictions_without_rules": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Jurisdictions Without Rules" + }, + "departments_without_staff": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array", + "title": "Departments Without Staff" + }, + "uncovered_categories": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Uncovered Categories" + }, + "total_gaps": { + "type": "integer", + "title": "Total Gaps" + } + }, + "type": "object", + "required": [ + "jurisdictions_without_rules", + "departments_without_staff", + "uncovered_categories", + "total_gaps" + ], + "title": "CoverageGapResponse" + }, + "DataSourceAdminRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "source_type": { + "$ref": "#/components/schemas/SourceType" + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "type": "boolean", + "title": "Schedule Enabled", + "default": true + }, + "next_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Next Sync At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "last_ingestion_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Ingestion At" + }, + "last_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Sync At" + }, + "last_sync_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Sync Status" + }, + "last_error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Error Message" + }, + "consecutive_failure_count": { + "type": "integer", + "title": "Consecutive Failure Count", + "default": 0 + }, + "sync_paused": { + "type": "boolean", + "title": "Sync Paused", + "default": false + }, + "health_status": { + "type": "string", + "title": "Health Status", + "default": "healthy" + }, + "active_failure_count": { + "type": "integer", + "title": "Active Failure Count", + "default": 0 + }, + "connector_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Connector Type" + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At" + }, + "connection_config": { + "additionalProperties": true, + "type": "object", + "title": "Connection Config" + } + }, + "type": "object", + "required": [ + "id", + "name", + "source_type", + "is_active", + "created_by", + "created_at", + "last_ingestion_at", + "connection_config" + ], + "title": "DataSourceAdminRead", + "description": "Full datasource shape including connection_config. Returned only by admin-gated endpoints." + }, + "DataSourceCreate": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "source_type": { + "$ref": "#/components/schemas/SourceType" + }, + "connection_config": { + "additionalProperties": true, + "type": "object", + "title": "Connection Config", + "default": {} + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "type": "boolean", + "title": "Schedule Enabled", + "default": true + } + }, + "type": "object", + "required": [ + "name", + "source_type" + ], + "title": "DataSourceCreate" + }, + "DataSourceRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "source_type": { + "$ref": "#/components/schemas/SourceType" + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "type": "boolean", + "title": "Schedule Enabled", + "default": true + }, + "next_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Next Sync At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "last_ingestion_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Ingestion At" + }, + "last_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Sync At" + }, + "last_sync_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Sync Status" + }, + "last_error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Error Message" + }, + "consecutive_failure_count": { + "type": "integer", + "title": "Consecutive Failure Count", + "default": 0 + }, + "sync_paused": { + "type": "boolean", + "title": "Sync Paused", + "default": false + }, + "health_status": { + "type": "string", + "title": "Health Status", + "default": "healthy" + }, + "active_failure_count": { + "type": "integer", + "title": "Active Failure Count", + "default": 0 + }, + "connector_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Connector Type" + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "name", + "source_type", + "is_active", + "created_by", + "created_at", + "last_ingestion_at" + ], + "title": "DataSourceRead", + "description": "Redacted datasource shape — safe for non-admin roles. connection_config omitted." + }, + "DataSourceUpdate": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "connection_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Connection Config" + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Schedule Enabled" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "DataSourceUpdate" + }, + "DeadlineCommand": { + "properties": { + "action": { + "type": "string", + "const": "set-records-deadline", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/DeadlinePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "DeadlineCommand" + }, + "DeadlinePayload": { + "properties": { + "deadline": { + "type": "string", + "title": "Deadline" + }, + "deadlineBasis": { + "type": "string", + "minLength": 1, + "title": "Deadlinebasis" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "deadline", + "deadlineBasis" + ], + "title": "DeadlinePayload" + }, + "Decision": { + "properties": { + "id": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Id" + }, + "outcome": { + "type": "string", + "enum": [ + "adopted", + "not_adopted", + "deferred", + "withdrawn" + ], + "title": "Outcome" + }, + "decided_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Decided At" + }, + "decision_text": { + "type": "string", + "maxLength": 1000000, + "minLength": 1, + "title": "Decision Text" + }, + "supporting_references": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Supporting References" + }, + "supersedes_decision_id": { + "anyOf": [ + { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$" + }, + { + "type": "null" + } + ], + "title": "Supersedes Decision Id" + }, + "reconciliation_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reconciliation Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "outcome", + "decision_text" + ], + "title": "Decision" + }, + "DepartmentCreate": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "code": { + "type": "string", + "title": "Code" + }, + "contact_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Contact Email" + } + }, + "type": "object", + "required": [ + "name", + "code" + ], + "title": "DepartmentCreate" + }, + "DepartmentRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "code": { + "type": "string", + "title": "Code" + }, + "contact_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Contact Email" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "name", + "code", + "contact_email", + "created_at" + ], + "title": "DepartmentRead" + }, + "DepartmentUpdate": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Code" + }, + "contact_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Contact Email" + } + }, + "type": "object", + "title": "DepartmentUpdate" + }, + "DisclosureTemplateCreate": { + "properties": { + "template_type": { + "type": "string", + "title": "Template Type" + }, + "state_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State Code" + }, + "content": { + "type": "string", + "title": "Content" + } + }, + "type": "object", + "required": [ + "template_type", + "content" + ], + "title": "DisclosureTemplateCreate" + }, + "DisclosureTemplateRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "template_type": { + "type": "string", + "title": "Template Type" + }, + "state_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State Code" + }, + "content": { + "type": "string", + "title": "Content" + }, + "version": { + "type": "integer", + "title": "Version" + }, + "updated_by": { + "type": "string", + "format": "uuid", + "title": "Updated By" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "template_type", + "state_code", + "content", + "version", + "updated_by", + "updated_at" + ], + "title": "DisclosureTemplateRead" + }, + "DisclosureTemplateRendered": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "template_type": { + "type": "string", + "title": "Template Type" + }, + "rendered_content": { + "type": "string", + "title": "Rendered Content" + }, + "has_unresolved_variables": { + "type": "boolean", + "title": "Has Unresolved Variables" + } + }, + "type": "object", + "required": [ + "id", + "template_type", + "rendered_content", + "has_unresolved_variables" + ], + "title": "DisclosureTemplateRendered" + }, + "DisclosureTemplateUpdate": { + "properties": { + "content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Content" + }, + "state_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State Code" + } + }, + "type": "object", + "title": "DisclosureTemplateUpdate" + }, + "DocumentChunkRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "chunk_index": { + "type": "integer", + "title": "Chunk Index" + }, + "content_text": { + "type": "string", + "title": "Content Text" + }, + "token_count": { + "type": "integer", + "title": "Token Count" + }, + "page_number": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Page Number" + } + }, + "type": "object", + "required": [ + "id", + "document_id", + "chunk_index", + "content_text", + "token_count", + "page_number" + ], + "title": "DocumentChunkRead" + }, + "DocumentRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "source_id": { + "type": "string", + "format": "uuid", + "title": "Source Id" + }, + "source_path": { + "type": "string", + "title": "Source Path" + }, + "filename": { + "type": "string", + "title": "Filename" + }, + "file_type": { + "type": "string", + "title": "File Type" + }, + "file_hash": { + "type": "string", + "title": "File Hash" + }, + "file_size": { + "type": "integer", + "title": "File Size" + }, + "ingestion_status": { + "$ref": "#/components/schemas/IngestionStatus" + }, + "ingestion_error": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Ingestion Error" + }, + "chunk_count": { + "type": "integer", + "title": "Chunk Count" + }, + "ingested_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Ingested At" + }, + "connector_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Connector Type" + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "source_id", + "source_path", + "filename", + "file_type", + "file_hash", + "file_size", + "ingestion_status", + "ingestion_error", + "chunk_count", + "ingested_at" + ], + "title": "DocumentRead" + }, + "DraftCommand": { + "properties": { + "action": { + "type": "string", + "const": "draft-records-response", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/DraftPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "DraftCommand" + }, + "DraftInput": { + "properties": { + "source_materials": { + "items": { + "$ref": "#/components/schemas/SourceInput" + }, + "type": "array", + "title": "Source Materials" + }, + "sentences": { + "items": { + "$ref": "#/components/schemas/SentenceInput" + }, + "type": "array", + "minItems": 1, + "title": "Sentences" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sentences" + ], + "title": "DraftInput" + }, + "DraftPayload": { + "properties": { + "responseDraft": { + "type": "string", + "minLength": 1, + "title": "Responsedraft" + }, + "citation": { + "type": "string", + "title": "Citation", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "responseDraft" + ], + "title": "DraftPayload" + }, + "ErrorModel": { + "properties": { + "detail": { + "anyOf": [ + { + "type": "string" + }, + { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + ], + "title": "Detail" + } + }, + "type": "object", + "required": [ + "detail" + ], + "title": "ErrorModel" + }, + "Evidence": { + "properties": { + "filename": { + "type": "string", + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$", + "title": "Filename" + }, + "description": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Description" + }, + "media_type": { + "type": "string", + "enum": [ + "text/plain", + "image/jpeg", + "image/png", + "image/webp", + "application/pdf", + "audio/webm", + "audio/ogg", + "audio/wav", + "audio/mpeg", + "audio/mp4" + ], + "title": "Media Type" + }, + "content_base64": { + "type": "string", + "maxLength": 14000000, + "minLength": 1, + "title": "Content Base64" + }, + "sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "filename", + "description", + "media_type", + "content_base64", + "sha256" + ], + "title": "Evidence" + }, + "EvidenceItem": { + "properties": { + "filename": { + "type": "string", + "maxLength": 151, + "minLength": 1, + "title": "Filename" + }, + "media_type": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Media Type" + }, + "description": { + "type": "string", + "maxLength": 2000, + "title": "Description", + "default": "" + }, + "content_base64": { + "type": "string", + "maxLength": 14000000, + "minLength": 1, + "title": "Content Base64" + }, + "sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "filename", + "media_type", + "content_base64", + "sha256" + ], + "title": "EvidenceItem" + }, + "EvidenceItems": { + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/EvidenceItem" + }, + "type": "array", + "maxItems": 10, + "minItems": 1, + "title": "Items" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "items" + ], + "title": "EvidenceItems" + }, + "ExemptionAccuracyReport": { + "properties": { + "category": { + "type": "string", + "title": "Category" + }, + "total_flags": { + "type": "integer", + "title": "Total Flags" + }, + "accepted": { + "type": "integer", + "title": "Accepted" + }, + "rejected": { + "type": "integer", + "title": "Rejected" + }, + "pending": { + "type": "integer", + "title": "Pending" + }, + "acceptance_rate": { + "type": "number", + "title": "Acceptance Rate" + } + }, + "type": "object", + "required": [ + "category", + "total_flags", + "accepted", + "rejected", + "pending", + "acceptance_rate" + ], + "title": "ExemptionAccuracyReport" + }, + "ExemptionDashboard": { + "properties": { + "total_flags": { + "type": "integer", + "title": "Total Flags" + }, + "by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "By Status" + }, + "by_category": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "By Category" + }, + "acceptance_rate": { + "type": "number", + "title": "Acceptance Rate" + }, + "total_rules": { + "type": "integer", + "title": "Total Rules" + }, + "active_rules": { + "type": "integer", + "title": "Active Rules" + } + }, + "type": "object", + "required": [ + "total_flags", + "by_status", + "by_category", + "acceptance_rate", + "total_rules", + "active_rules" + ], + "title": "ExemptionDashboard" + }, + "ExemptionDecisionCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-exemption-decision", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ExemptionDecisionPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "ExemptionDecisionCommand" + }, + "ExemptionDecisionPayload": { + "properties": { + "exemptionSource": { + "type": "string", + "minLength": 1, + "title": "Exemptionsource" + }, + "exemptionKind": { + "type": "string", + "minLength": 1, + "title": "Exemptionkind" + }, + "exemptionFinding": { + "type": "string", + "minLength": 1, + "title": "Exemptionfinding" + }, + "exemptionDecision": { + "type": "string", + "enum": [ + "release", + "redact", + "exempt" + ], + "title": "Exemptiondecision" + }, + "exemptionBasis": { + "type": "string", + "minLength": 1, + "title": "Exemptionbasis" + }, + "exemptionReviewer": { + "type": "string", + "title": "Exemptionreviewer", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "exemptionSource", + "exemptionKind", + "exemptionFinding", + "exemptionDecision", + "exemptionBasis" + ], + "title": "ExemptionDecisionPayload" + }, + "ExemptionDecisionView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "source": { + "type": "string", + "title": "Source" + }, + "kind": { + "type": "string", + "title": "Kind" + }, + "finding": { + "type": "string", + "title": "Finding" + }, + "decision": { + "type": "string", + "enum": [ + "release", + "redact", + "exempt" + ], + "title": "Decision" + }, + "basis": { + "type": "string", + "title": "Basis" + }, + "reviewer": { + "type": "string", + "title": "Reviewer" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "source", + "kind", + "finding", + "decision", + "basis", + "reviewer", + "created_at_unix_seconds" + ], + "title": "ExemptionDecisionView" + }, + "ExemptionFlagRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "chunk_id": { + "type": "string", + "format": "uuid", + "title": "Chunk Id" + }, + "rule_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Rule Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "category": { + "type": "string", + "title": "Category" + }, + "matched_text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Matched Text" + }, + "confidence": { + "type": "number", + "title": "Confidence" + }, + "status": { + "$ref": "#/components/schemas/FlagStatus" + }, + "reviewed_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Reviewed By" + }, + "reviewed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Reviewed At" + }, + "review_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Reason" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "chunk_id", + "rule_id", + "request_id", + "category", + "matched_text", + "confidence", + "status", + "reviewed_by", + "reviewed_at", + "review_reason", + "created_at" + ], + "title": "ExemptionFlagRead" + }, + "ExemptionFlagReview": { + "properties": { + "status": { + "$ref": "#/components/schemas/FlagStatus" + }, + "review_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Reason" + } + }, + "type": "object", + "required": [ + "status" + ], + "title": "ExemptionFlagReview" + }, + "ExemptionNoteCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-exemption-review", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ExemptionNotePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "ExemptionNoteCommand" + }, + "ExemptionNotePayload": { + "properties": { + "exemptionNote": { + "type": "string", + "minLength": 1, + "title": "Exemptionnote" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "exemptionNote" + ], + "title": "ExemptionNotePayload" + }, + "ExemptionRuleCreate": { + "properties": { + "state_code": { + "type": "string", + "title": "State Code" + }, + "category": { + "type": "string", + "title": "Category" + }, + "rule_type": { + "$ref": "#/components/schemas/RuleType" + }, + "rule_definition": { + "type": "string", + "title": "Rule Definition" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "enabled": { + "type": "boolean", + "title": "Enabled", + "default": true + } + }, + "type": "object", + "required": [ + "state_code", + "category", + "rule_type", + "rule_definition" + ], + "title": "ExemptionRuleCreate" + }, + "ExemptionRuleRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "state_code": { + "type": "string", + "title": "State Code" + }, + "category": { + "type": "string", + "title": "Category" + }, + "rule_type": { + "$ref": "#/components/schemas/RuleType" + }, + "rule_definition": { + "type": "string", + "title": "Rule Definition" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "enabled": { + "type": "boolean", + "title": "Enabled" + }, + "version": { + "type": "integer", + "title": "Version", + "default": 1 + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "state_code", + "category", + "rule_type", + "rule_definition", + "description", + "enabled", + "created_by", + "created_at" + ], + "title": "ExemptionRuleRead" + }, + "ExemptionRuleUpdate": { + "properties": { + "rule_definition": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Rule Definition" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "enabled": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Enabled" + } + }, + "type": "object", + "title": "ExemptionRuleUpdate" + }, + "ExportReceipt": { + "properties": { + "export_path": { + "type": "string", + "maxLength": 32768, + "minLength": 1, + "title": "Export Path" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "export_path" + ], + "title": "ExportReceipt" + }, + "FeeEstimateCommand": { + "properties": { + "action": { + "type": "string", + "const": "estimate-records-fee", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/FeeEstimatePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "FeeEstimateCommand" + }, + "FeeEstimatePayload": { + "properties": { + "feeEstimate": { + "type": "string", + "minLength": 1, + "title": "Feeestimate" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "feeEstimate" + ], + "title": "FeeEstimatePayload" + }, + "FeeEstimateRequest": { + "properties": { + "page_count": { + "type": "integer", + "title": "Page Count" + }, + "fee_schedule_id": { + "type": "string", + "format": "uuid", + "title": "Fee Schedule Id" + } + }, + "type": "object", + "required": [ + "page_count", + "fee_schedule_id" + ], + "title": "FeeEstimateRequest" + }, + "FeeEstimateResponse": { + "properties": { + "page_count": { + "type": "integer", + "title": "Page Count" + }, + "unit_price": { + "type": "number", + "title": "Unit Price" + }, + "total": { + "type": "number", + "title": "Total" + }, + "fee_type": { + "type": "string", + "title": "Fee Type" + }, + "description": { + "type": "string", + "title": "Description" + } + }, + "type": "object", + "required": [ + "page_count", + "unit_price", + "total", + "fee_type", + "description" + ], + "title": "FeeEstimateResponse" + }, + "FeeLineCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-fee-line", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/FeeLinePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "FeeLineCommand" + }, + "FeeLineItemCreate": { + "properties": { + "description": { + "type": "string", + "title": "Description" + }, + "quantity": { + "type": "integer", + "title": "Quantity", + "default": 1 + }, + "unit_price": { + "type": "number", + "title": "Unit Price" + }, + "fee_schedule_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Fee Schedule Id" + } + }, + "type": "object", + "required": [ + "description", + "unit_price" + ], + "title": "FeeLineItemCreate" + }, + "FeeLineItemRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "fee_schedule_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Fee Schedule Id" + }, + "description": { + "type": "string", + "title": "Description" + }, + "quantity": { + "type": "integer", + "title": "Quantity" + }, + "unit_price": { + "type": "number", + "title": "Unit Price" + }, + "total": { + "type": "number", + "title": "Total" + }, + "status": { + "type": "string", + "title": "Status" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "fee_schedule_id", + "description", + "quantity", + "unit_price", + "total", + "status", + "created_at" + ], + "title": "FeeLineItemRead" + }, + "FeeLinePayload": { + "properties": { + "feeLineDescription": { + "type": "string", + "minLength": 1, + "title": "Feelinedescription" + }, + "feeScheduleBasis": { + "type": "string", + "minLength": 1, + "title": "Feeschedulebasis" + }, + "feeLineAmount": { + "type": "string", + "title": "Feelineamount" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "feeLineDescription", + "feeScheduleBasis", + "feeLineAmount" + ], + "title": "FeeLinePayload" + }, + "FeeLineView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "description": { + "type": "string", + "title": "Description" + }, + "schedule_basis": { + "type": "string", + "title": "Schedule Basis" + }, + "amount_cents": { + "type": "integer", + "title": "Amount Cents" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "description", + "schedule_basis", + "amount_cents", + "created_at_unix_seconds" + ], + "title": "FeeLineView" + }, + "FeeScheduleCreate": { + "properties": { + "jurisdiction": { + "type": "string", + "title": "Jurisdiction" + }, + "fee_type": { + "type": "string", + "title": "Fee Type" + }, + "amount": { + "type": "number", + "title": "Amount" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "effective_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective Date" + } + }, + "type": "object", + "required": [ + "jurisdiction", + "fee_type", + "amount" + ], + "title": "FeeScheduleCreate" + }, + "FeeScheduleRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "jurisdiction": { + "type": "string", + "title": "Jurisdiction" + }, + "fee_type": { + "type": "string", + "title": "Fee Type" + }, + "amount": { + "type": "number", + "title": "Amount" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "effective_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective Date" + }, + "created_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "jurisdiction", + "fee_type", + "amount", + "description", + "effective_date", + "created_by", + "created_at" + ], + "title": "FeeScheduleRead" + }, + "FeeScheduleUpdate": { + "properties": { + "fee_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Fee Type" + }, + "amount": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Amount" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "effective_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective Date" + } + }, + "type": "object", + "title": "FeeScheduleUpdate" + }, + "FeeWaiverCommand": { + "properties": { + "action": { + "type": "string", + "const": "waive-records-fee", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/FeeWaiverPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "FeeWaiverCommand" + }, + "FeeWaiverCreateRequest": { + "properties": { + "waiver_type": { + "type": "string", + "title": "Waiver Type" + }, + "reason": { + "type": "string", + "title": "Reason" + } + }, + "type": "object", + "required": [ + "waiver_type", + "reason" + ], + "title": "FeeWaiverCreateRequest" + }, + "FeeWaiverPayload": { + "properties": { + "feeWaiverReason": { + "type": "string", + "minLength": 1, + "title": "Feewaiverreason" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "feeWaiverReason" + ], + "title": "FeeWaiverPayload" + }, + "FeeWaiverReadResponse": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "waiver_type": { + "type": "string", + "title": "Waiver Type" + }, + "reason": { + "type": "string", + "title": "Reason" + }, + "status": { + "type": "string", + "title": "Status" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + }, + "created_at": { + "type": "string", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "waiver_type", + "reason", + "status", + "created_at" + ], + "title": "FeeWaiverReadResponse" + }, + "FeeWaiverReviewRequest": { + "properties": { + "status": { + "type": "string", + "title": "Status" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + } + }, + "type": "object", + "required": [ + "status" + ], + "title": "FeeWaiverReviewRequest" + }, + "FinishCommand": { + "properties": { + "action": { + "type": "string", + "enum": [ + "fulfill-records-request", + "close-records-request" + ], + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/NativePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "FinishCommand" + }, + "FlagStatus": { + "type": "string", + "enum": [ + "flagged", + "reviewed", + "accepted", + "rejected" + ], + "title": "FlagStatus" + }, + "FormPlan": { + "properties": { + "action": { + "type": "string", + "const": "form-plan", + "title": "Action" + }, + "formName": { + "type": "string", + "maxLength": 500, + "title": "Formname", + "default": "" + }, + "fields": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 50, + "title": "Fields" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "FormPlan" + }, + "GeneratedDraft": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "model": { + "type": "string", + "minLength": 1, + "title": "Model" + }, + "previous_response_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Previous Response Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text", + "model", + "previous_response_sha256" + ], + "title": "GeneratedDraft" + }, + "HTTPValidationError": { + "properties": { + "detail": { + "items": { + "$ref": "#/components/schemas/ValidationError" + }, + "type": "array", + "title": "Detail" + } + }, + "type": "object", + "title": "HTTPValidationError" + }, + "Handoff": { + "properties": { + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "request_id" + ], + "title": "Handoff" + }, + "ImportBundleCreate": { + "properties": { + "job_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Job Id" + }, + "connector_type": { + "type": "string", + "minLength": 1, + "title": "Connector Type" + }, + "source": { + "$ref": "#/components/schemas/SourceCreate" + }, + "sources": { + "items": { + "$ref": "#/components/schemas/SourceCreate" + }, + "type": "array", + "title": "Sources" + }, + "titles": { + "items": { + "$ref": "#/components/schemas/TitleCreate" + }, + "type": "array", + "title": "Titles" + }, + "chapters": { + "items": { + "$ref": "#/components/schemas/ChapterCreate" + }, + "type": "array", + "title": "Chapters" + }, + "sections": { + "items": { + "$ref": "#/components/schemas/SectionCreate" + }, + "type": "array", + "title": "Sections" + }, + "versions": { + "items": { + "$ref": "#/components/schemas/SectionVersionCreate" + }, + "type": "array", + "title": "Versions" + }, + "provenance": { + "additionalProperties": true, + "type": "object", + "title": "Provenance" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "connector_type", + "source" + ], + "title": "ImportBundleCreate", + "description": "Request body for local fixture/file-drop import jobs." + }, + "InclusionStatus": { + "type": "string", + "enum": [ + "included", + "excluded", + "pending" + ], + "title": "InclusionStatus" + }, + "IngestionStats": { + "properties": { + "total_sources": { + "type": "integer", + "title": "Total Sources" + }, + "active_sources": { + "type": "integer", + "title": "Active Sources" + }, + "total_documents": { + "type": "integer", + "title": "Total Documents" + }, + "documents_by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Documents By Status" + }, + "total_chunks": { + "type": "integer", + "title": "Total Chunks" + } + }, + "type": "object", + "required": [ + "total_sources", + "active_sources", + "total_documents", + "documents_by_status", + "total_chunks" + ], + "title": "IngestionStats" + }, + "IngestionStatus": { + "type": "string", + "enum": [ + "pending", + "processing", + "completed", + "failed" + ], + "title": "IngestionStatus" + }, + "InitiativeInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "policy": { + "$ref": "#/components/schemas/PolicySelection" + }, + "responsible_staff": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Responsible Staff" + }, + "target": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "title": "Target" + }, + "unit": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Unit" + }, + "due_on": { + "type": "string", + "format": "date", + "title": "Due On" + }, + "status": { + "type": "string", + "enum": [ + "planned", + "active", + "completed", + "cancelled" + ], + "title": "Status", + "default": "planned" + }, + "milestones": { + "items": { + "$ref": "#/components/schemas/Milestone" + }, + "type": "array", + "maxItems": 100, + "title": "Milestones" + }, + "measurements": { + "items": { + "$ref": "#/components/schemas/Measurement" + }, + "type": "array", + "maxItems": 1000, + "title": "Measurements" + }, + "note": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "policy", + "responsible_staff", + "target", + "unit", + "due_on", + "note" + ], + "title": "InitiativeInput" + }, + "InspectionInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "property_reference": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Property Reference" + }, + "inspection_reference": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Inspection Reference" + }, + "dataset_kind": { + "type": "string", + "enum": [ + "municipal", + "fictional" + ], + "title": "Dataset Kind" + }, + "inspector_notes": { + "type": "string", + "maxLength": 10000, + "minLength": 1, + "title": "Inspector Notes" + }, + "photo_observations": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 30, + "title": "Photo Observations" + }, + "voice_notes": { + "type": "string", + "maxLength": 10000, + "title": "Voice Notes", + "default": "" + }, + "evidence": { + "items": { + "$ref": "#/components/schemas/Evidence" + }, + "type": "array", + "maxItems": 10, + "title": "Evidence" + }, + "linked_sources": { + "items": { + "$ref": "#/components/schemas/townlight_inspections__workflow_models__SourceLink" + }, + "type": "array", + "maxItems": 30, + "title": "Linked Sources" + }, + "assigned_to": { + "type": "string", + "maxLength": 255, + "title": "Assigned To", + "default": "" + }, + "staff_notes": { + "type": "string", + "maxLength": 10000, + "title": "Staff Notes", + "default": "" + }, + "notice_draft": { + "type": "string", + "maxLength": 10000, + "title": "Notice Draft", + "default": "" + }, + "review_state": { + "type": "string", + "enum": [ + "draft", + "follow_up", + "reviewed" + ], + "title": "Review State", + "default": "draft" + }, + "review_notes": { + "type": "string", + "maxLength": 4000, + "title": "Review Notes", + "default": "" + }, + "public_summary": { + "type": "string", + "maxLength": 10000, + "title": "Public Summary", + "default": "" + }, + "analysis": { + "anyOf": [ + { + "$ref": "#/components/schemas/AnalysisRecord" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "property_reference", + "inspection_reference", + "dataset_kind", + "inspector_notes" + ], + "title": "InspectionInput" + }, + "IntakeInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "project_name": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Project Name" + }, + "project_description": { + "type": "string", + "maxLength": 10000, + "minLength": 1, + "title": "Project Description" + }, + "location": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Location" + }, + "applicant_contact": { + "type": "string", + "maxLength": 2000, + "title": "Applicant Contact", + "default": "" + }, + "requirement_revision": { + "type": "string", + "format": "uuid", + "title": "Requirement Revision" + }, + "materials": { + "items": { + "$ref": "#/components/schemas/MaterialReview" + }, + "type": "array", + "maxItems": 100, + "minItems": 1, + "title": "Materials" + }, + "linked_sources": { + "items": { + "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink" + }, + "type": "array", + "maxItems": 30, + "title": "Linked Sources" + }, + "staff_notes": { + "type": "string", + "maxLength": 10000, + "title": "Staff Notes", + "default": "" + }, + "assigned_to": { + "type": "string", + "maxLength": 255, + "title": "Assigned To", + "default": "" + }, + "review_state": { + "type": "string", + "enum": [ + "draft", + "follow_up", + "reviewed" + ], + "title": "Review State", + "default": "draft" + }, + "review_notes": { + "type": "string", + "maxLength": 4000, + "title": "Review Notes", + "default": "" + }, + "public_summary": { + "type": "string", + "maxLength": 10000, + "title": "Public Summary", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "project_name", + "project_description", + "location", + "requirement_revision", + "materials" + ], + "title": "IntakeInput" + }, + "InterpretationNoteCreate": { + "properties": { + "note_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Note Id" + }, + "note_text": { + "type": "string", + "minLength": 1, + "title": "Note Text" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "note_text" + ], + "title": "InterpretationNoteCreate", + "description": "Request body for staff-only interpretation notes." + }, + "InterviewRequest": { + "properties": { + "last_answer": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Answer" + }, + "last_field": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Field" + }, + "skipped_fields": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Skipped Fields" + } + }, + "type": "object", + "title": "InterviewRequest" + }, + "InterviewResponse": { + "properties": { + "question": { + "type": "string", + "title": "Question" + }, + "target_field": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Target Field" + }, + "all_complete": { + "type": "boolean", + "title": "All Complete" + }, + "completed_fields": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Completed Fields" + }, + "onboarding_status": { + "type": "string", + "title": "Onboarding Status" + }, + "skipped_fields": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Skipped Fields" + } + }, + "type": "object", + "required": [ + "question", + "target_field", + "all_complete", + "completed_fields", + "onboarding_status", + "skipped_fields" + ], + "title": "InterviewResponse" + }, + "ManagedFileReceipt": { + "properties": { + "original_path": { + "type": "string", + "minLength": 1, + "title": "Original Path" + }, + "stored_path": { + "type": "string", + "minLength": 1, + "title": "Stored Path" + }, + "file_name": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "File Name" + }, + "sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Sha256" + }, + "size_bytes": { + "type": "integer", + "maximum": 2147483647.0, + "minimum": 0.0, + "title": "Size Bytes" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "original_path", + "stored_path", + "file_name", + "sha256", + "size_bytes" + ], + "title": "ManagedFileReceipt" + }, + "ManagedSource": { + "properties": { + "original_path": { + "type": "string", + "title": "Original Path" + }, + "stored_path": { + "type": "string", + "title": "Stored Path" + }, + "file_name": { + "type": "string", + "title": "File Name" + }, + "sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Sha256" + }, + "size_bytes": { + "type": "integer", + "minimum": 0.0, + "title": "Size Bytes" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "original_path", + "stored_path", + "file_name", + "sha256", + "size_bytes" + ], + "title": "ManagedSource" + }, + "Material": { + "properties": { + "material_id": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]{1,80}$", + "title": "Material Id" + }, + "description": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Description" + }, + "citation": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Citation" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "material_id", + "description", + "citation" + ], + "title": "Material" + }, + "MaterialReview": { + "properties": { + "material_id": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Material Id" + }, + "status": { + "type": "string", + "enum": [ + "not_reviewed", + "provided", + "missing", + "unclear" + ], + "title": "Status", + "default": "not_reviewed" + }, + "note": { + "type": "string", + "maxLength": 2000, + "title": "Note", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "material_id" + ], + "title": "MaterialReview" + }, + "Measurement": { + "properties": { + "recorded_on": { + "type": "string", + "format": "date", + "title": "Recorded On" + }, + "value": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "title": "Value" + }, + "evidence": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Evidence" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "recorded_on", + "value", + "evidence" + ], + "title": "Measurement" + }, + "MediaAnalysis": { + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/EvidenceItem" + }, + "type": "array", + "maxItems": 10, + "minItems": 1, + "title": "Items" + }, + "code_links": { + "items": { + "$ref": "#/components/schemas/CodeLink" + }, + "type": "array", + "maxItems": 30, + "title": "Code Links" + }, + "inspector_supplied_text": { + "type": "string", + "maxLength": 10000, + "title": "Inspector Supplied Text", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "items" + ], + "title": "MediaAnalysis" + }, + "MeetingInput": { + "properties": { + "title": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Title" + }, + "scheduled_start": { + "type": "string", + "format": "date-time", + "title": "Scheduled Start" + }, + "location": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Location" + }, + "meeting_type": { + "type": "string", + "enum": [ + "regular", + "special", + "emergency", + "closed_session", + "executive" + ], + "title": "Meeting Type", + "default": "regular" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "scheduled_start", + "location" + ], + "title": "MeetingInput" + }, + "MeetingLink": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + }, + "relation": { + "type": "string", + "enum": [ + "hearing", + "context", + "precedent" + ], + "title": "Relation" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256", + "relation" + ], + "title": "MeetingLink" + }, + "MeetingSearch": { + "properties": { + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "MeetingSearch" + }, + "MeetingStageInput": { + "properties": { + "to_status": { + "type": "string", + "enum": [ + "SCHEDULED", + "NOTICED", + "PACKET_POSTED", + "IN_PROGRESS", + "RECESSED", + "ADJOURNED", + "TRANSCRIPT_READY", + "MINUTES_DRAFTED", + "MINUTES_POSTED", + "MINUTES_ADOPTED", + "MINUTES_SIGNED", + "ARCHIVED", + "CANCELLED" + ], + "title": "To Status" + }, + "statutory_basis": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Statutory Basis" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "to_status" + ], + "title": "MeetingStageInput" + }, + "MeetingsSearch": { + "properties": { + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "MeetingsSearch" + }, + "MeetingsSourceSelection": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "MeetingsSourceSelection" + }, + "MessageCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-message", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/MessagePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "MessageCommand" + }, + "MessageCreate": { + "properties": { + "message_text": { + "type": "string", + "title": "Message Text" + }, + "is_internal": { + "type": "boolean", + "title": "Is Internal", + "default": false + } + }, + "type": "object", + "required": [ + "message_text" + ], + "title": "MessageCreate" + }, + "MessagePayload": { + "properties": { + "requestMessageBody": { + "type": "string", + "minLength": 1, + "title": "Requestmessagebody" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requestMessageBody" + ], + "title": "MessagePayload" + }, + "MessageRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "sender_type": { + "type": "string", + "title": "Sender Type" + }, + "sender_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Sender Id" + }, + "message_text": { + "type": "string", + "title": "Message Text" + }, + "is_internal": { + "type": "boolean", + "title": "Is Internal" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "sender_type", + "sender_id", + "message_text", + "is_internal", + "created_at" + ], + "title": "MessageRead" + }, + "MessageView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "author": { + "type": "string", + "title": "Author" + }, + "author_role": { + "type": "string", + "title": "Author Role" + }, + "body": { + "type": "string", + "title": "Body" + }, + "visibility": { + "type": "string", + "title": "Visibility" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "author", + "author_role", + "body", + "visibility", + "created_at_unix_seconds" + ], + "title": "MessageView" + }, + "Milestone": { + "properties": { + "title": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Title" + }, + "due_on": { + "type": "string", + "format": "date", + "title": "Due On" + }, + "completed_on": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Completed On" + }, + "evidence": { + "type": "string", + "maxLength": 2000, + "title": "Evidence", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "due_on" + ], + "title": "Milestone" + }, + "MinutesDecision": { + "properties": { + "action": { + "type": "string", + "enum": [ + "post", + "adopt", + "sign" + ], + "title": "Action" + }, + "note": { + "type": "string", + "title": "Note", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "MinutesDecision" + }, + "ModelRegistryCreate": { + "properties": { + "model_name": { + "type": "string", + "title": "Model Name" + }, + "model_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Version" + }, + "parameter_count": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parameter Count" + }, + "license": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License" + }, + "model_card_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Card Url" + }, + "is_active": { + "type": "boolean", + "title": "Is Active", + "default": false + }, + "context_window_size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Context Window Size" + }, + "supports_ner": { + "type": "boolean", + "title": "Supports Ner", + "default": false + }, + "supports_vision": { + "type": "boolean", + "title": "Supports Vision", + "default": false + } + }, + "type": "object", + "required": [ + "model_name" + ], + "title": "ModelRegistryCreate", + "description": "Schema for creating a new model_registry record (POST body)." + }, + "ModelRegistryRead": { + "properties": { + "id": { + "type": "integer", + "title": "Id" + }, + "model_name": { + "type": "string", + "title": "Model Name" + }, + "model_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Version" + }, + "parameter_count": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parameter Count" + }, + "license": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License" + }, + "model_card_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Card Url" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "added_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Added At" + }, + "context_window_size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Context Window Size" + }, + "supports_ner": { + "type": "boolean", + "title": "Supports Ner" + }, + "supports_vision": { + "type": "boolean", + "title": "Supports Vision" + } + }, + "type": "object", + "required": [ + "id", + "model_name", + "is_active", + "supports_ner", + "supports_vision" + ], + "title": "ModelRegistryRead", + "description": "Schema for returning a model_registry record (GET response).\n\n``from_attributes=True`` allows construction directly from an ORM instance." + }, + "ModelRegistryUpdate": { + "properties": { + "model_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Name" + }, + "model_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Version" + }, + "parameter_count": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parameter Count" + }, + "license": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License" + }, + "model_card_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Card Url" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + }, + "context_window_size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Context Window Size" + }, + "supports_ner": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Supports Ner" + }, + "supports_vision": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Supports Vision" + } + }, + "type": "object", + "title": "ModelRegistryUpdate", + "description": "Schema for partially updating a model_registry record (PATCH body).\n\nEvery field is optional so callers can send only the fields they want to\nchange." + }, + "MotionCorrection": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "reason": { + "type": "string", + "minLength": 1, + "title": "Reason" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text", + "reason" + ], + "title": "MotionCorrection" + }, + "MotionInput": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "seconded_by": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Seconded By" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text" + ], + "title": "MotionInput" + }, + "NativePayload": { + "properties": {}, + "additionalProperties": false, + "type": "object", + "title": "NativePayload" + }, + "NativeRequestRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "requester_name": { + "type": "string", + "title": "Requester Name" + }, + "requester_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Email" + }, + "requester_phone": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Phone" + }, + "requester_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Type" + }, + "date_received": { + "type": "string", + "format": "date-time", + "title": "Date Received" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "description": { + "type": "string", + "title": "Description" + }, + "status": { + "$ref": "#/components/schemas/RequestStatus" + }, + "assigned_to": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "created_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "response_draft": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Response Draft" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + }, + "estimated_fee": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Estimated Fee" + }, + "fee_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Fee Status" + }, + "fee_waiver_requested": { + "type": "boolean", + "title": "Fee Waiver Requested", + "default": false + }, + "priority": { + "type": "string", + "title": "Priority", + "default": "normal" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + }, + "closed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Closed At" + }, + "closure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Closure Reason" + }, + "desktop_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Desktop Id" + }, + "public_tracking_number": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Public Tracking Number" + }, + "submitted_via": { + "type": "string", + "title": "Submitted Via" + }, + "deadline_label": { + "type": "string", + "title": "Deadline Label" + }, + "deadline_basis": { + "type": "string", + "title": "Deadline Basis" + }, + "deadline_reviewed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Deadline Reviewed At" + } + }, + "type": "object", + "required": [ + "id", + "requester_name", + "requester_email", + "date_received", + "statutory_deadline", + "description", + "status", + "assigned_to", + "created_by", + "created_at", + "response_draft", + "review_notes", + "desktop_id", + "public_tracking_number", + "submitted_via", + "deadline_label", + "deadline_basis", + "deadline_reviewed_at" + ], + "title": "NativeRequestRead" + }, + "NoticeDocumentInput": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text" + ], + "title": "NoticeDocumentInput" + }, + "NoticeDraft": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "body": { + "type": "string", + "maxLength": 100000, + "minLength": 1, + "title": "Body" + }, + "notice_type": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Notice Type" + }, + "statutory_basis": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Statutory Basis" + }, + "event_date": { + "type": "string", + "format": "date", + "title": "Event Date" + }, + "lead_days": { + "type": "integer", + "maximum": 365.0, + "minimum": 0.0, + "title": "Lead Days" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "body", + "notice_type", + "statutory_basis", + "event_date", + "lead_days" + ], + "title": "NoticeDraft" + }, + "NoticeInput": { + "properties": { + "notice_type": { + "type": "string", + "enum": [ + "regular", + "special", + "emergency", + "closed_session", + "executive" + ], + "title": "Notice Type" + }, + "posted_at": { + "type": "string", + "format": "date-time", + "title": "Posted At" + }, + "minimum_notice_hours": { + "type": "integer", + "minimum": 0.0, + "title": "Minimum Notice Hours" + }, + "statutory_basis": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Statutory Basis" + }, + "approved_by": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Approved By" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "notice_type", + "posted_at", + "minimum_notice_hours" + ], + "title": "NoticeInput" + }, + "NoticeProofInput": { + "properties": { + "location": { + "type": "string", + "minLength": 1, + "title": "Location" + }, + "note": { + "type": "string", + "title": "Note", + "default": "" + }, + "document_delivery_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Document Delivery Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "location" + ], + "title": "NoticeProofInput" + }, + "NotificationLogRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "template_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Template Id" + }, + "recipient_email": { + "type": "string", + "title": "Recipient Email" + }, + "request_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Request Id" + }, + "channel": { + "type": "string", + "title": "Channel" + }, + "status": { + "type": "string", + "title": "Status" + }, + "sent_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Sent At" + }, + "error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Message" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "template_id", + "recipient_email", + "request_id", + "channel", + "status", + "sent_at", + "error_message", + "created_at" + ], + "title": "NotificationLogRead" + }, + "NotificationTemplateCreate": { + "properties": { + "event_type": { + "type": "string", + "title": "Event Type" + }, + "channel": { + "type": "string", + "title": "Channel", + "default": "email" + }, + "subject_template": { + "type": "string", + "title": "Subject Template" + }, + "body_template": { + "type": "string", + "title": "Body Template" + } + }, + "type": "object", + "required": [ + "event_type", + "subject_template", + "body_template" + ], + "title": "NotificationTemplateCreate" + }, + "NotificationTemplateRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "event_type": { + "type": "string", + "title": "Event Type" + }, + "channel": { + "type": "string", + "title": "Channel" + }, + "subject_template": { + "type": "string", + "title": "Subject Template" + }, + "body_template": { + "type": "string", + "title": "Body Template" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "event_type", + "channel", + "subject_template", + "body_template", + "is_active", + "created_at" + ], + "title": "NotificationTemplateRead" + }, + "NotificationTemplateUpdate": { + "properties": { + "subject_template": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Subject Template" + }, + "body_template": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Body Template" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "NotificationTemplateUpdate" + }, + "NotificationView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "notification_id": { + "type": "string", + "title": "Notification Id" + }, + "module_id": { + "type": "string", + "title": "Module Id" + }, + "record_id": { + "type": "string", + "title": "Record Id" + }, + "audience": { + "type": "string", + "title": "Audience" + }, + "channel": { + "type": "string", + "title": "Channel" + }, + "subject": { + "type": "string", + "title": "Subject" + }, + "body": { + "type": "string", + "title": "Body" + }, + "status": { + "type": "string", + "title": "Status" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + }, + "sent_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Sent At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "notification_id", + "module_id", + "record_id", + "audience", + "channel", + "subject", + "body", + "status", + "created_at_unix_seconds", + "sent_at_unix_seconds" + ], + "title": "NotificationView" + }, + "OllamaModelInfo": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Size" + }, + "details": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Details" + } + }, + "type": "object", + "required": [ + "name" + ], + "title": "OllamaModelInfo" + }, + "OllamaStatus": { + "properties": { + "status": { + "type": "string", + "title": "Status" + }, + "models": { + "items": { + "$ref": "#/components/schemas/OllamaModelInfo" + }, + "type": "array", + "title": "Models" + } + }, + "type": "object", + "required": [ + "status", + "models" + ], + "title": "OllamaStatus" + }, + "OperationalMetrics": { + "properties": { + "average_response_time_days": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Average Response Time Days" + }, + "median_response_time_days": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Median Response Time Days" + }, + "requests_by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Requests By Status" + }, + "requests_by_department": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Requests By Department" + }, + "deadline_compliance_rate": { + "type": "number", + "title": "Deadline Compliance Rate" + }, + "total_open": { + "type": "integer", + "title": "Total Open" + }, + "total_closed": { + "type": "integer", + "title": "Total Closed" + }, + "total_overdue": { + "type": "integer", + "title": "Total Overdue" + }, + "clarification_frequency": { + "type": "number", + "title": "Clarification Frequency" + }, + "top_request_topics": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Top Request Topics" + } + }, + "type": "object", + "required": [ + "average_response_time_days", + "median_response_time_days", + "requests_by_status", + "requests_by_department", + "deadline_compliance_rate", + "total_open", + "total_closed", + "total_overdue", + "clarification_frequency", + "top_request_topics" + ], + "title": "OperationalMetrics" + }, + "Outline": { + "properties": { + "title": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Title" + }, + "question_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "maxItems": 50, + "minItems": 1, + "title": "Question Ids" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "question_ids" + ], + "title": "Outline" + }, + "Packet": { + "properties": { + "expected_revision": { + "type": "string", + "format": "uuid", + "title": "Expected Revision" + }, + "visibility": { + "type": "string", + "enum": [ + "staff_only", + "records_copy" + ], + "title": "Visibility" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "expected_revision", + "visibility" + ], + "title": "Packet" + }, + "PacketInput": { + "properties": { + "agenda_item_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "title": "Agenda Item Ids" + }, + "source_files": { + "items": { + "$ref": "#/components/schemas/ManagedSource" + }, + "type": "array", + "title": "Source Files" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "agenda_item_ids" + ], + "title": "PacketInput" + }, + "Pathway": { + "properties": { + "project_type": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Project Type" + }, + "proposal": { + "type": "string", + "maxLength": 4000, + "title": "Proposal", + "default": "" + }, + "location_context": { + "type": "string", + "maxLength": 1000, + "title": "Location Context", + "default": "" + }, + "requirement_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Requirement Revision" + }, + "fee_link": { + "anyOf": [ + { + "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "project_type" + ], + "title": "Pathway" + }, + "PathwayStep": { + "properties": { + "step": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Step" + }, + "citation": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Citation" + }, + "typical_time": { + "type": "string", + "maxLength": 1000, + "title": "Typical Time", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "step", + "citation" + ], + "title": "PathwayStep" + }, + "PlainLanguageSummaryCreate": { + "properties": { + "summary_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Summary Id" + }, + "section_version_id": { + "type": "string", + "minLength": 1, + "title": "Section Version Id" + }, + "summary_text": { + "type": "string", + "minLength": 1, + "title": "Summary Text" + }, + "language_code": { + "type": "string", + "title": "Language Code", + "default": "en" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "section_version_id", + "summary_text" + ], + "title": "PlainLanguageSummaryCreate", + "description": "Request body for staff-drafted plain-language summaries." + }, + "PolicySelection": { + "properties": { + "plan_id": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Plan Id" + }, + "revision_id": { + "type": "string", + "maxLength": 36, + "minLength": 36, + "title": "Revision Id" + }, + "policy_id": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Policy Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "plan_id", + "revision_id", + "policy_id" + ], + "title": "PolicySelection" + }, + "PortalModeResponse": { + "properties": { + "mode": { + "type": "string", + "enum": [ + "public", + "private" + ], + "title": "Mode", + "description": "Active portal posture for this deployment. ``public`` = minimal resident surface (landing + authenticated records-request submission + resident registration) reachable without staff auth. ``private`` = staff-only; no public routes, no resident self-registration." + } + }, + "type": "object", + "required": [ + "mode" + ], + "title": "PortalModeResponse", + "description": "T5D — schema for ``GET /config/portal-mode``.\n\nExposed to the frontend on boot so it can branch routing without a\nuser-identity lookup. The payload is intentionally the single field\nbelow — no staff config, no user state, no schema version." + }, + "PrepareArtifact": { + "properties": { + "kind": { + "type": "string", + "enum": [ + "response", + "release-package" + ], + "title": "Kind" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "kind" + ], + "title": "PrepareArtifact" + }, + "Proof": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + }, + "filename": { + "type": "string", + "maxLength": 150, + "minLength": 1, + "title": "Filename" + }, + "content_base64": { + "type": "string", + "maxLength": 7000000, + "minLength": 1, + "title": "Content Base64" + }, + "location": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Location" + }, + "published_at": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Published At" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence", + "filename", + "content_base64", + "location", + "published_at" + ], + "title": "Proof" + }, + "Proposal": { + "properties": { + "id": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Id" + }, + "version_id": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Version Id" + }, + "meeting_id": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "ordinance_number": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Ordinance Number" + }, + "proposed_text": { + "type": "string", + "maxLength": 1000000, + "minLength": 1, + "title": "Proposed Text" + }, + "supersedes_id": { + "anyOf": [ + { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$" + }, + { + "type": "null" + } + ], + "title": "Supersedes Id" + }, + "reconciliation_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reconciliation Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "version_id", + "meeting_id", + "title", + "ordinance_number", + "proposed_text" + ], + "title": "Proposal" + }, + "PublicExplore": { + "properties": { + "goal": { + "type": "string", + "maxLength": 500, + "title": "Goal", + "default": "" + }, + "topic": { + "type": "string", + "maxLength": 160, + "title": "Topic", + "default": "" + }, + "neighborhood": { + "type": "string", + "maxLength": 255, + "title": "Neighborhood", + "default": "" + }, + "plan_type": { + "type": "string", + "maxLength": 120, + "title": "Plan Type", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "title": "PublicExplore" + }, + "PublicIntake": { + "properties": { + "requester": { + "type": "string", + "minLength": 1, + "title": "Requester" + }, + "requesterContact": { + "type": "string", + "minLength": 1, + "title": "Requestercontact" + }, + "summary": { + "type": "string", + "minLength": 1, + "title": "Summary" + }, + "deadline": { + "type": "string", + "title": "Deadline", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requester", + "requesterContact", + "summary" + ], + "title": "PublicIntake" + }, + "PublicLookup": { + "properties": { + "trackingNumber": { + "type": "string", + "minLength": 1, + "title": "Trackingnumber" + }, + "requesterContact": { + "type": "string", + "minLength": 1, + "title": "Requestercontact" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "trackingNumber", + "requesterContact" + ], + "title": "PublicLookup" + }, + "PublicMessage": { + "properties": { + "trackingNumber": { + "type": "string", + "minLength": 1, + "title": "Trackingnumber" + }, + "requesterContact": { + "type": "string", + "minLength": 1, + "title": "Requestercontact" + }, + "publicRequestMessage": { + "type": "string", + "minLength": 1, + "title": "Publicrequestmessage" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "trackingNumber", + "requesterContact", + "publicRequestMessage" + ], + "title": "PublicMessage" + }, + "PublicStatusView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "label": { + "type": "string", + "title": "Label" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "status": { + "type": "string", + "title": "Status" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "label", + "summary", + "status", + "created_at_unix_seconds" + ], + "title": "PublicStatusView" + }, + "PublicationView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "source_module": { + "type": "string", + "title": "Source Module" + }, + "source_record_id": { + "type": "string", + "title": "Source Record Id" + }, + "record_type": { + "type": "string", + "title": "Record Type" + }, + "public_payload": { + "type": "string", + "title": "Public Payload" + }, + "payload_hash": { + "type": "string", + "title": "Payload Hash" + }, + "published_at_unix_seconds": { + "type": "integer", + "title": "Published At Unix Seconds" + }, + "retracted_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Retracted At Unix Seconds" + }, + "retracted_by": { + "type": "string", + "title": "Retracted By", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "source_module", + "source_record_id", + "record_type", + "public_payload", + "payload_hash", + "published_at_unix_seconds" + ], + "title": "PublicationView" + }, + "PublishingPlan": { + "properties": { + "action": { + "type": "string", + "const": "publishing-workflow", + "title": "Action" + }, + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "hasReview": { + "type": "boolean", + "title": "Hasreview", + "default": false + }, + "hasPlainLanguage": { + "type": "boolean", + "title": "Hasplainlanguage", + "default": false + }, + "hasTranslationReview": { + "type": "boolean", + "title": "Hastranslationreview", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "PublishingPlan" + }, + "Question": { + "properties": { + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + }, + "question": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Question" + }, + "kind": { + "type": "string", + "enum": [ + "use", + "dimension" + ], + "title": "Kind" + }, + "key": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Key" + }, + "audience": { + "type": "string", + "enum": [ + "resident", + "staff" + ], + "title": "Audience", + "default": "resident" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "jurisdiction", + "query", + "question", + "kind", + "key" + ], + "title": "Question" + }, + "QuestionAnswerRequest": { + "properties": { + "question": { + "type": "string", + "minLength": 1, + "title": "Question" + }, + "section_number": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Section Number" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "question" + ], + "title": "QuestionAnswerRequest", + "description": "Request body for citation-grounded code Q&A." + }, + "RecordsDocumentView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "attachment_id": { + "type": "string", + "title": "Attachment Id" + }, + "title": { + "type": "string", + "title": "Title" + }, + "original_path": { + "type": "string", + "title": "Original Path" + }, + "stored_path": { + "type": "string", + "title": "Stored Path" + }, + "citation": { + "type": "string", + "title": "Citation" + }, + "sha256": { + "type": "string", + "title": "Sha256" + }, + "size_bytes": { + "type": "integer", + "title": "Size Bytes" + }, + "status": { + "type": "string", + "title": "Status" + }, + "added_by": { + "type": "string", + "title": "Added By" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + }, + "release_original_path": { + "type": "string", + "title": "Release Original Path", + "default": "" + }, + "release_stored_path": { + "type": "string", + "title": "Release Stored Path", + "default": "" + }, + "release_file_name": { + "type": "string", + "title": "Release File Name", + "default": "" + }, + "release_sha256": { + "type": "string", + "title": "Release Sha256", + "default": "" + }, + "release_size_bytes": { + "type": "integer", + "title": "Release Size Bytes", + "default": 0 + }, + "release_status": { + "type": "string", + "title": "Release Status", + "default": "" + }, + "release_note": { + "type": "string", + "title": "Release Note", + "default": "" + }, + "release_added_by": { + "type": "string", + "title": "Release Added By", + "default": "" + }, + "release_added_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Release Added At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "attachment_id", + "title", + "original_path", + "stored_path", + "citation", + "sha256", + "size_bytes", + "status", + "added_by", + "created_at_unix_seconds" + ], + "title": "RecordsDocumentView" + }, + "RecordsOperationRead": { + "properties": { + "action": { + "type": "string", + "title": "Action" + }, + "message": { + "type": "string", + "title": "Message" + }, + "request": { + "$ref": "#/components/schemas/RecordsView" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "message", + "request" + ], + "title": "RecordsOperationRead" + }, + "RecordsStateRead": { + "properties": { + "demo_fixture": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Demo Fixture" + }, + "records_requests": { + "items": { + "$ref": "#/components/schemas/RecordsView" + }, + "type": "array", + "title": "Records Requests" + }, + "notification_events": { + "items": { + "$ref": "#/components/schemas/NotificationView" + }, + "type": "array", + "title": "Notification Events" + }, + "publication_events": { + "items": { + "$ref": "#/components/schemas/PublicationView" + }, + "type": "array", + "title": "Publication Events" + }, + "audit_entries": { + "items": { + "$ref": "#/components/schemas/AuditView" + }, + "type": "array", + "title": "Audit Entries" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "records_requests" + ], + "title": "RecordsStateRead" + }, + "RecordsView": { + "properties": { + "request_id": { + "type": "string", + "title": "Request Id" + }, + "id": { + "type": "string", + "title": "Id" + }, + "public_tracking_number": { + "type": "string", + "title": "Public Tracking Number" + }, + "requester": { + "type": "string", + "title": "Requester" + }, + "requester_contact": { + "type": "string", + "title": "Requester Contact" + }, + "submitted_via": { + "type": "string", + "title": "Submitted Via" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "deadline": { + "type": "string", + "title": "Deadline" + }, + "deadline_basis": { + "type": "string", + "title": "Deadline Basis" + }, + "status": { + "type": "string", + "title": "Status" + }, + "assigned_to": { + "type": "string", + "title": "Assigned To" + }, + "clarification_notes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Clarification Notes" + }, + "search_notes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Search Notes" + }, + "search_sessions": { + "items": { + "$ref": "#/components/schemas/SearchReceiptView" + }, + "type": "array", + "title": "Search Sessions" + }, + "exemption_reviews": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Exemption Reviews" + }, + "exemption_decisions": { + "items": { + "$ref": "#/components/schemas/ExemptionDecisionView" + }, + "type": "array", + "title": "Exemption Decisions" + }, + "fee_estimate": { + "type": "string", + "title": "Fee Estimate" + }, + "fee_line_items": { + "items": { + "$ref": "#/components/schemas/FeeLineView" + }, + "type": "array", + "title": "Fee Line Items" + }, + "fee_waiver_reason": { + "type": "string", + "title": "Fee Waiver Reason" + }, + "citations": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Citations" + }, + "response_draft": { + "type": "string", + "title": "Response Draft" + }, + "approval_notes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Approval Notes" + }, + "exports": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Exports" + }, + "documents": { + "items": { + "$ref": "#/components/schemas/RecordsDocumentView" + }, + "type": "array", + "title": "Documents" + }, + "release_packages": { + "items": { + "$ref": "#/components/schemas/ReleasePackageView" + }, + "type": "array", + "title": "Release Packages" + }, + "timeline": { + "items": { + "$ref": "#/components/schemas/TimelineView" + }, + "type": "array", + "title": "Timeline" + }, + "public_status_events": { + "items": { + "$ref": "#/components/schemas/PublicStatusView" + }, + "type": "array", + "title": "Public Status Events" + }, + "messages": { + "items": { + "$ref": "#/components/schemas/MessageView" + }, + "type": "array", + "title": "Messages" + }, + "deadline_reviewed_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Deadline Reviewed At Unix Seconds" + }, + "approved_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Approved At Unix Seconds" + }, + "fulfilled_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Fulfilled At Unix Seconds" + }, + "closed_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Closed At Unix Seconds" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "request_id", + "id", + "public_tracking_number", + "requester", + "requester_contact", + "submitted_via", + "summary", + "deadline", + "deadline_basis", + "status", + "assigned_to", + "clarification_notes", + "search_notes", + "search_sessions", + "exemption_reviews", + "exemption_decisions", + "fee_estimate", + "fee_line_items", + "fee_waiver_reason", + "citations", + "response_draft", + "approval_notes", + "exports", + "timeline", + "public_status_events", + "messages", + "deadline_reviewed_at_unix_seconds", + "approved_at_unix_seconds", + "fulfilled_at_unix_seconds", + "closed_at_unix_seconds", + "created_at_unix_seconds" + ], + "title": "RecordsView" + }, + "ReleasePackageView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "export_path": { + "type": "string", + "title": "Export Path" + }, + "package_hash": { + "type": "string", + "title": "Package Hash" + }, + "document_count": { + "type": "integer", + "title": "Document Count" + }, + "release_artifact_count": { + "type": "integer", + "title": "Release Artifact Count" + }, + "search_session_count": { + "type": "integer", + "title": "Search Session Count" + }, + "release_count": { + "type": "integer", + "title": "Release Count" + }, + "redacted_count": { + "type": "integer", + "title": "Redacted Count" + }, + "exempt_count": { + "type": "integer", + "title": "Exempt Count" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "export_path", + "package_hash", + "document_count", + "release_artifact_count", + "search_session_count", + "release_count", + "redacted_count", + "exempt_count", + "created_at_unix_seconds" + ], + "title": "ReleasePackageView" + }, + "RepeatLookup": { + "properties": { + "property_reference": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Property Reference" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "property_reference" + ], + "title": "RepeatLookup" + }, + "RequestCreate": { + "properties": { + "requester_name": { + "type": "string", + "maxLength": 255, + "title": "Requester Name" + }, + "requester_email": { + "anyOf": [ + { + "type": "string", + "maxLength": 255 + }, + { + "type": "null" + } + ], + "title": "Requester Email" + }, + "requester_phone": { + "anyOf": [ + { + "type": "string", + "maxLength": 50 + }, + { + "type": "null" + } + ], + "title": "Requester Phone" + }, + "requester_type": { + "anyOf": [ + { + "type": "string", + "maxLength": 100 + }, + { + "type": "null" + } + ], + "title": "Requester Type" + }, + "description": { + "type": "string", + "maxLength": 10000, + "title": "Description" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "priority": { + "type": "string", + "title": "Priority", + "default": "normal" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string", + "pattern": "^(narrow|moderate|broad)$" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + } + }, + "type": "object", + "required": [ + "requester_name", + "description" + ], + "title": "RequestCreate" + }, + "RequestDocumentAdd": { + "properties": { + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "relevance_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Relevance Note" + } + }, + "type": "object", + "required": [ + "document_id" + ], + "title": "RequestDocumentAdd" + }, + "RequestDocumentRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "relevance_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Relevance Note" + }, + "exemption_flags": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Exemption Flags" + }, + "inclusion_status": { + "$ref": "#/components/schemas/InclusionStatus" + }, + "attached_at": { + "type": "string", + "format": "date-time", + "title": "Attached At" + }, + "attached_by": { + "type": "string", + "format": "uuid", + "title": "Attached By" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "document_id", + "relevance_note", + "exemption_flags", + "inclusion_status", + "attached_at", + "attached_by" + ], + "title": "RequestDocumentRead" + }, + "RequestRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "requester_name": { + "type": "string", + "title": "Requester Name" + }, + "requester_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Email" + }, + "requester_phone": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Phone" + }, + "requester_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Type" + }, + "date_received": { + "type": "string", + "format": "date-time", + "title": "Date Received" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "description": { + "type": "string", + "title": "Description" + }, + "status": { + "$ref": "#/components/schemas/RequestStatus" + }, + "assigned_to": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "created_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "response_draft": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Response Draft" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + }, + "estimated_fee": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Estimated Fee" + }, + "fee_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Fee Status" + }, + "fee_waiver_requested": { + "type": "boolean", + "title": "Fee Waiver Requested", + "default": false + }, + "priority": { + "type": "string", + "title": "Priority", + "default": "normal" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + }, + "closed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Closed At" + }, + "closure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Closure Reason" + } + }, + "type": "object", + "required": [ + "id", + "requester_name", + "requester_email", + "date_received", + "statutory_deadline", + "description", + "status", + "assigned_to", + "created_by", + "created_at", + "response_draft", + "review_notes" + ], + "title": "RequestRead" + }, + "RequestStats": { + "properties": { + "total_requests": { + "type": "integer", + "title": "Total Requests" + }, + "by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "By Status" + }, + "approaching_deadline": { + "type": "integer", + "title": "Approaching Deadline" + }, + "overdue": { + "type": "integer", + "title": "Overdue" + } + }, + "type": "object", + "required": [ + "total_requests", + "by_status", + "approaching_deadline", + "overdue" + ], + "title": "RequestStats" + }, + "RequestStatus": { + "type": "string", + "enum": [ + "received", + "clarification_needed", + "assigned", + "searching", + "in_review", + "ready_for_release", + "drafted", + "approved", + "fulfilled", + "closed" + ], + "title": "RequestStatus" + }, + "RequestUpdate": { + "properties": { + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "status": { + "anyOf": [ + { + "$ref": "#/components/schemas/RequestStatus" + }, + { + "type": "null" + } + ] + }, + "assigned_to": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "response_draft": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Response Draft" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + } + }, + "type": "object", + "title": "RequestUpdate" + }, + "RequirementBundle": { + "properties": { + "requirement_id": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]{1,100}$", + "title": "Requirement Id" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "project_type": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Project Type" + }, + "source_reference": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Source Reference" + }, + "source_date": { + "type": "string", + "format": "date", + "title": "Source Date" + }, + "effective_on": { + "type": "string", + "format": "date", + "title": "Effective On" + }, + "dataset_kind": { + "type": "string", + "enum": [ + "municipal", + "fictional" + ], + "title": "Dataset Kind" + }, + "filename": { + "type": "string", + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$", + "title": "Filename" + }, + "content_base64": { + "type": "string", + "maxLength": 14000000, + "minLength": 1, + "title": "Content Base64" + }, + "sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Sha256" + }, + "materials": { + "items": { + "$ref": "#/components/schemas/Material" + }, + "type": "array", + "maxItems": 100, + "minItems": 1, + "title": "Materials" + }, + "pathway": { + "items": { + "$ref": "#/components/schemas/PathwayStep" + }, + "type": "array", + "maxItems": 100, + "title": "Pathway" + }, + "fee_link": { + "anyOf": [ + { + "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink" + }, + { + "type": "null" + } + ] + }, + "staff_note": { + "type": "string", + "maxLength": 4000, + "title": "Staff Note", + "default": "" + }, + "change_note": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Change Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requirement_id", + "title", + "jurisdiction", + "project_type", + "source_reference", + "source_date", + "effective_on", + "dataset_kind", + "filename", + "content_base64", + "sha256", + "materials", + "change_note" + ], + "title": "RequirementBundle" + }, + "ResponseLetterCreate": { + "properties": { + "template_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Template Id" + } + }, + "type": "object", + "title": "ResponseLetterCreate" + }, + "ResponseLetterRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "template_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Template Id" + }, + "generated_content": { + "type": "string", + "title": "Generated Content" + }, + "edited_content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Edited Content" + }, + "status": { + "type": "string", + "title": "Status" + }, + "generated_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Generated By" + }, + "approved_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Approved By" + }, + "sent_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Sent At" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "template_id", + "generated_content", + "edited_content", + "status", + "generated_by", + "approved_by", + "sent_at", + "created_at" + ], + "title": "ResponseLetterRead" + }, + "ResponseLetterUpdate": { + "properties": { + "edited_content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Edited Content" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + } + }, + "type": "object", + "title": "ResponseLetterUpdate" + }, + "ReviewInput": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "body": { + "type": "string", + "maxLength": 5000, + "title": "Body", + "default": "" + }, + "hasAltText": { + "type": "boolean", + "title": "Hasalttext", + "default": false + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "en" + } + }, + "additionalProperties": false, + "type": "object", + "title": "ReviewInput" + }, + "Revision": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + }, + "document": { + "$ref": "#/components/schemas/NoticeDraft" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence", + "document" + ], + "title": "Revision" + }, + "RewriteInput": { + "properties": { + "action": { + "type": "string", + "enum": [ + "plain-language", + "language-variant" + ], + "title": "Action" + }, + "text": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Text" + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "text" + ], + "title": "RewriteInput" + }, + "RewriteResult": { + "properties": { + "action": { + "type": "string", + "enum": [ + "plain-language", + "language-variant" + ], + "title": "Action" + }, + "text": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Text" + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "" + }, + "outcome": { + "type": "string", + "enum": [ + "generated", + "unavailable" + ], + "title": "Outcome" + }, + "generated": { + "anyOf": [ + { + "type": "string", + "maxLength": 100000 + }, + { + "type": "null" + } + ], + "title": "Generated" + }, + "model": { + "anyOf": [ + { + "type": "string", + "maxLength": 200 + }, + { + "type": "null" + } + ], + "title": "Model" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "text", + "outcome" + ], + "title": "RewriteResult" + }, + "Rule": { + "properties": { + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "zone_code": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Zone Code" + }, + "key": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Key" + }, + "section_number": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Section Number" + }, + "kind": { + "type": "string", + "enum": [ + "use", + "dimension" + ], + "title": "Kind" + }, + "value": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Value" + }, + "overlay_code": { + "anyOf": [ + { + "type": "string", + "maxLength": 255 + }, + { + "type": "null" + } + ], + "title": "Overlay Code" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "jurisdiction", + "zone_code", + "key", + "section_number", + "kind", + "value" + ], + "title": "Rule" + }, + "RuleTestMatch": { + "properties": { + "matched_text": { + "type": "string", + "title": "Matched Text" + }, + "start": { + "type": "integer", + "title": "Start" + }, + "end": { + "type": "integer", + "title": "End" + } + }, + "type": "object", + "required": [ + "matched_text", + "start", + "end" + ], + "title": "RuleTestMatch" + }, + "RuleTestRequest": { + "properties": { + "sample_text": { + "type": "string", + "title": "Sample Text" + } + }, + "type": "object", + "required": [ + "sample_text" + ], + "title": "RuleTestRequest" + }, + "RuleTestResponse": { + "properties": { + "rule_id": { + "type": "string", + "format": "uuid", + "title": "Rule Id" + }, + "rule_type": { + "type": "string", + "title": "Rule Type" + }, + "matched": { + "type": "boolean", + "title": "Matched" + }, + "matches": { + "items": { + "$ref": "#/components/schemas/RuleTestMatch" + }, + "type": "array", + "title": "Matches" + } + }, + "type": "object", + "required": [ + "rule_id", + "rule_type", + "matched", + "matches" + ], + "title": "RuleTestResponse" + }, + "RuleType": { + "type": "string", + "enum": [ + "regex", + "keyword", + "llm_prompt" + ], + "title": "RuleType" + }, + "SaveReview": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "body": { + "type": "string", + "maxLength": 5000, + "title": "Body", + "default": "" + }, + "hasAltText": { + "type": "boolean", + "title": "Hasalttext", + "default": false + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "en" + }, + "ai_analysis": { + "anyOf": [ + { + "type": "string", + "maxLength": 100000 + }, + { + "type": "null" + } + ], + "title": "Ai Analysis" + }, + "ai_analysis_model": { + "anyOf": [ + { + "type": "string", + "maxLength": 200 + }, + { + "type": "null" + } + ], + "title": "Ai Analysis Model" + }, + "ai_outcome": { + "type": "string", + "enum": [ + "generated", + "unavailable", + "failed" + ], + "title": "Ai Outcome" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "ai_outcome" + ], + "title": "SaveReview" + }, + "SearchFilterOptions": { + "properties": { + "file_types": { + "items": { + "type": "string" + }, + "type": "array", + "title": "File Types" + }, + "source_names": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Source Names" + }, + "departments": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array", + "title": "Departments", + "default": [] + }, + "date_range": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Date Range" + } + }, + "type": "object", + "required": [ + "file_types", + "source_names" + ], + "title": "SearchFilterOptions" + }, + "SearchInput": { + "properties": { + "query": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "SearchInput" + }, + "SearchNoteCommand": { + "properties": { + "action": { + "type": "string", + "const": "record-records-search", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/SearchNotePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "SearchNoteCommand" + }, + "SearchNotePayload": { + "properties": { + "sourceNote": { + "type": "string", + "minLength": 1, + "title": "Sourcenote" + }, + "citation": { + "type": "string", + "title": "Citation", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sourceNote" + ], + "title": "SearchNotePayload" + }, + "SearchReceiptCommand": { + "properties": { + "action": { + "type": "string", + "const": "record-records-search-session", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/SearchReceiptPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "SearchReceiptCommand" + }, + "SearchReceiptPayload": { + "properties": { + "searchQuery": { + "type": "string", + "minLength": 1, + "title": "Searchquery" + }, + "searchLocations": { + "type": "string", + "minLength": 1, + "title": "Searchlocations" + }, + "searchResultTitle": { + "type": "string", + "minLength": 1, + "title": "Searchresulttitle" + }, + "searchResultCitation": { + "type": "string", + "minLength": 1, + "title": "Searchresultcitation" + }, + "searchResultSummary": { + "type": "string", + "minLength": 1, + "title": "Searchresultsummary" + }, + "searchResultStatus": { + "type": "string", + "title": "Searchresultstatus", + "default": "" + }, + "searchReviewer": { + "type": "string", + "title": "Searchreviewer", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "searchQuery", + "searchLocations", + "searchResultTitle", + "searchResultCitation", + "searchResultSummary" + ], + "title": "SearchReceiptPayload" + }, + "SearchReceiptView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "query": { + "type": "string", + "title": "Query" + }, + "locations": { + "type": "string", + "title": "Locations" + }, + "reviewer": { + "type": "string", + "title": "Reviewer" + }, + "results": { + "items": { + "$ref": "#/components/schemas/SearchResultView" + }, + "type": "array", + "title": "Results" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "query", + "locations", + "reviewer", + "results", + "created_at_unix_seconds" + ], + "title": "SearchReceiptView" + }, + "SearchRequest": { + "properties": { + "query": { + "type": "string", + "title": "Query" + }, + "session_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Session Id" + }, + "filters": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Filters" + }, + "limit": { + "type": "integer", + "maximum": 50.0, + "title": "Limit", + "default": 10 + }, + "synthesize": { + "type": "boolean", + "title": "Synthesize", + "default": false + } + }, + "type": "object", + "required": [ + "query" + ], + "title": "SearchRequest" + }, + "SearchResponse": { + "properties": { + "query_id": { + "type": "string", + "format": "uuid", + "title": "Query Id" + }, + "session_id": { + "type": "string", + "format": "uuid", + "title": "Session Id" + }, + "query_text": { + "type": "string", + "title": "Query Text" + }, + "results": { + "items": { + "$ref": "#/components/schemas/SearchResultItem" + }, + "type": "array", + "title": "Results" + }, + "results_count": { + "type": "integer", + "title": "Results Count" + }, + "synthesized_answer": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Synthesized Answer" + }, + "ai_generated": { + "type": "boolean", + "title": "Ai Generated", + "default": false + } + }, + "type": "object", + "required": [ + "query_id", + "session_id", + "query_text", + "results", + "results_count" + ], + "title": "SearchResponse" + }, + "SearchResultItem": { + "properties": { + "chunk_id": { + "type": "string", + "format": "uuid", + "title": "Chunk Id" + }, + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "filename": { + "type": "string", + "title": "Filename" + }, + "file_type": { + "type": "string", + "title": "File Type" + }, + "source_path": { + "type": "string", + "title": "Source Path" + }, + "page_number": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Page Number" + }, + "content_text": { + "type": "string", + "title": "Content Text" + }, + "similarity_score": { + "type": "number", + "title": "Similarity Score" + }, + "rank": { + "type": "integer", + "title": "Rank" + } + }, + "type": "object", + "required": [ + "chunk_id", + "document_id", + "filename", + "file_type", + "source_path", + "page_number", + "content_text", + "similarity_score", + "rank" + ], + "title": "SearchResultItem" + }, + "SearchResultView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "title": { + "type": "string", + "title": "Title" + }, + "citation": { + "type": "string", + "title": "Citation" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "status": { + "type": "string", + "title": "Status" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "title", + "citation", + "summary", + "status" + ], + "title": "SearchResultView" + }, + "SearchSessionRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "user_id": { + "type": "string", + "format": "uuid", + "title": "User Id" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "queries": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array", + "title": "Queries", + "default": [] + } + }, + "type": "object", + "required": [ + "id", + "user_id", + "created_at" + ], + "title": "SearchSessionRead" + }, + "SectionCreate": { + "properties": { + "section_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Section Id" + }, + "chapter_id": { + "type": "string", + "minLength": 1, + "title": "Chapter Id" + }, + "section_number": { + "type": "string", + "minLength": 1, + "title": "Section Number" + }, + "section_heading": { + "type": "string", + "minLength": 1, + "title": "Section Heading" + }, + "parent_section_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parent Section Id" + }, + "sort_order": { + "type": "integer", + "title": "Sort Order", + "default": 0 + }, + "administrative_regulation_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Administrative Regulation Refs" + }, + "resolution_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Resolution Refs" + }, + "policy_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Policy Refs" + }, + "approved_summary_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Approved Summary Refs" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "chapter_id", + "section_number", + "section_heading" + ], + "title": "SectionCreate", + "description": "Request body for creating a code section or subsection." + }, + "SectionVersionCreate": { + "properties": { + "version_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Version Id" + }, + "section_id": { + "type": "string", + "minLength": 1, + "title": "Section Id" + }, + "source_id": { + "type": "string", + "minLength": 1, + "title": "Source Id" + }, + "version_label": { + "type": "string", + "minLength": 1, + "title": "Version Label" + }, + "body": { + "type": "string", + "minLength": 1, + "title": "Body" + }, + "effective_start": { + "type": "string", + "format": "date", + "title": "Effective Start" + }, + "effective_end": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective End" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + }, + "is_current": { + "type": "boolean", + "title": "Is Current", + "default": false + }, + "adoption_event_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Adoption Event Id" + }, + "amendment_event_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Amendment Event Id" + }, + "amendment_summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Amendment Summary" + }, + "prior_version_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Prior Version Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "section_id", + "source_id", + "version_label", + "body", + "effective_start" + ], + "title": "SectionVersionCreate", + "description": "Request body for adding an immutable section version." + }, + "Selection": { + "properties": { + "recording_id": { + "type": "string", + "format": "uuid", + "title": "Recording Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "recording_id", + "expected_sha256" + ], + "title": "Selection" + }, + "SentenceInput": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "citations": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Citations" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text" + ], + "title": "SentenceInput" + }, + "ServiceAccountCreate": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole", + "default": "read_only" + } + }, + "type": "object", + "required": [ + "name" + ], + "title": "ServiceAccountCreate" + }, + "ServiceAccountCreated": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "api_key": { + "type": "string", + "title": "Api Key" + } + }, + "type": "object", + "required": [ + "id", + "name", + "role", + "created_by", + "created_at", + "is_active", + "api_key" + ], + "title": "ServiceAccountCreated", + "description": "Returned only on creation — includes the plaintext API key (shown once)." + }, + "ServiceAccountRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + } + }, + "type": "object", + "required": [ + "id", + "name", + "role", + "created_by", + "created_at", + "is_active" + ], + "title": "ServiceAccountRead" + }, + "ServiceAccountUpdate": { + "properties": { + "role": { + "anyOf": [ + { + "$ref": "#/components/schemas/UserRole" + }, + { + "type": "null" + } + ] + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "ServiceAccountUpdate" + }, + "Snapshot": { + "properties": { + "expected_revision": { + "type": "string", + "format": "uuid", + "title": "Expected Revision" + }, + "visibility": { + "type": "string", + "enum": [ + "staff_only", + "public" + ], + "title": "Visibility" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "expected_revision", + "visibility" + ], + "title": "Snapshot" + }, + "SourceCreate": { + "properties": { + "source_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Id" + }, + "name": { + "type": "string", + "minLength": 1, + "title": "Name" + }, + "publisher": { + "type": "string", + "minLength": 1, + "title": "Publisher" + }, + "source_type": { + "type": "string", + "minLength": 1, + "title": "Source Type" + }, + "source_category": { + "type": "string", + "minLength": 1, + "title": "Source Category" + }, + "source_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Url" + }, + "file_reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "File Reference" + }, + "retrieved_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Retrieved At" + }, + "retrieval_method": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Retrieval Method" + }, + "checksum": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Checksum" + }, + "source_owner": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Owner" + }, + "is_official": { + "type": "boolean", + "title": "Is Official", + "default": true + }, + "official_status_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Official Status Note" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + }, + "staff_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Staff Notes" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "name", + "publisher", + "source_type", + "source_category" + ], + "title": "SourceCreate", + "description": "Request body for registering an official or explicitly labeled source." + }, + "SourceInput": { + "properties": { + "source_id": { + "type": "string", + "minLength": 1, + "title": "Source Id" + }, + "label": { + "type": "string", + "minLength": 1, + "title": "Label" + }, + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "label", + "text" + ], + "title": "SourceInput" + }, + "SourceSnapshot": { + "properties": { + "visibility": { + "type": "string", + "enum": [ + "public", + "staff_only" + ], + "title": "Visibility" + }, + "meeting_event_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "maxItems": 50, + "title": "Meeting Event Ids" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "visibility" + ], + "title": "SourceSnapshot" + }, + "SourceType": { + "type": "string", + "enum": [ + "manual_drop", + "file_system", + "rest_api", + "odbc" + ], + "title": "SourceType" + }, + "StaffRecordsIntake": { + "properties": { + "requester": { + "type": "string", + "minLength": 1, + "title": "Requester" + }, + "summary": { + "type": "string", + "minLength": 1, + "title": "Summary" + }, + "deadline": { + "type": "string", + "title": "Deadline" + }, + "deadlineBasis": { + "type": "string", + "title": "Deadlinebasis", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requester", + "summary", + "deadline" + ], + "title": "StaffRecordsIntake", + "description": "Existing native create-records-request input; no caller-supplied actor." + }, + "StandardsExplanation": { + "properties": { + "question": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Question" + }, + "process_section": { + "type": "string", + "maxLength": 255, + "title": "Process Section", + "default": "" + }, + "zone_code": { + "type": "string", + "maxLength": 40, + "title": "Zone Code", + "default": "" + }, + "rule_types": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 10, + "title": "Rule Types" + }, + "observed": { + "additionalProperties": { + "type": "string" + }, + "type": "object", + "title": "Observed" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "question" + ], + "title": "StandardsExplanation" + }, + "SyncFailureRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "source_id": { + "type": "string", + "format": "uuid", + "title": "Source Id" + }, + "source_path": { + "type": "string", + "title": "Source Path" + }, + "error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Message" + }, + "error_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Class" + }, + "http_status_code": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Http Status Code" + }, + "retry_count": { + "type": "integer", + "title": "Retry Count" + }, + "status": { + "type": "string", + "title": "Status" + }, + "first_failed_at": { + "type": "string", + "format": "date-time", + "title": "First Failed At" + }, + "last_retried_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Retried At" + }, + "dismissed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Dismissed At" + }, + "dismissed_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Dismissed By" + } + }, + "type": "object", + "required": [ + "id", + "source_id", + "source_path", + "error_message", + "error_class", + "http_status_code", + "retry_count", + "status", + "first_failed_at", + "last_retried_at", + "dismissed_at", + "dismissed_by" + ], + "title": "SyncFailureRead" + }, + "SyncRunLogRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "source_id": { + "type": "string", + "format": "uuid", + "title": "Source Id" + }, + "started_at": { + "type": "string", + "format": "date-time", + "title": "Started At" + }, + "finished_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Finished At" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + }, + "records_attempted": { + "type": "integer", + "title": "Records Attempted" + }, + "records_succeeded": { + "type": "integer", + "title": "Records Succeeded" + }, + "records_failed": { + "type": "integer", + "title": "Records Failed" + }, + "error_summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Summary" + } + }, + "type": "object", + "required": [ + "id", + "source_id", + "started_at", + "finished_at", + "status", + "records_attempted", + "records_succeeded", + "records_failed", + "error_summary" + ], + "title": "SyncRunLogRead" + }, + "SystemStatus": { + "properties": { + "version": { + "type": "string", + "title": "Version" + }, + "database": { + "type": "string", + "title": "Database" + }, + "ollama": { + "type": "string", + "title": "Ollama" + }, + "redis": { + "type": "string", + "title": "Redis" + }, + "user_count": { + "type": "integer", + "title": "User Count" + }, + "audit_log_count": { + "type": "integer", + "title": "Audit Log Count" + }, + "suite_session": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Suite Session" + } + }, + "type": "object", + "required": [ + "version", + "database", + "ollama", + "redis", + "user_count", + "audit_log_count" + ], + "title": "SystemStatus" + }, + "TaggedPlan": { + "properties": { + "action": { + "type": "string", + "const": "tagged-pdf", + "title": "Action" + }, + "headingLevels": { + "items": { + "type": "integer", + "maximum": 4294967295.0, + "minimum": 0.0 + }, + "type": "array", + "maxItems": 50, + "title": "Headinglevels" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "TaggedPlan" + }, + "TestConnectionRequest": { + "properties": { + "source_type": { + "type": "string", + "title": "Source Type" + }, + "host": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Host" + }, + "port": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Port" + }, + "path": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Path" + }, + "username": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Username" + }, + "password": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Password" + }, + "rest_api_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Rest Api Config" + }, + "odbc_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Odbc Config" + } + }, + "type": "object", + "required": [ + "source_type" + ], + "title": "TestConnectionRequest", + "description": "Dedicated schema for test-connection. NOT the create schema.\n\nSecurity: credentials in this request body are never persisted, never\nwritten to audit logs, and never returned in the response." + }, + "TestConnectionResponse": { + "properties": { + "success": { + "type": "boolean", + "title": "Success" + }, + "message": { + "type": "string", + "title": "Message" + }, + "latency_ms": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Latency Ms" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + }, + "warning": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Warning" + }, + "differing_keys": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Differing Keys" + } + }, + "type": "object", + "required": [ + "success", + "message" + ], + "title": "TestConnectionResponse" + }, + "TimelineEventCreate": { + "properties": { + "event_type": { + "type": "string", + "title": "Event Type" + }, + "description": { + "type": "string", + "title": "Description" + }, + "internal_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Internal Note" + } + }, + "type": "object", + "required": [ + "event_type", + "description" + ], + "title": "TimelineEventCreate" + }, + "TimelineEventRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "event_type": { + "type": "string", + "title": "Event Type" + }, + "actor_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Actor Id" + }, + "actor_role": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Actor Role" + }, + "description": { + "type": "string", + "title": "Description" + }, + "internal_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Internal Note" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "event_type", + "actor_id", + "actor_role", + "description", + "internal_note", + "created_at" + ], + "title": "TimelineEventRead" + }, + "TimelineView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "action": { + "type": "string", + "title": "Action" + }, + "actor": { + "type": "string", + "title": "Actor" + }, + "note": { + "type": "string", + "title": "Note" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "action", + "actor", + "note", + "created_at_unix_seconds" + ], + "title": "TimelineView" + }, + "TitleCreate": { + "properties": { + "title_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Title Id" + }, + "title_number": { + "type": "string", + "minLength": 1, + "title": "Title Number" + }, + "title_name": { + "type": "string", + "minLength": 1, + "title": "Title Name" + }, + "sort_order": { + "type": "integer", + "title": "Sort Order", + "default": 0 + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title_number", + "title_name" + ], + "title": "TitleCreate", + "description": "Request body for creating a code title." + }, + "TranscriptInput": { + "properties": { + "source_label": { + "type": "string", + "minLength": 1, + "title": "Source Label" + }, + "transcript_text": { + "type": "string", + "minLength": 1, + "title": "Transcript Text" + }, + "correction_of_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Correction Of Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_label", + "transcript_text" + ], + "title": "TranscriptInput" + }, + "UserRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "email": { + "type": "string", + "format": "email", + "title": "Email" + }, + "is_active": { + "type": "boolean", + "title": "Is Active", + "default": true + }, + "is_superuser": { + "type": "boolean", + "title": "Is Superuser", + "default": false + }, + "is_verified": { + "type": "boolean", + "title": "Is Verified", + "default": false + }, + "full_name": { + "type": "string", + "title": "Full Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "last_login": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Login" + }, + "must_change_password": { + "type": "boolean", + "title": "Must Change Password", + "default": false + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + } + }, + "type": "object", + "required": [ + "id", + "email", + "full_name", + "role", + "created_at", + "last_login" + ], + "title": "UserRead" + }, + "UserRole": { + "type": "string", + "enum": [ + "admin", + "staff", + "reviewer", + "read_only", + "liaison", + "public" + ], + "title": "UserRole" + }, + "UserSelfUpdate": { + "properties": { + "password": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Password" + }, + "email": { + "anyOf": [ + { + "type": "string", + "format": "email" + }, + { + "type": "null" + } + ], + "title": "Email" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + }, + "is_superuser": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Superuser" + }, + "is_verified": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Verified" + }, + "full_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Full Name" + } + }, + "type": "object", + "title": "UserSelfUpdate", + "description": "Schema for user self-update via PATCH /users/me.\n\nExcludes role and department_id. Any payload containing those fields is\nrejected at parse time (HTTP 422). Role and department changes require\nadmin privileges via /admin/users/{id}." + }, + "UserUpdateRequest": { + "properties": { + "full_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Full Name" + }, + "role": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Role" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "UserUpdateRequest" + }, + "ValidationError": { + "properties": { + "loc": { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "integer" + } + ] + }, + "type": "array", + "title": "Location" + }, + "msg": { + "type": "string", + "title": "Message" + }, + "type": { + "type": "string", + "title": "Error Type" + }, + "input": { + "title": "Input" + }, + "ctx": { + "type": "object", + "title": "Context" + } + }, + "type": "object", + "required": [ + "loc", + "msg", + "type" + ], + "title": "ValidationError" + }, + "Version": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence" + ], + "title": "Version" + }, + "VoteCorrection": { + "properties": { + "vote": { + "type": "string", + "minLength": 1, + "title": "Vote" + }, + "reason": { + "type": "string", + "minLength": 1, + "title": "Reason" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "vote", + "reason" + ], + "title": "VoteCorrection" + }, + "VoteInput": { + "properties": { + "voter_name": { + "type": "string", + "minLength": 1, + "title": "Voter Name" + }, + "vote": { + "type": "string", + "minLength": 1, + "title": "Vote" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "voter_name", + "vote" + ], + "title": "VoteInput" + }, + "_ParcelLookupIn": { + "properties": { + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "jurisdiction", + "query" + ], + "title": "_ParcelLookupIn" + }, + "townlight_inspections__workflow_models__SourceLink": { + "properties": { + "provider": { + "type": "string", + "const": "code", + "title": "Provider", + "default": "code" + }, + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "SourceLink" + }, + "townlight_permitting__workflow_models__SourceLink": { + "properties": { + "provider": { + "type": "string", + "enum": [ + "code", + "zoning" + ], + "title": "Provider" + }, + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "source_id", + "expected_sha256" + ], + "title": "SourceLink" + }, + "townlight_runtime__inspections_bridge__Search": { + "properties": { + "provider": { + "type": "string", + "const": "code", + "title": "Provider" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "query" + ], + "title": "Search" + }, + "townlight_runtime__notice_bridge__Review": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + }, + "note": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence", + "note" + ], + "title": "Review" + }, + "townlight_runtime__permitting_bridge__Import": { + "properties": { + "bundle": { + "$ref": "#/components/schemas/RequirementBundle" + }, + "expected_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "bundle" + ], + "title": "Import" + }, + "townlight_runtime__permitting_bridge__Search": { + "properties": { + "provider": { + "type": "string", + "enum": [ + "code", + "zoning" + ], + "title": "Provider" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "query" + ], + "title": "Search" + }, + "townlight_runtime__planning_bridge__Import": { + "properties": { + "bundle": { + "additionalProperties": true, + "type": "object", + "title": "Bundle" + }, + "expected_previous_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Expected Previous Revision" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "bundle" + ], + "title": "Import" + }, + "townlight_runtime__planning_bridge__Search": { + "properties": { + "query": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Query" + }, + "plan_type": { + "anyOf": [ + { + "type": "string", + "maxLength": 40 + }, + { + "type": "null" + } + ], + "title": "Plan Type" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "Search" + }, + "townlight_runtime__zoning_bridge__Review": { + "properties": { + "answer": { + "type": "string", + "maxLength": 10000, + "title": "Answer", + "default": "" + }, + "notes": { + "type": "string", + "maxLength": 10000, + "title": "Notes", + "default": "" + }, + "queue_status": { + "type": "string", + "enum": [ + "open", + "in_review", + "resolved", + "closed" + ], + "title": "Queue Status", + "default": "resolved" + } + }, + "additionalProperties": false, + "type": "object", + "title": "Review" + } + }, + "securitySchemes": { + "OAuth2PasswordBearer": { + "type": "oauth2", + "flows": { + "password": { + "scopes": {}, + "tokenUrl": "auth/jwt/login" + } + } + } + } + }, + "x-townlight-component": { + "view": "access", + "identity": "Townlight Access 0.5.0", + "evidence": "source-schema-only" + } +} diff --git a/docs/beta-1/api/access.html b/docs/beta-1/api/access.html new file mode 100644 index 0000000..a6e0c5e --- /dev/null +++ b/docs/beta-1/api/access.html @@ -0,0 +1,12073 @@ +Townlight Access API reference
Townlight

Townlight Access API reference

+

Prepared source candidate, November 2, 2026. New signed Windows installed acceptance and publication remain pending.

+

Townlight Access 0.5.0. The HTTP host is Townlight Records 1.8.0.dev2. Component package versions and the host API version are separate identities.

+

Generated from the actual native inspections-preview composition without application lifespan, migrations or database/network access. It describes route and validation contracts; it does not establish endpoint behavior, individual authorization or installed acceptance. Standalone product applications have separate deployment boundaries.

+

Machine-readable OpenAPI schema · Operating manual and limits

+

HTTP operations

+
POST /desktop/v1/access/drafts/{draft_id}/export +
{
+  "tags": [
+    "native-access"
+  ],
+  "summary": "Export Draft",
+  "operationId": "export_draft_desktop_v1_access_drafts__draft_id__export_post",
+  "parameters": [
+    {
+      "name": "draft_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Draft Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/access/exports/{artifact_id}/complete +
{
+  "tags": [
+    "native-access"
+  ],
+  "summary": "Complete Export",
+  "operationId": "complete_export_desktop_v1_access_exports__artifact_id__complete_post",
+  "parameters": [
+    {
+      "name": "artifact_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Artifact Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/ExportReceipt"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/access/review-context +
{
+  "tags": [
+    "native-access"
+  ],
+  "summary": "Review Context",
+  "operationId": "review_context_desktop_v1_access_review_context_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/ReviewInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/access/reviews +
{
+  "tags": [
+    "native-access"
+  ],
+  "summary": "Save Review",
+  "operationId": "save_review_desktop_v1_access_reviews_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/SaveReview"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/access/reviews/{review_id}/delete +
{
+  "tags": [
+    "native-access"
+  ],
+  "summary": "Delete Review",
+  "operationId": "delete_review_desktop_v1_access_reviews__review_id__delete_post",
+  "parameters": [
+    {
+      "name": "review_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Review Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/access/reviews/{review_id}/export +
{
+  "tags": [
+    "native-access"
+  ],
+  "summary": "Prepare Export",
+  "operationId": "prepare_export_desktop_v1_access_reviews__review_id__export_post",
+  "parameters": [
+    {
+      "name": "review_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Review Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/access/rewrite-context +
{
+  "tags": [
+    "native-access"
+  ],
+  "summary": "Rewrite Context",
+  "operationId": "rewrite_context_desktop_v1_access_rewrite_context_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/RewriteInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/access/rewrite-result +
{
+  "tags": [
+    "native-access"
+  ],
+  "summary": "Rewrite Result",
+  "operationId": "rewrite_result_desktop_v1_access_rewrite_result_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/RewriteResult"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/access/state +
{
+  "tags": [
+    "native-access"
+  ],
+  "summary": "Access State",
+  "operationId": "access_state_desktop_v1_access_state_get",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/access/tools +
{
+  "tags": [
+    "native-access"
+  ],
+  "summary": "Tool",
+  "operationId": "tool_desktop_v1_access_tools_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "oneOf": [
+            {
+              "$ref": "#/components/schemas/FormPlan"
+            },
+            {
+              "$ref": "#/components/schemas/PublishingPlan"
+            },
+            {
+              "$ref": "#/components/schemas/AdaPlan"
+            },
+            {
+              "$ref": "#/components/schemas/TaggedPlan"
+            }
+          ],
+          "discriminator": {
+            "propertyName": "action",
+            "mapping": {
+              "form-plan": "#/components/schemas/FormPlan",
+              "publishing-workflow": "#/components/schemas/PublishingPlan",
+              "ada-title-ii": "#/components/schemas/AdaPlan",
+              "tagged-pdf": "#/components/schemas/TaggedPlan"
+            }
+          },
+          "title": "Data"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+

Request and response data dictionary

+

Each schema includes the actual required fields, types, constraints and descriptions. References resolve against the machine-readable document.

+
ActionItemInput
+{
+  "properties": {
+    "description": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Description"
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "source_motion_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Motion Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "description"
+  ],
+  "title": "ActionItemInput"
+}
+
+
AdaPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "ada-title-ii",
+      "title": "Action"
+    },
+    "serviceArea": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Servicearea"
+    },
+    "hasCoordinatorReview": {
+      "type": "boolean",
+      "title": "Hascoordinatorreview",
+      "default": false
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "serviceArea"
+  ],
+  "title": "AdaPlan"
+}
+
+
AdminUserCreateRequest
+{
+  "properties": {
+    "email": {
+      "type": "string",
+      "title": "Email"
+    },
+    "password": {
+      "type": "string",
+      "title": "Password"
+    },
+    "full_name": {
+      "type": "string",
+      "title": "Full Name",
+      "default": ""
+    },
+    "role": {
+      "type": "string",
+      "title": "Role",
+      "default": "staff"
+    }
+  },
+  "type": "object",
+  "required": [
+    "email",
+    "password"
+  ],
+  "title": "AdminUserCreateRequest"
+}
+
+
AdminUserCreateResponse
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "email": {
+      "type": "string",
+      "title": "Email"
+    },
+    "full_name": {
+      "type": "string",
+      "title": "Full Name"
+    },
+    "role": {
+      "type": "string",
+      "title": "Role"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "email",
+    "full_name",
+    "role",
+    "is_active"
+  ],
+  "title": "AdminUserCreateResponse"
+}
+
+
AgendaAssignment
+{
+  "properties": {
+    "meeting_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Meeting Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "meeting_id"
+  ],
+  "title": "AgendaAssignment"
+}
+
+
AgendaInput
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "department_name": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Department Name"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "department_name"
+  ],
+  "title": "AgendaInput"
+}
+
+
AgendaReviewInput
+{
+  "properties": {
+    "to_status": {
+      "type": "string",
+      "enum": [
+        "DRAFTED",
+        "SUBMITTED",
+        "DEPT_APPROVED",
+        "LEGAL_REVIEWED",
+        "CLERK_ACCEPTED",
+        "ON_AGENDA",
+        "IN_PACKET",
+        "POSTED",
+        "HEARD",
+        "DISPOSED",
+        "ARCHIVED"
+      ],
+      "title": "To Status"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "to_status"
+  ],
+  "title": "AgendaReviewInput"
+}
+
+
AmendmentInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "policy": {
+      "$ref": "#/components/schemas/PolicySelection"
+    },
+    "proposal": {
+      "type": "string",
+      "maxLength": 20000,
+      "minLength": 1,
+      "title": "Proposal"
+    },
+    "responsible_staff": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Responsible Staff"
+    },
+    "status": {
+      "type": "string",
+      "enum": [
+        "draft",
+        "review",
+        "adopted",
+        "withdrawn"
+      ],
+      "title": "Status",
+      "default": "draft"
+    },
+    "review_note": {
+      "type": "string",
+      "maxLength": 5000,
+      "title": "Review Note",
+      "default": ""
+    },
+    "adoption_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Adoption Revision"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "policy",
+    "proposal",
+    "responsible_staff",
+    "note"
+  ],
+  "title": "AmendmentInput"
+}
+
+
AnalysisObservation
+{
+  "properties": {
+    "source": {
+      "type": "string",
+      "maxLength": 64,
+      "minLength": 1,
+      "title": "Source"
+    },
+    "filename": {
+      "type": "string",
+      "maxLength": 160,
+      "title": "Filename",
+      "default": ""
+    },
+    "media_type": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Media Type",
+      "default": ""
+    },
+    "text": {
+      "type": "string",
+      "maxLength": 4000,
+      "minLength": 1,
+      "title": "Text"
+    },
+    "adapter": {
+      "type": "string",
+      "maxLength": 120,
+      "title": "Adapter",
+      "default": ""
+    },
+    "citation_source_ids": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Citation Source Ids"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source",
+    "text"
+  ],
+  "title": "AnalysisObservation",
+  "description": "One draft observation, named with the adapter that actually produced it."
+}
+
+
AnalysisRecord
+{
+  "properties": {
+    "observations": {
+      "items": {
+        "$ref": "#/components/schemas/AnalysisObservation"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Observations"
+    },
+    "cited_sections": {
+      "items": {
+        "$ref": "#/components/schemas/CitedSection"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Cited Sections"
+    },
+    "unavailable": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Unavailable"
+    },
+    "runtime": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Runtime"
+    },
+    "review_required": {
+      "type": "boolean",
+      "title": "Review Required",
+      "default": true
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "AnalysisRecord",
+  "description": "The adapter output that accompanies a saved inspection draft."
+}
+
+
ApprovalCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "approve-records-response",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ApprovalPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "ApprovalCommand"
+}
+
+
ApprovalPayload
+{
+  "properties": {
+    "approvalNote": {
+      "type": "string",
+      "title": "Approvalnote",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "ApprovalPayload"
+}
+
+
ArchiveInput
+{
+  "properties": {
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "public",
+        "closed_session"
+      ],
+      "title": "Visibility"
+    },
+    "packet_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Packet Id"
+    },
+    "minutes_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Minutes Id"
+    },
+    "plain_language_summary": {
+      "type": "string",
+      "title": "Plain Language Summary",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "visibility"
+  ],
+  "title": "ArchiveInput"
+}
+
+
ArtifactPlan
+{
+  "properties": {
+    "artifact_id": {
+      "type": "string",
+      "title": "Artifact Id"
+    },
+    "file_name": {
+      "type": "string",
+      "title": "File Name"
+    },
+    "content": {
+      "type": "string",
+      "title": "Content"
+    },
+    "sha256": {
+      "type": "string",
+      "title": "Sha256"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "artifact_id",
+    "file_name",
+    "content",
+    "sha256",
+    "created_at_unix_seconds"
+  ],
+  "title": "ArtifactPlan"
+}
+
+
AssignCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "assign-records-request",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/AssignmentPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "AssignCommand"
+}
+
+
AssignmentPayload
+{
+  "properties": {
+    "assignedTo": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Assignedto"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "assignedTo"
+  ],
+  "title": "AssignmentPayload"
+}
+
+
AttachDocument
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation",
+      "default": ""
+    },
+    "file": {
+      "$ref": "#/components/schemas/ManagedFileReceipt"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "file"
+  ],
+  "title": "AttachDocument"
+}
+
+
AttachReleaseCopy
+{
+  "properties": {
+    "status": {
+      "type": "string",
+      "enum": [
+        "release-ready copy",
+        "redacted copy"
+      ],
+      "title": "Status"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note",
+      "default": ""
+    },
+    "added_by": {
+      "type": "string",
+      "title": "Added By",
+      "default": ""
+    },
+    "file": {
+      "$ref": "#/components/schemas/ManagedFileReceipt"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "status",
+    "file"
+  ],
+  "title": "AttachReleaseCopy"
+}
+
+
AuditChainVerification
+{
+  "properties": {
+    "is_valid": {
+      "type": "boolean",
+      "title": "Is Valid"
+    },
+    "entries_checked": {
+      "type": "integer",
+      "title": "Entries Checked"
+    },
+    "error_message": {
+      "type": "string",
+      "title": "Error Message"
+    }
+  },
+  "type": "object",
+  "required": [
+    "is_valid",
+    "entries_checked",
+    "error_message"
+  ],
+  "title": "AuditChainVerification"
+}
+
+
AuditLogRead
+{
+  "properties": {
+    "id": {
+      "type": "integer",
+      "title": "Id"
+    },
+    "prev_hash": {
+      "type": "string",
+      "title": "Prev Hash"
+    },
+    "entry_hash": {
+      "type": "string",
+      "title": "Entry Hash"
+    },
+    "timestamp": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Timestamp"
+    },
+    "user_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "User Id"
+    },
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "resource_type": {
+      "type": "string",
+      "title": "Resource Type"
+    },
+    "resource_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Resource Id"
+    },
+    "details": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Details"
+    },
+    "ai_generated": {
+      "type": "boolean",
+      "title": "Ai Generated"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "prev_hash",
+    "entry_hash",
+    "timestamp",
+    "user_id",
+    "action",
+    "resource_type",
+    "resource_id",
+    "details",
+    "ai_generated"
+  ],
+  "title": "AuditLogRead"
+}
+
+
AuditView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "module_id": {
+      "type": "string",
+      "title": "Module Id"
+    },
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    },
+    "previous_hash": {
+      "type": "string",
+      "title": "Previous Hash"
+    },
+    "entry_hash": {
+      "type": "string",
+      "title": "Entry Hash"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "module_id",
+    "action",
+    "summary",
+    "created_at_unix_seconds",
+    "previous_hash",
+    "entry_hash"
+  ],
+  "title": "AuditView"
+}
+
+
BearerResponse
+{
+  "properties": {
+    "access_token": {
+      "type": "string",
+      "title": "Access Token"
+    },
+    "token_type": {
+      "type": "string",
+      "title": "Token Type"
+    }
+  },
+  "type": "object",
+  "required": [
+    "access_token",
+    "token_type"
+  ],
+  "title": "BearerResponse"
+}
+
+
Body_auth_jwt_login_auth_jwt_login_post
+{
+  "properties": {
+    "grant_type": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^password$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Grant Type"
+    },
+    "username": {
+      "type": "string",
+      "title": "Username"
+    },
+    "password": {
+      "type": "string",
+      "format": "password",
+      "title": "Password"
+    },
+    "scope": {
+      "type": "string",
+      "title": "Scope",
+      "default": ""
+    },
+    "client_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Client Id"
+    },
+    "client_secret": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "format": "password",
+      "title": "Client Secret"
+    }
+  },
+  "type": "object",
+  "required": [
+    "username",
+    "password"
+  ],
+  "title": "Body_auth_jwt_login_auth_jwt_login_post"
+}
+
+
Body_upload_file_datasources_upload_post
+{
+  "properties": {
+    "file": {
+      "type": "string",
+      "contentMediaType": "application/octet-stream",
+      "title": "File"
+    }
+  },
+  "type": "object",
+  "required": [
+    "file"
+  ],
+  "title": "Body_upload_file_datasources_upload_post"
+}
+
+
CalculateDeadlineCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "calculate-records-deadline",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/CalculateDeadlinePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "CalculateDeadlineCommand"
+}
+
+
CalculateDeadlinePayload
+{
+  "properties": {
+    "deadlineReceivedDate": {
+      "type": "string",
+      "title": "Deadlinereceiveddate"
+    },
+    "deadlineRuleName": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Deadlinerulename"
+    },
+    "deadlineDayCount": {
+      "type": "string",
+      "title": "Deadlinedaycount"
+    },
+    "deadlineDayType": {
+      "type": "string",
+      "title": "Deadlinedaytype"
+    },
+    "deadlineBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Deadlinebasis"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "deadlineReceivedDate",
+    "deadlineRuleName",
+    "deadlineDayCount",
+    "deadlineDayType",
+    "deadlineBasis"
+  ],
+  "title": "CalculateDeadlinePayload"
+}
+
+
ChapterCreate
+{
+  "properties": {
+    "chapter_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Chapter Id"
+    },
+    "title_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title Id"
+    },
+    "chapter_number": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Chapter Number"
+    },
+    "chapter_name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Chapter Name"
+    },
+    "sort_order": {
+      "type": "integer",
+      "title": "Sort Order",
+      "default": 0
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title_id",
+    "chapter_number",
+    "chapter_name"
+  ],
+  "title": "ChapterCreate",
+  "description": "Request body for creating a code chapter."
+}
+
+
CitedSection
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "citation": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Citation"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "version": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Version",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "citation"
+  ],
+  "title": "CitedSection",
+  "description": "One resolved public Code section; never a caller-supplied quotation."
+}
+
+
CityProfileCreate
+{
+  "properties": {
+    "city_name": {
+      "type": "string",
+      "title": "City Name"
+    },
+    "state": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State"
+    },
+    "county": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "County"
+    },
+    "population_band": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Population Band"
+    },
+    "email_platform": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email Platform"
+    },
+    "has_dedicated_it": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Has Dedicated It"
+    },
+    "monthly_request_volume": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Monthly Request Volume"
+    },
+    "profile_data": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Profile Data",
+      "default": {}
+    },
+    "gap_map": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Gap Map",
+      "default": {}
+    }
+  },
+  "type": "object",
+  "required": [
+    "city_name"
+  ],
+  "title": "CityProfileCreate"
+}
+
+
CityProfileRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "city_name": {
+      "type": "string",
+      "title": "City Name"
+    },
+    "state": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State"
+    },
+    "county": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "County"
+    },
+    "population_band": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Population Band"
+    },
+    "email_platform": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email Platform"
+    },
+    "has_dedicated_it": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Has Dedicated It"
+    },
+    "monthly_request_volume": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Monthly Request Volume"
+    },
+    "onboarding_status": {
+      "type": "string",
+      "title": "Onboarding Status"
+    },
+    "profile_data": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Profile Data"
+    },
+    "gap_map": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Gap Map"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "updated_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "city_name",
+    "state",
+    "county",
+    "population_band",
+    "email_platform",
+    "has_dedicated_it",
+    "monthly_request_volume",
+    "onboarding_status",
+    "profile_data",
+    "gap_map",
+    "created_at",
+    "updated_at"
+  ],
+  "title": "CityProfileRead"
+}
+
+
CityProfileUpdate
+{
+  "properties": {
+    "city_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "City Name"
+    },
+    "state": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State"
+    },
+    "county": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "County"
+    },
+    "population_band": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Population Band"
+    },
+    "email_platform": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email Platform"
+    },
+    "has_dedicated_it": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Has Dedicated It"
+    },
+    "monthly_request_volume": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Monthly Request Volume"
+    },
+    "onboarding_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Onboarding Status"
+    },
+    "profile_data": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Profile Data"
+    },
+    "gap_map": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Gap Map"
+    }
+  },
+  "type": "object",
+  "title": "CityProfileUpdate"
+}
+
+
ClarificationCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "request-records-clarification",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ClarificationPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "ClarificationCommand"
+}
+
+
ClarificationPayload
+{
+  "properties": {
+    "clarificationNote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Clarificationnote"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "clarificationNote"
+  ],
+  "title": "ClarificationPayload"
+}
+
+
Closeout
+{
+  "properties": {
+    "decision_id": {
+      "type": "string",
+      "pattern": "^[A-Za-z0-9_-]{1,64}$",
+      "title": "Decision Id"
+    },
+    "version_id": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Version Id"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "version_label": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Version Label"
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 1000000,
+      "minLength": 1,
+      "title": "Body"
+    },
+    "effective_start": {
+      "type": "string",
+      "format": "date",
+      "title": "Effective Start"
+    },
+    "effective_end": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective End"
+    },
+    "is_current": {
+      "type": "boolean",
+      "title": "Is Current"
+    },
+    "reconciliation_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reconciliation Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "decision_id",
+    "version_id",
+    "source_id",
+    "version_label",
+    "body",
+    "effective_start",
+    "is_current"
+  ],
+  "title": "Closeout"
+}
+
+
CodeContext
+{
+  "properties": {
+    "section_number": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Section Number"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "section_number"
+  ],
+  "title": "CodeContext"
+}
+
+
CodeLink
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "const": "code",
+      "title": "Provider",
+      "default": "code"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "CodeLink"
+}
+
+
CodeSearch
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "CodeSearch"
+}
+
+
CodeSourceSelection
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 200,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "CodeSourceSelection"
+}
+
+
CompleteArtifact
+{
+  "properties": {
+    "export_path": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Export Path"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "export_path"
+  ],
+  "title": "CompleteArtifact"
+}
+
+
ConnectionSearch
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "enum": [
+        "meetings",
+        "zoning"
+      ],
+      "title": "Provider"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "query"
+  ],
+  "title": "ConnectionSearch"
+}
+
+
CoverageGapResponse
+{
+  "properties": {
+    "jurisdictions_without_rules": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Jurisdictions Without Rules"
+    },
+    "departments_without_staff": {
+      "items": {
+        "additionalProperties": true,
+        "type": "object"
+      },
+      "type": "array",
+      "title": "Departments Without Staff"
+    },
+    "uncovered_categories": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Uncovered Categories"
+    },
+    "total_gaps": {
+      "type": "integer",
+      "title": "Total Gaps"
+    }
+  },
+  "type": "object",
+  "required": [
+    "jurisdictions_without_rules",
+    "departments_without_staff",
+    "uncovered_categories",
+    "total_gaps"
+  ],
+  "title": "CoverageGapResponse"
+}
+
+
DataSourceAdminRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "source_type": {
+      "$ref": "#/components/schemas/SourceType"
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "type": "boolean",
+      "title": "Schedule Enabled",
+      "default": true
+    },
+    "next_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Next Sync At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "last_ingestion_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Ingestion At"
+    },
+    "last_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync At"
+    },
+    "last_sync_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync Status"
+    },
+    "last_error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Error Message"
+    },
+    "consecutive_failure_count": {
+      "type": "integer",
+      "title": "Consecutive Failure Count",
+      "default": 0
+    },
+    "sync_paused": {
+      "type": "boolean",
+      "title": "Sync Paused",
+      "default": false
+    },
+    "health_status": {
+      "type": "string",
+      "title": "Health Status",
+      "default": "healthy"
+    },
+    "active_failure_count": {
+      "type": "integer",
+      "title": "Active Failure Count",
+      "default": 0
+    },
+    "connector_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connector Type"
+    },
+    "updated_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Updated At"
+    },
+    "connection_config": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Connection Config"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "source_type",
+    "is_active",
+    "created_by",
+    "created_at",
+    "last_ingestion_at",
+    "connection_config"
+  ],
+  "title": "DataSourceAdminRead",
+  "description": "Full datasource shape including connection_config. Returned only by admin-gated endpoints."
+}
+
+
DataSourceCreate
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "source_type": {
+      "$ref": "#/components/schemas/SourceType"
+    },
+    "connection_config": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Connection Config",
+      "default": {}
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "type": "boolean",
+      "title": "Schedule Enabled",
+      "default": true
+    }
+  },
+  "type": "object",
+  "required": [
+    "name",
+    "source_type"
+  ],
+  "title": "DataSourceCreate"
+}
+
+
DataSourceRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "source_type": {
+      "$ref": "#/components/schemas/SourceType"
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "type": "boolean",
+      "title": "Schedule Enabled",
+      "default": true
+    },
+    "next_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Next Sync At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "last_ingestion_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Ingestion At"
+    },
+    "last_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync At"
+    },
+    "last_sync_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync Status"
+    },
+    "last_error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Error Message"
+    },
+    "consecutive_failure_count": {
+      "type": "integer",
+      "title": "Consecutive Failure Count",
+      "default": 0
+    },
+    "sync_paused": {
+      "type": "boolean",
+      "title": "Sync Paused",
+      "default": false
+    },
+    "health_status": {
+      "type": "string",
+      "title": "Health Status",
+      "default": "healthy"
+    },
+    "active_failure_count": {
+      "type": "integer",
+      "title": "Active Failure Count",
+      "default": 0
+    },
+    "connector_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connector Type"
+    },
+    "updated_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "source_type",
+    "is_active",
+    "created_by",
+    "created_at",
+    "last_ingestion_at"
+  ],
+  "title": "DataSourceRead",
+  "description": "Redacted datasource shape — safe for non-admin roles. connection_config omitted."
+}
+
+
DataSourceUpdate
+{
+  "properties": {
+    "name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Name"
+    },
+    "connection_config": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connection Config"
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Schedule Enabled"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "DataSourceUpdate"
+}
+
+
DeadlineCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "set-records-deadline",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/DeadlinePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "DeadlineCommand"
+}
+
+
DeadlinePayload
+{
+  "properties": {
+    "deadline": {
+      "type": "string",
+      "title": "Deadline"
+    },
+    "deadlineBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Deadlinebasis"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "deadline",
+    "deadlineBasis"
+  ],
+  "title": "DeadlinePayload"
+}
+
+
Decision
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "pattern": "^[A-Za-z0-9_-]{1,64}$",
+      "title": "Id"
+    },
+    "outcome": {
+      "type": "string",
+      "enum": [
+        "adopted",
+        "not_adopted",
+        "deferred",
+        "withdrawn"
+      ],
+      "title": "Outcome"
+    },
+    "decided_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Decided At"
+    },
+    "decision_text": {
+      "type": "string",
+      "maxLength": 1000000,
+      "minLength": 1,
+      "title": "Decision Text"
+    },
+    "supporting_references": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Supporting References"
+    },
+    "supersedes_decision_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^[A-Za-z0-9_-]{1,64}$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supersedes Decision Id"
+    },
+    "reconciliation_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reconciliation Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "outcome",
+    "decision_text"
+  ],
+  "title": "Decision"
+}
+
+
DepartmentCreate
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "code": {
+      "type": "string",
+      "title": "Code"
+    },
+    "contact_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Contact Email"
+    }
+  },
+  "type": "object",
+  "required": [
+    "name",
+    "code"
+  ],
+  "title": "DepartmentCreate"
+}
+
+
DepartmentRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "code": {
+      "type": "string",
+      "title": "Code"
+    },
+    "contact_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Contact Email"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "code",
+    "contact_email",
+    "created_at"
+  ],
+  "title": "DepartmentRead"
+}
+
+
DepartmentUpdate
+{
+  "properties": {
+    "name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Name"
+    },
+    "code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Code"
+    },
+    "contact_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Contact Email"
+    }
+  },
+  "type": "object",
+  "title": "DepartmentUpdate"
+}
+
+
DisclosureTemplateCreate
+{
+  "properties": {
+    "template_type": {
+      "type": "string",
+      "title": "Template Type"
+    },
+    "state_code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State Code"
+    },
+    "content": {
+      "type": "string",
+      "title": "Content"
+    }
+  },
+  "type": "object",
+  "required": [
+    "template_type",
+    "content"
+  ],
+  "title": "DisclosureTemplateCreate"
+}
+
+
DisclosureTemplateRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "template_type": {
+      "type": "string",
+      "title": "Template Type"
+    },
+    "state_code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State Code"
+    },
+    "content": {
+      "type": "string",
+      "title": "Content"
+    },
+    "version": {
+      "type": "integer",
+      "title": "Version"
+    },
+    "updated_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Updated By"
+    },
+    "updated_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "template_type",
+    "state_code",
+    "content",
+    "version",
+    "updated_by",
+    "updated_at"
+  ],
+  "title": "DisclosureTemplateRead"
+}
+
+
DisclosureTemplateRendered
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "template_type": {
+      "type": "string",
+      "title": "Template Type"
+    },
+    "rendered_content": {
+      "type": "string",
+      "title": "Rendered Content"
+    },
+    "has_unresolved_variables": {
+      "type": "boolean",
+      "title": "Has Unresolved Variables"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "template_type",
+    "rendered_content",
+    "has_unresolved_variables"
+  ],
+  "title": "DisclosureTemplateRendered"
+}
+
+
DisclosureTemplateUpdate
+{
+  "properties": {
+    "content": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Content"
+    },
+    "state_code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State Code"
+    }
+  },
+  "type": "object",
+  "title": "DisclosureTemplateUpdate"
+}
+
+
DocumentChunkRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "chunk_index": {
+      "type": "integer",
+      "title": "Chunk Index"
+    },
+    "content_text": {
+      "type": "string",
+      "title": "Content Text"
+    },
+    "token_count": {
+      "type": "integer",
+      "title": "Token Count"
+    },
+    "page_number": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Page Number"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "document_id",
+    "chunk_index",
+    "content_text",
+    "token_count",
+    "page_number"
+  ],
+  "title": "DocumentChunkRead"
+}
+
+
DocumentRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "source_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Source Id"
+    },
+    "source_path": {
+      "type": "string",
+      "title": "Source Path"
+    },
+    "filename": {
+      "type": "string",
+      "title": "Filename"
+    },
+    "file_type": {
+      "type": "string",
+      "title": "File Type"
+    },
+    "file_hash": {
+      "type": "string",
+      "title": "File Hash"
+    },
+    "file_size": {
+      "type": "integer",
+      "title": "File Size"
+    },
+    "ingestion_status": {
+      "$ref": "#/components/schemas/IngestionStatus"
+    },
+    "ingestion_error": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ingestion Error"
+    },
+    "chunk_count": {
+      "type": "integer",
+      "title": "Chunk Count"
+    },
+    "ingested_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ingested At"
+    },
+    "connector_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connector Type"
+    },
+    "updated_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "source_id",
+    "source_path",
+    "filename",
+    "file_type",
+    "file_hash",
+    "file_size",
+    "ingestion_status",
+    "ingestion_error",
+    "chunk_count",
+    "ingested_at"
+  ],
+  "title": "DocumentRead"
+}
+
+
DraftCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "draft-records-response",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/DraftPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "DraftCommand"
+}
+
+
DraftInput
+{
+  "properties": {
+    "source_materials": {
+      "items": {
+        "$ref": "#/components/schemas/SourceInput"
+      },
+      "type": "array",
+      "title": "Source Materials"
+    },
+    "sentences": {
+      "items": {
+        "$ref": "#/components/schemas/SentenceInput"
+      },
+      "type": "array",
+      "minItems": 1,
+      "title": "Sentences"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sentences"
+  ],
+  "title": "DraftInput"
+}
+
+
DraftPayload
+{
+  "properties": {
+    "responseDraft": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Responsedraft"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "responseDraft"
+  ],
+  "title": "DraftPayload"
+}
+
+
ErrorModel
+{
+  "properties": {
+    "detail": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "additionalProperties": {
+            "type": "string"
+          },
+          "type": "object"
+        }
+      ],
+      "title": "Detail"
+    }
+  },
+  "type": "object",
+  "required": [
+    "detail"
+  ],
+  "title": "ErrorModel"
+}
+
+
Evidence
+{
+  "properties": {
+    "filename": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$",
+      "title": "Filename"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Description"
+    },
+    "media_type": {
+      "type": "string",
+      "enum": [
+        "text/plain",
+        "image/jpeg",
+        "image/png",
+        "image/webp",
+        "application/pdf",
+        "audio/webm",
+        "audio/ogg",
+        "audio/wav",
+        "audio/mpeg",
+        "audio/mp4"
+      ],
+      "title": "Media Type"
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 14000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "filename",
+    "description",
+    "media_type",
+    "content_base64",
+    "sha256"
+  ],
+  "title": "Evidence"
+}
+
+
EvidenceItem
+{
+  "properties": {
+    "filename": {
+      "type": "string",
+      "maxLength": 151,
+      "minLength": 1,
+      "title": "Filename"
+    },
+    "media_type": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Media Type"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Description",
+      "default": ""
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 14000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "filename",
+    "media_type",
+    "content_base64",
+    "sha256"
+  ],
+  "title": "EvidenceItem"
+}
+
+
EvidenceItems
+{
+  "properties": {
+    "items": {
+      "items": {
+        "$ref": "#/components/schemas/EvidenceItem"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "minItems": 1,
+      "title": "Items"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "items"
+  ],
+  "title": "EvidenceItems"
+}
+
+
ExemptionAccuracyReport
+{
+  "properties": {
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "total_flags": {
+      "type": "integer",
+      "title": "Total Flags"
+    },
+    "accepted": {
+      "type": "integer",
+      "title": "Accepted"
+    },
+    "rejected": {
+      "type": "integer",
+      "title": "Rejected"
+    },
+    "pending": {
+      "type": "integer",
+      "title": "Pending"
+    },
+    "acceptance_rate": {
+      "type": "number",
+      "title": "Acceptance Rate"
+    }
+  },
+  "type": "object",
+  "required": [
+    "category",
+    "total_flags",
+    "accepted",
+    "rejected",
+    "pending",
+    "acceptance_rate"
+  ],
+  "title": "ExemptionAccuracyReport"
+}
+
+
ExemptionDashboard
+{
+  "properties": {
+    "total_flags": {
+      "type": "integer",
+      "title": "Total Flags"
+    },
+    "by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "By Status"
+    },
+    "by_category": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "By Category"
+    },
+    "acceptance_rate": {
+      "type": "number",
+      "title": "Acceptance Rate"
+    },
+    "total_rules": {
+      "type": "integer",
+      "title": "Total Rules"
+    },
+    "active_rules": {
+      "type": "integer",
+      "title": "Active Rules"
+    }
+  },
+  "type": "object",
+  "required": [
+    "total_flags",
+    "by_status",
+    "by_category",
+    "acceptance_rate",
+    "total_rules",
+    "active_rules"
+  ],
+  "title": "ExemptionDashboard"
+}
+
+
ExemptionDecisionCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-exemption-decision",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ExemptionDecisionPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "ExemptionDecisionCommand"
+}
+
+
ExemptionDecisionPayload
+{
+  "properties": {
+    "exemptionSource": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionsource"
+    },
+    "exemptionKind": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionkind"
+    },
+    "exemptionFinding": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionfinding"
+    },
+    "exemptionDecision": {
+      "type": "string",
+      "enum": [
+        "release",
+        "redact",
+        "exempt"
+      ],
+      "title": "Exemptiondecision"
+    },
+    "exemptionBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionbasis"
+    },
+    "exemptionReviewer": {
+      "type": "string",
+      "title": "Exemptionreviewer",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "exemptionSource",
+    "exemptionKind",
+    "exemptionFinding",
+    "exemptionDecision",
+    "exemptionBasis"
+  ],
+  "title": "ExemptionDecisionPayload"
+}
+
+
ExemptionDecisionView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "source": {
+      "type": "string",
+      "title": "Source"
+    },
+    "kind": {
+      "type": "string",
+      "title": "Kind"
+    },
+    "finding": {
+      "type": "string",
+      "title": "Finding"
+    },
+    "decision": {
+      "type": "string",
+      "enum": [
+        "release",
+        "redact",
+        "exempt"
+      ],
+      "title": "Decision"
+    },
+    "basis": {
+      "type": "string",
+      "title": "Basis"
+    },
+    "reviewer": {
+      "type": "string",
+      "title": "Reviewer"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "source",
+    "kind",
+    "finding",
+    "decision",
+    "basis",
+    "reviewer",
+    "created_at_unix_seconds"
+  ],
+  "title": "ExemptionDecisionView"
+}
+
+
ExemptionFlagRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "chunk_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Chunk Id"
+    },
+    "rule_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Rule Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "matched_text": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Matched Text"
+    },
+    "confidence": {
+      "type": "number",
+      "title": "Confidence"
+    },
+    "status": {
+      "$ref": "#/components/schemas/FlagStatus"
+    },
+    "reviewed_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reviewed By"
+    },
+    "reviewed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reviewed At"
+    },
+    "review_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Reason"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "chunk_id",
+    "rule_id",
+    "request_id",
+    "category",
+    "matched_text",
+    "confidence",
+    "status",
+    "reviewed_by",
+    "reviewed_at",
+    "review_reason",
+    "created_at"
+  ],
+  "title": "ExemptionFlagRead"
+}
+
+
ExemptionFlagReview
+{
+  "properties": {
+    "status": {
+      "$ref": "#/components/schemas/FlagStatus"
+    },
+    "review_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Reason"
+    }
+  },
+  "type": "object",
+  "required": [
+    "status"
+  ],
+  "title": "ExemptionFlagReview"
+}
+
+
ExemptionNoteCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-exemption-review",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ExemptionNotePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "ExemptionNoteCommand"
+}
+
+
ExemptionNotePayload
+{
+  "properties": {
+    "exemptionNote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionnote"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "exemptionNote"
+  ],
+  "title": "ExemptionNotePayload"
+}
+
+
ExemptionRuleCreate
+{
+  "properties": {
+    "state_code": {
+      "type": "string",
+      "title": "State Code"
+    },
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "rule_type": {
+      "$ref": "#/components/schemas/RuleType"
+    },
+    "rule_definition": {
+      "type": "string",
+      "title": "Rule Definition"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "enabled": {
+      "type": "boolean",
+      "title": "Enabled",
+      "default": true
+    }
+  },
+  "type": "object",
+  "required": [
+    "state_code",
+    "category",
+    "rule_type",
+    "rule_definition"
+  ],
+  "title": "ExemptionRuleCreate"
+}
+
+
ExemptionRuleRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "state_code": {
+      "type": "string",
+      "title": "State Code"
+    },
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "rule_type": {
+      "$ref": "#/components/schemas/RuleType"
+    },
+    "rule_definition": {
+      "type": "string",
+      "title": "Rule Definition"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "enabled": {
+      "type": "boolean",
+      "title": "Enabled"
+    },
+    "version": {
+      "type": "integer",
+      "title": "Version",
+      "default": 1
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "state_code",
+    "category",
+    "rule_type",
+    "rule_definition",
+    "description",
+    "enabled",
+    "created_by",
+    "created_at"
+  ],
+  "title": "ExemptionRuleRead"
+}
+
+
ExemptionRuleUpdate
+{
+  "properties": {
+    "rule_definition": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Rule Definition"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "enabled": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Enabled"
+    }
+  },
+  "type": "object",
+  "title": "ExemptionRuleUpdate"
+}
+
+
ExportReceipt
+{
+  "properties": {
+    "export_path": {
+      "type": "string",
+      "maxLength": 32768,
+      "minLength": 1,
+      "title": "Export Path"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "export_path"
+  ],
+  "title": "ExportReceipt"
+}
+
+
FeeEstimateCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "estimate-records-fee",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/FeeEstimatePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "FeeEstimateCommand"
+}
+
+
FeeEstimatePayload
+{
+  "properties": {
+    "feeEstimate": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feeestimate"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "feeEstimate"
+  ],
+  "title": "FeeEstimatePayload"
+}
+
+
FeeEstimateRequest
+{
+  "properties": {
+    "page_count": {
+      "type": "integer",
+      "title": "Page Count"
+    },
+    "fee_schedule_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Fee Schedule Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "page_count",
+    "fee_schedule_id"
+  ],
+  "title": "FeeEstimateRequest"
+}
+
+
FeeEstimateResponse
+{
+  "properties": {
+    "page_count": {
+      "type": "integer",
+      "title": "Page Count"
+    },
+    "unit_price": {
+      "type": "number",
+      "title": "Unit Price"
+    },
+    "total": {
+      "type": "number",
+      "title": "Total"
+    },
+    "fee_type": {
+      "type": "string",
+      "title": "Fee Type"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    }
+  },
+  "type": "object",
+  "required": [
+    "page_count",
+    "unit_price",
+    "total",
+    "fee_type",
+    "description"
+  ],
+  "title": "FeeEstimateResponse"
+}
+
+
FeeLineCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-fee-line",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/FeeLinePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "FeeLineCommand"
+}
+
+
FeeLineItemCreate
+{
+  "properties": {
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "quantity": {
+      "type": "integer",
+      "title": "Quantity",
+      "default": 1
+    },
+    "unit_price": {
+      "type": "number",
+      "title": "Unit Price"
+    },
+    "fee_schedule_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Schedule Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "description",
+    "unit_price"
+  ],
+  "title": "FeeLineItemCreate"
+}
+
+
FeeLineItemRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "fee_schedule_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Schedule Id"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "quantity": {
+      "type": "integer",
+      "title": "Quantity"
+    },
+    "unit_price": {
+      "type": "number",
+      "title": "Unit Price"
+    },
+    "total": {
+      "type": "number",
+      "title": "Total"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "fee_schedule_id",
+    "description",
+    "quantity",
+    "unit_price",
+    "total",
+    "status",
+    "created_at"
+  ],
+  "title": "FeeLineItemRead"
+}
+
+
FeeLinePayload
+{
+  "properties": {
+    "feeLineDescription": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feelinedescription"
+    },
+    "feeScheduleBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feeschedulebasis"
+    },
+    "feeLineAmount": {
+      "type": "string",
+      "title": "Feelineamount"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "feeLineDescription",
+    "feeScheduleBasis",
+    "feeLineAmount"
+  ],
+  "title": "FeeLinePayload"
+}
+
+
FeeLineView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "schedule_basis": {
+      "type": "string",
+      "title": "Schedule Basis"
+    },
+    "amount_cents": {
+      "type": "integer",
+      "title": "Amount Cents"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "description",
+    "schedule_basis",
+    "amount_cents",
+    "created_at_unix_seconds"
+  ],
+  "title": "FeeLineView"
+}
+
+
FeeScheduleCreate
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "title": "Jurisdiction"
+    },
+    "fee_type": {
+      "type": "string",
+      "title": "Fee Type"
+    },
+    "amount": {
+      "type": "number",
+      "title": "Amount"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "effective_date": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective Date"
+    }
+  },
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "fee_type",
+    "amount"
+  ],
+  "title": "FeeScheduleCreate"
+}
+
+
FeeScheduleRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "jurisdiction": {
+      "type": "string",
+      "title": "Jurisdiction"
+    },
+    "fee_type": {
+      "type": "string",
+      "title": "Fee Type"
+    },
+    "amount": {
+      "type": "number",
+      "title": "Amount"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "effective_date": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective Date"
+    },
+    "created_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "jurisdiction",
+    "fee_type",
+    "amount",
+    "description",
+    "effective_date",
+    "created_by",
+    "created_at"
+  ],
+  "title": "FeeScheduleRead"
+}
+
+
FeeScheduleUpdate
+{
+  "properties": {
+    "fee_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Type"
+    },
+    "amount": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Amount"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "effective_date": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective Date"
+    }
+  },
+  "type": "object",
+  "title": "FeeScheduleUpdate"
+}
+
+
FeeWaiverCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "waive-records-fee",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/FeeWaiverPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "FeeWaiverCommand"
+}
+
+
FeeWaiverCreateRequest
+{
+  "properties": {
+    "waiver_type": {
+      "type": "string",
+      "title": "Waiver Type"
+    },
+    "reason": {
+      "type": "string",
+      "title": "Reason"
+    }
+  },
+  "type": "object",
+  "required": [
+    "waiver_type",
+    "reason"
+  ],
+  "title": "FeeWaiverCreateRequest"
+}
+
+
FeeWaiverPayload
+{
+  "properties": {
+    "feeWaiverReason": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feewaiverreason"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "feeWaiverReason"
+  ],
+  "title": "FeeWaiverPayload"
+}
+
+
FeeWaiverReadResponse
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "waiver_type": {
+      "type": "string",
+      "title": "Waiver Type"
+    },
+    "reason": {
+      "type": "string",
+      "title": "Reason"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    },
+    "created_at": {
+      "type": "string",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "waiver_type",
+    "reason",
+    "status",
+    "created_at"
+  ],
+  "title": "FeeWaiverReadResponse"
+}
+
+
FeeWaiverReviewRequest
+{
+  "properties": {
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    }
+  },
+  "type": "object",
+  "required": [
+    "status"
+  ],
+  "title": "FeeWaiverReviewRequest"
+}
+
+
FinishCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "fulfill-records-request",
+        "close-records-request"
+      ],
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/NativePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "FinishCommand"
+}
+
+
FlagStatus
+{
+  "type": "string",
+  "enum": [
+    "flagged",
+    "reviewed",
+    "accepted",
+    "rejected"
+  ],
+  "title": "FlagStatus"
+}
+
+
FormPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "form-plan",
+      "title": "Action"
+    },
+    "formName": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Formname",
+      "default": ""
+    },
+    "fields": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 50,
+      "title": "Fields"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "FormPlan"
+}
+
+
GeneratedDraft
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "model": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Model"
+    },
+    "previous_response_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Previous Response Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text",
+    "model",
+    "previous_response_sha256"
+  ],
+  "title": "GeneratedDraft"
+}
+
+
HTTPValidationError
+{
+  "properties": {
+    "detail": {
+      "items": {
+        "$ref": "#/components/schemas/ValidationError"
+      },
+      "type": "array",
+      "title": "Detail"
+    }
+  },
+  "type": "object",
+  "title": "HTTPValidationError"
+}
+
+
Handoff
+{
+  "properties": {
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "request_id"
+  ],
+  "title": "Handoff"
+}
+
+
ImportBundleCreate
+{
+  "properties": {
+    "job_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Job Id"
+    },
+    "connector_type": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Connector Type"
+    },
+    "source": {
+      "$ref": "#/components/schemas/SourceCreate"
+    },
+    "sources": {
+      "items": {
+        "$ref": "#/components/schemas/SourceCreate"
+      },
+      "type": "array",
+      "title": "Sources"
+    },
+    "titles": {
+      "items": {
+        "$ref": "#/components/schemas/TitleCreate"
+      },
+      "type": "array",
+      "title": "Titles"
+    },
+    "chapters": {
+      "items": {
+        "$ref": "#/components/schemas/ChapterCreate"
+      },
+      "type": "array",
+      "title": "Chapters"
+    },
+    "sections": {
+      "items": {
+        "$ref": "#/components/schemas/SectionCreate"
+      },
+      "type": "array",
+      "title": "Sections"
+    },
+    "versions": {
+      "items": {
+        "$ref": "#/components/schemas/SectionVersionCreate"
+      },
+      "type": "array",
+      "title": "Versions"
+    },
+    "provenance": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Provenance"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "connector_type",
+    "source"
+  ],
+  "title": "ImportBundleCreate",
+  "description": "Request body for local fixture/file-drop import jobs."
+}
+
+
InclusionStatus
+{
+  "type": "string",
+  "enum": [
+    "included",
+    "excluded",
+    "pending"
+  ],
+  "title": "InclusionStatus"
+}
+
+
IngestionStats
+{
+  "properties": {
+    "total_sources": {
+      "type": "integer",
+      "title": "Total Sources"
+    },
+    "active_sources": {
+      "type": "integer",
+      "title": "Active Sources"
+    },
+    "total_documents": {
+      "type": "integer",
+      "title": "Total Documents"
+    },
+    "documents_by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "Documents By Status"
+    },
+    "total_chunks": {
+      "type": "integer",
+      "title": "Total Chunks"
+    }
+  },
+  "type": "object",
+  "required": [
+    "total_sources",
+    "active_sources",
+    "total_documents",
+    "documents_by_status",
+    "total_chunks"
+  ],
+  "title": "IngestionStats"
+}
+
+
IngestionStatus
+{
+  "type": "string",
+  "enum": [
+    "pending",
+    "processing",
+    "completed",
+    "failed"
+  ],
+  "title": "IngestionStatus"
+}
+
+
InitiativeInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "policy": {
+      "$ref": "#/components/schemas/PolicySelection"
+    },
+    "responsible_staff": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Responsible Staff"
+    },
+    "target": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "string"
+        }
+      ],
+      "title": "Target"
+    },
+    "unit": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Unit"
+    },
+    "due_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Due On"
+    },
+    "status": {
+      "type": "string",
+      "enum": [
+        "planned",
+        "active",
+        "completed",
+        "cancelled"
+      ],
+      "title": "Status",
+      "default": "planned"
+    },
+    "milestones": {
+      "items": {
+        "$ref": "#/components/schemas/Milestone"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "title": "Milestones"
+    },
+    "measurements": {
+      "items": {
+        "$ref": "#/components/schemas/Measurement"
+      },
+      "type": "array",
+      "maxItems": 1000,
+      "title": "Measurements"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "policy",
+    "responsible_staff",
+    "target",
+    "unit",
+    "due_on",
+    "note"
+  ],
+  "title": "InitiativeInput"
+}
+
+
InspectionInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "property_reference": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Property Reference"
+    },
+    "inspection_reference": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Inspection Reference"
+    },
+    "dataset_kind": {
+      "type": "string",
+      "enum": [
+        "municipal",
+        "fictional"
+      ],
+      "title": "Dataset Kind"
+    },
+    "inspector_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "minLength": 1,
+      "title": "Inspector Notes"
+    },
+    "photo_observations": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Photo Observations"
+    },
+    "voice_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Voice Notes",
+      "default": ""
+    },
+    "evidence": {
+      "items": {
+        "$ref": "#/components/schemas/Evidence"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "title": "Evidence"
+    },
+    "linked_sources": {
+      "items": {
+        "$ref": "#/components/schemas/townlight_inspections__workflow_models__SourceLink"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Linked Sources"
+    },
+    "assigned_to": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Assigned To",
+      "default": ""
+    },
+    "staff_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Staff Notes",
+      "default": ""
+    },
+    "notice_draft": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Notice Draft",
+      "default": ""
+    },
+    "review_state": {
+      "type": "string",
+      "enum": [
+        "draft",
+        "follow_up",
+        "reviewed"
+      ],
+      "title": "Review State",
+      "default": "draft"
+    },
+    "review_notes": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Review Notes",
+      "default": ""
+    },
+    "public_summary": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Public Summary",
+      "default": ""
+    },
+    "analysis": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/AnalysisRecord"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "property_reference",
+    "inspection_reference",
+    "dataset_kind",
+    "inspector_notes"
+  ],
+  "title": "InspectionInput"
+}
+
+
IntakeInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "project_name": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Project Name"
+    },
+    "project_description": {
+      "type": "string",
+      "maxLength": 10000,
+      "minLength": 1,
+      "title": "Project Description"
+    },
+    "location": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Location"
+    },
+    "applicant_contact": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Applicant Contact",
+      "default": ""
+    },
+    "requirement_revision": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Requirement Revision"
+    },
+    "materials": {
+      "items": {
+        "$ref": "#/components/schemas/MaterialReview"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "minItems": 1,
+      "title": "Materials"
+    },
+    "linked_sources": {
+      "items": {
+        "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Linked Sources"
+    },
+    "staff_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Staff Notes",
+      "default": ""
+    },
+    "assigned_to": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Assigned To",
+      "default": ""
+    },
+    "review_state": {
+      "type": "string",
+      "enum": [
+        "draft",
+        "follow_up",
+        "reviewed"
+      ],
+      "title": "Review State",
+      "default": "draft"
+    },
+    "review_notes": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Review Notes",
+      "default": ""
+    },
+    "public_summary": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Public Summary",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "project_name",
+    "project_description",
+    "location",
+    "requirement_revision",
+    "materials"
+  ],
+  "title": "IntakeInput"
+}
+
+
InterpretationNoteCreate
+{
+  "properties": {
+    "note_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Note Id"
+    },
+    "note_text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Note Text"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "note_text"
+  ],
+  "title": "InterpretationNoteCreate",
+  "description": "Request body for staff-only interpretation notes."
+}
+
+
InterviewRequest
+{
+  "properties": {
+    "last_answer": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Answer"
+    },
+    "last_field": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Field"
+    },
+    "skipped_fields": {
+      "anyOf": [
+        {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Skipped Fields"
+    }
+  },
+  "type": "object",
+  "title": "InterviewRequest"
+}
+
+
InterviewResponse
+{
+  "properties": {
+    "question": {
+      "type": "string",
+      "title": "Question"
+    },
+    "target_field": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Target Field"
+    },
+    "all_complete": {
+      "type": "boolean",
+      "title": "All Complete"
+    },
+    "completed_fields": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Completed Fields"
+    },
+    "onboarding_status": {
+      "type": "string",
+      "title": "Onboarding Status"
+    },
+    "skipped_fields": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Skipped Fields"
+    }
+  },
+  "type": "object",
+  "required": [
+    "question",
+    "target_field",
+    "all_complete",
+    "completed_fields",
+    "onboarding_status",
+    "skipped_fields"
+  ],
+  "title": "InterviewResponse"
+}
+
+
ManagedFileReceipt
+{
+  "properties": {
+    "original_path": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Original Path"
+    },
+    "stored_path": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Stored Path"
+    },
+    "file_name": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "File Name"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Sha256"
+    },
+    "size_bytes": {
+      "type": "integer",
+      "maximum": 2147483647.0,
+      "minimum": 0.0,
+      "title": "Size Bytes"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "original_path",
+    "stored_path",
+    "file_name",
+    "sha256",
+    "size_bytes"
+  ],
+  "title": "ManagedFileReceipt"
+}
+
+
ManagedSource
+{
+  "properties": {
+    "original_path": {
+      "type": "string",
+      "title": "Original Path"
+    },
+    "stored_path": {
+      "type": "string",
+      "title": "Stored Path"
+    },
+    "file_name": {
+      "type": "string",
+      "title": "File Name"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Sha256"
+    },
+    "size_bytes": {
+      "type": "integer",
+      "minimum": 0.0,
+      "title": "Size Bytes"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "original_path",
+    "stored_path",
+    "file_name",
+    "sha256",
+    "size_bytes"
+  ],
+  "title": "ManagedSource"
+}
+
+
Material
+{
+  "properties": {
+    "material_id": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9_-]{1,80}$",
+      "title": "Material Id"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Description"
+    },
+    "citation": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Citation"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "material_id",
+    "description",
+    "citation"
+  ],
+  "title": "Material"
+}
+
+
MaterialReview
+{
+  "properties": {
+    "material_id": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Material Id"
+    },
+    "status": {
+      "type": "string",
+      "enum": [
+        "not_reviewed",
+        "provided",
+        "missing",
+        "unclear"
+      ],
+      "title": "Status",
+      "default": "not_reviewed"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Note",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "material_id"
+  ],
+  "title": "MaterialReview"
+}
+
+
Measurement
+{
+  "properties": {
+    "recorded_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Recorded On"
+    },
+    "value": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "string"
+        }
+      ],
+      "title": "Value"
+    },
+    "evidence": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Evidence"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "recorded_on",
+    "value",
+    "evidence"
+  ],
+  "title": "Measurement"
+}
+
+
MediaAnalysis
+{
+  "properties": {
+    "items": {
+      "items": {
+        "$ref": "#/components/schemas/EvidenceItem"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "minItems": 1,
+      "title": "Items"
+    },
+    "code_links": {
+      "items": {
+        "$ref": "#/components/schemas/CodeLink"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Code Links"
+    },
+    "inspector_supplied_text": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Inspector Supplied Text",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "items"
+  ],
+  "title": "MediaAnalysis"
+}
+
+
MeetingInput
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "scheduled_start": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Scheduled Start"
+    },
+    "location": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Location"
+    },
+    "meeting_type": {
+      "type": "string",
+      "enum": [
+        "regular",
+        "special",
+        "emergency",
+        "closed_session",
+        "executive"
+      ],
+      "title": "Meeting Type",
+      "default": "regular"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "scheduled_start",
+    "location"
+  ],
+  "title": "MeetingInput"
+}
+
+
MeetingLink
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 200,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    },
+    "relation": {
+      "type": "string",
+      "enum": [
+        "hearing",
+        "context",
+        "precedent"
+      ],
+      "title": "Relation"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256",
+    "relation"
+  ],
+  "title": "MeetingLink"
+}
+
+
MeetingSearch
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "MeetingSearch"
+}
+
+
MeetingStageInput
+{
+  "properties": {
+    "to_status": {
+      "type": "string",
+      "enum": [
+        "SCHEDULED",
+        "NOTICED",
+        "PACKET_POSTED",
+        "IN_PROGRESS",
+        "RECESSED",
+        "ADJOURNED",
+        "TRANSCRIPT_READY",
+        "MINUTES_DRAFTED",
+        "MINUTES_POSTED",
+        "MINUTES_ADOPTED",
+        "MINUTES_SIGNED",
+        "ARCHIVED",
+        "CANCELLED"
+      ],
+      "title": "To Status"
+    },
+    "statutory_basis": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Basis"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "to_status"
+  ],
+  "title": "MeetingStageInput"
+}
+
+
MeetingsSearch
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "MeetingsSearch"
+}
+
+
MeetingsSourceSelection
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 200,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "MeetingsSourceSelection"
+}
+
+
MessageCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-message",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/MessagePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "MessageCommand"
+}
+
+
MessageCreate
+{
+  "properties": {
+    "message_text": {
+      "type": "string",
+      "title": "Message Text"
+    },
+    "is_internal": {
+      "type": "boolean",
+      "title": "Is Internal",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "message_text"
+  ],
+  "title": "MessageCreate"
+}
+
+
MessagePayload
+{
+  "properties": {
+    "requestMessageBody": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestmessagebody"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requestMessageBody"
+  ],
+  "title": "MessagePayload"
+}
+
+
MessageRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "sender_type": {
+      "type": "string",
+      "title": "Sender Type"
+    },
+    "sender_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sender Id"
+    },
+    "message_text": {
+      "type": "string",
+      "title": "Message Text"
+    },
+    "is_internal": {
+      "type": "boolean",
+      "title": "Is Internal"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "sender_type",
+    "sender_id",
+    "message_text",
+    "is_internal",
+    "created_at"
+  ],
+  "title": "MessageRead"
+}
+
+
MessageView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "author": {
+      "type": "string",
+      "title": "Author"
+    },
+    "author_role": {
+      "type": "string",
+      "title": "Author Role"
+    },
+    "body": {
+      "type": "string",
+      "title": "Body"
+    },
+    "visibility": {
+      "type": "string",
+      "title": "Visibility"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "author",
+    "author_role",
+    "body",
+    "visibility",
+    "created_at_unix_seconds"
+  ],
+  "title": "MessageView"
+}
+
+
Milestone
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "due_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Due On"
+    },
+    "completed_on": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Completed On"
+    },
+    "evidence": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Evidence",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "due_on"
+  ],
+  "title": "Milestone"
+}
+
+
MinutesDecision
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "post",
+        "adopt",
+        "sign"
+      ],
+      "title": "Action"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "MinutesDecision"
+}
+
+
ModelRegistryCreate
+{
+  "properties": {
+    "model_name": {
+      "type": "string",
+      "title": "Model Name"
+    },
+    "model_version": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Version"
+    },
+    "parameter_count": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parameter Count"
+    },
+    "license": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "License"
+    },
+    "model_card_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Card Url"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active",
+      "default": false
+    },
+    "context_window_size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Context Window Size"
+    },
+    "supports_ner": {
+      "type": "boolean",
+      "title": "Supports Ner",
+      "default": false
+    },
+    "supports_vision": {
+      "type": "boolean",
+      "title": "Supports Vision",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "model_name"
+  ],
+  "title": "ModelRegistryCreate",
+  "description": "Schema for creating a new model_registry record (POST body)."
+}
+
+
ModelRegistryRead
+{
+  "properties": {
+    "id": {
+      "type": "integer",
+      "title": "Id"
+    },
+    "model_name": {
+      "type": "string",
+      "title": "Model Name"
+    },
+    "model_version": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Version"
+    },
+    "parameter_count": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parameter Count"
+    },
+    "license": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "License"
+    },
+    "model_card_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Card Url"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "added_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Added At"
+    },
+    "context_window_size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Context Window Size"
+    },
+    "supports_ner": {
+      "type": "boolean",
+      "title": "Supports Ner"
+    },
+    "supports_vision": {
+      "type": "boolean",
+      "title": "Supports Vision"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "model_name",
+    "is_active",
+    "supports_ner",
+    "supports_vision"
+  ],
+  "title": "ModelRegistryRead",
+  "description": "Schema for returning a model_registry record (GET response).\n\n``from_attributes=True`` allows construction directly from an ORM instance."
+}
+
+
ModelRegistryUpdate
+{
+  "properties": {
+    "model_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Name"
+    },
+    "model_version": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Version"
+    },
+    "parameter_count": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parameter Count"
+    },
+    "license": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "License"
+    },
+    "model_card_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Card Url"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    },
+    "context_window_size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Context Window Size"
+    },
+    "supports_ner": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supports Ner"
+    },
+    "supports_vision": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supports Vision"
+    }
+  },
+  "type": "object",
+  "title": "ModelRegistryUpdate",
+  "description": "Schema for partially updating a model_registry record (PATCH body).\n\nEvery field is optional so callers can send only the fields they want to\nchange."
+}
+
+
MotionCorrection
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "reason": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Reason"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text",
+    "reason"
+  ],
+  "title": "MotionCorrection"
+}
+
+
MotionInput
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "seconded_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "minLength": 1
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Seconded By"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text"
+  ],
+  "title": "MotionInput"
+}
+
+
NativePayload
+{
+  "properties": {},
+  "additionalProperties": false,
+  "type": "object",
+  "title": "NativePayload"
+}
+
+
NativeRequestRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "requester_name": {
+      "type": "string",
+      "title": "Requester Name"
+    },
+    "requester_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Email"
+    },
+    "requester_phone": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Phone"
+    },
+    "requester_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Type"
+    },
+    "date_received": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Date Received"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "status": {
+      "$ref": "#/components/schemas/RequestStatus"
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "created_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "response_draft": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Response Draft"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    },
+    "estimated_fee": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Estimated Fee"
+    },
+    "fee_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Status"
+    },
+    "fee_waiver_requested": {
+      "type": "boolean",
+      "title": "Fee Waiver Requested",
+      "default": false
+    },
+    "priority": {
+      "type": "string",
+      "title": "Priority",
+      "default": "normal"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    },
+    "closed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closed At"
+    },
+    "closure_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closure Reason"
+    },
+    "desktop_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Desktop Id"
+    },
+    "public_tracking_number": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Public Tracking Number"
+    },
+    "submitted_via": {
+      "type": "string",
+      "title": "Submitted Via"
+    },
+    "deadline_label": {
+      "type": "string",
+      "title": "Deadline Label"
+    },
+    "deadline_basis": {
+      "type": "string",
+      "title": "Deadline Basis"
+    },
+    "deadline_reviewed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Deadline Reviewed At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "requester_name",
+    "requester_email",
+    "date_received",
+    "statutory_deadline",
+    "description",
+    "status",
+    "assigned_to",
+    "created_by",
+    "created_at",
+    "response_draft",
+    "review_notes",
+    "desktop_id",
+    "public_tracking_number",
+    "submitted_via",
+    "deadline_label",
+    "deadline_basis",
+    "deadline_reviewed_at"
+  ],
+  "title": "NativeRequestRead"
+}
+
+
NoticeDocumentInput
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text"
+  ],
+  "title": "NoticeDocumentInput"
+}
+
+
NoticeDraft
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 100000,
+      "minLength": 1,
+      "title": "Body"
+    },
+    "notice_type": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Notice Type"
+    },
+    "statutory_basis": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Statutory Basis"
+    },
+    "event_date": {
+      "type": "string",
+      "format": "date",
+      "title": "Event Date"
+    },
+    "lead_days": {
+      "type": "integer",
+      "maximum": 365.0,
+      "minimum": 0.0,
+      "title": "Lead Days"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "body",
+    "notice_type",
+    "statutory_basis",
+    "event_date",
+    "lead_days"
+  ],
+  "title": "NoticeDraft"
+}
+
+
NoticeInput
+{
+  "properties": {
+    "notice_type": {
+      "type": "string",
+      "enum": [
+        "regular",
+        "special",
+        "emergency",
+        "closed_session",
+        "executive"
+      ],
+      "title": "Notice Type"
+    },
+    "posted_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Posted At"
+    },
+    "minimum_notice_hours": {
+      "type": "integer",
+      "minimum": 0.0,
+      "title": "Minimum Notice Hours"
+    },
+    "statutory_basis": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Basis"
+    },
+    "approved_by": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Approved By"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "notice_type",
+    "posted_at",
+    "minimum_notice_hours"
+  ],
+  "title": "NoticeInput"
+}
+
+
NoticeProofInput
+{
+  "properties": {
+    "location": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Location"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note",
+      "default": ""
+    },
+    "document_delivery_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Document Delivery Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "location"
+  ],
+  "title": "NoticeProofInput"
+}
+
+
NotificationLogRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "template_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Template Id"
+    },
+    "recipient_email": {
+      "type": "string",
+      "title": "Recipient Email"
+    },
+    "request_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Request Id"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "sent_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sent At"
+    },
+    "error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Message"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "template_id",
+    "recipient_email",
+    "request_id",
+    "channel",
+    "status",
+    "sent_at",
+    "error_message",
+    "created_at"
+  ],
+  "title": "NotificationLogRead"
+}
+
+
NotificationTemplateCreate
+{
+  "properties": {
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel",
+      "default": "email"
+    },
+    "subject_template": {
+      "type": "string",
+      "title": "Subject Template"
+    },
+    "body_template": {
+      "type": "string",
+      "title": "Body Template"
+    }
+  },
+  "type": "object",
+  "required": [
+    "event_type",
+    "subject_template",
+    "body_template"
+  ],
+  "title": "NotificationTemplateCreate"
+}
+
+
NotificationTemplateRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel"
+    },
+    "subject_template": {
+      "type": "string",
+      "title": "Subject Template"
+    },
+    "body_template": {
+      "type": "string",
+      "title": "Body Template"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "event_type",
+    "channel",
+    "subject_template",
+    "body_template",
+    "is_active",
+    "created_at"
+  ],
+  "title": "NotificationTemplateRead"
+}
+
+
NotificationTemplateUpdate
+{
+  "properties": {
+    "subject_template": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Subject Template"
+    },
+    "body_template": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Body Template"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "NotificationTemplateUpdate"
+}
+
+
NotificationView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "notification_id": {
+      "type": "string",
+      "title": "Notification Id"
+    },
+    "module_id": {
+      "type": "string",
+      "title": "Module Id"
+    },
+    "record_id": {
+      "type": "string",
+      "title": "Record Id"
+    },
+    "audience": {
+      "type": "string",
+      "title": "Audience"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel"
+    },
+    "subject": {
+      "type": "string",
+      "title": "Subject"
+    },
+    "body": {
+      "type": "string",
+      "title": "Body"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    },
+    "sent_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sent At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "notification_id",
+    "module_id",
+    "record_id",
+    "audience",
+    "channel",
+    "subject",
+    "body",
+    "status",
+    "created_at_unix_seconds",
+    "sent_at_unix_seconds"
+  ],
+  "title": "NotificationView"
+}
+
+
OllamaModelInfo
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Size"
+    },
+    "details": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Details"
+    }
+  },
+  "type": "object",
+  "required": [
+    "name"
+  ],
+  "title": "OllamaModelInfo"
+}
+
+
OllamaStatus
+{
+  "properties": {
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "models": {
+      "items": {
+        "$ref": "#/components/schemas/OllamaModelInfo"
+      },
+      "type": "array",
+      "title": "Models"
+    }
+  },
+  "type": "object",
+  "required": [
+    "status",
+    "models"
+  ],
+  "title": "OllamaStatus"
+}
+
+
OperationalMetrics
+{
+  "properties": {
+    "average_response_time_days": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Average Response Time Days"
+    },
+    "median_response_time_days": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Median Response Time Days"
+    },
+    "requests_by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "Requests By Status"
+    },
+    "requests_by_department": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "Requests By Department"
+    },
+    "deadline_compliance_rate": {
+      "type": "number",
+      "title": "Deadline Compliance Rate"
+    },
+    "total_open": {
+      "type": "integer",
+      "title": "Total Open"
+    },
+    "total_closed": {
+      "type": "integer",
+      "title": "Total Closed"
+    },
+    "total_overdue": {
+      "type": "integer",
+      "title": "Total Overdue"
+    },
+    "clarification_frequency": {
+      "type": "number",
+      "title": "Clarification Frequency"
+    },
+    "top_request_topics": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Top Request Topics"
+    }
+  },
+  "type": "object",
+  "required": [
+    "average_response_time_days",
+    "median_response_time_days",
+    "requests_by_status",
+    "requests_by_department",
+    "deadline_compliance_rate",
+    "total_open",
+    "total_closed",
+    "total_overdue",
+    "clarification_frequency",
+    "top_request_topics"
+  ],
+  "title": "OperationalMetrics"
+}
+
+
Outline
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "question_ids": {
+      "items": {
+        "type": "string",
+        "format": "uuid"
+      },
+      "type": "array",
+      "maxItems": 50,
+      "minItems": 1,
+      "title": "Question Ids"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "question_ids"
+  ],
+  "title": "Outline"
+}
+
+
Packet
+{
+  "properties": {
+    "expected_revision": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Expected Revision"
+    },
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "staff_only",
+        "records_copy"
+      ],
+      "title": "Visibility"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "expected_revision",
+    "visibility"
+  ],
+  "title": "Packet"
+}
+
+
PacketInput
+{
+  "properties": {
+    "agenda_item_ids": {
+      "items": {
+        "type": "string",
+        "format": "uuid"
+      },
+      "type": "array",
+      "title": "Agenda Item Ids"
+    },
+    "source_files": {
+      "items": {
+        "$ref": "#/components/schemas/ManagedSource"
+      },
+      "type": "array",
+      "title": "Source Files"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "agenda_item_ids"
+  ],
+  "title": "PacketInput"
+}
+
+
Pathway
+{
+  "properties": {
+    "project_type": {
+      "type": "string",
+      "maxLength": 120,
+      "minLength": 1,
+      "title": "Project Type"
+    },
+    "proposal": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Proposal",
+      "default": ""
+    },
+    "location_context": {
+      "type": "string",
+      "maxLength": 1000,
+      "title": "Location Context",
+      "default": ""
+    },
+    "requirement_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requirement Revision"
+    },
+    "fee_link": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "project_type"
+  ],
+  "title": "Pathway"
+}
+
+
PathwayStep
+{
+  "properties": {
+    "step": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Step"
+    },
+    "citation": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Citation"
+    },
+    "typical_time": {
+      "type": "string",
+      "maxLength": 1000,
+      "title": "Typical Time",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "step",
+    "citation"
+  ],
+  "title": "PathwayStep"
+}
+
+
PlainLanguageSummaryCreate
+{
+  "properties": {
+    "summary_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Summary Id"
+    },
+    "section_version_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Version Id"
+    },
+    "summary_text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Summary Text"
+    },
+    "language_code": {
+      "type": "string",
+      "title": "Language Code",
+      "default": "en"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "section_version_id",
+    "summary_text"
+  ],
+  "title": "PlainLanguageSummaryCreate",
+  "description": "Request body for staff-drafted plain-language summaries."
+}
+
+
PolicySelection
+{
+  "properties": {
+    "plan_id": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Plan Id"
+    },
+    "revision_id": {
+      "type": "string",
+      "maxLength": 36,
+      "minLength": 36,
+      "title": "Revision Id"
+    },
+    "policy_id": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Policy Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "plan_id",
+    "revision_id",
+    "policy_id"
+  ],
+  "title": "PolicySelection"
+}
+
+
PortalModeResponse
+{
+  "properties": {
+    "mode": {
+      "type": "string",
+      "enum": [
+        "public",
+        "private"
+      ],
+      "title": "Mode",
+      "description": "Active portal posture for this deployment. ``public`` = minimal resident surface (landing + authenticated records-request submission + resident registration) reachable without staff auth. ``private`` = staff-only; no public routes, no resident self-registration."
+    }
+  },
+  "type": "object",
+  "required": [
+    "mode"
+  ],
+  "title": "PortalModeResponse",
+  "description": "T5D — schema for ``GET /config/portal-mode``.\n\nExposed to the frontend on boot so it can branch routing without a\nuser-identity lookup. The payload is intentionally the single field\nbelow — no staff config, no user state, no schema version."
+}
+
+
PrepareArtifact
+{
+  "properties": {
+    "kind": {
+      "type": "string",
+      "enum": [
+        "response",
+        "release-package"
+      ],
+      "title": "Kind"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "kind"
+  ],
+  "title": "PrepareArtifact"
+}
+
+
Proof
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    },
+    "filename": {
+      "type": "string",
+      "maxLength": 150,
+      "minLength": 1,
+      "title": "Filename"
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 7000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "location": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Location"
+    },
+    "published_at": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Published At"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence",
+    "filename",
+    "content_base64",
+    "location",
+    "published_at"
+  ],
+  "title": "Proof"
+}
+
+
Proposal
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "pattern": "^[A-Za-z0-9_-]{1,64}$",
+      "title": "Id"
+    },
+    "version_id": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Version Id"
+    },
+    "meeting_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Meeting Id"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "ordinance_number": {
+      "type": "string",
+      "maxLength": 120,
+      "minLength": 1,
+      "title": "Ordinance Number"
+    },
+    "proposed_text": {
+      "type": "string",
+      "maxLength": 1000000,
+      "minLength": 1,
+      "title": "Proposed Text"
+    },
+    "supersedes_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^[A-Za-z0-9_-]{1,64}$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supersedes Id"
+    },
+    "reconciliation_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reconciliation Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "version_id",
+    "meeting_id",
+    "title",
+    "ordinance_number",
+    "proposed_text"
+  ],
+  "title": "Proposal"
+}
+
+
PublicExplore
+{
+  "properties": {
+    "goal": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Goal",
+      "default": ""
+    },
+    "topic": {
+      "type": "string",
+      "maxLength": 160,
+      "title": "Topic",
+      "default": ""
+    },
+    "neighborhood": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Neighborhood",
+      "default": ""
+    },
+    "plan_type": {
+      "type": "string",
+      "maxLength": 120,
+      "title": "Plan Type",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "PublicExplore"
+}
+
+
PublicIntake
+{
+  "properties": {
+    "requester": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requester"
+    },
+    "requesterContact": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestercontact"
+    },
+    "summary": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Summary"
+    },
+    "deadline": {
+      "type": "string",
+      "title": "Deadline",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requester",
+    "requesterContact",
+    "summary"
+  ],
+  "title": "PublicIntake"
+}
+
+
PublicLookup
+{
+  "properties": {
+    "trackingNumber": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Trackingnumber"
+    },
+    "requesterContact": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestercontact"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "trackingNumber",
+    "requesterContact"
+  ],
+  "title": "PublicLookup"
+}
+
+
PublicMessage
+{
+  "properties": {
+    "trackingNumber": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Trackingnumber"
+    },
+    "requesterContact": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestercontact"
+    },
+    "publicRequestMessage": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Publicrequestmessage"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "trackingNumber",
+    "requesterContact",
+    "publicRequestMessage"
+  ],
+  "title": "PublicMessage"
+}
+
+
PublicStatusView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "label": {
+      "type": "string",
+      "title": "Label"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "label",
+    "summary",
+    "status",
+    "created_at_unix_seconds"
+  ],
+  "title": "PublicStatusView"
+}
+
+
PublicationView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "source_module": {
+      "type": "string",
+      "title": "Source Module"
+    },
+    "source_record_id": {
+      "type": "string",
+      "title": "Source Record Id"
+    },
+    "record_type": {
+      "type": "string",
+      "title": "Record Type"
+    },
+    "public_payload": {
+      "type": "string",
+      "title": "Public Payload"
+    },
+    "payload_hash": {
+      "type": "string",
+      "title": "Payload Hash"
+    },
+    "published_at_unix_seconds": {
+      "type": "integer",
+      "title": "Published At Unix Seconds"
+    },
+    "retracted_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Retracted At Unix Seconds"
+    },
+    "retracted_by": {
+      "type": "string",
+      "title": "Retracted By",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "source_module",
+    "source_record_id",
+    "record_type",
+    "public_payload",
+    "payload_hash",
+    "published_at_unix_seconds"
+  ],
+  "title": "PublicationView"
+}
+
+
PublishingPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "publishing-workflow",
+      "title": "Action"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "hasReview": {
+      "type": "boolean",
+      "title": "Hasreview",
+      "default": false
+    },
+    "hasPlainLanguage": {
+      "type": "boolean",
+      "title": "Hasplainlanguage",
+      "default": false
+    },
+    "hasTranslationReview": {
+      "type": "boolean",
+      "title": "Hastranslationreview",
+      "default": false
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "PublishingPlan"
+}
+
+
Question
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    },
+    "question": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Question"
+    },
+    "kind": {
+      "type": "string",
+      "enum": [
+        "use",
+        "dimension"
+      ],
+      "title": "Kind"
+    },
+    "key": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Key"
+    },
+    "audience": {
+      "type": "string",
+      "enum": [
+        "resident",
+        "staff"
+      ],
+      "title": "Audience",
+      "default": "resident"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "query",
+    "question",
+    "kind",
+    "key"
+  ],
+  "title": "Question"
+}
+
+
QuestionAnswerRequest
+{
+  "properties": {
+    "question": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Question"
+    },
+    "section_number": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Section Number"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "question"
+  ],
+  "title": "QuestionAnswerRequest",
+  "description": "Request body for citation-grounded code Q&A."
+}
+
+
RecordsDocumentView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "attachment_id": {
+      "type": "string",
+      "title": "Attachment Id"
+    },
+    "title": {
+      "type": "string",
+      "title": "Title"
+    },
+    "original_path": {
+      "type": "string",
+      "title": "Original Path"
+    },
+    "stored_path": {
+      "type": "string",
+      "title": "Stored Path"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation"
+    },
+    "sha256": {
+      "type": "string",
+      "title": "Sha256"
+    },
+    "size_bytes": {
+      "type": "integer",
+      "title": "Size Bytes"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "added_by": {
+      "type": "string",
+      "title": "Added By"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    },
+    "release_original_path": {
+      "type": "string",
+      "title": "Release Original Path",
+      "default": ""
+    },
+    "release_stored_path": {
+      "type": "string",
+      "title": "Release Stored Path",
+      "default": ""
+    },
+    "release_file_name": {
+      "type": "string",
+      "title": "Release File Name",
+      "default": ""
+    },
+    "release_sha256": {
+      "type": "string",
+      "title": "Release Sha256",
+      "default": ""
+    },
+    "release_size_bytes": {
+      "type": "integer",
+      "title": "Release Size Bytes",
+      "default": 0
+    },
+    "release_status": {
+      "type": "string",
+      "title": "Release Status",
+      "default": ""
+    },
+    "release_note": {
+      "type": "string",
+      "title": "Release Note",
+      "default": ""
+    },
+    "release_added_by": {
+      "type": "string",
+      "title": "Release Added By",
+      "default": ""
+    },
+    "release_added_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Release Added At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "attachment_id",
+    "title",
+    "original_path",
+    "stored_path",
+    "citation",
+    "sha256",
+    "size_bytes",
+    "status",
+    "added_by",
+    "created_at_unix_seconds"
+  ],
+  "title": "RecordsDocumentView"
+}
+
+
RecordsOperationRead
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "message": {
+      "type": "string",
+      "title": "Message"
+    },
+    "request": {
+      "$ref": "#/components/schemas/RecordsView"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "message",
+    "request"
+  ],
+  "title": "RecordsOperationRead"
+}
+
+
RecordsStateRead
+{
+  "properties": {
+    "demo_fixture": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Demo Fixture"
+    },
+    "records_requests": {
+      "items": {
+        "$ref": "#/components/schemas/RecordsView"
+      },
+      "type": "array",
+      "title": "Records Requests"
+    },
+    "notification_events": {
+      "items": {
+        "$ref": "#/components/schemas/NotificationView"
+      },
+      "type": "array",
+      "title": "Notification Events"
+    },
+    "publication_events": {
+      "items": {
+        "$ref": "#/components/schemas/PublicationView"
+      },
+      "type": "array",
+      "title": "Publication Events"
+    },
+    "audit_entries": {
+      "items": {
+        "$ref": "#/components/schemas/AuditView"
+      },
+      "type": "array",
+      "title": "Audit Entries"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "records_requests"
+  ],
+  "title": "RecordsStateRead"
+}
+
+
RecordsView
+{
+  "properties": {
+    "request_id": {
+      "type": "string",
+      "title": "Request Id"
+    },
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "public_tracking_number": {
+      "type": "string",
+      "title": "Public Tracking Number"
+    },
+    "requester": {
+      "type": "string",
+      "title": "Requester"
+    },
+    "requester_contact": {
+      "type": "string",
+      "title": "Requester Contact"
+    },
+    "submitted_via": {
+      "type": "string",
+      "title": "Submitted Via"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "deadline": {
+      "type": "string",
+      "title": "Deadline"
+    },
+    "deadline_basis": {
+      "type": "string",
+      "title": "Deadline Basis"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "assigned_to": {
+      "type": "string",
+      "title": "Assigned To"
+    },
+    "clarification_notes": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Clarification Notes"
+    },
+    "search_notes": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Search Notes"
+    },
+    "search_sessions": {
+      "items": {
+        "$ref": "#/components/schemas/SearchReceiptView"
+      },
+      "type": "array",
+      "title": "Search Sessions"
+    },
+    "exemption_reviews": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Exemption Reviews"
+    },
+    "exemption_decisions": {
+      "items": {
+        "$ref": "#/components/schemas/ExemptionDecisionView"
+      },
+      "type": "array",
+      "title": "Exemption Decisions"
+    },
+    "fee_estimate": {
+      "type": "string",
+      "title": "Fee Estimate"
+    },
+    "fee_line_items": {
+      "items": {
+        "$ref": "#/components/schemas/FeeLineView"
+      },
+      "type": "array",
+      "title": "Fee Line Items"
+    },
+    "fee_waiver_reason": {
+      "type": "string",
+      "title": "Fee Waiver Reason"
+    },
+    "citations": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Citations"
+    },
+    "response_draft": {
+      "type": "string",
+      "title": "Response Draft"
+    },
+    "approval_notes": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Approval Notes"
+    },
+    "exports": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Exports"
+    },
+    "documents": {
+      "items": {
+        "$ref": "#/components/schemas/RecordsDocumentView"
+      },
+      "type": "array",
+      "title": "Documents"
+    },
+    "release_packages": {
+      "items": {
+        "$ref": "#/components/schemas/ReleasePackageView"
+      },
+      "type": "array",
+      "title": "Release Packages"
+    },
+    "timeline": {
+      "items": {
+        "$ref": "#/components/schemas/TimelineView"
+      },
+      "type": "array",
+      "title": "Timeline"
+    },
+    "public_status_events": {
+      "items": {
+        "$ref": "#/components/schemas/PublicStatusView"
+      },
+      "type": "array",
+      "title": "Public Status Events"
+    },
+    "messages": {
+      "items": {
+        "$ref": "#/components/schemas/MessageView"
+      },
+      "type": "array",
+      "title": "Messages"
+    },
+    "deadline_reviewed_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Deadline Reviewed At Unix Seconds"
+    },
+    "approved_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Approved At Unix Seconds"
+    },
+    "fulfilled_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fulfilled At Unix Seconds"
+    },
+    "closed_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closed At Unix Seconds"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "request_id",
+    "id",
+    "public_tracking_number",
+    "requester",
+    "requester_contact",
+    "submitted_via",
+    "summary",
+    "deadline",
+    "deadline_basis",
+    "status",
+    "assigned_to",
+    "clarification_notes",
+    "search_notes",
+    "search_sessions",
+    "exemption_reviews",
+    "exemption_decisions",
+    "fee_estimate",
+    "fee_line_items",
+    "fee_waiver_reason",
+    "citations",
+    "response_draft",
+    "approval_notes",
+    "exports",
+    "timeline",
+    "public_status_events",
+    "messages",
+    "deadline_reviewed_at_unix_seconds",
+    "approved_at_unix_seconds",
+    "fulfilled_at_unix_seconds",
+    "closed_at_unix_seconds",
+    "created_at_unix_seconds"
+  ],
+  "title": "RecordsView"
+}
+
+
ReleasePackageView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "export_path": {
+      "type": "string",
+      "title": "Export Path"
+    },
+    "package_hash": {
+      "type": "string",
+      "title": "Package Hash"
+    },
+    "document_count": {
+      "type": "integer",
+      "title": "Document Count"
+    },
+    "release_artifact_count": {
+      "type": "integer",
+      "title": "Release Artifact Count"
+    },
+    "search_session_count": {
+      "type": "integer",
+      "title": "Search Session Count"
+    },
+    "release_count": {
+      "type": "integer",
+      "title": "Release Count"
+    },
+    "redacted_count": {
+      "type": "integer",
+      "title": "Redacted Count"
+    },
+    "exempt_count": {
+      "type": "integer",
+      "title": "Exempt Count"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "export_path",
+    "package_hash",
+    "document_count",
+    "release_artifact_count",
+    "search_session_count",
+    "release_count",
+    "redacted_count",
+    "exempt_count",
+    "created_at_unix_seconds"
+  ],
+  "title": "ReleasePackageView"
+}
+
+
RepeatLookup
+{
+  "properties": {
+    "property_reference": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Property Reference"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "property_reference"
+  ],
+  "title": "RepeatLookup"
+}
+
+
RequestCreate
+{
+  "properties": {
+    "requester_name": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Requester Name"
+    },
+    "requester_email": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 255
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Email"
+    },
+    "requester_phone": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 50
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Phone"
+    },
+    "requester_type": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 100
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Type"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Description"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "priority": {
+      "type": "string",
+      "title": "Priority",
+      "default": "normal"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^(narrow|moderate|broad)$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "requester_name",
+    "description"
+  ],
+  "title": "RequestCreate"
+}
+
+
RequestDocumentAdd
+{
+  "properties": {
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "relevance_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Relevance Note"
+    }
+  },
+  "type": "object",
+  "required": [
+    "document_id"
+  ],
+  "title": "RequestDocumentAdd"
+}
+
+
RequestDocumentRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "relevance_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Relevance Note"
+    },
+    "exemption_flags": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Exemption Flags"
+    },
+    "inclusion_status": {
+      "$ref": "#/components/schemas/InclusionStatus"
+    },
+    "attached_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Attached At"
+    },
+    "attached_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Attached By"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "document_id",
+    "relevance_note",
+    "exemption_flags",
+    "inclusion_status",
+    "attached_at",
+    "attached_by"
+  ],
+  "title": "RequestDocumentRead"
+}
+
+
RequestRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "requester_name": {
+      "type": "string",
+      "title": "Requester Name"
+    },
+    "requester_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Email"
+    },
+    "requester_phone": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Phone"
+    },
+    "requester_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Type"
+    },
+    "date_received": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Date Received"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "status": {
+      "$ref": "#/components/schemas/RequestStatus"
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "created_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "response_draft": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Response Draft"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    },
+    "estimated_fee": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Estimated Fee"
+    },
+    "fee_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Status"
+    },
+    "fee_waiver_requested": {
+      "type": "boolean",
+      "title": "Fee Waiver Requested",
+      "default": false
+    },
+    "priority": {
+      "type": "string",
+      "title": "Priority",
+      "default": "normal"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    },
+    "closed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closed At"
+    },
+    "closure_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closure Reason"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "requester_name",
+    "requester_email",
+    "date_received",
+    "statutory_deadline",
+    "description",
+    "status",
+    "assigned_to",
+    "created_by",
+    "created_at",
+    "response_draft",
+    "review_notes"
+  ],
+  "title": "RequestRead"
+}
+
+
RequestStats
+{
+  "properties": {
+    "total_requests": {
+      "type": "integer",
+      "title": "Total Requests"
+    },
+    "by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "By Status"
+    },
+    "approaching_deadline": {
+      "type": "integer",
+      "title": "Approaching Deadline"
+    },
+    "overdue": {
+      "type": "integer",
+      "title": "Overdue"
+    }
+  },
+  "type": "object",
+  "required": [
+    "total_requests",
+    "by_status",
+    "approaching_deadline",
+    "overdue"
+  ],
+  "title": "RequestStats"
+}
+
+
RequestStatus
+{
+  "type": "string",
+  "enum": [
+    "received",
+    "clarification_needed",
+    "assigned",
+    "searching",
+    "in_review",
+    "ready_for_release",
+    "drafted",
+    "approved",
+    "fulfilled",
+    "closed"
+  ],
+  "title": "RequestStatus"
+}
+
+
RequestUpdate
+{
+  "properties": {
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/RequestStatus"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "response_draft": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Response Draft"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    }
+  },
+  "type": "object",
+  "title": "RequestUpdate"
+}
+
+
RequirementBundle
+{
+  "properties": {
+    "requirement_id": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9_-]{1,100}$",
+      "title": "Requirement Id"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "project_type": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Project Type"
+    },
+    "source_reference": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Source Reference"
+    },
+    "source_date": {
+      "type": "string",
+      "format": "date",
+      "title": "Source Date"
+    },
+    "effective_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Effective On"
+    },
+    "dataset_kind": {
+      "type": "string",
+      "enum": [
+        "municipal",
+        "fictional"
+      ],
+      "title": "Dataset Kind"
+    },
+    "filename": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$",
+      "title": "Filename"
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 14000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Sha256"
+    },
+    "materials": {
+      "items": {
+        "$ref": "#/components/schemas/Material"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "minItems": 1,
+      "title": "Materials"
+    },
+    "pathway": {
+      "items": {
+        "$ref": "#/components/schemas/PathwayStep"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "title": "Pathway"
+    },
+    "fee_link": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    },
+    "staff_note": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Staff Note",
+      "default": ""
+    },
+    "change_note": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Change Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requirement_id",
+    "title",
+    "jurisdiction",
+    "project_type",
+    "source_reference",
+    "source_date",
+    "effective_on",
+    "dataset_kind",
+    "filename",
+    "content_base64",
+    "sha256",
+    "materials",
+    "change_note"
+  ],
+  "title": "RequirementBundle"
+}
+
+
ResponseLetterCreate
+{
+  "properties": {
+    "template_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Template Id"
+    }
+  },
+  "type": "object",
+  "title": "ResponseLetterCreate"
+}
+
+
ResponseLetterRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "template_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Template Id"
+    },
+    "generated_content": {
+      "type": "string",
+      "title": "Generated Content"
+    },
+    "edited_content": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Edited Content"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "generated_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Generated By"
+    },
+    "approved_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Approved By"
+    },
+    "sent_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sent At"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "template_id",
+    "generated_content",
+    "edited_content",
+    "status",
+    "generated_by",
+    "approved_by",
+    "sent_at",
+    "created_at"
+  ],
+  "title": "ResponseLetterRead"
+}
+
+
ResponseLetterUpdate
+{
+  "properties": {
+    "edited_content": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Edited Content"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Status"
+    }
+  },
+  "type": "object",
+  "title": "ResponseLetterUpdate"
+}
+
+
ReviewInput
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 5000,
+      "title": "Body",
+      "default": ""
+    },
+    "hasAltText": {
+      "type": "boolean",
+      "title": "Hasalttext",
+      "default": false
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": "en"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "ReviewInput"
+}
+
+
Revision
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    },
+    "document": {
+      "$ref": "#/components/schemas/NoticeDraft"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence",
+    "document"
+  ],
+  "title": "Revision"
+}
+
+
RewriteInput
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "plain-language",
+        "language-variant"
+      ],
+      "title": "Action"
+    },
+    "text": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Text"
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "text"
+  ],
+  "title": "RewriteInput"
+}
+
+
RewriteResult
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "plain-language",
+        "language-variant"
+      ],
+      "title": "Action"
+    },
+    "text": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Text"
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": ""
+    },
+    "outcome": {
+      "type": "string",
+      "enum": [
+        "generated",
+        "unavailable"
+      ],
+      "title": "Outcome"
+    },
+    "generated": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 100000
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Generated"
+    },
+    "model": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 200
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "text",
+    "outcome"
+  ],
+  "title": "RewriteResult"
+}
+
+
Rule
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "zone_code": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Zone Code"
+    },
+    "key": {
+      "type": "string",
+      "maxLength": 120,
+      "minLength": 1,
+      "title": "Key"
+    },
+    "section_number": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Section Number"
+    },
+    "kind": {
+      "type": "string",
+      "enum": [
+        "use",
+        "dimension"
+      ],
+      "title": "Kind"
+    },
+    "value": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Value"
+    },
+    "overlay_code": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 255
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Overlay Code"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "zone_code",
+    "key",
+    "section_number",
+    "kind",
+    "value"
+  ],
+  "title": "Rule"
+}
+
+
RuleTestMatch
+{
+  "properties": {
+    "matched_text": {
+      "type": "string",
+      "title": "Matched Text"
+    },
+    "start": {
+      "type": "integer",
+      "title": "Start"
+    },
+    "end": {
+      "type": "integer",
+      "title": "End"
+    }
+  },
+  "type": "object",
+  "required": [
+    "matched_text",
+    "start",
+    "end"
+  ],
+  "title": "RuleTestMatch"
+}
+
+
RuleTestRequest
+{
+  "properties": {
+    "sample_text": {
+      "type": "string",
+      "title": "Sample Text"
+    }
+  },
+  "type": "object",
+  "required": [
+    "sample_text"
+  ],
+  "title": "RuleTestRequest"
+}
+
+
RuleTestResponse
+{
+  "properties": {
+    "rule_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Rule Id"
+    },
+    "rule_type": {
+      "type": "string",
+      "title": "Rule Type"
+    },
+    "matched": {
+      "type": "boolean",
+      "title": "Matched"
+    },
+    "matches": {
+      "items": {
+        "$ref": "#/components/schemas/RuleTestMatch"
+      },
+      "type": "array",
+      "title": "Matches"
+    }
+  },
+  "type": "object",
+  "required": [
+    "rule_id",
+    "rule_type",
+    "matched",
+    "matches"
+  ],
+  "title": "RuleTestResponse"
+}
+
+
RuleType
+{
+  "type": "string",
+  "enum": [
+    "regex",
+    "keyword",
+    "llm_prompt"
+  ],
+  "title": "RuleType"
+}
+
+
SaveReview
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 5000,
+      "title": "Body",
+      "default": ""
+    },
+    "hasAltText": {
+      "type": "boolean",
+      "title": "Hasalttext",
+      "default": false
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": "en"
+    },
+    "ai_analysis": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 100000
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ai Analysis"
+    },
+    "ai_analysis_model": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 200
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ai Analysis Model"
+    },
+    "ai_outcome": {
+      "type": "string",
+      "enum": [
+        "generated",
+        "unavailable",
+        "failed"
+      ],
+      "title": "Ai Outcome"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "ai_outcome"
+  ],
+  "title": "SaveReview"
+}
+
+
SearchFilterOptions
+{
+  "properties": {
+    "file_types": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "File Types"
+    },
+    "source_names": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Source Names"
+    },
+    "departments": {
+      "items": {
+        "additionalProperties": true,
+        "type": "object"
+      },
+      "type": "array",
+      "title": "Departments",
+      "default": []
+    },
+    "date_range": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Date Range"
+    }
+  },
+  "type": "object",
+  "required": [
+    "file_types",
+    "source_names"
+  ],
+  "title": "SearchFilterOptions"
+}
+
+
SearchInput
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "SearchInput"
+}
+
+
SearchNoteCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "record-records-search",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/SearchNotePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "SearchNoteCommand"
+}
+
+
SearchNotePayload
+{
+  "properties": {
+    "sourceNote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Sourcenote"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sourceNote"
+  ],
+  "title": "SearchNotePayload"
+}
+
+
SearchReceiptCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "record-records-search-session",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/SearchReceiptPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "SearchReceiptCommand"
+}
+
+
SearchReceiptPayload
+{
+  "properties": {
+    "searchQuery": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchquery"
+    },
+    "searchLocations": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchlocations"
+    },
+    "searchResultTitle": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchresulttitle"
+    },
+    "searchResultCitation": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchresultcitation"
+    },
+    "searchResultSummary": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchresultsummary"
+    },
+    "searchResultStatus": {
+      "type": "string",
+      "title": "Searchresultstatus",
+      "default": ""
+    },
+    "searchReviewer": {
+      "type": "string",
+      "title": "Searchreviewer",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "searchQuery",
+    "searchLocations",
+    "searchResultTitle",
+    "searchResultCitation",
+    "searchResultSummary"
+  ],
+  "title": "SearchReceiptPayload"
+}
+
+
SearchReceiptView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "query": {
+      "type": "string",
+      "title": "Query"
+    },
+    "locations": {
+      "type": "string",
+      "title": "Locations"
+    },
+    "reviewer": {
+      "type": "string",
+      "title": "Reviewer"
+    },
+    "results": {
+      "items": {
+        "$ref": "#/components/schemas/SearchResultView"
+      },
+      "type": "array",
+      "title": "Results"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "query",
+    "locations",
+    "reviewer",
+    "results",
+    "created_at_unix_seconds"
+  ],
+  "title": "SearchReceiptView"
+}
+
+
SearchRequest
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "title": "Query"
+    },
+    "session_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Session Id"
+    },
+    "filters": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Filters"
+    },
+    "limit": {
+      "type": "integer",
+      "maximum": 50.0,
+      "title": "Limit",
+      "default": 10
+    },
+    "synthesize": {
+      "type": "boolean",
+      "title": "Synthesize",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "SearchRequest"
+}
+
+
SearchResponse
+{
+  "properties": {
+    "query_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Query Id"
+    },
+    "session_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Session Id"
+    },
+    "query_text": {
+      "type": "string",
+      "title": "Query Text"
+    },
+    "results": {
+      "items": {
+        "$ref": "#/components/schemas/SearchResultItem"
+      },
+      "type": "array",
+      "title": "Results"
+    },
+    "results_count": {
+      "type": "integer",
+      "title": "Results Count"
+    },
+    "synthesized_answer": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Synthesized Answer"
+    },
+    "ai_generated": {
+      "type": "boolean",
+      "title": "Ai Generated",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "query_id",
+    "session_id",
+    "query_text",
+    "results",
+    "results_count"
+  ],
+  "title": "SearchResponse"
+}
+
+
SearchResultItem
+{
+  "properties": {
+    "chunk_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Chunk Id"
+    },
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "filename": {
+      "type": "string",
+      "title": "Filename"
+    },
+    "file_type": {
+      "type": "string",
+      "title": "File Type"
+    },
+    "source_path": {
+      "type": "string",
+      "title": "Source Path"
+    },
+    "page_number": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Page Number"
+    },
+    "content_text": {
+      "type": "string",
+      "title": "Content Text"
+    },
+    "similarity_score": {
+      "type": "number",
+      "title": "Similarity Score"
+    },
+    "rank": {
+      "type": "integer",
+      "title": "Rank"
+    }
+  },
+  "type": "object",
+  "required": [
+    "chunk_id",
+    "document_id",
+    "filename",
+    "file_type",
+    "source_path",
+    "page_number",
+    "content_text",
+    "similarity_score",
+    "rank"
+  ],
+  "title": "SearchResultItem"
+}
+
+
SearchResultView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "title": {
+      "type": "string",
+      "title": "Title"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "title",
+    "citation",
+    "summary",
+    "status"
+  ],
+  "title": "SearchResultView"
+}
+
+
SearchSessionRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "user_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "User Id"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "queries": {
+      "items": {
+        "additionalProperties": true,
+        "type": "object"
+      },
+      "type": "array",
+      "title": "Queries",
+      "default": []
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "user_id",
+    "created_at"
+  ],
+  "title": "SearchSessionRead"
+}
+
+
SectionCreate
+{
+  "properties": {
+    "section_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Section Id"
+    },
+    "chapter_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Chapter Id"
+    },
+    "section_number": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Number"
+    },
+    "section_heading": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Heading"
+    },
+    "parent_section_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parent Section Id"
+    },
+    "sort_order": {
+      "type": "integer",
+      "title": "Sort Order",
+      "default": 0
+    },
+    "administrative_regulation_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Administrative Regulation Refs"
+    },
+    "resolution_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Resolution Refs"
+    },
+    "policy_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Policy Refs"
+    },
+    "approved_summary_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Approved Summary Refs"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "chapter_id",
+    "section_number",
+    "section_heading"
+  ],
+  "title": "SectionCreate",
+  "description": "Request body for creating a code section or subsection."
+}
+
+
SectionVersionCreate
+{
+  "properties": {
+    "version_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Version Id"
+    },
+    "section_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Id"
+    },
+    "source_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "version_label": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Version Label"
+    },
+    "body": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Body"
+    },
+    "effective_start": {
+      "type": "string",
+      "format": "date",
+      "title": "Effective Start"
+    },
+    "effective_end": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective End"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    },
+    "is_current": {
+      "type": "boolean",
+      "title": "Is Current",
+      "default": false
+    },
+    "adoption_event_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Adoption Event Id"
+    },
+    "amendment_event_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Amendment Event Id"
+    },
+    "amendment_summary": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Amendment Summary"
+    },
+    "prior_version_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Prior Version Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "section_id",
+    "source_id",
+    "version_label",
+    "body",
+    "effective_start"
+  ],
+  "title": "SectionVersionCreate",
+  "description": "Request body for adding an immutable section version."
+}
+
+
Selection
+{
+  "properties": {
+    "recording_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Recording Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "recording_id",
+    "expected_sha256"
+  ],
+  "title": "Selection"
+}
+
+
SentenceInput
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "citations": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Citations"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text"
+  ],
+  "title": "SentenceInput"
+}
+
+
ServiceAccountCreate
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole",
+      "default": "read_only"
+    }
+  },
+  "type": "object",
+  "required": [
+    "name"
+  ],
+  "title": "ServiceAccountCreate"
+}
+
+
ServiceAccountCreated
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "api_key": {
+      "type": "string",
+      "title": "Api Key"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "role",
+    "created_by",
+    "created_at",
+    "is_active",
+    "api_key"
+  ],
+  "title": "ServiceAccountCreated",
+  "description": "Returned only on creation — includes the plaintext API key (shown once)."
+}
+
+
ServiceAccountRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "role",
+    "created_by",
+    "created_at",
+    "is_active"
+  ],
+  "title": "ServiceAccountRead"
+}
+
+
ServiceAccountUpdate
+{
+  "properties": {
+    "role": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/UserRole"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "ServiceAccountUpdate"
+}
+
+
Snapshot
+{
+  "properties": {
+    "expected_revision": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Expected Revision"
+    },
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "staff_only",
+        "public"
+      ],
+      "title": "Visibility"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "expected_revision",
+    "visibility"
+  ],
+  "title": "Snapshot"
+}
+
+
SourceCreate
+{
+  "properties": {
+    "source_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Id"
+    },
+    "name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Name"
+    },
+    "publisher": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Publisher"
+    },
+    "source_type": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Type"
+    },
+    "source_category": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Category"
+    },
+    "source_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Url"
+    },
+    "file_reference": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "File Reference"
+    },
+    "retrieved_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Retrieved At"
+    },
+    "retrieval_method": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Retrieval Method"
+    },
+    "checksum": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Checksum"
+    },
+    "source_owner": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Owner"
+    },
+    "is_official": {
+      "type": "boolean",
+      "title": "Is Official",
+      "default": true
+    },
+    "official_status_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Official Status Note"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    },
+    "staff_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Staff Notes"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "name",
+    "publisher",
+    "source_type",
+    "source_category"
+  ],
+  "title": "SourceCreate",
+  "description": "Request body for registering an official or explicitly labeled source."
+}
+
+
SourceInput
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "label": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Label"
+    },
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "label",
+    "text"
+  ],
+  "title": "SourceInput"
+}
+
+
SourceSnapshot
+{
+  "properties": {
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "public",
+        "staff_only"
+      ],
+      "title": "Visibility"
+    },
+    "meeting_event_ids": {
+      "items": {
+        "type": "string",
+        "format": "uuid"
+      },
+      "type": "array",
+      "maxItems": 50,
+      "title": "Meeting Event Ids"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "visibility"
+  ],
+  "title": "SourceSnapshot"
+}
+
+
SourceType
+{
+  "type": "string",
+  "enum": [
+    "manual_drop",
+    "file_system",
+    "rest_api",
+    "odbc"
+  ],
+  "title": "SourceType"
+}
+
+
StaffRecordsIntake
+{
+  "properties": {
+    "requester": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requester"
+    },
+    "summary": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Summary"
+    },
+    "deadline": {
+      "type": "string",
+      "title": "Deadline"
+    },
+    "deadlineBasis": {
+      "type": "string",
+      "title": "Deadlinebasis",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requester",
+    "summary",
+    "deadline"
+  ],
+  "title": "StaffRecordsIntake",
+  "description": "Existing native create-records-request input; no caller-supplied actor."
+}
+
+
StandardsExplanation
+{
+  "properties": {
+    "question": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Question"
+    },
+    "process_section": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Process Section",
+      "default": ""
+    },
+    "zone_code": {
+      "type": "string",
+      "maxLength": 40,
+      "title": "Zone Code",
+      "default": ""
+    },
+    "rule_types": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "title": "Rule Types"
+    },
+    "observed": {
+      "additionalProperties": {
+        "type": "string"
+      },
+      "type": "object",
+      "title": "Observed"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "question"
+  ],
+  "title": "StandardsExplanation"
+}
+
+
SyncFailureRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "source_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Source Id"
+    },
+    "source_path": {
+      "type": "string",
+      "title": "Source Path"
+    },
+    "error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Message"
+    },
+    "error_class": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Class"
+    },
+    "http_status_code": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Http Status Code"
+    },
+    "retry_count": {
+      "type": "integer",
+      "title": "Retry Count"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "first_failed_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "First Failed At"
+    },
+    "last_retried_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Retried At"
+    },
+    "dismissed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Dismissed At"
+    },
+    "dismissed_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Dismissed By"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "source_id",
+    "source_path",
+    "error_message",
+    "error_class",
+    "http_status_code",
+    "retry_count",
+    "status",
+    "first_failed_at",
+    "last_retried_at",
+    "dismissed_at",
+    "dismissed_by"
+  ],
+  "title": "SyncFailureRead"
+}
+
+
SyncRunLogRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "source_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Source Id"
+    },
+    "started_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Started At"
+    },
+    "finished_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Finished At"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Status"
+    },
+    "records_attempted": {
+      "type": "integer",
+      "title": "Records Attempted"
+    },
+    "records_succeeded": {
+      "type": "integer",
+      "title": "Records Succeeded"
+    },
+    "records_failed": {
+      "type": "integer",
+      "title": "Records Failed"
+    },
+    "error_summary": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Summary"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "source_id",
+    "started_at",
+    "finished_at",
+    "status",
+    "records_attempted",
+    "records_succeeded",
+    "records_failed",
+    "error_summary"
+  ],
+  "title": "SyncRunLogRead"
+}
+
+
SystemStatus
+{
+  "properties": {
+    "version": {
+      "type": "string",
+      "title": "Version"
+    },
+    "database": {
+      "type": "string",
+      "title": "Database"
+    },
+    "ollama": {
+      "type": "string",
+      "title": "Ollama"
+    },
+    "redis": {
+      "type": "string",
+      "title": "Redis"
+    },
+    "user_count": {
+      "type": "integer",
+      "title": "User Count"
+    },
+    "audit_log_count": {
+      "type": "integer",
+      "title": "Audit Log Count"
+    },
+    "suite_session": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Suite Session"
+    }
+  },
+  "type": "object",
+  "required": [
+    "version",
+    "database",
+    "ollama",
+    "redis",
+    "user_count",
+    "audit_log_count"
+  ],
+  "title": "SystemStatus"
+}
+
+
TaggedPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "tagged-pdf",
+      "title": "Action"
+    },
+    "headingLevels": {
+      "items": {
+        "type": "integer",
+        "maximum": 4294967295.0,
+        "minimum": 0.0
+      },
+      "type": "array",
+      "maxItems": 50,
+      "title": "Headinglevels"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "TaggedPlan"
+}
+
+
TestConnectionRequest
+{
+  "properties": {
+    "source_type": {
+      "type": "string",
+      "title": "Source Type"
+    },
+    "host": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Host"
+    },
+    "port": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Port"
+    },
+    "path": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Path"
+    },
+    "username": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Username"
+    },
+    "password": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Password"
+    },
+    "rest_api_config": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Rest Api Config"
+    },
+    "odbc_config": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Odbc Config"
+    }
+  },
+  "type": "object",
+  "required": [
+    "source_type"
+  ],
+  "title": "TestConnectionRequest",
+  "description": "Dedicated schema for test-connection. NOT the create schema.\n\nSecurity: credentials in this request body are never persisted, never\nwritten to audit logs, and never returned in the response."
+}
+
+
TestConnectionResponse
+{
+  "properties": {
+    "success": {
+      "type": "boolean",
+      "title": "Success"
+    },
+    "message": {
+      "type": "string",
+      "title": "Message"
+    },
+    "latency_ms": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Latency Ms"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Status"
+    },
+    "warning": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Warning"
+    },
+    "differing_keys": {
+      "anyOf": [
+        {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Differing Keys"
+    }
+  },
+  "type": "object",
+  "required": [
+    "success",
+    "message"
+  ],
+  "title": "TestConnectionResponse"
+}
+
+
TimelineEventCreate
+{
+  "properties": {
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "internal_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Internal Note"
+    }
+  },
+  "type": "object",
+  "required": [
+    "event_type",
+    "description"
+  ],
+  "title": "TimelineEventCreate"
+}
+
+
TimelineEventRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "actor_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Actor Id"
+    },
+    "actor_role": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Actor Role"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "internal_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Internal Note"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "event_type",
+    "actor_id",
+    "actor_role",
+    "description",
+    "internal_note",
+    "created_at"
+  ],
+  "title": "TimelineEventRead"
+}
+
+
TimelineView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "actor": {
+      "type": "string",
+      "title": "Actor"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "action",
+    "actor",
+    "note",
+    "created_at_unix_seconds"
+  ],
+  "title": "TimelineView"
+}
+
+
TitleCreate
+{
+  "properties": {
+    "title_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Title Id"
+    },
+    "title_number": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title Number"
+    },
+    "title_name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title Name"
+    },
+    "sort_order": {
+      "type": "integer",
+      "title": "Sort Order",
+      "default": 0
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title_number",
+    "title_name"
+  ],
+  "title": "TitleCreate",
+  "description": "Request body for creating a code title."
+}
+
+
TranscriptInput
+{
+  "properties": {
+    "source_label": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Label"
+    },
+    "transcript_text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Transcript Text"
+    },
+    "correction_of_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Correction Of Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_label",
+    "transcript_text"
+  ],
+  "title": "TranscriptInput"
+}
+
+
UserRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "email": {
+      "type": "string",
+      "format": "email",
+      "title": "Email"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active",
+      "default": true
+    },
+    "is_superuser": {
+      "type": "boolean",
+      "title": "Is Superuser",
+      "default": false
+    },
+    "is_verified": {
+      "type": "boolean",
+      "title": "Is Verified",
+      "default": false
+    },
+    "full_name": {
+      "type": "string",
+      "title": "Full Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "last_login": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Login"
+    },
+    "must_change_password": {
+      "type": "boolean",
+      "title": "Must Change Password",
+      "default": false
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "email",
+    "full_name",
+    "role",
+    "created_at",
+    "last_login"
+  ],
+  "title": "UserRead"
+}
+
+
UserRole
+{
+  "type": "string",
+  "enum": [
+    "admin",
+    "staff",
+    "reviewer",
+    "read_only",
+    "liaison",
+    "public"
+  ],
+  "title": "UserRole"
+}
+
+
UserSelfUpdate
+{
+  "properties": {
+    "password": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Password"
+    },
+    "email": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "email"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    },
+    "is_superuser": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Superuser"
+    },
+    "is_verified": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Verified"
+    },
+    "full_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Full Name"
+    }
+  },
+  "type": "object",
+  "title": "UserSelfUpdate",
+  "description": "Schema for user self-update via PATCH /users/me.\n\nExcludes role and department_id. Any payload containing those fields is\nrejected at parse time (HTTP 422). Role and department changes require\nadmin privileges via /admin/users/{id}."
+}
+
+
UserUpdateRequest
+{
+  "properties": {
+    "full_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Full Name"
+    },
+    "role": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Role"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "UserUpdateRequest"
+}
+
+
ValidationError
+{
+  "properties": {
+    "loc": {
+      "items": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "integer"
+          }
+        ]
+      },
+      "type": "array",
+      "title": "Location"
+    },
+    "msg": {
+      "type": "string",
+      "title": "Message"
+    },
+    "type": {
+      "type": "string",
+      "title": "Error Type"
+    },
+    "input": {
+      "title": "Input"
+    },
+    "ctx": {
+      "type": "object",
+      "title": "Context"
+    }
+  },
+  "type": "object",
+  "required": [
+    "loc",
+    "msg",
+    "type"
+  ],
+  "title": "ValidationError"
+}
+
+
Version
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence"
+  ],
+  "title": "Version"
+}
+
+
VoteCorrection
+{
+  "properties": {
+    "vote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Vote"
+    },
+    "reason": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Reason"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "vote",
+    "reason"
+  ],
+  "title": "VoteCorrection"
+}
+
+
VoteInput
+{
+  "properties": {
+    "voter_name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Voter Name"
+    },
+    "vote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Vote"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "voter_name",
+    "vote"
+  ],
+  "title": "VoteInput"
+}
+
+
_ParcelLookupIn
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "query"
+  ],
+  "title": "_ParcelLookupIn"
+}
+
+
townlight_inspections__workflow_models__SourceLink
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "const": "code",
+      "title": "Provider",
+      "default": "code"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "SourceLink"
+}
+
+
townlight_permitting__workflow_models__SourceLink
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "enum": [
+        "code",
+        "zoning"
+      ],
+      "title": "Provider"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "SourceLink"
+}
+
+
townlight_runtime__inspections_bridge__Search
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "const": "code",
+      "title": "Provider"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "query"
+  ],
+  "title": "Search"
+}
+
+
townlight_runtime__notice_bridge__Review
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence",
+    "note"
+  ],
+  "title": "Review"
+}
+
+
townlight_runtime__permitting_bridge__Import
+{
+  "properties": {
+    "bundle": {
+      "$ref": "#/components/schemas/RequirementBundle"
+    },
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "bundle"
+  ],
+  "title": "Import"
+}
+
+
townlight_runtime__permitting_bridge__Search
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "enum": [
+        "code",
+        "zoning"
+      ],
+      "title": "Provider"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "query"
+  ],
+  "title": "Search"
+}
+
+
townlight_runtime__planning_bridge__Import
+{
+  "properties": {
+    "bundle": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Bundle"
+    },
+    "expected_previous_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Previous Revision"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "bundle"
+  ],
+  "title": "Import"
+}
+
+
townlight_runtime__planning_bridge__Search
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Query"
+    },
+    "plan_type": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 40
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Plan Type"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "Search"
+}
+
+
townlight_runtime__zoning_bridge__Review
+{
+  "properties": {
+    "answer": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Answer",
+      "default": ""
+    },
+    "notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Notes",
+      "default": ""
+    },
+    "queue_status": {
+      "type": "string",
+      "enum": [
+        "open",
+        "in_review",
+        "resolved",
+        "closed"
+      ],
+      "title": "Queue Status",
+      "default": "resolved"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "Review"
+}
+
Townlight · AGPL-3.0-only · Source schema evidence only
\ No newline at end of file diff --git a/docs/beta-1/api/code-openapi.json b/docs/beta-1/api/code-openapi.json new file mode 100644 index 0000000..8565cb0 --- /dev/null +++ b/docs/beta-1/api/code-openapi.json @@ -0,0 +1,12264 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "Townlight Records", + "description": "Prepared source schema for the actual native composition; installed acceptance remains pending. Exported without lifespan, migrations or database/network access.", + "version": "1.8.0.dev2" + }, + "paths": { + "/desktop/v1/code-sources/search": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Search Code Sources", + "operationId": "search_code_sources_desktop_v1_code_sources_search_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CodeSearch" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/code/imports": { + "post": { + "tags": [ + "native-code" + ], + "summary": "Imports", + "operationId": "imports_desktop_v1_code_imports_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ImportBundleCreate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "get": { + "tags": [ + "native-code" + ], + "summary": "List Imports", + "operationId": "list_imports_desktop_v1_code_imports_get", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/code/sources": { + "get": { + "tags": [ + "native-code" + ], + "summary": "Sources", + "operationId": "sources_desktop_v1_code_sources_get", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/code/workspace": { + "get": { + "tags": [ + "native-code" + ], + "summary": "Workspace", + "operationId": "workspace_desktop_v1_code_workspace_get", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/code/lookup": { + "get": { + "tags": [ + "native-code" + ], + "summary": "Lookup", + "operationId": "lookup_desktop_v1_code_lookup_get", + "parameters": [ + { + "name": "section_number", + "in": "query", + "required": true, + "schema": { + "type": "string", + "title": "Section Number" + } + }, + { + "name": "as_of", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/code/sections/{section_id}/history": { + "get": { + "tags": [ + "native-code" + ], + "summary": "Section History", + "operationId": "section_history_desktop_v1_code_sections__section_id__history_get", + "parameters": [ + { + "name": "section_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Section Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/code/citation": { + "get": { + "tags": [ + "native-code" + ], + "summary": "Citation", + "operationId": "citation_desktop_v1_code_citation_get", + "parameters": [ + { + "name": "section_number", + "in": "query", + "required": true, + "schema": { + "type": "string", + "title": "Section Number" + } + }, + { + "name": "as_of", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/code/search": { + "get": { + "tags": [ + "native-code" + ], + "summary": "Search", + "operationId": "search_desktop_v1_code_search_get", + "parameters": [ + { + "name": "q", + "in": "query", + "required": true, + "schema": { + "type": "string", + "title": "Q" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/code/imports/{job_id}/tree": { + "get": { + "tags": [ + "native-code" + ], + "summary": "Import Tree", + "operationId": "import_tree_desktop_v1_code_imports__job_id__tree_get", + "parameters": [ + { + "name": "job_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Job Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/code/imports/{job_id}/provenance": { + "get": { + "tags": [ + "native-code" + ], + "summary": "Import Provenance", + "operationId": "import_provenance_desktop_v1_code_imports__job_id__provenance_get", + "parameters": [ + { + "name": "job_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Job Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/code/export": { + "get": { + "tags": [ + "native-code" + ], + "summary": "Export Section", + "operationId": "export_section_desktop_v1_code_export_get", + "parameters": [ + { + "name": "section_ref", + "in": "query", + "required": true, + "schema": { + "type": "string", + "title": "Section Ref" + } + }, + { + "name": "as_of", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/code/questions": { + "post": { + "tags": [ + "native-code" + ], + "summary": "Questions", + "operationId": "questions_desktop_v1_code_questions_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/QuestionAnswerRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/code/sections/{section_id}/notes": { + "post": { + "tags": [ + "native-code" + ], + "summary": "Create Note", + "operationId": "create_note_desktop_v1_code_sections__section_id__notes_post", + "parameters": [ + { + "name": "section_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Section Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InterpretationNoteCreate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "get": { + "tags": [ + "native-code" + ], + "summary": "List Notes", + "operationId": "list_notes_desktop_v1_code_sections__section_id__notes_get", + "parameters": [ + { + "name": "section_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Section Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/code/sections/{section_id}/summaries": { + "post": { + "tags": [ + "native-code" + ], + "summary": "Create Summary", + "operationId": "create_summary_desktop_v1_code_sections__section_id__summaries_post", + "parameters": [ + { + "name": "section_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Section Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PlainLanguageSummaryCreate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "get": { + "tags": [ + "native-code" + ], + "summary": "List Summaries", + "operationId": "list_summaries_desktop_v1_code_sections__section_id__summaries_get", + "parameters": [ + { + "name": "section_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Section Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/code/summaries/{summary_id}/approve": { + "post": { + "tags": [ + "native-code" + ], + "summary": "Approve Summary", + "operationId": "approve_summary_desktop_v1_code_summaries__summary_id__approve_post", + "parameters": [ + { + "name": "summary_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Summary Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/code/connections": { + "get": { + "summary": "List Connections", + "operationId": "list_connections_desktop_v1_code_connections_get", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "summary": "Create Connection", + "operationId": "create_connection_desktop_v1_code_connections_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Proposal" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/code/connections/{connection_id}": { + "get": { + "summary": "Get Connection", + "operationId": "get_connection_desktop_v1_code_connections__connection_id__get", + "parameters": [ + { + "name": "connection_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Connection Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/code/connections/{connection_id}/closeout": { + "post": { + "summary": "Closeout Connection", + "operationId": "closeout_connection_desktop_v1_code_connections__connection_id__closeout_post", + "parameters": [ + { + "name": "connection_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Connection Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Closeout" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "ActionItemInput": { + "properties": { + "description": { + "type": "string", + "minLength": 1, + "title": "Description" + }, + "assigned_to": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "source_motion_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Source Motion Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "description" + ], + "title": "ActionItemInput" + }, + "AdaPlan": { + "properties": { + "action": { + "type": "string", + "const": "ada-title-ii", + "title": "Action" + }, + "serviceArea": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Servicearea" + }, + "hasCoordinatorReview": { + "type": "boolean", + "title": "Hascoordinatorreview", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "serviceArea" + ], + "title": "AdaPlan" + }, + "AdminUserCreateRequest": { + "properties": { + "email": { + "type": "string", + "title": "Email" + }, + "password": { + "type": "string", + "title": "Password" + }, + "full_name": { + "type": "string", + "title": "Full Name", + "default": "" + }, + "role": { + "type": "string", + "title": "Role", + "default": "staff" + } + }, + "type": "object", + "required": [ + "email", + "password" + ], + "title": "AdminUserCreateRequest" + }, + "AdminUserCreateResponse": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "email": { + "type": "string", + "title": "Email" + }, + "full_name": { + "type": "string", + "title": "Full Name" + }, + "role": { + "type": "string", + "title": "Role" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + } + }, + "type": "object", + "required": [ + "id", + "email", + "full_name", + "role", + "is_active" + ], + "title": "AdminUserCreateResponse" + }, + "AgendaAssignment": { + "properties": { + "meeting_id": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "meeting_id" + ], + "title": "AgendaAssignment" + }, + "AgendaInput": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "department_name": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Department Name" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "department_name" + ], + "title": "AgendaInput" + }, + "AgendaReviewInput": { + "properties": { + "to_status": { + "type": "string", + "enum": [ + "DRAFTED", + "SUBMITTED", + "DEPT_APPROVED", + "LEGAL_REVIEWED", + "CLERK_ACCEPTED", + "ON_AGENDA", + "IN_PACKET", + "POSTED", + "HEARD", + "DISPOSED", + "ARCHIVED" + ], + "title": "To Status" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "to_status" + ], + "title": "AgendaReviewInput" + }, + "AmendmentInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "policy": { + "$ref": "#/components/schemas/PolicySelection" + }, + "proposal": { + "type": "string", + "maxLength": 20000, + "minLength": 1, + "title": "Proposal" + }, + "responsible_staff": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Responsible Staff" + }, + "status": { + "type": "string", + "enum": [ + "draft", + "review", + "adopted", + "withdrawn" + ], + "title": "Status", + "default": "draft" + }, + "review_note": { + "type": "string", + "maxLength": 5000, + "title": "Review Note", + "default": "" + }, + "adoption_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Adoption Revision" + }, + "note": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "policy", + "proposal", + "responsible_staff", + "note" + ], + "title": "AmendmentInput" + }, + "AnalysisObservation": { + "properties": { + "source": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "title": "Source" + }, + "filename": { + "type": "string", + "maxLength": 160, + "title": "Filename", + "default": "" + }, + "media_type": { + "type": "string", + "maxLength": 80, + "title": "Media Type", + "default": "" + }, + "text": { + "type": "string", + "maxLength": 4000, + "minLength": 1, + "title": "Text" + }, + "adapter": { + "type": "string", + "maxLength": 120, + "title": "Adapter", + "default": "" + }, + "citation_source_ids": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 30, + "title": "Citation Source Ids" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source", + "text" + ], + "title": "AnalysisObservation", + "description": "One draft observation, named with the adapter that actually produced it." + }, + "AnalysisRecord": { + "properties": { + "observations": { + "items": { + "$ref": "#/components/schemas/AnalysisObservation" + }, + "type": "array", + "maxItems": 30, + "title": "Observations" + }, + "cited_sections": { + "items": { + "$ref": "#/components/schemas/CitedSection" + }, + "type": "array", + "maxItems": 30, + "title": "Cited Sections" + }, + "unavailable": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 30, + "title": "Unavailable" + }, + "runtime": { + "additionalProperties": true, + "type": "object", + "title": "Runtime" + }, + "review_required": { + "type": "boolean", + "title": "Review Required", + "default": true + } + }, + "additionalProperties": false, + "type": "object", + "title": "AnalysisRecord", + "description": "The adapter output that accompanies a saved inspection draft." + }, + "ApprovalCommand": { + "properties": { + "action": { + "type": "string", + "const": "approve-records-response", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ApprovalPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "ApprovalCommand" + }, + "ApprovalPayload": { + "properties": { + "approvalNote": { + "type": "string", + "title": "Approvalnote", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "title": "ApprovalPayload" + }, + "ArchiveInput": { + "properties": { + "visibility": { + "type": "string", + "enum": [ + "public", + "closed_session" + ], + "title": "Visibility" + }, + "packet_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Packet Id" + }, + "minutes_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Minutes Id" + }, + "plain_language_summary": { + "type": "string", + "title": "Plain Language Summary", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "visibility" + ], + "title": "ArchiveInput" + }, + "ArtifactPlan": { + "properties": { + "artifact_id": { + "type": "string", + "title": "Artifact Id" + }, + "file_name": { + "type": "string", + "title": "File Name" + }, + "content": { + "type": "string", + "title": "Content" + }, + "sha256": { + "type": "string", + "title": "Sha256" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "artifact_id", + "file_name", + "content", + "sha256", + "created_at_unix_seconds" + ], + "title": "ArtifactPlan" + }, + "AssignCommand": { + "properties": { + "action": { + "type": "string", + "const": "assign-records-request", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/AssignmentPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "AssignCommand" + }, + "AssignmentPayload": { + "properties": { + "assignedTo": { + "type": "string", + "minLength": 1, + "title": "Assignedto" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "assignedTo" + ], + "title": "AssignmentPayload" + }, + "AttachDocument": { + "properties": { + "title": { + "type": "string", + "minLength": 1, + "title": "Title" + }, + "citation": { + "type": "string", + "title": "Citation", + "default": "" + }, + "file": { + "$ref": "#/components/schemas/ManagedFileReceipt" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "file" + ], + "title": "AttachDocument" + }, + "AttachReleaseCopy": { + "properties": { + "status": { + "type": "string", + "enum": [ + "release-ready copy", + "redacted copy" + ], + "title": "Status" + }, + "note": { + "type": "string", + "title": "Note", + "default": "" + }, + "added_by": { + "type": "string", + "title": "Added By", + "default": "" + }, + "file": { + "$ref": "#/components/schemas/ManagedFileReceipt" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "status", + "file" + ], + "title": "AttachReleaseCopy" + }, + "AuditChainVerification": { + "properties": { + "is_valid": { + "type": "boolean", + "title": "Is Valid" + }, + "entries_checked": { + "type": "integer", + "title": "Entries Checked" + }, + "error_message": { + "type": "string", + "title": "Error Message" + } + }, + "type": "object", + "required": [ + "is_valid", + "entries_checked", + "error_message" + ], + "title": "AuditChainVerification" + }, + "AuditLogRead": { + "properties": { + "id": { + "type": "integer", + "title": "Id" + }, + "prev_hash": { + "type": "string", + "title": "Prev Hash" + }, + "entry_hash": { + "type": "string", + "title": "Entry Hash" + }, + "timestamp": { + "type": "string", + "format": "date-time", + "title": "Timestamp" + }, + "user_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "User Id" + }, + "action": { + "type": "string", + "title": "Action" + }, + "resource_type": { + "type": "string", + "title": "Resource Type" + }, + "resource_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Resource Id" + }, + "details": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Details" + }, + "ai_generated": { + "type": "boolean", + "title": "Ai Generated" + } + }, + "type": "object", + "required": [ + "id", + "prev_hash", + "entry_hash", + "timestamp", + "user_id", + "action", + "resource_type", + "resource_id", + "details", + "ai_generated" + ], + "title": "AuditLogRead" + }, + "AuditView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "module_id": { + "type": "string", + "title": "Module Id" + }, + "action": { + "type": "string", + "title": "Action" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + }, + "previous_hash": { + "type": "string", + "title": "Previous Hash" + }, + "entry_hash": { + "type": "string", + "title": "Entry Hash" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "module_id", + "action", + "summary", + "created_at_unix_seconds", + "previous_hash", + "entry_hash" + ], + "title": "AuditView" + }, + "BearerResponse": { + "properties": { + "access_token": { + "type": "string", + "title": "Access Token" + }, + "token_type": { + "type": "string", + "title": "Token Type" + } + }, + "type": "object", + "required": [ + "access_token", + "token_type" + ], + "title": "BearerResponse" + }, + "Body_auth_jwt_login_auth_jwt_login_post": { + "properties": { + "grant_type": { + "anyOf": [ + { + "type": "string", + "pattern": "^password$" + }, + { + "type": "null" + } + ], + "title": "Grant Type" + }, + "username": { + "type": "string", + "title": "Username" + }, + "password": { + "type": "string", + "format": "password", + "title": "Password" + }, + "scope": { + "type": "string", + "title": "Scope", + "default": "" + }, + "client_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Client Id" + }, + "client_secret": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "format": "password", + "title": "Client Secret" + } + }, + "type": "object", + "required": [ + "username", + "password" + ], + "title": "Body_auth_jwt_login_auth_jwt_login_post" + }, + "Body_upload_file_datasources_upload_post": { + "properties": { + "file": { + "type": "string", + "contentMediaType": "application/octet-stream", + "title": "File" + } + }, + "type": "object", + "required": [ + "file" + ], + "title": "Body_upload_file_datasources_upload_post" + }, + "CalculateDeadlineCommand": { + "properties": { + "action": { + "type": "string", + "const": "calculate-records-deadline", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/CalculateDeadlinePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "CalculateDeadlineCommand" + }, + "CalculateDeadlinePayload": { + "properties": { + "deadlineReceivedDate": { + "type": "string", + "title": "Deadlinereceiveddate" + }, + "deadlineRuleName": { + "type": "string", + "minLength": 1, + "title": "Deadlinerulename" + }, + "deadlineDayCount": { + "type": "string", + "title": "Deadlinedaycount" + }, + "deadlineDayType": { + "type": "string", + "title": "Deadlinedaytype" + }, + "deadlineBasis": { + "type": "string", + "minLength": 1, + "title": "Deadlinebasis" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "deadlineReceivedDate", + "deadlineRuleName", + "deadlineDayCount", + "deadlineDayType", + "deadlineBasis" + ], + "title": "CalculateDeadlinePayload" + }, + "ChapterCreate": { + "properties": { + "chapter_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Chapter Id" + }, + "title_id": { + "type": "string", + "minLength": 1, + "title": "Title Id" + }, + "chapter_number": { + "type": "string", + "minLength": 1, + "title": "Chapter Number" + }, + "chapter_name": { + "type": "string", + "minLength": 1, + "title": "Chapter Name" + }, + "sort_order": { + "type": "integer", + "title": "Sort Order", + "default": 0 + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title_id", + "chapter_number", + "chapter_name" + ], + "title": "ChapterCreate", + "description": "Request body for creating a code chapter." + }, + "CitedSection": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "citation": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Citation" + }, + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "version": { + "type": "string", + "maxLength": 80, + "title": "Version", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "citation" + ], + "title": "CitedSection", + "description": "One resolved public Code section; never a caller-supplied quotation." + }, + "CityProfileCreate": { + "properties": { + "city_name": { + "type": "string", + "title": "City Name" + }, + "state": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State" + }, + "county": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "County" + }, + "population_band": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Population Band" + }, + "email_platform": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Email Platform" + }, + "has_dedicated_it": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Has Dedicated It" + }, + "monthly_request_volume": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Monthly Request Volume" + }, + "profile_data": { + "additionalProperties": true, + "type": "object", + "title": "Profile Data", + "default": {} + }, + "gap_map": { + "additionalProperties": true, + "type": "object", + "title": "Gap Map", + "default": {} + } + }, + "type": "object", + "required": [ + "city_name" + ], + "title": "CityProfileCreate" + }, + "CityProfileRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "city_name": { + "type": "string", + "title": "City Name" + }, + "state": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State" + }, + "county": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "County" + }, + "population_band": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Population Band" + }, + "email_platform": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Email Platform" + }, + "has_dedicated_it": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Has Dedicated It" + }, + "monthly_request_volume": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Monthly Request Volume" + }, + "onboarding_status": { + "type": "string", + "title": "Onboarding Status" + }, + "profile_data": { + "additionalProperties": true, + "type": "object", + "title": "Profile Data" + }, + "gap_map": { + "additionalProperties": true, + "type": "object", + "title": "Gap Map" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "city_name", + "state", + "county", + "population_band", + "email_platform", + "has_dedicated_it", + "monthly_request_volume", + "onboarding_status", + "profile_data", + "gap_map", + "created_at", + "updated_at" + ], + "title": "CityProfileRead" + }, + "CityProfileUpdate": { + "properties": { + "city_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "City Name" + }, + "state": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State" + }, + "county": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "County" + }, + "population_band": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Population Band" + }, + "email_platform": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Email Platform" + }, + "has_dedicated_it": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Has Dedicated It" + }, + "monthly_request_volume": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Monthly Request Volume" + }, + "onboarding_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Onboarding Status" + }, + "profile_data": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Profile Data" + }, + "gap_map": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Gap Map" + } + }, + "type": "object", + "title": "CityProfileUpdate" + }, + "ClarificationCommand": { + "properties": { + "action": { + "type": "string", + "const": "request-records-clarification", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ClarificationPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "ClarificationCommand" + }, + "ClarificationPayload": { + "properties": { + "clarificationNote": { + "type": "string", + "minLength": 1, + "title": "Clarificationnote" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "clarificationNote" + ], + "title": "ClarificationPayload" + }, + "Closeout": { + "properties": { + "decision_id": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Decision Id" + }, + "version_id": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Version Id" + }, + "source_id": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Source Id" + }, + "version_label": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Version Label" + }, + "body": { + "type": "string", + "maxLength": 1000000, + "minLength": 1, + "title": "Body" + }, + "effective_start": { + "type": "string", + "format": "date", + "title": "Effective Start" + }, + "effective_end": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective End" + }, + "is_current": { + "type": "boolean", + "title": "Is Current" + }, + "reconciliation_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reconciliation Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "decision_id", + "version_id", + "source_id", + "version_label", + "body", + "effective_start", + "is_current" + ], + "title": "Closeout" + }, + "CodeContext": { + "properties": { + "section_number": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Section Number" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "section_number" + ], + "title": "CodeContext" + }, + "CodeLink": { + "properties": { + "provider": { + "type": "string", + "const": "code", + "title": "Provider", + "default": "code" + }, + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "CodeLink" + }, + "CodeSearch": { + "properties": { + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "CodeSearch" + }, + "CodeSourceSelection": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "CodeSourceSelection" + }, + "CompleteArtifact": { + "properties": { + "export_path": { + "type": "string", + "minLength": 1, + "title": "Export Path" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "export_path" + ], + "title": "CompleteArtifact" + }, + "ConnectionSearch": { + "properties": { + "provider": { + "type": "string", + "enum": [ + "meetings", + "zoning" + ], + "title": "Provider" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "query" + ], + "title": "ConnectionSearch" + }, + "CoverageGapResponse": { + "properties": { + "jurisdictions_without_rules": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Jurisdictions Without Rules" + }, + "departments_without_staff": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array", + "title": "Departments Without Staff" + }, + "uncovered_categories": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Uncovered Categories" + }, + "total_gaps": { + "type": "integer", + "title": "Total Gaps" + } + }, + "type": "object", + "required": [ + "jurisdictions_without_rules", + "departments_without_staff", + "uncovered_categories", + "total_gaps" + ], + "title": "CoverageGapResponse" + }, + "DataSourceAdminRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "source_type": { + "$ref": "#/components/schemas/SourceType" + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "type": "boolean", + "title": "Schedule Enabled", + "default": true + }, + "next_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Next Sync At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "last_ingestion_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Ingestion At" + }, + "last_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Sync At" + }, + "last_sync_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Sync Status" + }, + "last_error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Error Message" + }, + "consecutive_failure_count": { + "type": "integer", + "title": "Consecutive Failure Count", + "default": 0 + }, + "sync_paused": { + "type": "boolean", + "title": "Sync Paused", + "default": false + }, + "health_status": { + "type": "string", + "title": "Health Status", + "default": "healthy" + }, + "active_failure_count": { + "type": "integer", + "title": "Active Failure Count", + "default": 0 + }, + "connector_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Connector Type" + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At" + }, + "connection_config": { + "additionalProperties": true, + "type": "object", + "title": "Connection Config" + } + }, + "type": "object", + "required": [ + "id", + "name", + "source_type", + "is_active", + "created_by", + "created_at", + "last_ingestion_at", + "connection_config" + ], + "title": "DataSourceAdminRead", + "description": "Full datasource shape including connection_config. Returned only by admin-gated endpoints." + }, + "DataSourceCreate": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "source_type": { + "$ref": "#/components/schemas/SourceType" + }, + "connection_config": { + "additionalProperties": true, + "type": "object", + "title": "Connection Config", + "default": {} + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "type": "boolean", + "title": "Schedule Enabled", + "default": true + } + }, + "type": "object", + "required": [ + "name", + "source_type" + ], + "title": "DataSourceCreate" + }, + "DataSourceRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "source_type": { + "$ref": "#/components/schemas/SourceType" + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "type": "boolean", + "title": "Schedule Enabled", + "default": true + }, + "next_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Next Sync At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "last_ingestion_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Ingestion At" + }, + "last_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Sync At" + }, + "last_sync_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Sync Status" + }, + "last_error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Error Message" + }, + "consecutive_failure_count": { + "type": "integer", + "title": "Consecutive Failure Count", + "default": 0 + }, + "sync_paused": { + "type": "boolean", + "title": "Sync Paused", + "default": false + }, + "health_status": { + "type": "string", + "title": "Health Status", + "default": "healthy" + }, + "active_failure_count": { + "type": "integer", + "title": "Active Failure Count", + "default": 0 + }, + "connector_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Connector Type" + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "name", + "source_type", + "is_active", + "created_by", + "created_at", + "last_ingestion_at" + ], + "title": "DataSourceRead", + "description": "Redacted datasource shape — safe for non-admin roles. connection_config omitted." + }, + "DataSourceUpdate": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "connection_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Connection Config" + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Schedule Enabled" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "DataSourceUpdate" + }, + "DeadlineCommand": { + "properties": { + "action": { + "type": "string", + "const": "set-records-deadline", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/DeadlinePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "DeadlineCommand" + }, + "DeadlinePayload": { + "properties": { + "deadline": { + "type": "string", + "title": "Deadline" + }, + "deadlineBasis": { + "type": "string", + "minLength": 1, + "title": "Deadlinebasis" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "deadline", + "deadlineBasis" + ], + "title": "DeadlinePayload" + }, + "Decision": { + "properties": { + "id": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Id" + }, + "outcome": { + "type": "string", + "enum": [ + "adopted", + "not_adopted", + "deferred", + "withdrawn" + ], + "title": "Outcome" + }, + "decided_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Decided At" + }, + "decision_text": { + "type": "string", + "maxLength": 1000000, + "minLength": 1, + "title": "Decision Text" + }, + "supporting_references": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Supporting References" + }, + "supersedes_decision_id": { + "anyOf": [ + { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$" + }, + { + "type": "null" + } + ], + "title": "Supersedes Decision Id" + }, + "reconciliation_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reconciliation Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "outcome", + "decision_text" + ], + "title": "Decision" + }, + "DepartmentCreate": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "code": { + "type": "string", + "title": "Code" + }, + "contact_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Contact Email" + } + }, + "type": "object", + "required": [ + "name", + "code" + ], + "title": "DepartmentCreate" + }, + "DepartmentRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "code": { + "type": "string", + "title": "Code" + }, + "contact_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Contact Email" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "name", + "code", + "contact_email", + "created_at" + ], + "title": "DepartmentRead" + }, + "DepartmentUpdate": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Code" + }, + "contact_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Contact Email" + } + }, + "type": "object", + "title": "DepartmentUpdate" + }, + "DisclosureTemplateCreate": { + "properties": { + "template_type": { + "type": "string", + "title": "Template Type" + }, + "state_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State Code" + }, + "content": { + "type": "string", + "title": "Content" + } + }, + "type": "object", + "required": [ + "template_type", + "content" + ], + "title": "DisclosureTemplateCreate" + }, + "DisclosureTemplateRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "template_type": { + "type": "string", + "title": "Template Type" + }, + "state_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State Code" + }, + "content": { + "type": "string", + "title": "Content" + }, + "version": { + "type": "integer", + "title": "Version" + }, + "updated_by": { + "type": "string", + "format": "uuid", + "title": "Updated By" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "template_type", + "state_code", + "content", + "version", + "updated_by", + "updated_at" + ], + "title": "DisclosureTemplateRead" + }, + "DisclosureTemplateRendered": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "template_type": { + "type": "string", + "title": "Template Type" + }, + "rendered_content": { + "type": "string", + "title": "Rendered Content" + }, + "has_unresolved_variables": { + "type": "boolean", + "title": "Has Unresolved Variables" + } + }, + "type": "object", + "required": [ + "id", + "template_type", + "rendered_content", + "has_unresolved_variables" + ], + "title": "DisclosureTemplateRendered" + }, + "DisclosureTemplateUpdate": { + "properties": { + "content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Content" + }, + "state_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State Code" + } + }, + "type": "object", + "title": "DisclosureTemplateUpdate" + }, + "DocumentChunkRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "chunk_index": { + "type": "integer", + "title": "Chunk Index" + }, + "content_text": { + "type": "string", + "title": "Content Text" + }, + "token_count": { + "type": "integer", + "title": "Token Count" + }, + "page_number": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Page Number" + } + }, + "type": "object", + "required": [ + "id", + "document_id", + "chunk_index", + "content_text", + "token_count", + "page_number" + ], + "title": "DocumentChunkRead" + }, + "DocumentRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "source_id": { + "type": "string", + "format": "uuid", + "title": "Source Id" + }, + "source_path": { + "type": "string", + "title": "Source Path" + }, + "filename": { + "type": "string", + "title": "Filename" + }, + "file_type": { + "type": "string", + "title": "File Type" + }, + "file_hash": { + "type": "string", + "title": "File Hash" + }, + "file_size": { + "type": "integer", + "title": "File Size" + }, + "ingestion_status": { + "$ref": "#/components/schemas/IngestionStatus" + }, + "ingestion_error": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Ingestion Error" + }, + "chunk_count": { + "type": "integer", + "title": "Chunk Count" + }, + "ingested_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Ingested At" + }, + "connector_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Connector Type" + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "source_id", + "source_path", + "filename", + "file_type", + "file_hash", + "file_size", + "ingestion_status", + "ingestion_error", + "chunk_count", + "ingested_at" + ], + "title": "DocumentRead" + }, + "DraftCommand": { + "properties": { + "action": { + "type": "string", + "const": "draft-records-response", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/DraftPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "DraftCommand" + }, + "DraftInput": { + "properties": { + "source_materials": { + "items": { + "$ref": "#/components/schemas/SourceInput" + }, + "type": "array", + "title": "Source Materials" + }, + "sentences": { + "items": { + "$ref": "#/components/schemas/SentenceInput" + }, + "type": "array", + "minItems": 1, + "title": "Sentences" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sentences" + ], + "title": "DraftInput" + }, + "DraftPayload": { + "properties": { + "responseDraft": { + "type": "string", + "minLength": 1, + "title": "Responsedraft" + }, + "citation": { + "type": "string", + "title": "Citation", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "responseDraft" + ], + "title": "DraftPayload" + }, + "ErrorModel": { + "properties": { + "detail": { + "anyOf": [ + { + "type": "string" + }, + { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + ], + "title": "Detail" + } + }, + "type": "object", + "required": [ + "detail" + ], + "title": "ErrorModel" + }, + "Evidence": { + "properties": { + "filename": { + "type": "string", + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$", + "title": "Filename" + }, + "description": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Description" + }, + "media_type": { + "type": "string", + "enum": [ + "text/plain", + "image/jpeg", + "image/png", + "image/webp", + "application/pdf", + "audio/webm", + "audio/ogg", + "audio/wav", + "audio/mpeg", + "audio/mp4" + ], + "title": "Media Type" + }, + "content_base64": { + "type": "string", + "maxLength": 14000000, + "minLength": 1, + "title": "Content Base64" + }, + "sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "filename", + "description", + "media_type", + "content_base64", + "sha256" + ], + "title": "Evidence" + }, + "EvidenceItem": { + "properties": { + "filename": { + "type": "string", + "maxLength": 151, + "minLength": 1, + "title": "Filename" + }, + "media_type": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Media Type" + }, + "description": { + "type": "string", + "maxLength": 2000, + "title": "Description", + "default": "" + }, + "content_base64": { + "type": "string", + "maxLength": 14000000, + "minLength": 1, + "title": "Content Base64" + }, + "sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "filename", + "media_type", + "content_base64", + "sha256" + ], + "title": "EvidenceItem" + }, + "EvidenceItems": { + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/EvidenceItem" + }, + "type": "array", + "maxItems": 10, + "minItems": 1, + "title": "Items" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "items" + ], + "title": "EvidenceItems" + }, + "ExemptionAccuracyReport": { + "properties": { + "category": { + "type": "string", + "title": "Category" + }, + "total_flags": { + "type": "integer", + "title": "Total Flags" + }, + "accepted": { + "type": "integer", + "title": "Accepted" + }, + "rejected": { + "type": "integer", + "title": "Rejected" + }, + "pending": { + "type": "integer", + "title": "Pending" + }, + "acceptance_rate": { + "type": "number", + "title": "Acceptance Rate" + } + }, + "type": "object", + "required": [ + "category", + "total_flags", + "accepted", + "rejected", + "pending", + "acceptance_rate" + ], + "title": "ExemptionAccuracyReport" + }, + "ExemptionDashboard": { + "properties": { + "total_flags": { + "type": "integer", + "title": "Total Flags" + }, + "by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "By Status" + }, + "by_category": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "By Category" + }, + "acceptance_rate": { + "type": "number", + "title": "Acceptance Rate" + }, + "total_rules": { + "type": "integer", + "title": "Total Rules" + }, + "active_rules": { + "type": "integer", + "title": "Active Rules" + } + }, + "type": "object", + "required": [ + "total_flags", + "by_status", + "by_category", + "acceptance_rate", + "total_rules", + "active_rules" + ], + "title": "ExemptionDashboard" + }, + "ExemptionDecisionCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-exemption-decision", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ExemptionDecisionPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "ExemptionDecisionCommand" + }, + "ExemptionDecisionPayload": { + "properties": { + "exemptionSource": { + "type": "string", + "minLength": 1, + "title": "Exemptionsource" + }, + "exemptionKind": { + "type": "string", + "minLength": 1, + "title": "Exemptionkind" + }, + "exemptionFinding": { + "type": "string", + "minLength": 1, + "title": "Exemptionfinding" + }, + "exemptionDecision": { + "type": "string", + "enum": [ + "release", + "redact", + "exempt" + ], + "title": "Exemptiondecision" + }, + "exemptionBasis": { + "type": "string", + "minLength": 1, + "title": "Exemptionbasis" + }, + "exemptionReviewer": { + "type": "string", + "title": "Exemptionreviewer", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "exemptionSource", + "exemptionKind", + "exemptionFinding", + "exemptionDecision", + "exemptionBasis" + ], + "title": "ExemptionDecisionPayload" + }, + "ExemptionDecisionView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "source": { + "type": "string", + "title": "Source" + }, + "kind": { + "type": "string", + "title": "Kind" + }, + "finding": { + "type": "string", + "title": "Finding" + }, + "decision": { + "type": "string", + "enum": [ + "release", + "redact", + "exempt" + ], + "title": "Decision" + }, + "basis": { + "type": "string", + "title": "Basis" + }, + "reviewer": { + "type": "string", + "title": "Reviewer" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "source", + "kind", + "finding", + "decision", + "basis", + "reviewer", + "created_at_unix_seconds" + ], + "title": "ExemptionDecisionView" + }, + "ExemptionFlagRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "chunk_id": { + "type": "string", + "format": "uuid", + "title": "Chunk Id" + }, + "rule_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Rule Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "category": { + "type": "string", + "title": "Category" + }, + "matched_text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Matched Text" + }, + "confidence": { + "type": "number", + "title": "Confidence" + }, + "status": { + "$ref": "#/components/schemas/FlagStatus" + }, + "reviewed_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Reviewed By" + }, + "reviewed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Reviewed At" + }, + "review_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Reason" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "chunk_id", + "rule_id", + "request_id", + "category", + "matched_text", + "confidence", + "status", + "reviewed_by", + "reviewed_at", + "review_reason", + "created_at" + ], + "title": "ExemptionFlagRead" + }, + "ExemptionFlagReview": { + "properties": { + "status": { + "$ref": "#/components/schemas/FlagStatus" + }, + "review_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Reason" + } + }, + "type": "object", + "required": [ + "status" + ], + "title": "ExemptionFlagReview" + }, + "ExemptionNoteCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-exemption-review", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ExemptionNotePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "ExemptionNoteCommand" + }, + "ExemptionNotePayload": { + "properties": { + "exemptionNote": { + "type": "string", + "minLength": 1, + "title": "Exemptionnote" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "exemptionNote" + ], + "title": "ExemptionNotePayload" + }, + "ExemptionRuleCreate": { + "properties": { + "state_code": { + "type": "string", + "title": "State Code" + }, + "category": { + "type": "string", + "title": "Category" + }, + "rule_type": { + "$ref": "#/components/schemas/RuleType" + }, + "rule_definition": { + "type": "string", + "title": "Rule Definition" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "enabled": { + "type": "boolean", + "title": "Enabled", + "default": true + } + }, + "type": "object", + "required": [ + "state_code", + "category", + "rule_type", + "rule_definition" + ], + "title": "ExemptionRuleCreate" + }, + "ExemptionRuleRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "state_code": { + "type": "string", + "title": "State Code" + }, + "category": { + "type": "string", + "title": "Category" + }, + "rule_type": { + "$ref": "#/components/schemas/RuleType" + }, + "rule_definition": { + "type": "string", + "title": "Rule Definition" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "enabled": { + "type": "boolean", + "title": "Enabled" + }, + "version": { + "type": "integer", + "title": "Version", + "default": 1 + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "state_code", + "category", + "rule_type", + "rule_definition", + "description", + "enabled", + "created_by", + "created_at" + ], + "title": "ExemptionRuleRead" + }, + "ExemptionRuleUpdate": { + "properties": { + "rule_definition": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Rule Definition" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "enabled": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Enabled" + } + }, + "type": "object", + "title": "ExemptionRuleUpdate" + }, + "ExportReceipt": { + "properties": { + "export_path": { + "type": "string", + "maxLength": 32768, + "minLength": 1, + "title": "Export Path" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "export_path" + ], + "title": "ExportReceipt" + }, + "FeeEstimateCommand": { + "properties": { + "action": { + "type": "string", + "const": "estimate-records-fee", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/FeeEstimatePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "FeeEstimateCommand" + }, + "FeeEstimatePayload": { + "properties": { + "feeEstimate": { + "type": "string", + "minLength": 1, + "title": "Feeestimate" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "feeEstimate" + ], + "title": "FeeEstimatePayload" + }, + "FeeEstimateRequest": { + "properties": { + "page_count": { + "type": "integer", + "title": "Page Count" + }, + "fee_schedule_id": { + "type": "string", + "format": "uuid", + "title": "Fee Schedule Id" + } + }, + "type": "object", + "required": [ + "page_count", + "fee_schedule_id" + ], + "title": "FeeEstimateRequest" + }, + "FeeEstimateResponse": { + "properties": { + "page_count": { + "type": "integer", + "title": "Page Count" + }, + "unit_price": { + "type": "number", + "title": "Unit Price" + }, + "total": { + "type": "number", + "title": "Total" + }, + "fee_type": { + "type": "string", + "title": "Fee Type" + }, + "description": { + "type": "string", + "title": "Description" + } + }, + "type": "object", + "required": [ + "page_count", + "unit_price", + "total", + "fee_type", + "description" + ], + "title": "FeeEstimateResponse" + }, + "FeeLineCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-fee-line", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/FeeLinePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "FeeLineCommand" + }, + "FeeLineItemCreate": { + "properties": { + "description": { + "type": "string", + "title": "Description" + }, + "quantity": { + "type": "integer", + "title": "Quantity", + "default": 1 + }, + "unit_price": { + "type": "number", + "title": "Unit Price" + }, + "fee_schedule_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Fee Schedule Id" + } + }, + "type": "object", + "required": [ + "description", + "unit_price" + ], + "title": "FeeLineItemCreate" + }, + "FeeLineItemRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "fee_schedule_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Fee Schedule Id" + }, + "description": { + "type": "string", + "title": "Description" + }, + "quantity": { + "type": "integer", + "title": "Quantity" + }, + "unit_price": { + "type": "number", + "title": "Unit Price" + }, + "total": { + "type": "number", + "title": "Total" + }, + "status": { + "type": "string", + "title": "Status" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "fee_schedule_id", + "description", + "quantity", + "unit_price", + "total", + "status", + "created_at" + ], + "title": "FeeLineItemRead" + }, + "FeeLinePayload": { + "properties": { + "feeLineDescription": { + "type": "string", + "minLength": 1, + "title": "Feelinedescription" + }, + "feeScheduleBasis": { + "type": "string", + "minLength": 1, + "title": "Feeschedulebasis" + }, + "feeLineAmount": { + "type": "string", + "title": "Feelineamount" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "feeLineDescription", + "feeScheduleBasis", + "feeLineAmount" + ], + "title": "FeeLinePayload" + }, + "FeeLineView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "description": { + "type": "string", + "title": "Description" + }, + "schedule_basis": { + "type": "string", + "title": "Schedule Basis" + }, + "amount_cents": { + "type": "integer", + "title": "Amount Cents" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "description", + "schedule_basis", + "amount_cents", + "created_at_unix_seconds" + ], + "title": "FeeLineView" + }, + "FeeScheduleCreate": { + "properties": { + "jurisdiction": { + "type": "string", + "title": "Jurisdiction" + }, + "fee_type": { + "type": "string", + "title": "Fee Type" + }, + "amount": { + "type": "number", + "title": "Amount" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "effective_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective Date" + } + }, + "type": "object", + "required": [ + "jurisdiction", + "fee_type", + "amount" + ], + "title": "FeeScheduleCreate" + }, + "FeeScheduleRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "jurisdiction": { + "type": "string", + "title": "Jurisdiction" + }, + "fee_type": { + "type": "string", + "title": "Fee Type" + }, + "amount": { + "type": "number", + "title": "Amount" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "effective_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective Date" + }, + "created_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "jurisdiction", + "fee_type", + "amount", + "description", + "effective_date", + "created_by", + "created_at" + ], + "title": "FeeScheduleRead" + }, + "FeeScheduleUpdate": { + "properties": { + "fee_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Fee Type" + }, + "amount": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Amount" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "effective_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective Date" + } + }, + "type": "object", + "title": "FeeScheduleUpdate" + }, + "FeeWaiverCommand": { + "properties": { + "action": { + "type": "string", + "const": "waive-records-fee", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/FeeWaiverPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "FeeWaiverCommand" + }, + "FeeWaiverCreateRequest": { + "properties": { + "waiver_type": { + "type": "string", + "title": "Waiver Type" + }, + "reason": { + "type": "string", + "title": "Reason" + } + }, + "type": "object", + "required": [ + "waiver_type", + "reason" + ], + "title": "FeeWaiverCreateRequest" + }, + "FeeWaiverPayload": { + "properties": { + "feeWaiverReason": { + "type": "string", + "minLength": 1, + "title": "Feewaiverreason" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "feeWaiverReason" + ], + "title": "FeeWaiverPayload" + }, + "FeeWaiverReadResponse": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "waiver_type": { + "type": "string", + "title": "Waiver Type" + }, + "reason": { + "type": "string", + "title": "Reason" + }, + "status": { + "type": "string", + "title": "Status" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + }, + "created_at": { + "type": "string", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "waiver_type", + "reason", + "status", + "created_at" + ], + "title": "FeeWaiverReadResponse" + }, + "FeeWaiverReviewRequest": { + "properties": { + "status": { + "type": "string", + "title": "Status" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + } + }, + "type": "object", + "required": [ + "status" + ], + "title": "FeeWaiverReviewRequest" + }, + "FinishCommand": { + "properties": { + "action": { + "type": "string", + "enum": [ + "fulfill-records-request", + "close-records-request" + ], + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/NativePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "FinishCommand" + }, + "FlagStatus": { + "type": "string", + "enum": [ + "flagged", + "reviewed", + "accepted", + "rejected" + ], + "title": "FlagStatus" + }, + "FormPlan": { + "properties": { + "action": { + "type": "string", + "const": "form-plan", + "title": "Action" + }, + "formName": { + "type": "string", + "maxLength": 500, + "title": "Formname", + "default": "" + }, + "fields": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 50, + "title": "Fields" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "FormPlan" + }, + "GeneratedDraft": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "model": { + "type": "string", + "minLength": 1, + "title": "Model" + }, + "previous_response_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Previous Response Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text", + "model", + "previous_response_sha256" + ], + "title": "GeneratedDraft" + }, + "HTTPValidationError": { + "properties": { + "detail": { + "items": { + "$ref": "#/components/schemas/ValidationError" + }, + "type": "array", + "title": "Detail" + } + }, + "type": "object", + "title": "HTTPValidationError" + }, + "Handoff": { + "properties": { + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "request_id" + ], + "title": "Handoff" + }, + "ImportBundleCreate": { + "properties": { + "job_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Job Id" + }, + "connector_type": { + "type": "string", + "minLength": 1, + "title": "Connector Type" + }, + "source": { + "$ref": "#/components/schemas/SourceCreate" + }, + "sources": { + "items": { + "$ref": "#/components/schemas/SourceCreate" + }, + "type": "array", + "title": "Sources" + }, + "titles": { + "items": { + "$ref": "#/components/schemas/TitleCreate" + }, + "type": "array", + "title": "Titles" + }, + "chapters": { + "items": { + "$ref": "#/components/schemas/ChapterCreate" + }, + "type": "array", + "title": "Chapters" + }, + "sections": { + "items": { + "$ref": "#/components/schemas/SectionCreate" + }, + "type": "array", + "title": "Sections" + }, + "versions": { + "items": { + "$ref": "#/components/schemas/SectionVersionCreate" + }, + "type": "array", + "title": "Versions" + }, + "provenance": { + "additionalProperties": true, + "type": "object", + "title": "Provenance" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "connector_type", + "source" + ], + "title": "ImportBundleCreate", + "description": "Request body for local fixture/file-drop import jobs." + }, + "InclusionStatus": { + "type": "string", + "enum": [ + "included", + "excluded", + "pending" + ], + "title": "InclusionStatus" + }, + "IngestionStats": { + "properties": { + "total_sources": { + "type": "integer", + "title": "Total Sources" + }, + "active_sources": { + "type": "integer", + "title": "Active Sources" + }, + "total_documents": { + "type": "integer", + "title": "Total Documents" + }, + "documents_by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Documents By Status" + }, + "total_chunks": { + "type": "integer", + "title": "Total Chunks" + } + }, + "type": "object", + "required": [ + "total_sources", + "active_sources", + "total_documents", + "documents_by_status", + "total_chunks" + ], + "title": "IngestionStats" + }, + "IngestionStatus": { + "type": "string", + "enum": [ + "pending", + "processing", + "completed", + "failed" + ], + "title": "IngestionStatus" + }, + "InitiativeInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "policy": { + "$ref": "#/components/schemas/PolicySelection" + }, + "responsible_staff": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Responsible Staff" + }, + "target": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "title": "Target" + }, + "unit": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Unit" + }, + "due_on": { + "type": "string", + "format": "date", + "title": "Due On" + }, + "status": { + "type": "string", + "enum": [ + "planned", + "active", + "completed", + "cancelled" + ], + "title": "Status", + "default": "planned" + }, + "milestones": { + "items": { + "$ref": "#/components/schemas/Milestone" + }, + "type": "array", + "maxItems": 100, + "title": "Milestones" + }, + "measurements": { + "items": { + "$ref": "#/components/schemas/Measurement" + }, + "type": "array", + "maxItems": 1000, + "title": "Measurements" + }, + "note": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "policy", + "responsible_staff", + "target", + "unit", + "due_on", + "note" + ], + "title": "InitiativeInput" + }, + "InspectionInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "property_reference": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Property Reference" + }, + "inspection_reference": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Inspection Reference" + }, + "dataset_kind": { + "type": "string", + "enum": [ + "municipal", + "fictional" + ], + "title": "Dataset Kind" + }, + "inspector_notes": { + "type": "string", + "maxLength": 10000, + "minLength": 1, + "title": "Inspector Notes" + }, + "photo_observations": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 30, + "title": "Photo Observations" + }, + "voice_notes": { + "type": "string", + "maxLength": 10000, + "title": "Voice Notes", + "default": "" + }, + "evidence": { + "items": { + "$ref": "#/components/schemas/Evidence" + }, + "type": "array", + "maxItems": 10, + "title": "Evidence" + }, + "linked_sources": { + "items": { + "$ref": "#/components/schemas/townlight_inspections__workflow_models__SourceLink" + }, + "type": "array", + "maxItems": 30, + "title": "Linked Sources" + }, + "assigned_to": { + "type": "string", + "maxLength": 255, + "title": "Assigned To", + "default": "" + }, + "staff_notes": { + "type": "string", + "maxLength": 10000, + "title": "Staff Notes", + "default": "" + }, + "notice_draft": { + "type": "string", + "maxLength": 10000, + "title": "Notice Draft", + "default": "" + }, + "review_state": { + "type": "string", + "enum": [ + "draft", + "follow_up", + "reviewed" + ], + "title": "Review State", + "default": "draft" + }, + "review_notes": { + "type": "string", + "maxLength": 4000, + "title": "Review Notes", + "default": "" + }, + "public_summary": { + "type": "string", + "maxLength": 10000, + "title": "Public Summary", + "default": "" + }, + "analysis": { + "anyOf": [ + { + "$ref": "#/components/schemas/AnalysisRecord" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "property_reference", + "inspection_reference", + "dataset_kind", + "inspector_notes" + ], + "title": "InspectionInput" + }, + "IntakeInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "project_name": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Project Name" + }, + "project_description": { + "type": "string", + "maxLength": 10000, + "minLength": 1, + "title": "Project Description" + }, + "location": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Location" + }, + "applicant_contact": { + "type": "string", + "maxLength": 2000, + "title": "Applicant Contact", + "default": "" + }, + "requirement_revision": { + "type": "string", + "format": "uuid", + "title": "Requirement Revision" + }, + "materials": { + "items": { + "$ref": "#/components/schemas/MaterialReview" + }, + "type": "array", + "maxItems": 100, + "minItems": 1, + "title": "Materials" + }, + "linked_sources": { + "items": { + "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink" + }, + "type": "array", + "maxItems": 30, + "title": "Linked Sources" + }, + "staff_notes": { + "type": "string", + "maxLength": 10000, + "title": "Staff Notes", + "default": "" + }, + "assigned_to": { + "type": "string", + "maxLength": 255, + "title": "Assigned To", + "default": "" + }, + "review_state": { + "type": "string", + "enum": [ + "draft", + "follow_up", + "reviewed" + ], + "title": "Review State", + "default": "draft" + }, + "review_notes": { + "type": "string", + "maxLength": 4000, + "title": "Review Notes", + "default": "" + }, + "public_summary": { + "type": "string", + "maxLength": 10000, + "title": "Public Summary", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "project_name", + "project_description", + "location", + "requirement_revision", + "materials" + ], + "title": "IntakeInput" + }, + "InterpretationNoteCreate": { + "properties": { + "note_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Note Id" + }, + "note_text": { + "type": "string", + "minLength": 1, + "title": "Note Text" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "note_text" + ], + "title": "InterpretationNoteCreate", + "description": "Request body for staff-only interpretation notes." + }, + "InterviewRequest": { + "properties": { + "last_answer": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Answer" + }, + "last_field": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Field" + }, + "skipped_fields": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Skipped Fields" + } + }, + "type": "object", + "title": "InterviewRequest" + }, + "InterviewResponse": { + "properties": { + "question": { + "type": "string", + "title": "Question" + }, + "target_field": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Target Field" + }, + "all_complete": { + "type": "boolean", + "title": "All Complete" + }, + "completed_fields": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Completed Fields" + }, + "onboarding_status": { + "type": "string", + "title": "Onboarding Status" + }, + "skipped_fields": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Skipped Fields" + } + }, + "type": "object", + "required": [ + "question", + "target_field", + "all_complete", + "completed_fields", + "onboarding_status", + "skipped_fields" + ], + "title": "InterviewResponse" + }, + "ManagedFileReceipt": { + "properties": { + "original_path": { + "type": "string", + "minLength": 1, + "title": "Original Path" + }, + "stored_path": { + "type": "string", + "minLength": 1, + "title": "Stored Path" + }, + "file_name": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "File Name" + }, + "sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Sha256" + }, + "size_bytes": { + "type": "integer", + "maximum": 2147483647.0, + "minimum": 0.0, + "title": "Size Bytes" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "original_path", + "stored_path", + "file_name", + "sha256", + "size_bytes" + ], + "title": "ManagedFileReceipt" + }, + "ManagedSource": { + "properties": { + "original_path": { + "type": "string", + "title": "Original Path" + }, + "stored_path": { + "type": "string", + "title": "Stored Path" + }, + "file_name": { + "type": "string", + "title": "File Name" + }, + "sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Sha256" + }, + "size_bytes": { + "type": "integer", + "minimum": 0.0, + "title": "Size Bytes" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "original_path", + "stored_path", + "file_name", + "sha256", + "size_bytes" + ], + "title": "ManagedSource" + }, + "Material": { + "properties": { + "material_id": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]{1,80}$", + "title": "Material Id" + }, + "description": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Description" + }, + "citation": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Citation" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "material_id", + "description", + "citation" + ], + "title": "Material" + }, + "MaterialReview": { + "properties": { + "material_id": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Material Id" + }, + "status": { + "type": "string", + "enum": [ + "not_reviewed", + "provided", + "missing", + "unclear" + ], + "title": "Status", + "default": "not_reviewed" + }, + "note": { + "type": "string", + "maxLength": 2000, + "title": "Note", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "material_id" + ], + "title": "MaterialReview" + }, + "Measurement": { + "properties": { + "recorded_on": { + "type": "string", + "format": "date", + "title": "Recorded On" + }, + "value": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "title": "Value" + }, + "evidence": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Evidence" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "recorded_on", + "value", + "evidence" + ], + "title": "Measurement" + }, + "MediaAnalysis": { + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/EvidenceItem" + }, + "type": "array", + "maxItems": 10, + "minItems": 1, + "title": "Items" + }, + "code_links": { + "items": { + "$ref": "#/components/schemas/CodeLink" + }, + "type": "array", + "maxItems": 30, + "title": "Code Links" + }, + "inspector_supplied_text": { + "type": "string", + "maxLength": 10000, + "title": "Inspector Supplied Text", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "items" + ], + "title": "MediaAnalysis" + }, + "MeetingInput": { + "properties": { + "title": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Title" + }, + "scheduled_start": { + "type": "string", + "format": "date-time", + "title": "Scheduled Start" + }, + "location": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Location" + }, + "meeting_type": { + "type": "string", + "enum": [ + "regular", + "special", + "emergency", + "closed_session", + "executive" + ], + "title": "Meeting Type", + "default": "regular" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "scheduled_start", + "location" + ], + "title": "MeetingInput" + }, + "MeetingLink": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + }, + "relation": { + "type": "string", + "enum": [ + "hearing", + "context", + "precedent" + ], + "title": "Relation" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256", + "relation" + ], + "title": "MeetingLink" + }, + "MeetingSearch": { + "properties": { + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "MeetingSearch" + }, + "MeetingStageInput": { + "properties": { + "to_status": { + "type": "string", + "enum": [ + "SCHEDULED", + "NOTICED", + "PACKET_POSTED", + "IN_PROGRESS", + "RECESSED", + "ADJOURNED", + "TRANSCRIPT_READY", + "MINUTES_DRAFTED", + "MINUTES_POSTED", + "MINUTES_ADOPTED", + "MINUTES_SIGNED", + "ARCHIVED", + "CANCELLED" + ], + "title": "To Status" + }, + "statutory_basis": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Statutory Basis" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "to_status" + ], + "title": "MeetingStageInput" + }, + "MeetingsSearch": { + "properties": { + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "MeetingsSearch" + }, + "MeetingsSourceSelection": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "MeetingsSourceSelection" + }, + "MessageCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-message", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/MessagePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "MessageCommand" + }, + "MessageCreate": { + "properties": { + "message_text": { + "type": "string", + "title": "Message Text" + }, + "is_internal": { + "type": "boolean", + "title": "Is Internal", + "default": false + } + }, + "type": "object", + "required": [ + "message_text" + ], + "title": "MessageCreate" + }, + "MessagePayload": { + "properties": { + "requestMessageBody": { + "type": "string", + "minLength": 1, + "title": "Requestmessagebody" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requestMessageBody" + ], + "title": "MessagePayload" + }, + "MessageRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "sender_type": { + "type": "string", + "title": "Sender Type" + }, + "sender_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Sender Id" + }, + "message_text": { + "type": "string", + "title": "Message Text" + }, + "is_internal": { + "type": "boolean", + "title": "Is Internal" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "sender_type", + "sender_id", + "message_text", + "is_internal", + "created_at" + ], + "title": "MessageRead" + }, + "MessageView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "author": { + "type": "string", + "title": "Author" + }, + "author_role": { + "type": "string", + "title": "Author Role" + }, + "body": { + "type": "string", + "title": "Body" + }, + "visibility": { + "type": "string", + "title": "Visibility" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "author", + "author_role", + "body", + "visibility", + "created_at_unix_seconds" + ], + "title": "MessageView" + }, + "Milestone": { + "properties": { + "title": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Title" + }, + "due_on": { + "type": "string", + "format": "date", + "title": "Due On" + }, + "completed_on": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Completed On" + }, + "evidence": { + "type": "string", + "maxLength": 2000, + "title": "Evidence", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "due_on" + ], + "title": "Milestone" + }, + "MinutesDecision": { + "properties": { + "action": { + "type": "string", + "enum": [ + "post", + "adopt", + "sign" + ], + "title": "Action" + }, + "note": { + "type": "string", + "title": "Note", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "MinutesDecision" + }, + "ModelRegistryCreate": { + "properties": { + "model_name": { + "type": "string", + "title": "Model Name" + }, + "model_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Version" + }, + "parameter_count": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parameter Count" + }, + "license": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License" + }, + "model_card_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Card Url" + }, + "is_active": { + "type": "boolean", + "title": "Is Active", + "default": false + }, + "context_window_size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Context Window Size" + }, + "supports_ner": { + "type": "boolean", + "title": "Supports Ner", + "default": false + }, + "supports_vision": { + "type": "boolean", + "title": "Supports Vision", + "default": false + } + }, + "type": "object", + "required": [ + "model_name" + ], + "title": "ModelRegistryCreate", + "description": "Schema for creating a new model_registry record (POST body)." + }, + "ModelRegistryRead": { + "properties": { + "id": { + "type": "integer", + "title": "Id" + }, + "model_name": { + "type": "string", + "title": "Model Name" + }, + "model_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Version" + }, + "parameter_count": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parameter Count" + }, + "license": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License" + }, + "model_card_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Card Url" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "added_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Added At" + }, + "context_window_size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Context Window Size" + }, + "supports_ner": { + "type": "boolean", + "title": "Supports Ner" + }, + "supports_vision": { + "type": "boolean", + "title": "Supports Vision" + } + }, + "type": "object", + "required": [ + "id", + "model_name", + "is_active", + "supports_ner", + "supports_vision" + ], + "title": "ModelRegistryRead", + "description": "Schema for returning a model_registry record (GET response).\n\n``from_attributes=True`` allows construction directly from an ORM instance." + }, + "ModelRegistryUpdate": { + "properties": { + "model_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Name" + }, + "model_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Version" + }, + "parameter_count": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parameter Count" + }, + "license": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License" + }, + "model_card_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Card Url" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + }, + "context_window_size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Context Window Size" + }, + "supports_ner": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Supports Ner" + }, + "supports_vision": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Supports Vision" + } + }, + "type": "object", + "title": "ModelRegistryUpdate", + "description": "Schema for partially updating a model_registry record (PATCH body).\n\nEvery field is optional so callers can send only the fields they want to\nchange." + }, + "MotionCorrection": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "reason": { + "type": "string", + "minLength": 1, + "title": "Reason" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text", + "reason" + ], + "title": "MotionCorrection" + }, + "MotionInput": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "seconded_by": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Seconded By" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text" + ], + "title": "MotionInput" + }, + "NativePayload": { + "properties": {}, + "additionalProperties": false, + "type": "object", + "title": "NativePayload" + }, + "NativeRequestRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "requester_name": { + "type": "string", + "title": "Requester Name" + }, + "requester_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Email" + }, + "requester_phone": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Phone" + }, + "requester_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Type" + }, + "date_received": { + "type": "string", + "format": "date-time", + "title": "Date Received" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "description": { + "type": "string", + "title": "Description" + }, + "status": { + "$ref": "#/components/schemas/RequestStatus" + }, + "assigned_to": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "created_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "response_draft": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Response Draft" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + }, + "estimated_fee": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Estimated Fee" + }, + "fee_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Fee Status" + }, + "fee_waiver_requested": { + "type": "boolean", + "title": "Fee Waiver Requested", + "default": false + }, + "priority": { + "type": "string", + "title": "Priority", + "default": "normal" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + }, + "closed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Closed At" + }, + "closure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Closure Reason" + }, + "desktop_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Desktop Id" + }, + "public_tracking_number": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Public Tracking Number" + }, + "submitted_via": { + "type": "string", + "title": "Submitted Via" + }, + "deadline_label": { + "type": "string", + "title": "Deadline Label" + }, + "deadline_basis": { + "type": "string", + "title": "Deadline Basis" + }, + "deadline_reviewed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Deadline Reviewed At" + } + }, + "type": "object", + "required": [ + "id", + "requester_name", + "requester_email", + "date_received", + "statutory_deadline", + "description", + "status", + "assigned_to", + "created_by", + "created_at", + "response_draft", + "review_notes", + "desktop_id", + "public_tracking_number", + "submitted_via", + "deadline_label", + "deadline_basis", + "deadline_reviewed_at" + ], + "title": "NativeRequestRead" + }, + "NoticeDocumentInput": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text" + ], + "title": "NoticeDocumentInput" + }, + "NoticeDraft": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "body": { + "type": "string", + "maxLength": 100000, + "minLength": 1, + "title": "Body" + }, + "notice_type": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Notice Type" + }, + "statutory_basis": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Statutory Basis" + }, + "event_date": { + "type": "string", + "format": "date", + "title": "Event Date" + }, + "lead_days": { + "type": "integer", + "maximum": 365.0, + "minimum": 0.0, + "title": "Lead Days" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "body", + "notice_type", + "statutory_basis", + "event_date", + "lead_days" + ], + "title": "NoticeDraft" + }, + "NoticeInput": { + "properties": { + "notice_type": { + "type": "string", + "enum": [ + "regular", + "special", + "emergency", + "closed_session", + "executive" + ], + "title": "Notice Type" + }, + "posted_at": { + "type": "string", + "format": "date-time", + "title": "Posted At" + }, + "minimum_notice_hours": { + "type": "integer", + "minimum": 0.0, + "title": "Minimum Notice Hours" + }, + "statutory_basis": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Statutory Basis" + }, + "approved_by": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Approved By" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "notice_type", + "posted_at", + "minimum_notice_hours" + ], + "title": "NoticeInput" + }, + "NoticeProofInput": { + "properties": { + "location": { + "type": "string", + "minLength": 1, + "title": "Location" + }, + "note": { + "type": "string", + "title": "Note", + "default": "" + }, + "document_delivery_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Document Delivery Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "location" + ], + "title": "NoticeProofInput" + }, + "NotificationLogRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "template_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Template Id" + }, + "recipient_email": { + "type": "string", + "title": "Recipient Email" + }, + "request_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Request Id" + }, + "channel": { + "type": "string", + "title": "Channel" + }, + "status": { + "type": "string", + "title": "Status" + }, + "sent_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Sent At" + }, + "error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Message" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "template_id", + "recipient_email", + "request_id", + "channel", + "status", + "sent_at", + "error_message", + "created_at" + ], + "title": "NotificationLogRead" + }, + "NotificationTemplateCreate": { + "properties": { + "event_type": { + "type": "string", + "title": "Event Type" + }, + "channel": { + "type": "string", + "title": "Channel", + "default": "email" + }, + "subject_template": { + "type": "string", + "title": "Subject Template" + }, + "body_template": { + "type": "string", + "title": "Body Template" + } + }, + "type": "object", + "required": [ + "event_type", + "subject_template", + "body_template" + ], + "title": "NotificationTemplateCreate" + }, + "NotificationTemplateRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "event_type": { + "type": "string", + "title": "Event Type" + }, + "channel": { + "type": "string", + "title": "Channel" + }, + "subject_template": { + "type": "string", + "title": "Subject Template" + }, + "body_template": { + "type": "string", + "title": "Body Template" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "event_type", + "channel", + "subject_template", + "body_template", + "is_active", + "created_at" + ], + "title": "NotificationTemplateRead" + }, + "NotificationTemplateUpdate": { + "properties": { + "subject_template": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Subject Template" + }, + "body_template": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Body Template" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "NotificationTemplateUpdate" + }, + "NotificationView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "notification_id": { + "type": "string", + "title": "Notification Id" + }, + "module_id": { + "type": "string", + "title": "Module Id" + }, + "record_id": { + "type": "string", + "title": "Record Id" + }, + "audience": { + "type": "string", + "title": "Audience" + }, + "channel": { + "type": "string", + "title": "Channel" + }, + "subject": { + "type": "string", + "title": "Subject" + }, + "body": { + "type": "string", + "title": "Body" + }, + "status": { + "type": "string", + "title": "Status" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + }, + "sent_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Sent At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "notification_id", + "module_id", + "record_id", + "audience", + "channel", + "subject", + "body", + "status", + "created_at_unix_seconds", + "sent_at_unix_seconds" + ], + "title": "NotificationView" + }, + "OllamaModelInfo": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Size" + }, + "details": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Details" + } + }, + "type": "object", + "required": [ + "name" + ], + "title": "OllamaModelInfo" + }, + "OllamaStatus": { + "properties": { + "status": { + "type": "string", + "title": "Status" + }, + "models": { + "items": { + "$ref": "#/components/schemas/OllamaModelInfo" + }, + "type": "array", + "title": "Models" + } + }, + "type": "object", + "required": [ + "status", + "models" + ], + "title": "OllamaStatus" + }, + "OperationalMetrics": { + "properties": { + "average_response_time_days": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Average Response Time Days" + }, + "median_response_time_days": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Median Response Time Days" + }, + "requests_by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Requests By Status" + }, + "requests_by_department": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Requests By Department" + }, + "deadline_compliance_rate": { + "type": "number", + "title": "Deadline Compliance Rate" + }, + "total_open": { + "type": "integer", + "title": "Total Open" + }, + "total_closed": { + "type": "integer", + "title": "Total Closed" + }, + "total_overdue": { + "type": "integer", + "title": "Total Overdue" + }, + "clarification_frequency": { + "type": "number", + "title": "Clarification Frequency" + }, + "top_request_topics": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Top Request Topics" + } + }, + "type": "object", + "required": [ + "average_response_time_days", + "median_response_time_days", + "requests_by_status", + "requests_by_department", + "deadline_compliance_rate", + "total_open", + "total_closed", + "total_overdue", + "clarification_frequency", + "top_request_topics" + ], + "title": "OperationalMetrics" + }, + "Outline": { + "properties": { + "title": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Title" + }, + "question_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "maxItems": 50, + "minItems": 1, + "title": "Question Ids" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "question_ids" + ], + "title": "Outline" + }, + "Packet": { + "properties": { + "expected_revision": { + "type": "string", + "format": "uuid", + "title": "Expected Revision" + }, + "visibility": { + "type": "string", + "enum": [ + "staff_only", + "records_copy" + ], + "title": "Visibility" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "expected_revision", + "visibility" + ], + "title": "Packet" + }, + "PacketInput": { + "properties": { + "agenda_item_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "title": "Agenda Item Ids" + }, + "source_files": { + "items": { + "$ref": "#/components/schemas/ManagedSource" + }, + "type": "array", + "title": "Source Files" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "agenda_item_ids" + ], + "title": "PacketInput" + }, + "Pathway": { + "properties": { + "project_type": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Project Type" + }, + "proposal": { + "type": "string", + "maxLength": 4000, + "title": "Proposal", + "default": "" + }, + "location_context": { + "type": "string", + "maxLength": 1000, + "title": "Location Context", + "default": "" + }, + "requirement_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Requirement Revision" + }, + "fee_link": { + "anyOf": [ + { + "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "project_type" + ], + "title": "Pathway" + }, + "PathwayStep": { + "properties": { + "step": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Step" + }, + "citation": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Citation" + }, + "typical_time": { + "type": "string", + "maxLength": 1000, + "title": "Typical Time", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "step", + "citation" + ], + "title": "PathwayStep" + }, + "PlainLanguageSummaryCreate": { + "properties": { + "summary_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Summary Id" + }, + "section_version_id": { + "type": "string", + "minLength": 1, + "title": "Section Version Id" + }, + "summary_text": { + "type": "string", + "minLength": 1, + "title": "Summary Text" + }, + "language_code": { + "type": "string", + "title": "Language Code", + "default": "en" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "section_version_id", + "summary_text" + ], + "title": "PlainLanguageSummaryCreate", + "description": "Request body for staff-drafted plain-language summaries." + }, + "PolicySelection": { + "properties": { + "plan_id": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Plan Id" + }, + "revision_id": { + "type": "string", + "maxLength": 36, + "minLength": 36, + "title": "Revision Id" + }, + "policy_id": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Policy Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "plan_id", + "revision_id", + "policy_id" + ], + "title": "PolicySelection" + }, + "PortalModeResponse": { + "properties": { + "mode": { + "type": "string", + "enum": [ + "public", + "private" + ], + "title": "Mode", + "description": "Active portal posture for this deployment. ``public`` = minimal resident surface (landing + authenticated records-request submission + resident registration) reachable without staff auth. ``private`` = staff-only; no public routes, no resident self-registration." + } + }, + "type": "object", + "required": [ + "mode" + ], + "title": "PortalModeResponse", + "description": "T5D — schema for ``GET /config/portal-mode``.\n\nExposed to the frontend on boot so it can branch routing without a\nuser-identity lookup. The payload is intentionally the single field\nbelow — no staff config, no user state, no schema version." + }, + "PrepareArtifact": { + "properties": { + "kind": { + "type": "string", + "enum": [ + "response", + "release-package" + ], + "title": "Kind" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "kind" + ], + "title": "PrepareArtifact" + }, + "Proof": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + }, + "filename": { + "type": "string", + "maxLength": 150, + "minLength": 1, + "title": "Filename" + }, + "content_base64": { + "type": "string", + "maxLength": 7000000, + "minLength": 1, + "title": "Content Base64" + }, + "location": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Location" + }, + "published_at": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Published At" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence", + "filename", + "content_base64", + "location", + "published_at" + ], + "title": "Proof" + }, + "Proposal": { + "properties": { + "id": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Id" + }, + "version_id": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Version Id" + }, + "meeting_id": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "ordinance_number": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Ordinance Number" + }, + "proposed_text": { + "type": "string", + "maxLength": 1000000, + "minLength": 1, + "title": "Proposed Text" + }, + "supersedes_id": { + "anyOf": [ + { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$" + }, + { + "type": "null" + } + ], + "title": "Supersedes Id" + }, + "reconciliation_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reconciliation Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "version_id", + "meeting_id", + "title", + "ordinance_number", + "proposed_text" + ], + "title": "Proposal" + }, + "PublicExplore": { + "properties": { + "goal": { + "type": "string", + "maxLength": 500, + "title": "Goal", + "default": "" + }, + "topic": { + "type": "string", + "maxLength": 160, + "title": "Topic", + "default": "" + }, + "neighborhood": { + "type": "string", + "maxLength": 255, + "title": "Neighborhood", + "default": "" + }, + "plan_type": { + "type": "string", + "maxLength": 120, + "title": "Plan Type", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "title": "PublicExplore" + }, + "PublicIntake": { + "properties": { + "requester": { + "type": "string", + "minLength": 1, + "title": "Requester" + }, + "requesterContact": { + "type": "string", + "minLength": 1, + "title": "Requestercontact" + }, + "summary": { + "type": "string", + "minLength": 1, + "title": "Summary" + }, + "deadline": { + "type": "string", + "title": "Deadline", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requester", + "requesterContact", + "summary" + ], + "title": "PublicIntake" + }, + "PublicLookup": { + "properties": { + "trackingNumber": { + "type": "string", + "minLength": 1, + "title": "Trackingnumber" + }, + "requesterContact": { + "type": "string", + "minLength": 1, + "title": "Requestercontact" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "trackingNumber", + "requesterContact" + ], + "title": "PublicLookup" + }, + "PublicMessage": { + "properties": { + "trackingNumber": { + "type": "string", + "minLength": 1, + "title": "Trackingnumber" + }, + "requesterContact": { + "type": "string", + "minLength": 1, + "title": "Requestercontact" + }, + "publicRequestMessage": { + "type": "string", + "minLength": 1, + "title": "Publicrequestmessage" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "trackingNumber", + "requesterContact", + "publicRequestMessage" + ], + "title": "PublicMessage" + }, + "PublicStatusView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "label": { + "type": "string", + "title": "Label" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "status": { + "type": "string", + "title": "Status" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "label", + "summary", + "status", + "created_at_unix_seconds" + ], + "title": "PublicStatusView" + }, + "PublicationView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "source_module": { + "type": "string", + "title": "Source Module" + }, + "source_record_id": { + "type": "string", + "title": "Source Record Id" + }, + "record_type": { + "type": "string", + "title": "Record Type" + }, + "public_payload": { + "type": "string", + "title": "Public Payload" + }, + "payload_hash": { + "type": "string", + "title": "Payload Hash" + }, + "published_at_unix_seconds": { + "type": "integer", + "title": "Published At Unix Seconds" + }, + "retracted_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Retracted At Unix Seconds" + }, + "retracted_by": { + "type": "string", + "title": "Retracted By", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "source_module", + "source_record_id", + "record_type", + "public_payload", + "payload_hash", + "published_at_unix_seconds" + ], + "title": "PublicationView" + }, + "PublishingPlan": { + "properties": { + "action": { + "type": "string", + "const": "publishing-workflow", + "title": "Action" + }, + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "hasReview": { + "type": "boolean", + "title": "Hasreview", + "default": false + }, + "hasPlainLanguage": { + "type": "boolean", + "title": "Hasplainlanguage", + "default": false + }, + "hasTranslationReview": { + "type": "boolean", + "title": "Hastranslationreview", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "PublishingPlan" + }, + "Question": { + "properties": { + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + }, + "question": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Question" + }, + "kind": { + "type": "string", + "enum": [ + "use", + "dimension" + ], + "title": "Kind" + }, + "key": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Key" + }, + "audience": { + "type": "string", + "enum": [ + "resident", + "staff" + ], + "title": "Audience", + "default": "resident" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "jurisdiction", + "query", + "question", + "kind", + "key" + ], + "title": "Question" + }, + "QuestionAnswerRequest": { + "properties": { + "question": { + "type": "string", + "minLength": 1, + "title": "Question" + }, + "section_number": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Section Number" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "question" + ], + "title": "QuestionAnswerRequest", + "description": "Request body for citation-grounded code Q&A." + }, + "RecordsDocumentView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "attachment_id": { + "type": "string", + "title": "Attachment Id" + }, + "title": { + "type": "string", + "title": "Title" + }, + "original_path": { + "type": "string", + "title": "Original Path" + }, + "stored_path": { + "type": "string", + "title": "Stored Path" + }, + "citation": { + "type": "string", + "title": "Citation" + }, + "sha256": { + "type": "string", + "title": "Sha256" + }, + "size_bytes": { + "type": "integer", + "title": "Size Bytes" + }, + "status": { + "type": "string", + "title": "Status" + }, + "added_by": { + "type": "string", + "title": "Added By" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + }, + "release_original_path": { + "type": "string", + "title": "Release Original Path", + "default": "" + }, + "release_stored_path": { + "type": "string", + "title": "Release Stored Path", + "default": "" + }, + "release_file_name": { + "type": "string", + "title": "Release File Name", + "default": "" + }, + "release_sha256": { + "type": "string", + "title": "Release Sha256", + "default": "" + }, + "release_size_bytes": { + "type": "integer", + "title": "Release Size Bytes", + "default": 0 + }, + "release_status": { + "type": "string", + "title": "Release Status", + "default": "" + }, + "release_note": { + "type": "string", + "title": "Release Note", + "default": "" + }, + "release_added_by": { + "type": "string", + "title": "Release Added By", + "default": "" + }, + "release_added_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Release Added At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "attachment_id", + "title", + "original_path", + "stored_path", + "citation", + "sha256", + "size_bytes", + "status", + "added_by", + "created_at_unix_seconds" + ], + "title": "RecordsDocumentView" + }, + "RecordsOperationRead": { + "properties": { + "action": { + "type": "string", + "title": "Action" + }, + "message": { + "type": "string", + "title": "Message" + }, + "request": { + "$ref": "#/components/schemas/RecordsView" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "message", + "request" + ], + "title": "RecordsOperationRead" + }, + "RecordsStateRead": { + "properties": { + "demo_fixture": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Demo Fixture" + }, + "records_requests": { + "items": { + "$ref": "#/components/schemas/RecordsView" + }, + "type": "array", + "title": "Records Requests" + }, + "notification_events": { + "items": { + "$ref": "#/components/schemas/NotificationView" + }, + "type": "array", + "title": "Notification Events" + }, + "publication_events": { + "items": { + "$ref": "#/components/schemas/PublicationView" + }, + "type": "array", + "title": "Publication Events" + }, + "audit_entries": { + "items": { + "$ref": "#/components/schemas/AuditView" + }, + "type": "array", + "title": "Audit Entries" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "records_requests" + ], + "title": "RecordsStateRead" + }, + "RecordsView": { + "properties": { + "request_id": { + "type": "string", + "title": "Request Id" + }, + "id": { + "type": "string", + "title": "Id" + }, + "public_tracking_number": { + "type": "string", + "title": "Public Tracking Number" + }, + "requester": { + "type": "string", + "title": "Requester" + }, + "requester_contact": { + "type": "string", + "title": "Requester Contact" + }, + "submitted_via": { + "type": "string", + "title": "Submitted Via" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "deadline": { + "type": "string", + "title": "Deadline" + }, + "deadline_basis": { + "type": "string", + "title": "Deadline Basis" + }, + "status": { + "type": "string", + "title": "Status" + }, + "assigned_to": { + "type": "string", + "title": "Assigned To" + }, + "clarification_notes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Clarification Notes" + }, + "search_notes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Search Notes" + }, + "search_sessions": { + "items": { + "$ref": "#/components/schemas/SearchReceiptView" + }, + "type": "array", + "title": "Search Sessions" + }, + "exemption_reviews": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Exemption Reviews" + }, + "exemption_decisions": { + "items": { + "$ref": "#/components/schemas/ExemptionDecisionView" + }, + "type": "array", + "title": "Exemption Decisions" + }, + "fee_estimate": { + "type": "string", + "title": "Fee Estimate" + }, + "fee_line_items": { + "items": { + "$ref": "#/components/schemas/FeeLineView" + }, + "type": "array", + "title": "Fee Line Items" + }, + "fee_waiver_reason": { + "type": "string", + "title": "Fee Waiver Reason" + }, + "citations": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Citations" + }, + "response_draft": { + "type": "string", + "title": "Response Draft" + }, + "approval_notes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Approval Notes" + }, + "exports": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Exports" + }, + "documents": { + "items": { + "$ref": "#/components/schemas/RecordsDocumentView" + }, + "type": "array", + "title": "Documents" + }, + "release_packages": { + "items": { + "$ref": "#/components/schemas/ReleasePackageView" + }, + "type": "array", + "title": "Release Packages" + }, + "timeline": { + "items": { + "$ref": "#/components/schemas/TimelineView" + }, + "type": "array", + "title": "Timeline" + }, + "public_status_events": { + "items": { + "$ref": "#/components/schemas/PublicStatusView" + }, + "type": "array", + "title": "Public Status Events" + }, + "messages": { + "items": { + "$ref": "#/components/schemas/MessageView" + }, + "type": "array", + "title": "Messages" + }, + "deadline_reviewed_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Deadline Reviewed At Unix Seconds" + }, + "approved_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Approved At Unix Seconds" + }, + "fulfilled_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Fulfilled At Unix Seconds" + }, + "closed_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Closed At Unix Seconds" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "request_id", + "id", + "public_tracking_number", + "requester", + "requester_contact", + "submitted_via", + "summary", + "deadline", + "deadline_basis", + "status", + "assigned_to", + "clarification_notes", + "search_notes", + "search_sessions", + "exemption_reviews", + "exemption_decisions", + "fee_estimate", + "fee_line_items", + "fee_waiver_reason", + "citations", + "response_draft", + "approval_notes", + "exports", + "timeline", + "public_status_events", + "messages", + "deadline_reviewed_at_unix_seconds", + "approved_at_unix_seconds", + "fulfilled_at_unix_seconds", + "closed_at_unix_seconds", + "created_at_unix_seconds" + ], + "title": "RecordsView" + }, + "ReleasePackageView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "export_path": { + "type": "string", + "title": "Export Path" + }, + "package_hash": { + "type": "string", + "title": "Package Hash" + }, + "document_count": { + "type": "integer", + "title": "Document Count" + }, + "release_artifact_count": { + "type": "integer", + "title": "Release Artifact Count" + }, + "search_session_count": { + "type": "integer", + "title": "Search Session Count" + }, + "release_count": { + "type": "integer", + "title": "Release Count" + }, + "redacted_count": { + "type": "integer", + "title": "Redacted Count" + }, + "exempt_count": { + "type": "integer", + "title": "Exempt Count" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "export_path", + "package_hash", + "document_count", + "release_artifact_count", + "search_session_count", + "release_count", + "redacted_count", + "exempt_count", + "created_at_unix_seconds" + ], + "title": "ReleasePackageView" + }, + "RepeatLookup": { + "properties": { + "property_reference": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Property Reference" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "property_reference" + ], + "title": "RepeatLookup" + }, + "RequestCreate": { + "properties": { + "requester_name": { + "type": "string", + "maxLength": 255, + "title": "Requester Name" + }, + "requester_email": { + "anyOf": [ + { + "type": "string", + "maxLength": 255 + }, + { + "type": "null" + } + ], + "title": "Requester Email" + }, + "requester_phone": { + "anyOf": [ + { + "type": "string", + "maxLength": 50 + }, + { + "type": "null" + } + ], + "title": "Requester Phone" + }, + "requester_type": { + "anyOf": [ + { + "type": "string", + "maxLength": 100 + }, + { + "type": "null" + } + ], + "title": "Requester Type" + }, + "description": { + "type": "string", + "maxLength": 10000, + "title": "Description" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "priority": { + "type": "string", + "title": "Priority", + "default": "normal" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string", + "pattern": "^(narrow|moderate|broad)$" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + } + }, + "type": "object", + "required": [ + "requester_name", + "description" + ], + "title": "RequestCreate" + }, + "RequestDocumentAdd": { + "properties": { + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "relevance_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Relevance Note" + } + }, + "type": "object", + "required": [ + "document_id" + ], + "title": "RequestDocumentAdd" + }, + "RequestDocumentRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "relevance_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Relevance Note" + }, + "exemption_flags": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Exemption Flags" + }, + "inclusion_status": { + "$ref": "#/components/schemas/InclusionStatus" + }, + "attached_at": { + "type": "string", + "format": "date-time", + "title": "Attached At" + }, + "attached_by": { + "type": "string", + "format": "uuid", + "title": "Attached By" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "document_id", + "relevance_note", + "exemption_flags", + "inclusion_status", + "attached_at", + "attached_by" + ], + "title": "RequestDocumentRead" + }, + "RequestRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "requester_name": { + "type": "string", + "title": "Requester Name" + }, + "requester_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Email" + }, + "requester_phone": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Phone" + }, + "requester_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Type" + }, + "date_received": { + "type": "string", + "format": "date-time", + "title": "Date Received" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "description": { + "type": "string", + "title": "Description" + }, + "status": { + "$ref": "#/components/schemas/RequestStatus" + }, + "assigned_to": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "created_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "response_draft": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Response Draft" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + }, + "estimated_fee": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Estimated Fee" + }, + "fee_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Fee Status" + }, + "fee_waiver_requested": { + "type": "boolean", + "title": "Fee Waiver Requested", + "default": false + }, + "priority": { + "type": "string", + "title": "Priority", + "default": "normal" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + }, + "closed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Closed At" + }, + "closure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Closure Reason" + } + }, + "type": "object", + "required": [ + "id", + "requester_name", + "requester_email", + "date_received", + "statutory_deadline", + "description", + "status", + "assigned_to", + "created_by", + "created_at", + "response_draft", + "review_notes" + ], + "title": "RequestRead" + }, + "RequestStats": { + "properties": { + "total_requests": { + "type": "integer", + "title": "Total Requests" + }, + "by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "By Status" + }, + "approaching_deadline": { + "type": "integer", + "title": "Approaching Deadline" + }, + "overdue": { + "type": "integer", + "title": "Overdue" + } + }, + "type": "object", + "required": [ + "total_requests", + "by_status", + "approaching_deadline", + "overdue" + ], + "title": "RequestStats" + }, + "RequestStatus": { + "type": "string", + "enum": [ + "received", + "clarification_needed", + "assigned", + "searching", + "in_review", + "ready_for_release", + "drafted", + "approved", + "fulfilled", + "closed" + ], + "title": "RequestStatus" + }, + "RequestUpdate": { + "properties": { + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "status": { + "anyOf": [ + { + "$ref": "#/components/schemas/RequestStatus" + }, + { + "type": "null" + } + ] + }, + "assigned_to": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "response_draft": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Response Draft" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + } + }, + "type": "object", + "title": "RequestUpdate" + }, + "RequirementBundle": { + "properties": { + "requirement_id": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]{1,100}$", + "title": "Requirement Id" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "project_type": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Project Type" + }, + "source_reference": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Source Reference" + }, + "source_date": { + "type": "string", + "format": "date", + "title": "Source Date" + }, + "effective_on": { + "type": "string", + "format": "date", + "title": "Effective On" + }, + "dataset_kind": { + "type": "string", + "enum": [ + "municipal", + "fictional" + ], + "title": "Dataset Kind" + }, + "filename": { + "type": "string", + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$", + "title": "Filename" + }, + "content_base64": { + "type": "string", + "maxLength": 14000000, + "minLength": 1, + "title": "Content Base64" + }, + "sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Sha256" + }, + "materials": { + "items": { + "$ref": "#/components/schemas/Material" + }, + "type": "array", + "maxItems": 100, + "minItems": 1, + "title": "Materials" + }, + "pathway": { + "items": { + "$ref": "#/components/schemas/PathwayStep" + }, + "type": "array", + "maxItems": 100, + "title": "Pathway" + }, + "fee_link": { + "anyOf": [ + { + "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink" + }, + { + "type": "null" + } + ] + }, + "staff_note": { + "type": "string", + "maxLength": 4000, + "title": "Staff Note", + "default": "" + }, + "change_note": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Change Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requirement_id", + "title", + "jurisdiction", + "project_type", + "source_reference", + "source_date", + "effective_on", + "dataset_kind", + "filename", + "content_base64", + "sha256", + "materials", + "change_note" + ], + "title": "RequirementBundle" + }, + "ResponseLetterCreate": { + "properties": { + "template_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Template Id" + } + }, + "type": "object", + "title": "ResponseLetterCreate" + }, + "ResponseLetterRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "template_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Template Id" + }, + "generated_content": { + "type": "string", + "title": "Generated Content" + }, + "edited_content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Edited Content" + }, + "status": { + "type": "string", + "title": "Status" + }, + "generated_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Generated By" + }, + "approved_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Approved By" + }, + "sent_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Sent At" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "template_id", + "generated_content", + "edited_content", + "status", + "generated_by", + "approved_by", + "sent_at", + "created_at" + ], + "title": "ResponseLetterRead" + }, + "ResponseLetterUpdate": { + "properties": { + "edited_content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Edited Content" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + } + }, + "type": "object", + "title": "ResponseLetterUpdate" + }, + "ReviewInput": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "body": { + "type": "string", + "maxLength": 5000, + "title": "Body", + "default": "" + }, + "hasAltText": { + "type": "boolean", + "title": "Hasalttext", + "default": false + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "en" + } + }, + "additionalProperties": false, + "type": "object", + "title": "ReviewInput" + }, + "Revision": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + }, + "document": { + "$ref": "#/components/schemas/NoticeDraft" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence", + "document" + ], + "title": "Revision" + }, + "RewriteInput": { + "properties": { + "action": { + "type": "string", + "enum": [ + "plain-language", + "language-variant" + ], + "title": "Action" + }, + "text": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Text" + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "text" + ], + "title": "RewriteInput" + }, + "RewriteResult": { + "properties": { + "action": { + "type": "string", + "enum": [ + "plain-language", + "language-variant" + ], + "title": "Action" + }, + "text": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Text" + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "" + }, + "outcome": { + "type": "string", + "enum": [ + "generated", + "unavailable" + ], + "title": "Outcome" + }, + "generated": { + "anyOf": [ + { + "type": "string", + "maxLength": 100000 + }, + { + "type": "null" + } + ], + "title": "Generated" + }, + "model": { + "anyOf": [ + { + "type": "string", + "maxLength": 200 + }, + { + "type": "null" + } + ], + "title": "Model" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "text", + "outcome" + ], + "title": "RewriteResult" + }, + "Rule": { + "properties": { + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "zone_code": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Zone Code" + }, + "key": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Key" + }, + "section_number": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Section Number" + }, + "kind": { + "type": "string", + "enum": [ + "use", + "dimension" + ], + "title": "Kind" + }, + "value": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Value" + }, + "overlay_code": { + "anyOf": [ + { + "type": "string", + "maxLength": 255 + }, + { + "type": "null" + } + ], + "title": "Overlay Code" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "jurisdiction", + "zone_code", + "key", + "section_number", + "kind", + "value" + ], + "title": "Rule" + }, + "RuleTestMatch": { + "properties": { + "matched_text": { + "type": "string", + "title": "Matched Text" + }, + "start": { + "type": "integer", + "title": "Start" + }, + "end": { + "type": "integer", + "title": "End" + } + }, + "type": "object", + "required": [ + "matched_text", + "start", + "end" + ], + "title": "RuleTestMatch" + }, + "RuleTestRequest": { + "properties": { + "sample_text": { + "type": "string", + "title": "Sample Text" + } + }, + "type": "object", + "required": [ + "sample_text" + ], + "title": "RuleTestRequest" + }, + "RuleTestResponse": { + "properties": { + "rule_id": { + "type": "string", + "format": "uuid", + "title": "Rule Id" + }, + "rule_type": { + "type": "string", + "title": "Rule Type" + }, + "matched": { + "type": "boolean", + "title": "Matched" + }, + "matches": { + "items": { + "$ref": "#/components/schemas/RuleTestMatch" + }, + "type": "array", + "title": "Matches" + } + }, + "type": "object", + "required": [ + "rule_id", + "rule_type", + "matched", + "matches" + ], + "title": "RuleTestResponse" + }, + "RuleType": { + "type": "string", + "enum": [ + "regex", + "keyword", + "llm_prompt" + ], + "title": "RuleType" + }, + "SaveReview": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "body": { + "type": "string", + "maxLength": 5000, + "title": "Body", + "default": "" + }, + "hasAltText": { + "type": "boolean", + "title": "Hasalttext", + "default": false + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "en" + }, + "ai_analysis": { + "anyOf": [ + { + "type": "string", + "maxLength": 100000 + }, + { + "type": "null" + } + ], + "title": "Ai Analysis" + }, + "ai_analysis_model": { + "anyOf": [ + { + "type": "string", + "maxLength": 200 + }, + { + "type": "null" + } + ], + "title": "Ai Analysis Model" + }, + "ai_outcome": { + "type": "string", + "enum": [ + "generated", + "unavailable", + "failed" + ], + "title": "Ai Outcome" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "ai_outcome" + ], + "title": "SaveReview" + }, + "SearchFilterOptions": { + "properties": { + "file_types": { + "items": { + "type": "string" + }, + "type": "array", + "title": "File Types" + }, + "source_names": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Source Names" + }, + "departments": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array", + "title": "Departments", + "default": [] + }, + "date_range": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Date Range" + } + }, + "type": "object", + "required": [ + "file_types", + "source_names" + ], + "title": "SearchFilterOptions" + }, + "SearchInput": { + "properties": { + "query": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "SearchInput" + }, + "SearchNoteCommand": { + "properties": { + "action": { + "type": "string", + "const": "record-records-search", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/SearchNotePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "SearchNoteCommand" + }, + "SearchNotePayload": { + "properties": { + "sourceNote": { + "type": "string", + "minLength": 1, + "title": "Sourcenote" + }, + "citation": { + "type": "string", + "title": "Citation", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sourceNote" + ], + "title": "SearchNotePayload" + }, + "SearchReceiptCommand": { + "properties": { + "action": { + "type": "string", + "const": "record-records-search-session", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/SearchReceiptPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "SearchReceiptCommand" + }, + "SearchReceiptPayload": { + "properties": { + "searchQuery": { + "type": "string", + "minLength": 1, + "title": "Searchquery" + }, + "searchLocations": { + "type": "string", + "minLength": 1, + "title": "Searchlocations" + }, + "searchResultTitle": { + "type": "string", + "minLength": 1, + "title": "Searchresulttitle" + }, + "searchResultCitation": { + "type": "string", + "minLength": 1, + "title": "Searchresultcitation" + }, + "searchResultSummary": { + "type": "string", + "minLength": 1, + "title": "Searchresultsummary" + }, + "searchResultStatus": { + "type": "string", + "title": "Searchresultstatus", + "default": "" + }, + "searchReviewer": { + "type": "string", + "title": "Searchreviewer", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "searchQuery", + "searchLocations", + "searchResultTitle", + "searchResultCitation", + "searchResultSummary" + ], + "title": "SearchReceiptPayload" + }, + "SearchReceiptView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "query": { + "type": "string", + "title": "Query" + }, + "locations": { + "type": "string", + "title": "Locations" + }, + "reviewer": { + "type": "string", + "title": "Reviewer" + }, + "results": { + "items": { + "$ref": "#/components/schemas/SearchResultView" + }, + "type": "array", + "title": "Results" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "query", + "locations", + "reviewer", + "results", + "created_at_unix_seconds" + ], + "title": "SearchReceiptView" + }, + "SearchRequest": { + "properties": { + "query": { + "type": "string", + "title": "Query" + }, + "session_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Session Id" + }, + "filters": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Filters" + }, + "limit": { + "type": "integer", + "maximum": 50.0, + "title": "Limit", + "default": 10 + }, + "synthesize": { + "type": "boolean", + "title": "Synthesize", + "default": false + } + }, + "type": "object", + "required": [ + "query" + ], + "title": "SearchRequest" + }, + "SearchResponse": { + "properties": { + "query_id": { + "type": "string", + "format": "uuid", + "title": "Query Id" + }, + "session_id": { + "type": "string", + "format": "uuid", + "title": "Session Id" + }, + "query_text": { + "type": "string", + "title": "Query Text" + }, + "results": { + "items": { + "$ref": "#/components/schemas/SearchResultItem" + }, + "type": "array", + "title": "Results" + }, + "results_count": { + "type": "integer", + "title": "Results Count" + }, + "synthesized_answer": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Synthesized Answer" + }, + "ai_generated": { + "type": "boolean", + "title": "Ai Generated", + "default": false + } + }, + "type": "object", + "required": [ + "query_id", + "session_id", + "query_text", + "results", + "results_count" + ], + "title": "SearchResponse" + }, + "SearchResultItem": { + "properties": { + "chunk_id": { + "type": "string", + "format": "uuid", + "title": "Chunk Id" + }, + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "filename": { + "type": "string", + "title": "Filename" + }, + "file_type": { + "type": "string", + "title": "File Type" + }, + "source_path": { + "type": "string", + "title": "Source Path" + }, + "page_number": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Page Number" + }, + "content_text": { + "type": "string", + "title": "Content Text" + }, + "similarity_score": { + "type": "number", + "title": "Similarity Score" + }, + "rank": { + "type": "integer", + "title": "Rank" + } + }, + "type": "object", + "required": [ + "chunk_id", + "document_id", + "filename", + "file_type", + "source_path", + "page_number", + "content_text", + "similarity_score", + "rank" + ], + "title": "SearchResultItem" + }, + "SearchResultView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "title": { + "type": "string", + "title": "Title" + }, + "citation": { + "type": "string", + "title": "Citation" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "status": { + "type": "string", + "title": "Status" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "title", + "citation", + "summary", + "status" + ], + "title": "SearchResultView" + }, + "SearchSessionRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "user_id": { + "type": "string", + "format": "uuid", + "title": "User Id" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "queries": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array", + "title": "Queries", + "default": [] + } + }, + "type": "object", + "required": [ + "id", + "user_id", + "created_at" + ], + "title": "SearchSessionRead" + }, + "SectionCreate": { + "properties": { + "section_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Section Id" + }, + "chapter_id": { + "type": "string", + "minLength": 1, + "title": "Chapter Id" + }, + "section_number": { + "type": "string", + "minLength": 1, + "title": "Section Number" + }, + "section_heading": { + "type": "string", + "minLength": 1, + "title": "Section Heading" + }, + "parent_section_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parent Section Id" + }, + "sort_order": { + "type": "integer", + "title": "Sort Order", + "default": 0 + }, + "administrative_regulation_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Administrative Regulation Refs" + }, + "resolution_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Resolution Refs" + }, + "policy_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Policy Refs" + }, + "approved_summary_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Approved Summary Refs" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "chapter_id", + "section_number", + "section_heading" + ], + "title": "SectionCreate", + "description": "Request body for creating a code section or subsection." + }, + "SectionVersionCreate": { + "properties": { + "version_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Version Id" + }, + "section_id": { + "type": "string", + "minLength": 1, + "title": "Section Id" + }, + "source_id": { + "type": "string", + "minLength": 1, + "title": "Source Id" + }, + "version_label": { + "type": "string", + "minLength": 1, + "title": "Version Label" + }, + "body": { + "type": "string", + "minLength": 1, + "title": "Body" + }, + "effective_start": { + "type": "string", + "format": "date", + "title": "Effective Start" + }, + "effective_end": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective End" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + }, + "is_current": { + "type": "boolean", + "title": "Is Current", + "default": false + }, + "adoption_event_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Adoption Event Id" + }, + "amendment_event_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Amendment Event Id" + }, + "amendment_summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Amendment Summary" + }, + "prior_version_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Prior Version Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "section_id", + "source_id", + "version_label", + "body", + "effective_start" + ], + "title": "SectionVersionCreate", + "description": "Request body for adding an immutable section version." + }, + "Selection": { + "properties": { + "recording_id": { + "type": "string", + "format": "uuid", + "title": "Recording Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "recording_id", + "expected_sha256" + ], + "title": "Selection" + }, + "SentenceInput": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "citations": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Citations" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text" + ], + "title": "SentenceInput" + }, + "ServiceAccountCreate": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole", + "default": "read_only" + } + }, + "type": "object", + "required": [ + "name" + ], + "title": "ServiceAccountCreate" + }, + "ServiceAccountCreated": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "api_key": { + "type": "string", + "title": "Api Key" + } + }, + "type": "object", + "required": [ + "id", + "name", + "role", + "created_by", + "created_at", + "is_active", + "api_key" + ], + "title": "ServiceAccountCreated", + "description": "Returned only on creation — includes the plaintext API key (shown once)." + }, + "ServiceAccountRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + } + }, + "type": "object", + "required": [ + "id", + "name", + "role", + "created_by", + "created_at", + "is_active" + ], + "title": "ServiceAccountRead" + }, + "ServiceAccountUpdate": { + "properties": { + "role": { + "anyOf": [ + { + "$ref": "#/components/schemas/UserRole" + }, + { + "type": "null" + } + ] + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "ServiceAccountUpdate" + }, + "Snapshot": { + "properties": { + "expected_revision": { + "type": "string", + "format": "uuid", + "title": "Expected Revision" + }, + "visibility": { + "type": "string", + "enum": [ + "staff_only", + "public" + ], + "title": "Visibility" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "expected_revision", + "visibility" + ], + "title": "Snapshot" + }, + "SourceCreate": { + "properties": { + "source_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Id" + }, + "name": { + "type": "string", + "minLength": 1, + "title": "Name" + }, + "publisher": { + "type": "string", + "minLength": 1, + "title": "Publisher" + }, + "source_type": { + "type": "string", + "minLength": 1, + "title": "Source Type" + }, + "source_category": { + "type": "string", + "minLength": 1, + "title": "Source Category" + }, + "source_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Url" + }, + "file_reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "File Reference" + }, + "retrieved_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Retrieved At" + }, + "retrieval_method": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Retrieval Method" + }, + "checksum": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Checksum" + }, + "source_owner": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Owner" + }, + "is_official": { + "type": "boolean", + "title": "Is Official", + "default": true + }, + "official_status_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Official Status Note" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + }, + "staff_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Staff Notes" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "name", + "publisher", + "source_type", + "source_category" + ], + "title": "SourceCreate", + "description": "Request body for registering an official or explicitly labeled source." + }, + "SourceInput": { + "properties": { + "source_id": { + "type": "string", + "minLength": 1, + "title": "Source Id" + }, + "label": { + "type": "string", + "minLength": 1, + "title": "Label" + }, + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "label", + "text" + ], + "title": "SourceInput" + }, + "SourceSnapshot": { + "properties": { + "visibility": { + "type": "string", + "enum": [ + "public", + "staff_only" + ], + "title": "Visibility" + }, + "meeting_event_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "maxItems": 50, + "title": "Meeting Event Ids" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "visibility" + ], + "title": "SourceSnapshot" + }, + "SourceType": { + "type": "string", + "enum": [ + "manual_drop", + "file_system", + "rest_api", + "odbc" + ], + "title": "SourceType" + }, + "StaffRecordsIntake": { + "properties": { + "requester": { + "type": "string", + "minLength": 1, + "title": "Requester" + }, + "summary": { + "type": "string", + "minLength": 1, + "title": "Summary" + }, + "deadline": { + "type": "string", + "title": "Deadline" + }, + "deadlineBasis": { + "type": "string", + "title": "Deadlinebasis", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requester", + "summary", + "deadline" + ], + "title": "StaffRecordsIntake", + "description": "Existing native create-records-request input; no caller-supplied actor." + }, + "StandardsExplanation": { + "properties": { + "question": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Question" + }, + "process_section": { + "type": "string", + "maxLength": 255, + "title": "Process Section", + "default": "" + }, + "zone_code": { + "type": "string", + "maxLength": 40, + "title": "Zone Code", + "default": "" + }, + "rule_types": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 10, + "title": "Rule Types" + }, + "observed": { + "additionalProperties": { + "type": "string" + }, + "type": "object", + "title": "Observed" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "question" + ], + "title": "StandardsExplanation" + }, + "SyncFailureRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "source_id": { + "type": "string", + "format": "uuid", + "title": "Source Id" + }, + "source_path": { + "type": "string", + "title": "Source Path" + }, + "error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Message" + }, + "error_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Class" + }, + "http_status_code": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Http Status Code" + }, + "retry_count": { + "type": "integer", + "title": "Retry Count" + }, + "status": { + "type": "string", + "title": "Status" + }, + "first_failed_at": { + "type": "string", + "format": "date-time", + "title": "First Failed At" + }, + "last_retried_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Retried At" + }, + "dismissed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Dismissed At" + }, + "dismissed_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Dismissed By" + } + }, + "type": "object", + "required": [ + "id", + "source_id", + "source_path", + "error_message", + "error_class", + "http_status_code", + "retry_count", + "status", + "first_failed_at", + "last_retried_at", + "dismissed_at", + "dismissed_by" + ], + "title": "SyncFailureRead" + }, + "SyncRunLogRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "source_id": { + "type": "string", + "format": "uuid", + "title": "Source Id" + }, + "started_at": { + "type": "string", + "format": "date-time", + "title": "Started At" + }, + "finished_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Finished At" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + }, + "records_attempted": { + "type": "integer", + "title": "Records Attempted" + }, + "records_succeeded": { + "type": "integer", + "title": "Records Succeeded" + }, + "records_failed": { + "type": "integer", + "title": "Records Failed" + }, + "error_summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Summary" + } + }, + "type": "object", + "required": [ + "id", + "source_id", + "started_at", + "finished_at", + "status", + "records_attempted", + "records_succeeded", + "records_failed", + "error_summary" + ], + "title": "SyncRunLogRead" + }, + "SystemStatus": { + "properties": { + "version": { + "type": "string", + "title": "Version" + }, + "database": { + "type": "string", + "title": "Database" + }, + "ollama": { + "type": "string", + "title": "Ollama" + }, + "redis": { + "type": "string", + "title": "Redis" + }, + "user_count": { + "type": "integer", + "title": "User Count" + }, + "audit_log_count": { + "type": "integer", + "title": "Audit Log Count" + }, + "suite_session": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Suite Session" + } + }, + "type": "object", + "required": [ + "version", + "database", + "ollama", + "redis", + "user_count", + "audit_log_count" + ], + "title": "SystemStatus" + }, + "TaggedPlan": { + "properties": { + "action": { + "type": "string", + "const": "tagged-pdf", + "title": "Action" + }, + "headingLevels": { + "items": { + "type": "integer", + "maximum": 4294967295.0, + "minimum": 0.0 + }, + "type": "array", + "maxItems": 50, + "title": "Headinglevels" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "TaggedPlan" + }, + "TestConnectionRequest": { + "properties": { + "source_type": { + "type": "string", + "title": "Source Type" + }, + "host": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Host" + }, + "port": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Port" + }, + "path": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Path" + }, + "username": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Username" + }, + "password": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Password" + }, + "rest_api_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Rest Api Config" + }, + "odbc_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Odbc Config" + } + }, + "type": "object", + "required": [ + "source_type" + ], + "title": "TestConnectionRequest", + "description": "Dedicated schema for test-connection. NOT the create schema.\n\nSecurity: credentials in this request body are never persisted, never\nwritten to audit logs, and never returned in the response." + }, + "TestConnectionResponse": { + "properties": { + "success": { + "type": "boolean", + "title": "Success" + }, + "message": { + "type": "string", + "title": "Message" + }, + "latency_ms": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Latency Ms" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + }, + "warning": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Warning" + }, + "differing_keys": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Differing Keys" + } + }, + "type": "object", + "required": [ + "success", + "message" + ], + "title": "TestConnectionResponse" + }, + "TimelineEventCreate": { + "properties": { + "event_type": { + "type": "string", + "title": "Event Type" + }, + "description": { + "type": "string", + "title": "Description" + }, + "internal_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Internal Note" + } + }, + "type": "object", + "required": [ + "event_type", + "description" + ], + "title": "TimelineEventCreate" + }, + "TimelineEventRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "event_type": { + "type": "string", + "title": "Event Type" + }, + "actor_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Actor Id" + }, + "actor_role": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Actor Role" + }, + "description": { + "type": "string", + "title": "Description" + }, + "internal_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Internal Note" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "event_type", + "actor_id", + "actor_role", + "description", + "internal_note", + "created_at" + ], + "title": "TimelineEventRead" + }, + "TimelineView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "action": { + "type": "string", + "title": "Action" + }, + "actor": { + "type": "string", + "title": "Actor" + }, + "note": { + "type": "string", + "title": "Note" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "action", + "actor", + "note", + "created_at_unix_seconds" + ], + "title": "TimelineView" + }, + "TitleCreate": { + "properties": { + "title_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Title Id" + }, + "title_number": { + "type": "string", + "minLength": 1, + "title": "Title Number" + }, + "title_name": { + "type": "string", + "minLength": 1, + "title": "Title Name" + }, + "sort_order": { + "type": "integer", + "title": "Sort Order", + "default": 0 + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title_number", + "title_name" + ], + "title": "TitleCreate", + "description": "Request body for creating a code title." + }, + "TranscriptInput": { + "properties": { + "source_label": { + "type": "string", + "minLength": 1, + "title": "Source Label" + }, + "transcript_text": { + "type": "string", + "minLength": 1, + "title": "Transcript Text" + }, + "correction_of_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Correction Of Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_label", + "transcript_text" + ], + "title": "TranscriptInput" + }, + "UserRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "email": { + "type": "string", + "format": "email", + "title": "Email" + }, + "is_active": { + "type": "boolean", + "title": "Is Active", + "default": true + }, + "is_superuser": { + "type": "boolean", + "title": "Is Superuser", + "default": false + }, + "is_verified": { + "type": "boolean", + "title": "Is Verified", + "default": false + }, + "full_name": { + "type": "string", + "title": "Full Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "last_login": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Login" + }, + "must_change_password": { + "type": "boolean", + "title": "Must Change Password", + "default": false + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + } + }, + "type": "object", + "required": [ + "id", + "email", + "full_name", + "role", + "created_at", + "last_login" + ], + "title": "UserRead" + }, + "UserRole": { + "type": "string", + "enum": [ + "admin", + "staff", + "reviewer", + "read_only", + "liaison", + "public" + ], + "title": "UserRole" + }, + "UserSelfUpdate": { + "properties": { + "password": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Password" + }, + "email": { + "anyOf": [ + { + "type": "string", + "format": "email" + }, + { + "type": "null" + } + ], + "title": "Email" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + }, + "is_superuser": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Superuser" + }, + "is_verified": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Verified" + }, + "full_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Full Name" + } + }, + "type": "object", + "title": "UserSelfUpdate", + "description": "Schema for user self-update via PATCH /users/me.\n\nExcludes role and department_id. Any payload containing those fields is\nrejected at parse time (HTTP 422). Role and department changes require\nadmin privileges via /admin/users/{id}." + }, + "UserUpdateRequest": { + "properties": { + "full_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Full Name" + }, + "role": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Role" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "UserUpdateRequest" + }, + "ValidationError": { + "properties": { + "loc": { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "integer" + } + ] + }, + "type": "array", + "title": "Location" + }, + "msg": { + "type": "string", + "title": "Message" + }, + "type": { + "type": "string", + "title": "Error Type" + }, + "input": { + "title": "Input" + }, + "ctx": { + "type": "object", + "title": "Context" + } + }, + "type": "object", + "required": [ + "loc", + "msg", + "type" + ], + "title": "ValidationError" + }, + "Version": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence" + ], + "title": "Version" + }, + "VoteCorrection": { + "properties": { + "vote": { + "type": "string", + "minLength": 1, + "title": "Vote" + }, + "reason": { + "type": "string", + "minLength": 1, + "title": "Reason" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "vote", + "reason" + ], + "title": "VoteCorrection" + }, + "VoteInput": { + "properties": { + "voter_name": { + "type": "string", + "minLength": 1, + "title": "Voter Name" + }, + "vote": { + "type": "string", + "minLength": 1, + "title": "Vote" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "voter_name", + "vote" + ], + "title": "VoteInput" + }, + "_ParcelLookupIn": { + "properties": { + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "jurisdiction", + "query" + ], + "title": "_ParcelLookupIn" + }, + "townlight_inspections__workflow_models__SourceLink": { + "properties": { + "provider": { + "type": "string", + "const": "code", + "title": "Provider", + "default": "code" + }, + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "SourceLink" + }, + "townlight_permitting__workflow_models__SourceLink": { + "properties": { + "provider": { + "type": "string", + "enum": [ + "code", + "zoning" + ], + "title": "Provider" + }, + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "source_id", + "expected_sha256" + ], + "title": "SourceLink" + }, + "townlight_runtime__inspections_bridge__Search": { + "properties": { + "provider": { + "type": "string", + "const": "code", + "title": "Provider" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "query" + ], + "title": "Search" + }, + "townlight_runtime__notice_bridge__Review": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + }, + "note": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence", + "note" + ], + "title": "Review" + }, + "townlight_runtime__permitting_bridge__Import": { + "properties": { + "bundle": { + "$ref": "#/components/schemas/RequirementBundle" + }, + "expected_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "bundle" + ], + "title": "Import" + }, + "townlight_runtime__permitting_bridge__Search": { + "properties": { + "provider": { + "type": "string", + "enum": [ + "code", + "zoning" + ], + "title": "Provider" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "query" + ], + "title": "Search" + }, + "townlight_runtime__planning_bridge__Import": { + "properties": { + "bundle": { + "additionalProperties": true, + "type": "object", + "title": "Bundle" + }, + "expected_previous_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Expected Previous Revision" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "bundle" + ], + "title": "Import" + }, + "townlight_runtime__planning_bridge__Search": { + "properties": { + "query": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Query" + }, + "plan_type": { + "anyOf": [ + { + "type": "string", + "maxLength": 40 + }, + { + "type": "null" + } + ], + "title": "Plan Type" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "Search" + }, + "townlight_runtime__zoning_bridge__Review": { + "properties": { + "answer": { + "type": "string", + "maxLength": 10000, + "title": "Answer", + "default": "" + }, + "notes": { + "type": "string", + "maxLength": 10000, + "title": "Notes", + "default": "" + }, + "queue_status": { + "type": "string", + "enum": [ + "open", + "in_review", + "resolved", + "closed" + ], + "title": "Queue Status", + "default": "resolved" + } + }, + "additionalProperties": false, + "type": "object", + "title": "Review" + } + }, + "securitySchemes": { + "OAuth2PasswordBearer": { + "type": "oauth2", + "flows": { + "password": { + "scopes": {}, + "tokenUrl": "auth/jwt/login" + } + } + } + } + }, + "x-townlight-component": { + "view": "code", + "identity": "Townlight Code 1.0.9", + "evidence": "source-schema-only" + } +} diff --git a/docs/beta-1/api/code.html b/docs/beta-1/api/code.html new file mode 100644 index 0000000..fcab814 --- /dev/null +++ b/docs/beta-1/api/code.html @@ -0,0 +1,12739 @@ +Townlight Code API reference
Townlight

Townlight Code API reference

+

Prepared source candidate, November 2, 2026. New signed Windows installed acceptance and publication remain pending.

+

Townlight Code 1.0.9. The HTTP host is Townlight Records 1.8.0.dev2. Component package versions and the host API version are separate identities.

+

Generated from the actual native inspections-preview composition without application lifespan, migrations or database/network access. It describes route and validation contracts; it does not establish endpoint behavior, individual authorization or installed acceptance. Standalone product applications have separate deployment boundaries.

+

Machine-readable OpenAPI schema · Operating manual and limits

+

HTTP operations

+
POST /desktop/v1/code-sources/search +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Search Code Sources",
+  "operationId": "search_code_sources_desktop_v1_code_sources_search_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/CodeSearch"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/code/citation +
{
+  "tags": [
+    "native-code"
+  ],
+  "summary": "Citation",
+  "operationId": "citation_desktop_v1_code_citation_get",
+  "parameters": [
+    {
+      "name": "section_number",
+      "in": "query",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Section Number"
+      }
+    },
+    {
+      "name": "as_of",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string",
+            "format": "date"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "As Of"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/code/connections +
{
+  "summary": "List Connections",
+  "operationId": "list_connections_desktop_v1_code_connections_get",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/code/connections +
{
+  "summary": "Create Connection",
+  "operationId": "create_connection_desktop_v1_code_connections_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/Proposal"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/code/connections/{connection_id} +
{
+  "summary": "Get Connection",
+  "operationId": "get_connection_desktop_v1_code_connections__connection_id__get",
+  "parameters": [
+    {
+      "name": "connection_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "pattern": "^[A-Za-z0-9_-]{1,64}$",
+        "title": "Connection Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/code/connections/{connection_id}/closeout +
{
+  "summary": "Closeout Connection",
+  "operationId": "closeout_connection_desktop_v1_code_connections__connection_id__closeout_post",
+  "parameters": [
+    {
+      "name": "connection_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "pattern": "^[A-Za-z0-9_-]{1,64}$",
+        "title": "Connection Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/Closeout"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/code/export +
{
+  "tags": [
+    "native-code"
+  ],
+  "summary": "Export Section",
+  "operationId": "export_section_desktop_v1_code_export_get",
+  "parameters": [
+    {
+      "name": "section_ref",
+      "in": "query",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Section Ref"
+      }
+    },
+    {
+      "name": "as_of",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string",
+            "format": "date"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "As Of"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/code/imports +
{
+  "tags": [
+    "native-code"
+  ],
+  "summary": "Imports",
+  "operationId": "imports_desktop_v1_code_imports_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/ImportBundleCreate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/code/imports +
{
+  "tags": [
+    "native-code"
+  ],
+  "summary": "List Imports",
+  "operationId": "list_imports_desktop_v1_code_imports_get",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/code/imports/{job_id}/provenance +
{
+  "tags": [
+    "native-code"
+  ],
+  "summary": "Import Provenance",
+  "operationId": "import_provenance_desktop_v1_code_imports__job_id__provenance_get",
+  "parameters": [
+    {
+      "name": "job_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Job Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/code/imports/{job_id}/tree +
{
+  "tags": [
+    "native-code"
+  ],
+  "summary": "Import Tree",
+  "operationId": "import_tree_desktop_v1_code_imports__job_id__tree_get",
+  "parameters": [
+    {
+      "name": "job_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Job Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/code/lookup +
{
+  "tags": [
+    "native-code"
+  ],
+  "summary": "Lookup",
+  "operationId": "lookup_desktop_v1_code_lookup_get",
+  "parameters": [
+    {
+      "name": "section_number",
+      "in": "query",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Section Number"
+      }
+    },
+    {
+      "name": "as_of",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string",
+            "format": "date"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "As Of"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/code/questions +
{
+  "tags": [
+    "native-code"
+  ],
+  "summary": "Questions",
+  "operationId": "questions_desktop_v1_code_questions_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/QuestionAnswerRequest"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/code/search +
{
+  "tags": [
+    "native-code"
+  ],
+  "summary": "Search",
+  "operationId": "search_desktop_v1_code_search_get",
+  "parameters": [
+    {
+      "name": "q",
+      "in": "query",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Q"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/code/sections/{section_id}/history +
{
+  "tags": [
+    "native-code"
+  ],
+  "summary": "Section History",
+  "operationId": "section_history_desktop_v1_code_sections__section_id__history_get",
+  "parameters": [
+    {
+      "name": "section_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Section Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/code/sections/{section_id}/notes +
{
+  "tags": [
+    "native-code"
+  ],
+  "summary": "Create Note",
+  "operationId": "create_note_desktop_v1_code_sections__section_id__notes_post",
+  "parameters": [
+    {
+      "name": "section_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Section Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/InterpretationNoteCreate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/code/sections/{section_id}/notes +
{
+  "tags": [
+    "native-code"
+  ],
+  "summary": "List Notes",
+  "operationId": "list_notes_desktop_v1_code_sections__section_id__notes_get",
+  "parameters": [
+    {
+      "name": "section_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Section Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/code/sections/{section_id}/summaries +
{
+  "tags": [
+    "native-code"
+  ],
+  "summary": "Create Summary",
+  "operationId": "create_summary_desktop_v1_code_sections__section_id__summaries_post",
+  "parameters": [
+    {
+      "name": "section_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Section Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/PlainLanguageSummaryCreate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/code/sections/{section_id}/summaries +
{
+  "tags": [
+    "native-code"
+  ],
+  "summary": "List Summaries",
+  "operationId": "list_summaries_desktop_v1_code_sections__section_id__summaries_get",
+  "parameters": [
+    {
+      "name": "section_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Section Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/code/sources +
{
+  "tags": [
+    "native-code"
+  ],
+  "summary": "Sources",
+  "operationId": "sources_desktop_v1_code_sources_get",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/code/summaries/{summary_id}/approve +
{
+  "tags": [
+    "native-code"
+  ],
+  "summary": "Approve Summary",
+  "operationId": "approve_summary_desktop_v1_code_summaries__summary_id__approve_post",
+  "parameters": [
+    {
+      "name": "summary_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Summary Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/code/workspace +
{
+  "tags": [
+    "native-code"
+  ],
+  "summary": "Workspace",
+  "operationId": "workspace_desktop_v1_code_workspace_get",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+

Request and response data dictionary

+

Each schema includes the actual required fields, types, constraints and descriptions. References resolve against the machine-readable document.

+
ActionItemInput
+{
+  "properties": {
+    "description": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Description"
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "source_motion_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Motion Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "description"
+  ],
+  "title": "ActionItemInput"
+}
+
+
AdaPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "ada-title-ii",
+      "title": "Action"
+    },
+    "serviceArea": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Servicearea"
+    },
+    "hasCoordinatorReview": {
+      "type": "boolean",
+      "title": "Hascoordinatorreview",
+      "default": false
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "serviceArea"
+  ],
+  "title": "AdaPlan"
+}
+
+
AdminUserCreateRequest
+{
+  "properties": {
+    "email": {
+      "type": "string",
+      "title": "Email"
+    },
+    "password": {
+      "type": "string",
+      "title": "Password"
+    },
+    "full_name": {
+      "type": "string",
+      "title": "Full Name",
+      "default": ""
+    },
+    "role": {
+      "type": "string",
+      "title": "Role",
+      "default": "staff"
+    }
+  },
+  "type": "object",
+  "required": [
+    "email",
+    "password"
+  ],
+  "title": "AdminUserCreateRequest"
+}
+
+
AdminUserCreateResponse
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "email": {
+      "type": "string",
+      "title": "Email"
+    },
+    "full_name": {
+      "type": "string",
+      "title": "Full Name"
+    },
+    "role": {
+      "type": "string",
+      "title": "Role"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "email",
+    "full_name",
+    "role",
+    "is_active"
+  ],
+  "title": "AdminUserCreateResponse"
+}
+
+
AgendaAssignment
+{
+  "properties": {
+    "meeting_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Meeting Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "meeting_id"
+  ],
+  "title": "AgendaAssignment"
+}
+
+
AgendaInput
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "department_name": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Department Name"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "department_name"
+  ],
+  "title": "AgendaInput"
+}
+
+
AgendaReviewInput
+{
+  "properties": {
+    "to_status": {
+      "type": "string",
+      "enum": [
+        "DRAFTED",
+        "SUBMITTED",
+        "DEPT_APPROVED",
+        "LEGAL_REVIEWED",
+        "CLERK_ACCEPTED",
+        "ON_AGENDA",
+        "IN_PACKET",
+        "POSTED",
+        "HEARD",
+        "DISPOSED",
+        "ARCHIVED"
+      ],
+      "title": "To Status"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "to_status"
+  ],
+  "title": "AgendaReviewInput"
+}
+
+
AmendmentInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "policy": {
+      "$ref": "#/components/schemas/PolicySelection"
+    },
+    "proposal": {
+      "type": "string",
+      "maxLength": 20000,
+      "minLength": 1,
+      "title": "Proposal"
+    },
+    "responsible_staff": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Responsible Staff"
+    },
+    "status": {
+      "type": "string",
+      "enum": [
+        "draft",
+        "review",
+        "adopted",
+        "withdrawn"
+      ],
+      "title": "Status",
+      "default": "draft"
+    },
+    "review_note": {
+      "type": "string",
+      "maxLength": 5000,
+      "title": "Review Note",
+      "default": ""
+    },
+    "adoption_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Adoption Revision"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "policy",
+    "proposal",
+    "responsible_staff",
+    "note"
+  ],
+  "title": "AmendmentInput"
+}
+
+
AnalysisObservation
+{
+  "properties": {
+    "source": {
+      "type": "string",
+      "maxLength": 64,
+      "minLength": 1,
+      "title": "Source"
+    },
+    "filename": {
+      "type": "string",
+      "maxLength": 160,
+      "title": "Filename",
+      "default": ""
+    },
+    "media_type": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Media Type",
+      "default": ""
+    },
+    "text": {
+      "type": "string",
+      "maxLength": 4000,
+      "minLength": 1,
+      "title": "Text"
+    },
+    "adapter": {
+      "type": "string",
+      "maxLength": 120,
+      "title": "Adapter",
+      "default": ""
+    },
+    "citation_source_ids": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Citation Source Ids"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source",
+    "text"
+  ],
+  "title": "AnalysisObservation",
+  "description": "One draft observation, named with the adapter that actually produced it."
+}
+
+
AnalysisRecord
+{
+  "properties": {
+    "observations": {
+      "items": {
+        "$ref": "#/components/schemas/AnalysisObservation"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Observations"
+    },
+    "cited_sections": {
+      "items": {
+        "$ref": "#/components/schemas/CitedSection"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Cited Sections"
+    },
+    "unavailable": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Unavailable"
+    },
+    "runtime": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Runtime"
+    },
+    "review_required": {
+      "type": "boolean",
+      "title": "Review Required",
+      "default": true
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "AnalysisRecord",
+  "description": "The adapter output that accompanies a saved inspection draft."
+}
+
+
ApprovalCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "approve-records-response",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ApprovalPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "ApprovalCommand"
+}
+
+
ApprovalPayload
+{
+  "properties": {
+    "approvalNote": {
+      "type": "string",
+      "title": "Approvalnote",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "ApprovalPayload"
+}
+
+
ArchiveInput
+{
+  "properties": {
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "public",
+        "closed_session"
+      ],
+      "title": "Visibility"
+    },
+    "packet_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Packet Id"
+    },
+    "minutes_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Minutes Id"
+    },
+    "plain_language_summary": {
+      "type": "string",
+      "title": "Plain Language Summary",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "visibility"
+  ],
+  "title": "ArchiveInput"
+}
+
+
ArtifactPlan
+{
+  "properties": {
+    "artifact_id": {
+      "type": "string",
+      "title": "Artifact Id"
+    },
+    "file_name": {
+      "type": "string",
+      "title": "File Name"
+    },
+    "content": {
+      "type": "string",
+      "title": "Content"
+    },
+    "sha256": {
+      "type": "string",
+      "title": "Sha256"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "artifact_id",
+    "file_name",
+    "content",
+    "sha256",
+    "created_at_unix_seconds"
+  ],
+  "title": "ArtifactPlan"
+}
+
+
AssignCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "assign-records-request",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/AssignmentPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "AssignCommand"
+}
+
+
AssignmentPayload
+{
+  "properties": {
+    "assignedTo": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Assignedto"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "assignedTo"
+  ],
+  "title": "AssignmentPayload"
+}
+
+
AttachDocument
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation",
+      "default": ""
+    },
+    "file": {
+      "$ref": "#/components/schemas/ManagedFileReceipt"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "file"
+  ],
+  "title": "AttachDocument"
+}
+
+
AttachReleaseCopy
+{
+  "properties": {
+    "status": {
+      "type": "string",
+      "enum": [
+        "release-ready copy",
+        "redacted copy"
+      ],
+      "title": "Status"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note",
+      "default": ""
+    },
+    "added_by": {
+      "type": "string",
+      "title": "Added By",
+      "default": ""
+    },
+    "file": {
+      "$ref": "#/components/schemas/ManagedFileReceipt"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "status",
+    "file"
+  ],
+  "title": "AttachReleaseCopy"
+}
+
+
AuditChainVerification
+{
+  "properties": {
+    "is_valid": {
+      "type": "boolean",
+      "title": "Is Valid"
+    },
+    "entries_checked": {
+      "type": "integer",
+      "title": "Entries Checked"
+    },
+    "error_message": {
+      "type": "string",
+      "title": "Error Message"
+    }
+  },
+  "type": "object",
+  "required": [
+    "is_valid",
+    "entries_checked",
+    "error_message"
+  ],
+  "title": "AuditChainVerification"
+}
+
+
AuditLogRead
+{
+  "properties": {
+    "id": {
+      "type": "integer",
+      "title": "Id"
+    },
+    "prev_hash": {
+      "type": "string",
+      "title": "Prev Hash"
+    },
+    "entry_hash": {
+      "type": "string",
+      "title": "Entry Hash"
+    },
+    "timestamp": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Timestamp"
+    },
+    "user_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "User Id"
+    },
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "resource_type": {
+      "type": "string",
+      "title": "Resource Type"
+    },
+    "resource_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Resource Id"
+    },
+    "details": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Details"
+    },
+    "ai_generated": {
+      "type": "boolean",
+      "title": "Ai Generated"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "prev_hash",
+    "entry_hash",
+    "timestamp",
+    "user_id",
+    "action",
+    "resource_type",
+    "resource_id",
+    "details",
+    "ai_generated"
+  ],
+  "title": "AuditLogRead"
+}
+
+
AuditView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "module_id": {
+      "type": "string",
+      "title": "Module Id"
+    },
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    },
+    "previous_hash": {
+      "type": "string",
+      "title": "Previous Hash"
+    },
+    "entry_hash": {
+      "type": "string",
+      "title": "Entry Hash"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "module_id",
+    "action",
+    "summary",
+    "created_at_unix_seconds",
+    "previous_hash",
+    "entry_hash"
+  ],
+  "title": "AuditView"
+}
+
+
BearerResponse
+{
+  "properties": {
+    "access_token": {
+      "type": "string",
+      "title": "Access Token"
+    },
+    "token_type": {
+      "type": "string",
+      "title": "Token Type"
+    }
+  },
+  "type": "object",
+  "required": [
+    "access_token",
+    "token_type"
+  ],
+  "title": "BearerResponse"
+}
+
+
Body_auth_jwt_login_auth_jwt_login_post
+{
+  "properties": {
+    "grant_type": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^password$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Grant Type"
+    },
+    "username": {
+      "type": "string",
+      "title": "Username"
+    },
+    "password": {
+      "type": "string",
+      "format": "password",
+      "title": "Password"
+    },
+    "scope": {
+      "type": "string",
+      "title": "Scope",
+      "default": ""
+    },
+    "client_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Client Id"
+    },
+    "client_secret": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "format": "password",
+      "title": "Client Secret"
+    }
+  },
+  "type": "object",
+  "required": [
+    "username",
+    "password"
+  ],
+  "title": "Body_auth_jwt_login_auth_jwt_login_post"
+}
+
+
Body_upload_file_datasources_upload_post
+{
+  "properties": {
+    "file": {
+      "type": "string",
+      "contentMediaType": "application/octet-stream",
+      "title": "File"
+    }
+  },
+  "type": "object",
+  "required": [
+    "file"
+  ],
+  "title": "Body_upload_file_datasources_upload_post"
+}
+
+
CalculateDeadlineCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "calculate-records-deadline",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/CalculateDeadlinePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "CalculateDeadlineCommand"
+}
+
+
CalculateDeadlinePayload
+{
+  "properties": {
+    "deadlineReceivedDate": {
+      "type": "string",
+      "title": "Deadlinereceiveddate"
+    },
+    "deadlineRuleName": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Deadlinerulename"
+    },
+    "deadlineDayCount": {
+      "type": "string",
+      "title": "Deadlinedaycount"
+    },
+    "deadlineDayType": {
+      "type": "string",
+      "title": "Deadlinedaytype"
+    },
+    "deadlineBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Deadlinebasis"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "deadlineReceivedDate",
+    "deadlineRuleName",
+    "deadlineDayCount",
+    "deadlineDayType",
+    "deadlineBasis"
+  ],
+  "title": "CalculateDeadlinePayload"
+}
+
+
ChapterCreate
+{
+  "properties": {
+    "chapter_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Chapter Id"
+    },
+    "title_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title Id"
+    },
+    "chapter_number": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Chapter Number"
+    },
+    "chapter_name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Chapter Name"
+    },
+    "sort_order": {
+      "type": "integer",
+      "title": "Sort Order",
+      "default": 0
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title_id",
+    "chapter_number",
+    "chapter_name"
+  ],
+  "title": "ChapterCreate",
+  "description": "Request body for creating a code chapter."
+}
+
+
CitedSection
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "citation": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Citation"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "version": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Version",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "citation"
+  ],
+  "title": "CitedSection",
+  "description": "One resolved public Code section; never a caller-supplied quotation."
+}
+
+
CityProfileCreate
+{
+  "properties": {
+    "city_name": {
+      "type": "string",
+      "title": "City Name"
+    },
+    "state": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State"
+    },
+    "county": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "County"
+    },
+    "population_band": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Population Band"
+    },
+    "email_platform": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email Platform"
+    },
+    "has_dedicated_it": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Has Dedicated It"
+    },
+    "monthly_request_volume": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Monthly Request Volume"
+    },
+    "profile_data": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Profile Data",
+      "default": {}
+    },
+    "gap_map": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Gap Map",
+      "default": {}
+    }
+  },
+  "type": "object",
+  "required": [
+    "city_name"
+  ],
+  "title": "CityProfileCreate"
+}
+
+
CityProfileRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "city_name": {
+      "type": "string",
+      "title": "City Name"
+    },
+    "state": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State"
+    },
+    "county": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "County"
+    },
+    "population_band": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Population Band"
+    },
+    "email_platform": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email Platform"
+    },
+    "has_dedicated_it": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Has Dedicated It"
+    },
+    "monthly_request_volume": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Monthly Request Volume"
+    },
+    "onboarding_status": {
+      "type": "string",
+      "title": "Onboarding Status"
+    },
+    "profile_data": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Profile Data"
+    },
+    "gap_map": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Gap Map"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "updated_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "city_name",
+    "state",
+    "county",
+    "population_band",
+    "email_platform",
+    "has_dedicated_it",
+    "monthly_request_volume",
+    "onboarding_status",
+    "profile_data",
+    "gap_map",
+    "created_at",
+    "updated_at"
+  ],
+  "title": "CityProfileRead"
+}
+
+
CityProfileUpdate
+{
+  "properties": {
+    "city_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "City Name"
+    },
+    "state": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State"
+    },
+    "county": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "County"
+    },
+    "population_band": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Population Band"
+    },
+    "email_platform": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email Platform"
+    },
+    "has_dedicated_it": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Has Dedicated It"
+    },
+    "monthly_request_volume": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Monthly Request Volume"
+    },
+    "onboarding_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Onboarding Status"
+    },
+    "profile_data": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Profile Data"
+    },
+    "gap_map": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Gap Map"
+    }
+  },
+  "type": "object",
+  "title": "CityProfileUpdate"
+}
+
+
ClarificationCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "request-records-clarification",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ClarificationPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "ClarificationCommand"
+}
+
+
ClarificationPayload
+{
+  "properties": {
+    "clarificationNote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Clarificationnote"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "clarificationNote"
+  ],
+  "title": "ClarificationPayload"
+}
+
+
Closeout
+{
+  "properties": {
+    "decision_id": {
+      "type": "string",
+      "pattern": "^[A-Za-z0-9_-]{1,64}$",
+      "title": "Decision Id"
+    },
+    "version_id": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Version Id"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "version_label": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Version Label"
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 1000000,
+      "minLength": 1,
+      "title": "Body"
+    },
+    "effective_start": {
+      "type": "string",
+      "format": "date",
+      "title": "Effective Start"
+    },
+    "effective_end": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective End"
+    },
+    "is_current": {
+      "type": "boolean",
+      "title": "Is Current"
+    },
+    "reconciliation_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reconciliation Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "decision_id",
+    "version_id",
+    "source_id",
+    "version_label",
+    "body",
+    "effective_start",
+    "is_current"
+  ],
+  "title": "Closeout"
+}
+
+
CodeContext
+{
+  "properties": {
+    "section_number": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Section Number"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "section_number"
+  ],
+  "title": "CodeContext"
+}
+
+
CodeLink
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "const": "code",
+      "title": "Provider",
+      "default": "code"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "CodeLink"
+}
+
+
CodeSearch
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "CodeSearch"
+}
+
+
CodeSourceSelection
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 200,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "CodeSourceSelection"
+}
+
+
CompleteArtifact
+{
+  "properties": {
+    "export_path": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Export Path"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "export_path"
+  ],
+  "title": "CompleteArtifact"
+}
+
+
ConnectionSearch
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "enum": [
+        "meetings",
+        "zoning"
+      ],
+      "title": "Provider"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "query"
+  ],
+  "title": "ConnectionSearch"
+}
+
+
CoverageGapResponse
+{
+  "properties": {
+    "jurisdictions_without_rules": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Jurisdictions Without Rules"
+    },
+    "departments_without_staff": {
+      "items": {
+        "additionalProperties": true,
+        "type": "object"
+      },
+      "type": "array",
+      "title": "Departments Without Staff"
+    },
+    "uncovered_categories": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Uncovered Categories"
+    },
+    "total_gaps": {
+      "type": "integer",
+      "title": "Total Gaps"
+    }
+  },
+  "type": "object",
+  "required": [
+    "jurisdictions_without_rules",
+    "departments_without_staff",
+    "uncovered_categories",
+    "total_gaps"
+  ],
+  "title": "CoverageGapResponse"
+}
+
+
DataSourceAdminRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "source_type": {
+      "$ref": "#/components/schemas/SourceType"
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "type": "boolean",
+      "title": "Schedule Enabled",
+      "default": true
+    },
+    "next_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Next Sync At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "last_ingestion_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Ingestion At"
+    },
+    "last_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync At"
+    },
+    "last_sync_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync Status"
+    },
+    "last_error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Error Message"
+    },
+    "consecutive_failure_count": {
+      "type": "integer",
+      "title": "Consecutive Failure Count",
+      "default": 0
+    },
+    "sync_paused": {
+      "type": "boolean",
+      "title": "Sync Paused",
+      "default": false
+    },
+    "health_status": {
+      "type": "string",
+      "title": "Health Status",
+      "default": "healthy"
+    },
+    "active_failure_count": {
+      "type": "integer",
+      "title": "Active Failure Count",
+      "default": 0
+    },
+    "connector_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connector Type"
+    },
+    "updated_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Updated At"
+    },
+    "connection_config": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Connection Config"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "source_type",
+    "is_active",
+    "created_by",
+    "created_at",
+    "last_ingestion_at",
+    "connection_config"
+  ],
+  "title": "DataSourceAdminRead",
+  "description": "Full datasource shape including connection_config. Returned only by admin-gated endpoints."
+}
+
+
DataSourceCreate
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "source_type": {
+      "$ref": "#/components/schemas/SourceType"
+    },
+    "connection_config": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Connection Config",
+      "default": {}
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "type": "boolean",
+      "title": "Schedule Enabled",
+      "default": true
+    }
+  },
+  "type": "object",
+  "required": [
+    "name",
+    "source_type"
+  ],
+  "title": "DataSourceCreate"
+}
+
+
DataSourceRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "source_type": {
+      "$ref": "#/components/schemas/SourceType"
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "type": "boolean",
+      "title": "Schedule Enabled",
+      "default": true
+    },
+    "next_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Next Sync At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "last_ingestion_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Ingestion At"
+    },
+    "last_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync At"
+    },
+    "last_sync_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync Status"
+    },
+    "last_error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Error Message"
+    },
+    "consecutive_failure_count": {
+      "type": "integer",
+      "title": "Consecutive Failure Count",
+      "default": 0
+    },
+    "sync_paused": {
+      "type": "boolean",
+      "title": "Sync Paused",
+      "default": false
+    },
+    "health_status": {
+      "type": "string",
+      "title": "Health Status",
+      "default": "healthy"
+    },
+    "active_failure_count": {
+      "type": "integer",
+      "title": "Active Failure Count",
+      "default": 0
+    },
+    "connector_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connector Type"
+    },
+    "updated_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "source_type",
+    "is_active",
+    "created_by",
+    "created_at",
+    "last_ingestion_at"
+  ],
+  "title": "DataSourceRead",
+  "description": "Redacted datasource shape — safe for non-admin roles. connection_config omitted."
+}
+
+
DataSourceUpdate
+{
+  "properties": {
+    "name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Name"
+    },
+    "connection_config": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connection Config"
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Schedule Enabled"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "DataSourceUpdate"
+}
+
+
DeadlineCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "set-records-deadline",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/DeadlinePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "DeadlineCommand"
+}
+
+
DeadlinePayload
+{
+  "properties": {
+    "deadline": {
+      "type": "string",
+      "title": "Deadline"
+    },
+    "deadlineBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Deadlinebasis"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "deadline",
+    "deadlineBasis"
+  ],
+  "title": "DeadlinePayload"
+}
+
+
Decision
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "pattern": "^[A-Za-z0-9_-]{1,64}$",
+      "title": "Id"
+    },
+    "outcome": {
+      "type": "string",
+      "enum": [
+        "adopted",
+        "not_adopted",
+        "deferred",
+        "withdrawn"
+      ],
+      "title": "Outcome"
+    },
+    "decided_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Decided At"
+    },
+    "decision_text": {
+      "type": "string",
+      "maxLength": 1000000,
+      "minLength": 1,
+      "title": "Decision Text"
+    },
+    "supporting_references": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Supporting References"
+    },
+    "supersedes_decision_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^[A-Za-z0-9_-]{1,64}$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supersedes Decision Id"
+    },
+    "reconciliation_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reconciliation Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "outcome",
+    "decision_text"
+  ],
+  "title": "Decision"
+}
+
+
DepartmentCreate
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "code": {
+      "type": "string",
+      "title": "Code"
+    },
+    "contact_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Contact Email"
+    }
+  },
+  "type": "object",
+  "required": [
+    "name",
+    "code"
+  ],
+  "title": "DepartmentCreate"
+}
+
+
DepartmentRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "code": {
+      "type": "string",
+      "title": "Code"
+    },
+    "contact_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Contact Email"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "code",
+    "contact_email",
+    "created_at"
+  ],
+  "title": "DepartmentRead"
+}
+
+
DepartmentUpdate
+{
+  "properties": {
+    "name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Name"
+    },
+    "code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Code"
+    },
+    "contact_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Contact Email"
+    }
+  },
+  "type": "object",
+  "title": "DepartmentUpdate"
+}
+
+
DisclosureTemplateCreate
+{
+  "properties": {
+    "template_type": {
+      "type": "string",
+      "title": "Template Type"
+    },
+    "state_code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State Code"
+    },
+    "content": {
+      "type": "string",
+      "title": "Content"
+    }
+  },
+  "type": "object",
+  "required": [
+    "template_type",
+    "content"
+  ],
+  "title": "DisclosureTemplateCreate"
+}
+
+
DisclosureTemplateRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "template_type": {
+      "type": "string",
+      "title": "Template Type"
+    },
+    "state_code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State Code"
+    },
+    "content": {
+      "type": "string",
+      "title": "Content"
+    },
+    "version": {
+      "type": "integer",
+      "title": "Version"
+    },
+    "updated_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Updated By"
+    },
+    "updated_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "template_type",
+    "state_code",
+    "content",
+    "version",
+    "updated_by",
+    "updated_at"
+  ],
+  "title": "DisclosureTemplateRead"
+}
+
+
DisclosureTemplateRendered
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "template_type": {
+      "type": "string",
+      "title": "Template Type"
+    },
+    "rendered_content": {
+      "type": "string",
+      "title": "Rendered Content"
+    },
+    "has_unresolved_variables": {
+      "type": "boolean",
+      "title": "Has Unresolved Variables"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "template_type",
+    "rendered_content",
+    "has_unresolved_variables"
+  ],
+  "title": "DisclosureTemplateRendered"
+}
+
+
DisclosureTemplateUpdate
+{
+  "properties": {
+    "content": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Content"
+    },
+    "state_code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State Code"
+    }
+  },
+  "type": "object",
+  "title": "DisclosureTemplateUpdate"
+}
+
+
DocumentChunkRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "chunk_index": {
+      "type": "integer",
+      "title": "Chunk Index"
+    },
+    "content_text": {
+      "type": "string",
+      "title": "Content Text"
+    },
+    "token_count": {
+      "type": "integer",
+      "title": "Token Count"
+    },
+    "page_number": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Page Number"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "document_id",
+    "chunk_index",
+    "content_text",
+    "token_count",
+    "page_number"
+  ],
+  "title": "DocumentChunkRead"
+}
+
+
DocumentRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "source_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Source Id"
+    },
+    "source_path": {
+      "type": "string",
+      "title": "Source Path"
+    },
+    "filename": {
+      "type": "string",
+      "title": "Filename"
+    },
+    "file_type": {
+      "type": "string",
+      "title": "File Type"
+    },
+    "file_hash": {
+      "type": "string",
+      "title": "File Hash"
+    },
+    "file_size": {
+      "type": "integer",
+      "title": "File Size"
+    },
+    "ingestion_status": {
+      "$ref": "#/components/schemas/IngestionStatus"
+    },
+    "ingestion_error": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ingestion Error"
+    },
+    "chunk_count": {
+      "type": "integer",
+      "title": "Chunk Count"
+    },
+    "ingested_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ingested At"
+    },
+    "connector_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connector Type"
+    },
+    "updated_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "source_id",
+    "source_path",
+    "filename",
+    "file_type",
+    "file_hash",
+    "file_size",
+    "ingestion_status",
+    "ingestion_error",
+    "chunk_count",
+    "ingested_at"
+  ],
+  "title": "DocumentRead"
+}
+
+
DraftCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "draft-records-response",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/DraftPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "DraftCommand"
+}
+
+
DraftInput
+{
+  "properties": {
+    "source_materials": {
+      "items": {
+        "$ref": "#/components/schemas/SourceInput"
+      },
+      "type": "array",
+      "title": "Source Materials"
+    },
+    "sentences": {
+      "items": {
+        "$ref": "#/components/schemas/SentenceInput"
+      },
+      "type": "array",
+      "minItems": 1,
+      "title": "Sentences"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sentences"
+  ],
+  "title": "DraftInput"
+}
+
+
DraftPayload
+{
+  "properties": {
+    "responseDraft": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Responsedraft"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "responseDraft"
+  ],
+  "title": "DraftPayload"
+}
+
+
ErrorModel
+{
+  "properties": {
+    "detail": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "additionalProperties": {
+            "type": "string"
+          },
+          "type": "object"
+        }
+      ],
+      "title": "Detail"
+    }
+  },
+  "type": "object",
+  "required": [
+    "detail"
+  ],
+  "title": "ErrorModel"
+}
+
+
Evidence
+{
+  "properties": {
+    "filename": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$",
+      "title": "Filename"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Description"
+    },
+    "media_type": {
+      "type": "string",
+      "enum": [
+        "text/plain",
+        "image/jpeg",
+        "image/png",
+        "image/webp",
+        "application/pdf",
+        "audio/webm",
+        "audio/ogg",
+        "audio/wav",
+        "audio/mpeg",
+        "audio/mp4"
+      ],
+      "title": "Media Type"
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 14000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "filename",
+    "description",
+    "media_type",
+    "content_base64",
+    "sha256"
+  ],
+  "title": "Evidence"
+}
+
+
EvidenceItem
+{
+  "properties": {
+    "filename": {
+      "type": "string",
+      "maxLength": 151,
+      "minLength": 1,
+      "title": "Filename"
+    },
+    "media_type": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Media Type"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Description",
+      "default": ""
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 14000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "filename",
+    "media_type",
+    "content_base64",
+    "sha256"
+  ],
+  "title": "EvidenceItem"
+}
+
+
EvidenceItems
+{
+  "properties": {
+    "items": {
+      "items": {
+        "$ref": "#/components/schemas/EvidenceItem"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "minItems": 1,
+      "title": "Items"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "items"
+  ],
+  "title": "EvidenceItems"
+}
+
+
ExemptionAccuracyReport
+{
+  "properties": {
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "total_flags": {
+      "type": "integer",
+      "title": "Total Flags"
+    },
+    "accepted": {
+      "type": "integer",
+      "title": "Accepted"
+    },
+    "rejected": {
+      "type": "integer",
+      "title": "Rejected"
+    },
+    "pending": {
+      "type": "integer",
+      "title": "Pending"
+    },
+    "acceptance_rate": {
+      "type": "number",
+      "title": "Acceptance Rate"
+    }
+  },
+  "type": "object",
+  "required": [
+    "category",
+    "total_flags",
+    "accepted",
+    "rejected",
+    "pending",
+    "acceptance_rate"
+  ],
+  "title": "ExemptionAccuracyReport"
+}
+
+
ExemptionDashboard
+{
+  "properties": {
+    "total_flags": {
+      "type": "integer",
+      "title": "Total Flags"
+    },
+    "by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "By Status"
+    },
+    "by_category": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "By Category"
+    },
+    "acceptance_rate": {
+      "type": "number",
+      "title": "Acceptance Rate"
+    },
+    "total_rules": {
+      "type": "integer",
+      "title": "Total Rules"
+    },
+    "active_rules": {
+      "type": "integer",
+      "title": "Active Rules"
+    }
+  },
+  "type": "object",
+  "required": [
+    "total_flags",
+    "by_status",
+    "by_category",
+    "acceptance_rate",
+    "total_rules",
+    "active_rules"
+  ],
+  "title": "ExemptionDashboard"
+}
+
+
ExemptionDecisionCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-exemption-decision",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ExemptionDecisionPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "ExemptionDecisionCommand"
+}
+
+
ExemptionDecisionPayload
+{
+  "properties": {
+    "exemptionSource": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionsource"
+    },
+    "exemptionKind": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionkind"
+    },
+    "exemptionFinding": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionfinding"
+    },
+    "exemptionDecision": {
+      "type": "string",
+      "enum": [
+        "release",
+        "redact",
+        "exempt"
+      ],
+      "title": "Exemptiondecision"
+    },
+    "exemptionBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionbasis"
+    },
+    "exemptionReviewer": {
+      "type": "string",
+      "title": "Exemptionreviewer",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "exemptionSource",
+    "exemptionKind",
+    "exemptionFinding",
+    "exemptionDecision",
+    "exemptionBasis"
+  ],
+  "title": "ExemptionDecisionPayload"
+}
+
+
ExemptionDecisionView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "source": {
+      "type": "string",
+      "title": "Source"
+    },
+    "kind": {
+      "type": "string",
+      "title": "Kind"
+    },
+    "finding": {
+      "type": "string",
+      "title": "Finding"
+    },
+    "decision": {
+      "type": "string",
+      "enum": [
+        "release",
+        "redact",
+        "exempt"
+      ],
+      "title": "Decision"
+    },
+    "basis": {
+      "type": "string",
+      "title": "Basis"
+    },
+    "reviewer": {
+      "type": "string",
+      "title": "Reviewer"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "source",
+    "kind",
+    "finding",
+    "decision",
+    "basis",
+    "reviewer",
+    "created_at_unix_seconds"
+  ],
+  "title": "ExemptionDecisionView"
+}
+
+
ExemptionFlagRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "chunk_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Chunk Id"
+    },
+    "rule_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Rule Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "matched_text": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Matched Text"
+    },
+    "confidence": {
+      "type": "number",
+      "title": "Confidence"
+    },
+    "status": {
+      "$ref": "#/components/schemas/FlagStatus"
+    },
+    "reviewed_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reviewed By"
+    },
+    "reviewed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reviewed At"
+    },
+    "review_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Reason"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "chunk_id",
+    "rule_id",
+    "request_id",
+    "category",
+    "matched_text",
+    "confidence",
+    "status",
+    "reviewed_by",
+    "reviewed_at",
+    "review_reason",
+    "created_at"
+  ],
+  "title": "ExemptionFlagRead"
+}
+
+
ExemptionFlagReview
+{
+  "properties": {
+    "status": {
+      "$ref": "#/components/schemas/FlagStatus"
+    },
+    "review_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Reason"
+    }
+  },
+  "type": "object",
+  "required": [
+    "status"
+  ],
+  "title": "ExemptionFlagReview"
+}
+
+
ExemptionNoteCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-exemption-review",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ExemptionNotePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "ExemptionNoteCommand"
+}
+
+
ExemptionNotePayload
+{
+  "properties": {
+    "exemptionNote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionnote"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "exemptionNote"
+  ],
+  "title": "ExemptionNotePayload"
+}
+
+
ExemptionRuleCreate
+{
+  "properties": {
+    "state_code": {
+      "type": "string",
+      "title": "State Code"
+    },
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "rule_type": {
+      "$ref": "#/components/schemas/RuleType"
+    },
+    "rule_definition": {
+      "type": "string",
+      "title": "Rule Definition"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "enabled": {
+      "type": "boolean",
+      "title": "Enabled",
+      "default": true
+    }
+  },
+  "type": "object",
+  "required": [
+    "state_code",
+    "category",
+    "rule_type",
+    "rule_definition"
+  ],
+  "title": "ExemptionRuleCreate"
+}
+
+
ExemptionRuleRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "state_code": {
+      "type": "string",
+      "title": "State Code"
+    },
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "rule_type": {
+      "$ref": "#/components/schemas/RuleType"
+    },
+    "rule_definition": {
+      "type": "string",
+      "title": "Rule Definition"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "enabled": {
+      "type": "boolean",
+      "title": "Enabled"
+    },
+    "version": {
+      "type": "integer",
+      "title": "Version",
+      "default": 1
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "state_code",
+    "category",
+    "rule_type",
+    "rule_definition",
+    "description",
+    "enabled",
+    "created_by",
+    "created_at"
+  ],
+  "title": "ExemptionRuleRead"
+}
+
+
ExemptionRuleUpdate
+{
+  "properties": {
+    "rule_definition": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Rule Definition"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "enabled": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Enabled"
+    }
+  },
+  "type": "object",
+  "title": "ExemptionRuleUpdate"
+}
+
+
ExportReceipt
+{
+  "properties": {
+    "export_path": {
+      "type": "string",
+      "maxLength": 32768,
+      "minLength": 1,
+      "title": "Export Path"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "export_path"
+  ],
+  "title": "ExportReceipt"
+}
+
+
FeeEstimateCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "estimate-records-fee",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/FeeEstimatePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "FeeEstimateCommand"
+}
+
+
FeeEstimatePayload
+{
+  "properties": {
+    "feeEstimate": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feeestimate"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "feeEstimate"
+  ],
+  "title": "FeeEstimatePayload"
+}
+
+
FeeEstimateRequest
+{
+  "properties": {
+    "page_count": {
+      "type": "integer",
+      "title": "Page Count"
+    },
+    "fee_schedule_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Fee Schedule Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "page_count",
+    "fee_schedule_id"
+  ],
+  "title": "FeeEstimateRequest"
+}
+
+
FeeEstimateResponse
+{
+  "properties": {
+    "page_count": {
+      "type": "integer",
+      "title": "Page Count"
+    },
+    "unit_price": {
+      "type": "number",
+      "title": "Unit Price"
+    },
+    "total": {
+      "type": "number",
+      "title": "Total"
+    },
+    "fee_type": {
+      "type": "string",
+      "title": "Fee Type"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    }
+  },
+  "type": "object",
+  "required": [
+    "page_count",
+    "unit_price",
+    "total",
+    "fee_type",
+    "description"
+  ],
+  "title": "FeeEstimateResponse"
+}
+
+
FeeLineCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-fee-line",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/FeeLinePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "FeeLineCommand"
+}
+
+
FeeLineItemCreate
+{
+  "properties": {
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "quantity": {
+      "type": "integer",
+      "title": "Quantity",
+      "default": 1
+    },
+    "unit_price": {
+      "type": "number",
+      "title": "Unit Price"
+    },
+    "fee_schedule_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Schedule Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "description",
+    "unit_price"
+  ],
+  "title": "FeeLineItemCreate"
+}
+
+
FeeLineItemRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "fee_schedule_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Schedule Id"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "quantity": {
+      "type": "integer",
+      "title": "Quantity"
+    },
+    "unit_price": {
+      "type": "number",
+      "title": "Unit Price"
+    },
+    "total": {
+      "type": "number",
+      "title": "Total"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "fee_schedule_id",
+    "description",
+    "quantity",
+    "unit_price",
+    "total",
+    "status",
+    "created_at"
+  ],
+  "title": "FeeLineItemRead"
+}
+
+
FeeLinePayload
+{
+  "properties": {
+    "feeLineDescription": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feelinedescription"
+    },
+    "feeScheduleBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feeschedulebasis"
+    },
+    "feeLineAmount": {
+      "type": "string",
+      "title": "Feelineamount"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "feeLineDescription",
+    "feeScheduleBasis",
+    "feeLineAmount"
+  ],
+  "title": "FeeLinePayload"
+}
+
+
FeeLineView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "schedule_basis": {
+      "type": "string",
+      "title": "Schedule Basis"
+    },
+    "amount_cents": {
+      "type": "integer",
+      "title": "Amount Cents"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "description",
+    "schedule_basis",
+    "amount_cents",
+    "created_at_unix_seconds"
+  ],
+  "title": "FeeLineView"
+}
+
+
FeeScheduleCreate
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "title": "Jurisdiction"
+    },
+    "fee_type": {
+      "type": "string",
+      "title": "Fee Type"
+    },
+    "amount": {
+      "type": "number",
+      "title": "Amount"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "effective_date": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective Date"
+    }
+  },
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "fee_type",
+    "amount"
+  ],
+  "title": "FeeScheduleCreate"
+}
+
+
FeeScheduleRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "jurisdiction": {
+      "type": "string",
+      "title": "Jurisdiction"
+    },
+    "fee_type": {
+      "type": "string",
+      "title": "Fee Type"
+    },
+    "amount": {
+      "type": "number",
+      "title": "Amount"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "effective_date": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective Date"
+    },
+    "created_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "jurisdiction",
+    "fee_type",
+    "amount",
+    "description",
+    "effective_date",
+    "created_by",
+    "created_at"
+  ],
+  "title": "FeeScheduleRead"
+}
+
+
FeeScheduleUpdate
+{
+  "properties": {
+    "fee_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Type"
+    },
+    "amount": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Amount"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "effective_date": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective Date"
+    }
+  },
+  "type": "object",
+  "title": "FeeScheduleUpdate"
+}
+
+
FeeWaiverCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "waive-records-fee",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/FeeWaiverPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "FeeWaiverCommand"
+}
+
+
FeeWaiverCreateRequest
+{
+  "properties": {
+    "waiver_type": {
+      "type": "string",
+      "title": "Waiver Type"
+    },
+    "reason": {
+      "type": "string",
+      "title": "Reason"
+    }
+  },
+  "type": "object",
+  "required": [
+    "waiver_type",
+    "reason"
+  ],
+  "title": "FeeWaiverCreateRequest"
+}
+
+
FeeWaiverPayload
+{
+  "properties": {
+    "feeWaiverReason": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feewaiverreason"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "feeWaiverReason"
+  ],
+  "title": "FeeWaiverPayload"
+}
+
+
FeeWaiverReadResponse
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "waiver_type": {
+      "type": "string",
+      "title": "Waiver Type"
+    },
+    "reason": {
+      "type": "string",
+      "title": "Reason"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    },
+    "created_at": {
+      "type": "string",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "waiver_type",
+    "reason",
+    "status",
+    "created_at"
+  ],
+  "title": "FeeWaiverReadResponse"
+}
+
+
FeeWaiverReviewRequest
+{
+  "properties": {
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    }
+  },
+  "type": "object",
+  "required": [
+    "status"
+  ],
+  "title": "FeeWaiverReviewRequest"
+}
+
+
FinishCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "fulfill-records-request",
+        "close-records-request"
+      ],
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/NativePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "FinishCommand"
+}
+
+
FlagStatus
+{
+  "type": "string",
+  "enum": [
+    "flagged",
+    "reviewed",
+    "accepted",
+    "rejected"
+  ],
+  "title": "FlagStatus"
+}
+
+
FormPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "form-plan",
+      "title": "Action"
+    },
+    "formName": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Formname",
+      "default": ""
+    },
+    "fields": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 50,
+      "title": "Fields"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "FormPlan"
+}
+
+
GeneratedDraft
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "model": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Model"
+    },
+    "previous_response_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Previous Response Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text",
+    "model",
+    "previous_response_sha256"
+  ],
+  "title": "GeneratedDraft"
+}
+
+
HTTPValidationError
+{
+  "properties": {
+    "detail": {
+      "items": {
+        "$ref": "#/components/schemas/ValidationError"
+      },
+      "type": "array",
+      "title": "Detail"
+    }
+  },
+  "type": "object",
+  "title": "HTTPValidationError"
+}
+
+
Handoff
+{
+  "properties": {
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "request_id"
+  ],
+  "title": "Handoff"
+}
+
+
ImportBundleCreate
+{
+  "properties": {
+    "job_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Job Id"
+    },
+    "connector_type": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Connector Type"
+    },
+    "source": {
+      "$ref": "#/components/schemas/SourceCreate"
+    },
+    "sources": {
+      "items": {
+        "$ref": "#/components/schemas/SourceCreate"
+      },
+      "type": "array",
+      "title": "Sources"
+    },
+    "titles": {
+      "items": {
+        "$ref": "#/components/schemas/TitleCreate"
+      },
+      "type": "array",
+      "title": "Titles"
+    },
+    "chapters": {
+      "items": {
+        "$ref": "#/components/schemas/ChapterCreate"
+      },
+      "type": "array",
+      "title": "Chapters"
+    },
+    "sections": {
+      "items": {
+        "$ref": "#/components/schemas/SectionCreate"
+      },
+      "type": "array",
+      "title": "Sections"
+    },
+    "versions": {
+      "items": {
+        "$ref": "#/components/schemas/SectionVersionCreate"
+      },
+      "type": "array",
+      "title": "Versions"
+    },
+    "provenance": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Provenance"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "connector_type",
+    "source"
+  ],
+  "title": "ImportBundleCreate",
+  "description": "Request body for local fixture/file-drop import jobs."
+}
+
+
InclusionStatus
+{
+  "type": "string",
+  "enum": [
+    "included",
+    "excluded",
+    "pending"
+  ],
+  "title": "InclusionStatus"
+}
+
+
IngestionStats
+{
+  "properties": {
+    "total_sources": {
+      "type": "integer",
+      "title": "Total Sources"
+    },
+    "active_sources": {
+      "type": "integer",
+      "title": "Active Sources"
+    },
+    "total_documents": {
+      "type": "integer",
+      "title": "Total Documents"
+    },
+    "documents_by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "Documents By Status"
+    },
+    "total_chunks": {
+      "type": "integer",
+      "title": "Total Chunks"
+    }
+  },
+  "type": "object",
+  "required": [
+    "total_sources",
+    "active_sources",
+    "total_documents",
+    "documents_by_status",
+    "total_chunks"
+  ],
+  "title": "IngestionStats"
+}
+
+
IngestionStatus
+{
+  "type": "string",
+  "enum": [
+    "pending",
+    "processing",
+    "completed",
+    "failed"
+  ],
+  "title": "IngestionStatus"
+}
+
+
InitiativeInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "policy": {
+      "$ref": "#/components/schemas/PolicySelection"
+    },
+    "responsible_staff": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Responsible Staff"
+    },
+    "target": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "string"
+        }
+      ],
+      "title": "Target"
+    },
+    "unit": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Unit"
+    },
+    "due_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Due On"
+    },
+    "status": {
+      "type": "string",
+      "enum": [
+        "planned",
+        "active",
+        "completed",
+        "cancelled"
+      ],
+      "title": "Status",
+      "default": "planned"
+    },
+    "milestones": {
+      "items": {
+        "$ref": "#/components/schemas/Milestone"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "title": "Milestones"
+    },
+    "measurements": {
+      "items": {
+        "$ref": "#/components/schemas/Measurement"
+      },
+      "type": "array",
+      "maxItems": 1000,
+      "title": "Measurements"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "policy",
+    "responsible_staff",
+    "target",
+    "unit",
+    "due_on",
+    "note"
+  ],
+  "title": "InitiativeInput"
+}
+
+
InspectionInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "property_reference": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Property Reference"
+    },
+    "inspection_reference": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Inspection Reference"
+    },
+    "dataset_kind": {
+      "type": "string",
+      "enum": [
+        "municipal",
+        "fictional"
+      ],
+      "title": "Dataset Kind"
+    },
+    "inspector_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "minLength": 1,
+      "title": "Inspector Notes"
+    },
+    "photo_observations": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Photo Observations"
+    },
+    "voice_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Voice Notes",
+      "default": ""
+    },
+    "evidence": {
+      "items": {
+        "$ref": "#/components/schemas/Evidence"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "title": "Evidence"
+    },
+    "linked_sources": {
+      "items": {
+        "$ref": "#/components/schemas/townlight_inspections__workflow_models__SourceLink"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Linked Sources"
+    },
+    "assigned_to": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Assigned To",
+      "default": ""
+    },
+    "staff_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Staff Notes",
+      "default": ""
+    },
+    "notice_draft": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Notice Draft",
+      "default": ""
+    },
+    "review_state": {
+      "type": "string",
+      "enum": [
+        "draft",
+        "follow_up",
+        "reviewed"
+      ],
+      "title": "Review State",
+      "default": "draft"
+    },
+    "review_notes": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Review Notes",
+      "default": ""
+    },
+    "public_summary": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Public Summary",
+      "default": ""
+    },
+    "analysis": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/AnalysisRecord"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "property_reference",
+    "inspection_reference",
+    "dataset_kind",
+    "inspector_notes"
+  ],
+  "title": "InspectionInput"
+}
+
+
IntakeInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "project_name": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Project Name"
+    },
+    "project_description": {
+      "type": "string",
+      "maxLength": 10000,
+      "minLength": 1,
+      "title": "Project Description"
+    },
+    "location": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Location"
+    },
+    "applicant_contact": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Applicant Contact",
+      "default": ""
+    },
+    "requirement_revision": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Requirement Revision"
+    },
+    "materials": {
+      "items": {
+        "$ref": "#/components/schemas/MaterialReview"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "minItems": 1,
+      "title": "Materials"
+    },
+    "linked_sources": {
+      "items": {
+        "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Linked Sources"
+    },
+    "staff_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Staff Notes",
+      "default": ""
+    },
+    "assigned_to": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Assigned To",
+      "default": ""
+    },
+    "review_state": {
+      "type": "string",
+      "enum": [
+        "draft",
+        "follow_up",
+        "reviewed"
+      ],
+      "title": "Review State",
+      "default": "draft"
+    },
+    "review_notes": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Review Notes",
+      "default": ""
+    },
+    "public_summary": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Public Summary",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "project_name",
+    "project_description",
+    "location",
+    "requirement_revision",
+    "materials"
+  ],
+  "title": "IntakeInput"
+}
+
+
InterpretationNoteCreate
+{
+  "properties": {
+    "note_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Note Id"
+    },
+    "note_text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Note Text"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "note_text"
+  ],
+  "title": "InterpretationNoteCreate",
+  "description": "Request body for staff-only interpretation notes."
+}
+
+
InterviewRequest
+{
+  "properties": {
+    "last_answer": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Answer"
+    },
+    "last_field": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Field"
+    },
+    "skipped_fields": {
+      "anyOf": [
+        {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Skipped Fields"
+    }
+  },
+  "type": "object",
+  "title": "InterviewRequest"
+}
+
+
InterviewResponse
+{
+  "properties": {
+    "question": {
+      "type": "string",
+      "title": "Question"
+    },
+    "target_field": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Target Field"
+    },
+    "all_complete": {
+      "type": "boolean",
+      "title": "All Complete"
+    },
+    "completed_fields": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Completed Fields"
+    },
+    "onboarding_status": {
+      "type": "string",
+      "title": "Onboarding Status"
+    },
+    "skipped_fields": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Skipped Fields"
+    }
+  },
+  "type": "object",
+  "required": [
+    "question",
+    "target_field",
+    "all_complete",
+    "completed_fields",
+    "onboarding_status",
+    "skipped_fields"
+  ],
+  "title": "InterviewResponse"
+}
+
+
ManagedFileReceipt
+{
+  "properties": {
+    "original_path": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Original Path"
+    },
+    "stored_path": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Stored Path"
+    },
+    "file_name": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "File Name"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Sha256"
+    },
+    "size_bytes": {
+      "type": "integer",
+      "maximum": 2147483647.0,
+      "minimum": 0.0,
+      "title": "Size Bytes"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "original_path",
+    "stored_path",
+    "file_name",
+    "sha256",
+    "size_bytes"
+  ],
+  "title": "ManagedFileReceipt"
+}
+
+
ManagedSource
+{
+  "properties": {
+    "original_path": {
+      "type": "string",
+      "title": "Original Path"
+    },
+    "stored_path": {
+      "type": "string",
+      "title": "Stored Path"
+    },
+    "file_name": {
+      "type": "string",
+      "title": "File Name"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Sha256"
+    },
+    "size_bytes": {
+      "type": "integer",
+      "minimum": 0.0,
+      "title": "Size Bytes"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "original_path",
+    "stored_path",
+    "file_name",
+    "sha256",
+    "size_bytes"
+  ],
+  "title": "ManagedSource"
+}
+
+
Material
+{
+  "properties": {
+    "material_id": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9_-]{1,80}$",
+      "title": "Material Id"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Description"
+    },
+    "citation": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Citation"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "material_id",
+    "description",
+    "citation"
+  ],
+  "title": "Material"
+}
+
+
MaterialReview
+{
+  "properties": {
+    "material_id": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Material Id"
+    },
+    "status": {
+      "type": "string",
+      "enum": [
+        "not_reviewed",
+        "provided",
+        "missing",
+        "unclear"
+      ],
+      "title": "Status",
+      "default": "not_reviewed"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Note",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "material_id"
+  ],
+  "title": "MaterialReview"
+}
+
+
Measurement
+{
+  "properties": {
+    "recorded_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Recorded On"
+    },
+    "value": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "string"
+        }
+      ],
+      "title": "Value"
+    },
+    "evidence": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Evidence"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "recorded_on",
+    "value",
+    "evidence"
+  ],
+  "title": "Measurement"
+}
+
+
MediaAnalysis
+{
+  "properties": {
+    "items": {
+      "items": {
+        "$ref": "#/components/schemas/EvidenceItem"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "minItems": 1,
+      "title": "Items"
+    },
+    "code_links": {
+      "items": {
+        "$ref": "#/components/schemas/CodeLink"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Code Links"
+    },
+    "inspector_supplied_text": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Inspector Supplied Text",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "items"
+  ],
+  "title": "MediaAnalysis"
+}
+
+
MeetingInput
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "scheduled_start": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Scheduled Start"
+    },
+    "location": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Location"
+    },
+    "meeting_type": {
+      "type": "string",
+      "enum": [
+        "regular",
+        "special",
+        "emergency",
+        "closed_session",
+        "executive"
+      ],
+      "title": "Meeting Type",
+      "default": "regular"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "scheduled_start",
+    "location"
+  ],
+  "title": "MeetingInput"
+}
+
+
MeetingLink
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 200,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    },
+    "relation": {
+      "type": "string",
+      "enum": [
+        "hearing",
+        "context",
+        "precedent"
+      ],
+      "title": "Relation"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256",
+    "relation"
+  ],
+  "title": "MeetingLink"
+}
+
+
MeetingSearch
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "MeetingSearch"
+}
+
+
MeetingStageInput
+{
+  "properties": {
+    "to_status": {
+      "type": "string",
+      "enum": [
+        "SCHEDULED",
+        "NOTICED",
+        "PACKET_POSTED",
+        "IN_PROGRESS",
+        "RECESSED",
+        "ADJOURNED",
+        "TRANSCRIPT_READY",
+        "MINUTES_DRAFTED",
+        "MINUTES_POSTED",
+        "MINUTES_ADOPTED",
+        "MINUTES_SIGNED",
+        "ARCHIVED",
+        "CANCELLED"
+      ],
+      "title": "To Status"
+    },
+    "statutory_basis": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Basis"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "to_status"
+  ],
+  "title": "MeetingStageInput"
+}
+
+
MeetingsSearch
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "MeetingsSearch"
+}
+
+
MeetingsSourceSelection
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 200,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "MeetingsSourceSelection"
+}
+
+
MessageCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-message",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/MessagePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "MessageCommand"
+}
+
+
MessageCreate
+{
+  "properties": {
+    "message_text": {
+      "type": "string",
+      "title": "Message Text"
+    },
+    "is_internal": {
+      "type": "boolean",
+      "title": "Is Internal",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "message_text"
+  ],
+  "title": "MessageCreate"
+}
+
+
MessagePayload
+{
+  "properties": {
+    "requestMessageBody": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestmessagebody"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requestMessageBody"
+  ],
+  "title": "MessagePayload"
+}
+
+
MessageRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "sender_type": {
+      "type": "string",
+      "title": "Sender Type"
+    },
+    "sender_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sender Id"
+    },
+    "message_text": {
+      "type": "string",
+      "title": "Message Text"
+    },
+    "is_internal": {
+      "type": "boolean",
+      "title": "Is Internal"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "sender_type",
+    "sender_id",
+    "message_text",
+    "is_internal",
+    "created_at"
+  ],
+  "title": "MessageRead"
+}
+
+
MessageView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "author": {
+      "type": "string",
+      "title": "Author"
+    },
+    "author_role": {
+      "type": "string",
+      "title": "Author Role"
+    },
+    "body": {
+      "type": "string",
+      "title": "Body"
+    },
+    "visibility": {
+      "type": "string",
+      "title": "Visibility"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "author",
+    "author_role",
+    "body",
+    "visibility",
+    "created_at_unix_seconds"
+  ],
+  "title": "MessageView"
+}
+
+
Milestone
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "due_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Due On"
+    },
+    "completed_on": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Completed On"
+    },
+    "evidence": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Evidence",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "due_on"
+  ],
+  "title": "Milestone"
+}
+
+
MinutesDecision
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "post",
+        "adopt",
+        "sign"
+      ],
+      "title": "Action"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "MinutesDecision"
+}
+
+
ModelRegistryCreate
+{
+  "properties": {
+    "model_name": {
+      "type": "string",
+      "title": "Model Name"
+    },
+    "model_version": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Version"
+    },
+    "parameter_count": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parameter Count"
+    },
+    "license": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "License"
+    },
+    "model_card_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Card Url"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active",
+      "default": false
+    },
+    "context_window_size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Context Window Size"
+    },
+    "supports_ner": {
+      "type": "boolean",
+      "title": "Supports Ner",
+      "default": false
+    },
+    "supports_vision": {
+      "type": "boolean",
+      "title": "Supports Vision",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "model_name"
+  ],
+  "title": "ModelRegistryCreate",
+  "description": "Schema for creating a new model_registry record (POST body)."
+}
+
+
ModelRegistryRead
+{
+  "properties": {
+    "id": {
+      "type": "integer",
+      "title": "Id"
+    },
+    "model_name": {
+      "type": "string",
+      "title": "Model Name"
+    },
+    "model_version": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Version"
+    },
+    "parameter_count": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parameter Count"
+    },
+    "license": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "License"
+    },
+    "model_card_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Card Url"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "added_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Added At"
+    },
+    "context_window_size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Context Window Size"
+    },
+    "supports_ner": {
+      "type": "boolean",
+      "title": "Supports Ner"
+    },
+    "supports_vision": {
+      "type": "boolean",
+      "title": "Supports Vision"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "model_name",
+    "is_active",
+    "supports_ner",
+    "supports_vision"
+  ],
+  "title": "ModelRegistryRead",
+  "description": "Schema for returning a model_registry record (GET response).\n\n``from_attributes=True`` allows construction directly from an ORM instance."
+}
+
+
ModelRegistryUpdate
+{
+  "properties": {
+    "model_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Name"
+    },
+    "model_version": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Version"
+    },
+    "parameter_count": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parameter Count"
+    },
+    "license": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "License"
+    },
+    "model_card_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Card Url"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    },
+    "context_window_size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Context Window Size"
+    },
+    "supports_ner": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supports Ner"
+    },
+    "supports_vision": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supports Vision"
+    }
+  },
+  "type": "object",
+  "title": "ModelRegistryUpdate",
+  "description": "Schema for partially updating a model_registry record (PATCH body).\n\nEvery field is optional so callers can send only the fields they want to\nchange."
+}
+
+
MotionCorrection
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "reason": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Reason"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text",
+    "reason"
+  ],
+  "title": "MotionCorrection"
+}
+
+
MotionInput
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "seconded_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "minLength": 1
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Seconded By"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text"
+  ],
+  "title": "MotionInput"
+}
+
+
NativePayload
+{
+  "properties": {},
+  "additionalProperties": false,
+  "type": "object",
+  "title": "NativePayload"
+}
+
+
NativeRequestRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "requester_name": {
+      "type": "string",
+      "title": "Requester Name"
+    },
+    "requester_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Email"
+    },
+    "requester_phone": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Phone"
+    },
+    "requester_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Type"
+    },
+    "date_received": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Date Received"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "status": {
+      "$ref": "#/components/schemas/RequestStatus"
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "created_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "response_draft": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Response Draft"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    },
+    "estimated_fee": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Estimated Fee"
+    },
+    "fee_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Status"
+    },
+    "fee_waiver_requested": {
+      "type": "boolean",
+      "title": "Fee Waiver Requested",
+      "default": false
+    },
+    "priority": {
+      "type": "string",
+      "title": "Priority",
+      "default": "normal"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    },
+    "closed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closed At"
+    },
+    "closure_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closure Reason"
+    },
+    "desktop_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Desktop Id"
+    },
+    "public_tracking_number": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Public Tracking Number"
+    },
+    "submitted_via": {
+      "type": "string",
+      "title": "Submitted Via"
+    },
+    "deadline_label": {
+      "type": "string",
+      "title": "Deadline Label"
+    },
+    "deadline_basis": {
+      "type": "string",
+      "title": "Deadline Basis"
+    },
+    "deadline_reviewed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Deadline Reviewed At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "requester_name",
+    "requester_email",
+    "date_received",
+    "statutory_deadline",
+    "description",
+    "status",
+    "assigned_to",
+    "created_by",
+    "created_at",
+    "response_draft",
+    "review_notes",
+    "desktop_id",
+    "public_tracking_number",
+    "submitted_via",
+    "deadline_label",
+    "deadline_basis",
+    "deadline_reviewed_at"
+  ],
+  "title": "NativeRequestRead"
+}
+
+
NoticeDocumentInput
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text"
+  ],
+  "title": "NoticeDocumentInput"
+}
+
+
NoticeDraft
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 100000,
+      "minLength": 1,
+      "title": "Body"
+    },
+    "notice_type": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Notice Type"
+    },
+    "statutory_basis": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Statutory Basis"
+    },
+    "event_date": {
+      "type": "string",
+      "format": "date",
+      "title": "Event Date"
+    },
+    "lead_days": {
+      "type": "integer",
+      "maximum": 365.0,
+      "minimum": 0.0,
+      "title": "Lead Days"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "body",
+    "notice_type",
+    "statutory_basis",
+    "event_date",
+    "lead_days"
+  ],
+  "title": "NoticeDraft"
+}
+
+
NoticeInput
+{
+  "properties": {
+    "notice_type": {
+      "type": "string",
+      "enum": [
+        "regular",
+        "special",
+        "emergency",
+        "closed_session",
+        "executive"
+      ],
+      "title": "Notice Type"
+    },
+    "posted_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Posted At"
+    },
+    "minimum_notice_hours": {
+      "type": "integer",
+      "minimum": 0.0,
+      "title": "Minimum Notice Hours"
+    },
+    "statutory_basis": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Basis"
+    },
+    "approved_by": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Approved By"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "notice_type",
+    "posted_at",
+    "minimum_notice_hours"
+  ],
+  "title": "NoticeInput"
+}
+
+
NoticeProofInput
+{
+  "properties": {
+    "location": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Location"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note",
+      "default": ""
+    },
+    "document_delivery_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Document Delivery Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "location"
+  ],
+  "title": "NoticeProofInput"
+}
+
+
NotificationLogRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "template_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Template Id"
+    },
+    "recipient_email": {
+      "type": "string",
+      "title": "Recipient Email"
+    },
+    "request_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Request Id"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "sent_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sent At"
+    },
+    "error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Message"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "template_id",
+    "recipient_email",
+    "request_id",
+    "channel",
+    "status",
+    "sent_at",
+    "error_message",
+    "created_at"
+  ],
+  "title": "NotificationLogRead"
+}
+
+
NotificationTemplateCreate
+{
+  "properties": {
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel",
+      "default": "email"
+    },
+    "subject_template": {
+      "type": "string",
+      "title": "Subject Template"
+    },
+    "body_template": {
+      "type": "string",
+      "title": "Body Template"
+    }
+  },
+  "type": "object",
+  "required": [
+    "event_type",
+    "subject_template",
+    "body_template"
+  ],
+  "title": "NotificationTemplateCreate"
+}
+
+
NotificationTemplateRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel"
+    },
+    "subject_template": {
+      "type": "string",
+      "title": "Subject Template"
+    },
+    "body_template": {
+      "type": "string",
+      "title": "Body Template"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "event_type",
+    "channel",
+    "subject_template",
+    "body_template",
+    "is_active",
+    "created_at"
+  ],
+  "title": "NotificationTemplateRead"
+}
+
+
NotificationTemplateUpdate
+{
+  "properties": {
+    "subject_template": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Subject Template"
+    },
+    "body_template": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Body Template"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "NotificationTemplateUpdate"
+}
+
+
NotificationView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "notification_id": {
+      "type": "string",
+      "title": "Notification Id"
+    },
+    "module_id": {
+      "type": "string",
+      "title": "Module Id"
+    },
+    "record_id": {
+      "type": "string",
+      "title": "Record Id"
+    },
+    "audience": {
+      "type": "string",
+      "title": "Audience"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel"
+    },
+    "subject": {
+      "type": "string",
+      "title": "Subject"
+    },
+    "body": {
+      "type": "string",
+      "title": "Body"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    },
+    "sent_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sent At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "notification_id",
+    "module_id",
+    "record_id",
+    "audience",
+    "channel",
+    "subject",
+    "body",
+    "status",
+    "created_at_unix_seconds",
+    "sent_at_unix_seconds"
+  ],
+  "title": "NotificationView"
+}
+
+
OllamaModelInfo
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Size"
+    },
+    "details": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Details"
+    }
+  },
+  "type": "object",
+  "required": [
+    "name"
+  ],
+  "title": "OllamaModelInfo"
+}
+
+
OllamaStatus
+{
+  "properties": {
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "models": {
+      "items": {
+        "$ref": "#/components/schemas/OllamaModelInfo"
+      },
+      "type": "array",
+      "title": "Models"
+    }
+  },
+  "type": "object",
+  "required": [
+    "status",
+    "models"
+  ],
+  "title": "OllamaStatus"
+}
+
+
OperationalMetrics
+{
+  "properties": {
+    "average_response_time_days": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Average Response Time Days"
+    },
+    "median_response_time_days": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Median Response Time Days"
+    },
+    "requests_by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "Requests By Status"
+    },
+    "requests_by_department": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "Requests By Department"
+    },
+    "deadline_compliance_rate": {
+      "type": "number",
+      "title": "Deadline Compliance Rate"
+    },
+    "total_open": {
+      "type": "integer",
+      "title": "Total Open"
+    },
+    "total_closed": {
+      "type": "integer",
+      "title": "Total Closed"
+    },
+    "total_overdue": {
+      "type": "integer",
+      "title": "Total Overdue"
+    },
+    "clarification_frequency": {
+      "type": "number",
+      "title": "Clarification Frequency"
+    },
+    "top_request_topics": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Top Request Topics"
+    }
+  },
+  "type": "object",
+  "required": [
+    "average_response_time_days",
+    "median_response_time_days",
+    "requests_by_status",
+    "requests_by_department",
+    "deadline_compliance_rate",
+    "total_open",
+    "total_closed",
+    "total_overdue",
+    "clarification_frequency",
+    "top_request_topics"
+  ],
+  "title": "OperationalMetrics"
+}
+
+
Outline
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "question_ids": {
+      "items": {
+        "type": "string",
+        "format": "uuid"
+      },
+      "type": "array",
+      "maxItems": 50,
+      "minItems": 1,
+      "title": "Question Ids"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "question_ids"
+  ],
+  "title": "Outline"
+}
+
+
Packet
+{
+  "properties": {
+    "expected_revision": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Expected Revision"
+    },
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "staff_only",
+        "records_copy"
+      ],
+      "title": "Visibility"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "expected_revision",
+    "visibility"
+  ],
+  "title": "Packet"
+}
+
+
PacketInput
+{
+  "properties": {
+    "agenda_item_ids": {
+      "items": {
+        "type": "string",
+        "format": "uuid"
+      },
+      "type": "array",
+      "title": "Agenda Item Ids"
+    },
+    "source_files": {
+      "items": {
+        "$ref": "#/components/schemas/ManagedSource"
+      },
+      "type": "array",
+      "title": "Source Files"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "agenda_item_ids"
+  ],
+  "title": "PacketInput"
+}
+
+
Pathway
+{
+  "properties": {
+    "project_type": {
+      "type": "string",
+      "maxLength": 120,
+      "minLength": 1,
+      "title": "Project Type"
+    },
+    "proposal": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Proposal",
+      "default": ""
+    },
+    "location_context": {
+      "type": "string",
+      "maxLength": 1000,
+      "title": "Location Context",
+      "default": ""
+    },
+    "requirement_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requirement Revision"
+    },
+    "fee_link": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "project_type"
+  ],
+  "title": "Pathway"
+}
+
+
PathwayStep
+{
+  "properties": {
+    "step": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Step"
+    },
+    "citation": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Citation"
+    },
+    "typical_time": {
+      "type": "string",
+      "maxLength": 1000,
+      "title": "Typical Time",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "step",
+    "citation"
+  ],
+  "title": "PathwayStep"
+}
+
+
PlainLanguageSummaryCreate
+{
+  "properties": {
+    "summary_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Summary Id"
+    },
+    "section_version_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Version Id"
+    },
+    "summary_text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Summary Text"
+    },
+    "language_code": {
+      "type": "string",
+      "title": "Language Code",
+      "default": "en"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "section_version_id",
+    "summary_text"
+  ],
+  "title": "PlainLanguageSummaryCreate",
+  "description": "Request body for staff-drafted plain-language summaries."
+}
+
+
PolicySelection
+{
+  "properties": {
+    "plan_id": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Plan Id"
+    },
+    "revision_id": {
+      "type": "string",
+      "maxLength": 36,
+      "minLength": 36,
+      "title": "Revision Id"
+    },
+    "policy_id": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Policy Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "plan_id",
+    "revision_id",
+    "policy_id"
+  ],
+  "title": "PolicySelection"
+}
+
+
PortalModeResponse
+{
+  "properties": {
+    "mode": {
+      "type": "string",
+      "enum": [
+        "public",
+        "private"
+      ],
+      "title": "Mode",
+      "description": "Active portal posture for this deployment. ``public`` = minimal resident surface (landing + authenticated records-request submission + resident registration) reachable without staff auth. ``private`` = staff-only; no public routes, no resident self-registration."
+    }
+  },
+  "type": "object",
+  "required": [
+    "mode"
+  ],
+  "title": "PortalModeResponse",
+  "description": "T5D — schema for ``GET /config/portal-mode``.\n\nExposed to the frontend on boot so it can branch routing without a\nuser-identity lookup. The payload is intentionally the single field\nbelow — no staff config, no user state, no schema version."
+}
+
+
PrepareArtifact
+{
+  "properties": {
+    "kind": {
+      "type": "string",
+      "enum": [
+        "response",
+        "release-package"
+      ],
+      "title": "Kind"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "kind"
+  ],
+  "title": "PrepareArtifact"
+}
+
+
Proof
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    },
+    "filename": {
+      "type": "string",
+      "maxLength": 150,
+      "minLength": 1,
+      "title": "Filename"
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 7000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "location": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Location"
+    },
+    "published_at": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Published At"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence",
+    "filename",
+    "content_base64",
+    "location",
+    "published_at"
+  ],
+  "title": "Proof"
+}
+
+
Proposal
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "pattern": "^[A-Za-z0-9_-]{1,64}$",
+      "title": "Id"
+    },
+    "version_id": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Version Id"
+    },
+    "meeting_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Meeting Id"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "ordinance_number": {
+      "type": "string",
+      "maxLength": 120,
+      "minLength": 1,
+      "title": "Ordinance Number"
+    },
+    "proposed_text": {
+      "type": "string",
+      "maxLength": 1000000,
+      "minLength": 1,
+      "title": "Proposed Text"
+    },
+    "supersedes_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^[A-Za-z0-9_-]{1,64}$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supersedes Id"
+    },
+    "reconciliation_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reconciliation Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "version_id",
+    "meeting_id",
+    "title",
+    "ordinance_number",
+    "proposed_text"
+  ],
+  "title": "Proposal"
+}
+
+
PublicExplore
+{
+  "properties": {
+    "goal": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Goal",
+      "default": ""
+    },
+    "topic": {
+      "type": "string",
+      "maxLength": 160,
+      "title": "Topic",
+      "default": ""
+    },
+    "neighborhood": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Neighborhood",
+      "default": ""
+    },
+    "plan_type": {
+      "type": "string",
+      "maxLength": 120,
+      "title": "Plan Type",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "PublicExplore"
+}
+
+
PublicIntake
+{
+  "properties": {
+    "requester": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requester"
+    },
+    "requesterContact": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestercontact"
+    },
+    "summary": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Summary"
+    },
+    "deadline": {
+      "type": "string",
+      "title": "Deadline",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requester",
+    "requesterContact",
+    "summary"
+  ],
+  "title": "PublicIntake"
+}
+
+
PublicLookup
+{
+  "properties": {
+    "trackingNumber": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Trackingnumber"
+    },
+    "requesterContact": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestercontact"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "trackingNumber",
+    "requesterContact"
+  ],
+  "title": "PublicLookup"
+}
+
+
PublicMessage
+{
+  "properties": {
+    "trackingNumber": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Trackingnumber"
+    },
+    "requesterContact": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestercontact"
+    },
+    "publicRequestMessage": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Publicrequestmessage"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "trackingNumber",
+    "requesterContact",
+    "publicRequestMessage"
+  ],
+  "title": "PublicMessage"
+}
+
+
PublicStatusView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "label": {
+      "type": "string",
+      "title": "Label"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "label",
+    "summary",
+    "status",
+    "created_at_unix_seconds"
+  ],
+  "title": "PublicStatusView"
+}
+
+
PublicationView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "source_module": {
+      "type": "string",
+      "title": "Source Module"
+    },
+    "source_record_id": {
+      "type": "string",
+      "title": "Source Record Id"
+    },
+    "record_type": {
+      "type": "string",
+      "title": "Record Type"
+    },
+    "public_payload": {
+      "type": "string",
+      "title": "Public Payload"
+    },
+    "payload_hash": {
+      "type": "string",
+      "title": "Payload Hash"
+    },
+    "published_at_unix_seconds": {
+      "type": "integer",
+      "title": "Published At Unix Seconds"
+    },
+    "retracted_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Retracted At Unix Seconds"
+    },
+    "retracted_by": {
+      "type": "string",
+      "title": "Retracted By",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "source_module",
+    "source_record_id",
+    "record_type",
+    "public_payload",
+    "payload_hash",
+    "published_at_unix_seconds"
+  ],
+  "title": "PublicationView"
+}
+
+
PublishingPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "publishing-workflow",
+      "title": "Action"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "hasReview": {
+      "type": "boolean",
+      "title": "Hasreview",
+      "default": false
+    },
+    "hasPlainLanguage": {
+      "type": "boolean",
+      "title": "Hasplainlanguage",
+      "default": false
+    },
+    "hasTranslationReview": {
+      "type": "boolean",
+      "title": "Hastranslationreview",
+      "default": false
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "PublishingPlan"
+}
+
+
Question
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    },
+    "question": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Question"
+    },
+    "kind": {
+      "type": "string",
+      "enum": [
+        "use",
+        "dimension"
+      ],
+      "title": "Kind"
+    },
+    "key": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Key"
+    },
+    "audience": {
+      "type": "string",
+      "enum": [
+        "resident",
+        "staff"
+      ],
+      "title": "Audience",
+      "default": "resident"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "query",
+    "question",
+    "kind",
+    "key"
+  ],
+  "title": "Question"
+}
+
+
QuestionAnswerRequest
+{
+  "properties": {
+    "question": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Question"
+    },
+    "section_number": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Section Number"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "question"
+  ],
+  "title": "QuestionAnswerRequest",
+  "description": "Request body for citation-grounded code Q&A."
+}
+
+
RecordsDocumentView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "attachment_id": {
+      "type": "string",
+      "title": "Attachment Id"
+    },
+    "title": {
+      "type": "string",
+      "title": "Title"
+    },
+    "original_path": {
+      "type": "string",
+      "title": "Original Path"
+    },
+    "stored_path": {
+      "type": "string",
+      "title": "Stored Path"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation"
+    },
+    "sha256": {
+      "type": "string",
+      "title": "Sha256"
+    },
+    "size_bytes": {
+      "type": "integer",
+      "title": "Size Bytes"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "added_by": {
+      "type": "string",
+      "title": "Added By"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    },
+    "release_original_path": {
+      "type": "string",
+      "title": "Release Original Path",
+      "default": ""
+    },
+    "release_stored_path": {
+      "type": "string",
+      "title": "Release Stored Path",
+      "default": ""
+    },
+    "release_file_name": {
+      "type": "string",
+      "title": "Release File Name",
+      "default": ""
+    },
+    "release_sha256": {
+      "type": "string",
+      "title": "Release Sha256",
+      "default": ""
+    },
+    "release_size_bytes": {
+      "type": "integer",
+      "title": "Release Size Bytes",
+      "default": 0
+    },
+    "release_status": {
+      "type": "string",
+      "title": "Release Status",
+      "default": ""
+    },
+    "release_note": {
+      "type": "string",
+      "title": "Release Note",
+      "default": ""
+    },
+    "release_added_by": {
+      "type": "string",
+      "title": "Release Added By",
+      "default": ""
+    },
+    "release_added_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Release Added At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "attachment_id",
+    "title",
+    "original_path",
+    "stored_path",
+    "citation",
+    "sha256",
+    "size_bytes",
+    "status",
+    "added_by",
+    "created_at_unix_seconds"
+  ],
+  "title": "RecordsDocumentView"
+}
+
+
RecordsOperationRead
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "message": {
+      "type": "string",
+      "title": "Message"
+    },
+    "request": {
+      "$ref": "#/components/schemas/RecordsView"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "message",
+    "request"
+  ],
+  "title": "RecordsOperationRead"
+}
+
+
RecordsStateRead
+{
+  "properties": {
+    "demo_fixture": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Demo Fixture"
+    },
+    "records_requests": {
+      "items": {
+        "$ref": "#/components/schemas/RecordsView"
+      },
+      "type": "array",
+      "title": "Records Requests"
+    },
+    "notification_events": {
+      "items": {
+        "$ref": "#/components/schemas/NotificationView"
+      },
+      "type": "array",
+      "title": "Notification Events"
+    },
+    "publication_events": {
+      "items": {
+        "$ref": "#/components/schemas/PublicationView"
+      },
+      "type": "array",
+      "title": "Publication Events"
+    },
+    "audit_entries": {
+      "items": {
+        "$ref": "#/components/schemas/AuditView"
+      },
+      "type": "array",
+      "title": "Audit Entries"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "records_requests"
+  ],
+  "title": "RecordsStateRead"
+}
+
+
RecordsView
+{
+  "properties": {
+    "request_id": {
+      "type": "string",
+      "title": "Request Id"
+    },
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "public_tracking_number": {
+      "type": "string",
+      "title": "Public Tracking Number"
+    },
+    "requester": {
+      "type": "string",
+      "title": "Requester"
+    },
+    "requester_contact": {
+      "type": "string",
+      "title": "Requester Contact"
+    },
+    "submitted_via": {
+      "type": "string",
+      "title": "Submitted Via"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "deadline": {
+      "type": "string",
+      "title": "Deadline"
+    },
+    "deadline_basis": {
+      "type": "string",
+      "title": "Deadline Basis"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "assigned_to": {
+      "type": "string",
+      "title": "Assigned To"
+    },
+    "clarification_notes": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Clarification Notes"
+    },
+    "search_notes": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Search Notes"
+    },
+    "search_sessions": {
+      "items": {
+        "$ref": "#/components/schemas/SearchReceiptView"
+      },
+      "type": "array",
+      "title": "Search Sessions"
+    },
+    "exemption_reviews": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Exemption Reviews"
+    },
+    "exemption_decisions": {
+      "items": {
+        "$ref": "#/components/schemas/ExemptionDecisionView"
+      },
+      "type": "array",
+      "title": "Exemption Decisions"
+    },
+    "fee_estimate": {
+      "type": "string",
+      "title": "Fee Estimate"
+    },
+    "fee_line_items": {
+      "items": {
+        "$ref": "#/components/schemas/FeeLineView"
+      },
+      "type": "array",
+      "title": "Fee Line Items"
+    },
+    "fee_waiver_reason": {
+      "type": "string",
+      "title": "Fee Waiver Reason"
+    },
+    "citations": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Citations"
+    },
+    "response_draft": {
+      "type": "string",
+      "title": "Response Draft"
+    },
+    "approval_notes": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Approval Notes"
+    },
+    "exports": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Exports"
+    },
+    "documents": {
+      "items": {
+        "$ref": "#/components/schemas/RecordsDocumentView"
+      },
+      "type": "array",
+      "title": "Documents"
+    },
+    "release_packages": {
+      "items": {
+        "$ref": "#/components/schemas/ReleasePackageView"
+      },
+      "type": "array",
+      "title": "Release Packages"
+    },
+    "timeline": {
+      "items": {
+        "$ref": "#/components/schemas/TimelineView"
+      },
+      "type": "array",
+      "title": "Timeline"
+    },
+    "public_status_events": {
+      "items": {
+        "$ref": "#/components/schemas/PublicStatusView"
+      },
+      "type": "array",
+      "title": "Public Status Events"
+    },
+    "messages": {
+      "items": {
+        "$ref": "#/components/schemas/MessageView"
+      },
+      "type": "array",
+      "title": "Messages"
+    },
+    "deadline_reviewed_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Deadline Reviewed At Unix Seconds"
+    },
+    "approved_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Approved At Unix Seconds"
+    },
+    "fulfilled_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fulfilled At Unix Seconds"
+    },
+    "closed_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closed At Unix Seconds"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "request_id",
+    "id",
+    "public_tracking_number",
+    "requester",
+    "requester_contact",
+    "submitted_via",
+    "summary",
+    "deadline",
+    "deadline_basis",
+    "status",
+    "assigned_to",
+    "clarification_notes",
+    "search_notes",
+    "search_sessions",
+    "exemption_reviews",
+    "exemption_decisions",
+    "fee_estimate",
+    "fee_line_items",
+    "fee_waiver_reason",
+    "citations",
+    "response_draft",
+    "approval_notes",
+    "exports",
+    "timeline",
+    "public_status_events",
+    "messages",
+    "deadline_reviewed_at_unix_seconds",
+    "approved_at_unix_seconds",
+    "fulfilled_at_unix_seconds",
+    "closed_at_unix_seconds",
+    "created_at_unix_seconds"
+  ],
+  "title": "RecordsView"
+}
+
+
ReleasePackageView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "export_path": {
+      "type": "string",
+      "title": "Export Path"
+    },
+    "package_hash": {
+      "type": "string",
+      "title": "Package Hash"
+    },
+    "document_count": {
+      "type": "integer",
+      "title": "Document Count"
+    },
+    "release_artifact_count": {
+      "type": "integer",
+      "title": "Release Artifact Count"
+    },
+    "search_session_count": {
+      "type": "integer",
+      "title": "Search Session Count"
+    },
+    "release_count": {
+      "type": "integer",
+      "title": "Release Count"
+    },
+    "redacted_count": {
+      "type": "integer",
+      "title": "Redacted Count"
+    },
+    "exempt_count": {
+      "type": "integer",
+      "title": "Exempt Count"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "export_path",
+    "package_hash",
+    "document_count",
+    "release_artifact_count",
+    "search_session_count",
+    "release_count",
+    "redacted_count",
+    "exempt_count",
+    "created_at_unix_seconds"
+  ],
+  "title": "ReleasePackageView"
+}
+
+
RepeatLookup
+{
+  "properties": {
+    "property_reference": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Property Reference"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "property_reference"
+  ],
+  "title": "RepeatLookup"
+}
+
+
RequestCreate
+{
+  "properties": {
+    "requester_name": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Requester Name"
+    },
+    "requester_email": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 255
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Email"
+    },
+    "requester_phone": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 50
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Phone"
+    },
+    "requester_type": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 100
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Type"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Description"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "priority": {
+      "type": "string",
+      "title": "Priority",
+      "default": "normal"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^(narrow|moderate|broad)$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "requester_name",
+    "description"
+  ],
+  "title": "RequestCreate"
+}
+
+
RequestDocumentAdd
+{
+  "properties": {
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "relevance_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Relevance Note"
+    }
+  },
+  "type": "object",
+  "required": [
+    "document_id"
+  ],
+  "title": "RequestDocumentAdd"
+}
+
+
RequestDocumentRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "relevance_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Relevance Note"
+    },
+    "exemption_flags": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Exemption Flags"
+    },
+    "inclusion_status": {
+      "$ref": "#/components/schemas/InclusionStatus"
+    },
+    "attached_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Attached At"
+    },
+    "attached_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Attached By"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "document_id",
+    "relevance_note",
+    "exemption_flags",
+    "inclusion_status",
+    "attached_at",
+    "attached_by"
+  ],
+  "title": "RequestDocumentRead"
+}
+
+
RequestRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "requester_name": {
+      "type": "string",
+      "title": "Requester Name"
+    },
+    "requester_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Email"
+    },
+    "requester_phone": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Phone"
+    },
+    "requester_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Type"
+    },
+    "date_received": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Date Received"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "status": {
+      "$ref": "#/components/schemas/RequestStatus"
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "created_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "response_draft": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Response Draft"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    },
+    "estimated_fee": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Estimated Fee"
+    },
+    "fee_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Status"
+    },
+    "fee_waiver_requested": {
+      "type": "boolean",
+      "title": "Fee Waiver Requested",
+      "default": false
+    },
+    "priority": {
+      "type": "string",
+      "title": "Priority",
+      "default": "normal"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    },
+    "closed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closed At"
+    },
+    "closure_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closure Reason"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "requester_name",
+    "requester_email",
+    "date_received",
+    "statutory_deadline",
+    "description",
+    "status",
+    "assigned_to",
+    "created_by",
+    "created_at",
+    "response_draft",
+    "review_notes"
+  ],
+  "title": "RequestRead"
+}
+
+
RequestStats
+{
+  "properties": {
+    "total_requests": {
+      "type": "integer",
+      "title": "Total Requests"
+    },
+    "by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "By Status"
+    },
+    "approaching_deadline": {
+      "type": "integer",
+      "title": "Approaching Deadline"
+    },
+    "overdue": {
+      "type": "integer",
+      "title": "Overdue"
+    }
+  },
+  "type": "object",
+  "required": [
+    "total_requests",
+    "by_status",
+    "approaching_deadline",
+    "overdue"
+  ],
+  "title": "RequestStats"
+}
+
+
RequestStatus
+{
+  "type": "string",
+  "enum": [
+    "received",
+    "clarification_needed",
+    "assigned",
+    "searching",
+    "in_review",
+    "ready_for_release",
+    "drafted",
+    "approved",
+    "fulfilled",
+    "closed"
+  ],
+  "title": "RequestStatus"
+}
+
+
RequestUpdate
+{
+  "properties": {
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/RequestStatus"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "response_draft": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Response Draft"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    }
+  },
+  "type": "object",
+  "title": "RequestUpdate"
+}
+
+
RequirementBundle
+{
+  "properties": {
+    "requirement_id": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9_-]{1,100}$",
+      "title": "Requirement Id"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "project_type": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Project Type"
+    },
+    "source_reference": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Source Reference"
+    },
+    "source_date": {
+      "type": "string",
+      "format": "date",
+      "title": "Source Date"
+    },
+    "effective_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Effective On"
+    },
+    "dataset_kind": {
+      "type": "string",
+      "enum": [
+        "municipal",
+        "fictional"
+      ],
+      "title": "Dataset Kind"
+    },
+    "filename": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$",
+      "title": "Filename"
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 14000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Sha256"
+    },
+    "materials": {
+      "items": {
+        "$ref": "#/components/schemas/Material"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "minItems": 1,
+      "title": "Materials"
+    },
+    "pathway": {
+      "items": {
+        "$ref": "#/components/schemas/PathwayStep"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "title": "Pathway"
+    },
+    "fee_link": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    },
+    "staff_note": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Staff Note",
+      "default": ""
+    },
+    "change_note": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Change Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requirement_id",
+    "title",
+    "jurisdiction",
+    "project_type",
+    "source_reference",
+    "source_date",
+    "effective_on",
+    "dataset_kind",
+    "filename",
+    "content_base64",
+    "sha256",
+    "materials",
+    "change_note"
+  ],
+  "title": "RequirementBundle"
+}
+
+
ResponseLetterCreate
+{
+  "properties": {
+    "template_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Template Id"
+    }
+  },
+  "type": "object",
+  "title": "ResponseLetterCreate"
+}
+
+
ResponseLetterRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "template_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Template Id"
+    },
+    "generated_content": {
+      "type": "string",
+      "title": "Generated Content"
+    },
+    "edited_content": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Edited Content"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "generated_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Generated By"
+    },
+    "approved_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Approved By"
+    },
+    "sent_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sent At"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "template_id",
+    "generated_content",
+    "edited_content",
+    "status",
+    "generated_by",
+    "approved_by",
+    "sent_at",
+    "created_at"
+  ],
+  "title": "ResponseLetterRead"
+}
+
+
ResponseLetterUpdate
+{
+  "properties": {
+    "edited_content": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Edited Content"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Status"
+    }
+  },
+  "type": "object",
+  "title": "ResponseLetterUpdate"
+}
+
+
ReviewInput
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 5000,
+      "title": "Body",
+      "default": ""
+    },
+    "hasAltText": {
+      "type": "boolean",
+      "title": "Hasalttext",
+      "default": false
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": "en"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "ReviewInput"
+}
+
+
Revision
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    },
+    "document": {
+      "$ref": "#/components/schemas/NoticeDraft"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence",
+    "document"
+  ],
+  "title": "Revision"
+}
+
+
RewriteInput
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "plain-language",
+        "language-variant"
+      ],
+      "title": "Action"
+    },
+    "text": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Text"
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "text"
+  ],
+  "title": "RewriteInput"
+}
+
+
RewriteResult
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "plain-language",
+        "language-variant"
+      ],
+      "title": "Action"
+    },
+    "text": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Text"
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": ""
+    },
+    "outcome": {
+      "type": "string",
+      "enum": [
+        "generated",
+        "unavailable"
+      ],
+      "title": "Outcome"
+    },
+    "generated": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 100000
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Generated"
+    },
+    "model": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 200
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "text",
+    "outcome"
+  ],
+  "title": "RewriteResult"
+}
+
+
Rule
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "zone_code": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Zone Code"
+    },
+    "key": {
+      "type": "string",
+      "maxLength": 120,
+      "minLength": 1,
+      "title": "Key"
+    },
+    "section_number": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Section Number"
+    },
+    "kind": {
+      "type": "string",
+      "enum": [
+        "use",
+        "dimension"
+      ],
+      "title": "Kind"
+    },
+    "value": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Value"
+    },
+    "overlay_code": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 255
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Overlay Code"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "zone_code",
+    "key",
+    "section_number",
+    "kind",
+    "value"
+  ],
+  "title": "Rule"
+}
+
+
RuleTestMatch
+{
+  "properties": {
+    "matched_text": {
+      "type": "string",
+      "title": "Matched Text"
+    },
+    "start": {
+      "type": "integer",
+      "title": "Start"
+    },
+    "end": {
+      "type": "integer",
+      "title": "End"
+    }
+  },
+  "type": "object",
+  "required": [
+    "matched_text",
+    "start",
+    "end"
+  ],
+  "title": "RuleTestMatch"
+}
+
+
RuleTestRequest
+{
+  "properties": {
+    "sample_text": {
+      "type": "string",
+      "title": "Sample Text"
+    }
+  },
+  "type": "object",
+  "required": [
+    "sample_text"
+  ],
+  "title": "RuleTestRequest"
+}
+
+
RuleTestResponse
+{
+  "properties": {
+    "rule_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Rule Id"
+    },
+    "rule_type": {
+      "type": "string",
+      "title": "Rule Type"
+    },
+    "matched": {
+      "type": "boolean",
+      "title": "Matched"
+    },
+    "matches": {
+      "items": {
+        "$ref": "#/components/schemas/RuleTestMatch"
+      },
+      "type": "array",
+      "title": "Matches"
+    }
+  },
+  "type": "object",
+  "required": [
+    "rule_id",
+    "rule_type",
+    "matched",
+    "matches"
+  ],
+  "title": "RuleTestResponse"
+}
+
+
RuleType
+{
+  "type": "string",
+  "enum": [
+    "regex",
+    "keyword",
+    "llm_prompt"
+  ],
+  "title": "RuleType"
+}
+
+
SaveReview
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 5000,
+      "title": "Body",
+      "default": ""
+    },
+    "hasAltText": {
+      "type": "boolean",
+      "title": "Hasalttext",
+      "default": false
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": "en"
+    },
+    "ai_analysis": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 100000
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ai Analysis"
+    },
+    "ai_analysis_model": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 200
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ai Analysis Model"
+    },
+    "ai_outcome": {
+      "type": "string",
+      "enum": [
+        "generated",
+        "unavailable",
+        "failed"
+      ],
+      "title": "Ai Outcome"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "ai_outcome"
+  ],
+  "title": "SaveReview"
+}
+
+
SearchFilterOptions
+{
+  "properties": {
+    "file_types": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "File Types"
+    },
+    "source_names": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Source Names"
+    },
+    "departments": {
+      "items": {
+        "additionalProperties": true,
+        "type": "object"
+      },
+      "type": "array",
+      "title": "Departments",
+      "default": []
+    },
+    "date_range": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Date Range"
+    }
+  },
+  "type": "object",
+  "required": [
+    "file_types",
+    "source_names"
+  ],
+  "title": "SearchFilterOptions"
+}
+
+
SearchInput
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "SearchInput"
+}
+
+
SearchNoteCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "record-records-search",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/SearchNotePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "SearchNoteCommand"
+}
+
+
SearchNotePayload
+{
+  "properties": {
+    "sourceNote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Sourcenote"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sourceNote"
+  ],
+  "title": "SearchNotePayload"
+}
+
+
SearchReceiptCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "record-records-search-session",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/SearchReceiptPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "SearchReceiptCommand"
+}
+
+
SearchReceiptPayload
+{
+  "properties": {
+    "searchQuery": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchquery"
+    },
+    "searchLocations": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchlocations"
+    },
+    "searchResultTitle": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchresulttitle"
+    },
+    "searchResultCitation": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchresultcitation"
+    },
+    "searchResultSummary": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchresultsummary"
+    },
+    "searchResultStatus": {
+      "type": "string",
+      "title": "Searchresultstatus",
+      "default": ""
+    },
+    "searchReviewer": {
+      "type": "string",
+      "title": "Searchreviewer",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "searchQuery",
+    "searchLocations",
+    "searchResultTitle",
+    "searchResultCitation",
+    "searchResultSummary"
+  ],
+  "title": "SearchReceiptPayload"
+}
+
+
SearchReceiptView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "query": {
+      "type": "string",
+      "title": "Query"
+    },
+    "locations": {
+      "type": "string",
+      "title": "Locations"
+    },
+    "reviewer": {
+      "type": "string",
+      "title": "Reviewer"
+    },
+    "results": {
+      "items": {
+        "$ref": "#/components/schemas/SearchResultView"
+      },
+      "type": "array",
+      "title": "Results"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "query",
+    "locations",
+    "reviewer",
+    "results",
+    "created_at_unix_seconds"
+  ],
+  "title": "SearchReceiptView"
+}
+
+
SearchRequest
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "title": "Query"
+    },
+    "session_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Session Id"
+    },
+    "filters": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Filters"
+    },
+    "limit": {
+      "type": "integer",
+      "maximum": 50.0,
+      "title": "Limit",
+      "default": 10
+    },
+    "synthesize": {
+      "type": "boolean",
+      "title": "Synthesize",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "SearchRequest"
+}
+
+
SearchResponse
+{
+  "properties": {
+    "query_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Query Id"
+    },
+    "session_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Session Id"
+    },
+    "query_text": {
+      "type": "string",
+      "title": "Query Text"
+    },
+    "results": {
+      "items": {
+        "$ref": "#/components/schemas/SearchResultItem"
+      },
+      "type": "array",
+      "title": "Results"
+    },
+    "results_count": {
+      "type": "integer",
+      "title": "Results Count"
+    },
+    "synthesized_answer": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Synthesized Answer"
+    },
+    "ai_generated": {
+      "type": "boolean",
+      "title": "Ai Generated",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "query_id",
+    "session_id",
+    "query_text",
+    "results",
+    "results_count"
+  ],
+  "title": "SearchResponse"
+}
+
+
SearchResultItem
+{
+  "properties": {
+    "chunk_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Chunk Id"
+    },
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "filename": {
+      "type": "string",
+      "title": "Filename"
+    },
+    "file_type": {
+      "type": "string",
+      "title": "File Type"
+    },
+    "source_path": {
+      "type": "string",
+      "title": "Source Path"
+    },
+    "page_number": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Page Number"
+    },
+    "content_text": {
+      "type": "string",
+      "title": "Content Text"
+    },
+    "similarity_score": {
+      "type": "number",
+      "title": "Similarity Score"
+    },
+    "rank": {
+      "type": "integer",
+      "title": "Rank"
+    }
+  },
+  "type": "object",
+  "required": [
+    "chunk_id",
+    "document_id",
+    "filename",
+    "file_type",
+    "source_path",
+    "page_number",
+    "content_text",
+    "similarity_score",
+    "rank"
+  ],
+  "title": "SearchResultItem"
+}
+
+
SearchResultView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "title": {
+      "type": "string",
+      "title": "Title"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "title",
+    "citation",
+    "summary",
+    "status"
+  ],
+  "title": "SearchResultView"
+}
+
+
SearchSessionRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "user_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "User Id"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "queries": {
+      "items": {
+        "additionalProperties": true,
+        "type": "object"
+      },
+      "type": "array",
+      "title": "Queries",
+      "default": []
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "user_id",
+    "created_at"
+  ],
+  "title": "SearchSessionRead"
+}
+
+
SectionCreate
+{
+  "properties": {
+    "section_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Section Id"
+    },
+    "chapter_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Chapter Id"
+    },
+    "section_number": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Number"
+    },
+    "section_heading": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Heading"
+    },
+    "parent_section_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parent Section Id"
+    },
+    "sort_order": {
+      "type": "integer",
+      "title": "Sort Order",
+      "default": 0
+    },
+    "administrative_regulation_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Administrative Regulation Refs"
+    },
+    "resolution_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Resolution Refs"
+    },
+    "policy_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Policy Refs"
+    },
+    "approved_summary_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Approved Summary Refs"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "chapter_id",
+    "section_number",
+    "section_heading"
+  ],
+  "title": "SectionCreate",
+  "description": "Request body for creating a code section or subsection."
+}
+
+
SectionVersionCreate
+{
+  "properties": {
+    "version_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Version Id"
+    },
+    "section_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Id"
+    },
+    "source_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "version_label": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Version Label"
+    },
+    "body": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Body"
+    },
+    "effective_start": {
+      "type": "string",
+      "format": "date",
+      "title": "Effective Start"
+    },
+    "effective_end": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective End"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    },
+    "is_current": {
+      "type": "boolean",
+      "title": "Is Current",
+      "default": false
+    },
+    "adoption_event_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Adoption Event Id"
+    },
+    "amendment_event_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Amendment Event Id"
+    },
+    "amendment_summary": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Amendment Summary"
+    },
+    "prior_version_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Prior Version Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "section_id",
+    "source_id",
+    "version_label",
+    "body",
+    "effective_start"
+  ],
+  "title": "SectionVersionCreate",
+  "description": "Request body for adding an immutable section version."
+}
+
+
Selection
+{
+  "properties": {
+    "recording_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Recording Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "recording_id",
+    "expected_sha256"
+  ],
+  "title": "Selection"
+}
+
+
SentenceInput
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "citations": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Citations"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text"
+  ],
+  "title": "SentenceInput"
+}
+
+
ServiceAccountCreate
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole",
+      "default": "read_only"
+    }
+  },
+  "type": "object",
+  "required": [
+    "name"
+  ],
+  "title": "ServiceAccountCreate"
+}
+
+
ServiceAccountCreated
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "api_key": {
+      "type": "string",
+      "title": "Api Key"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "role",
+    "created_by",
+    "created_at",
+    "is_active",
+    "api_key"
+  ],
+  "title": "ServiceAccountCreated",
+  "description": "Returned only on creation — includes the plaintext API key (shown once)."
+}
+
+
ServiceAccountRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "role",
+    "created_by",
+    "created_at",
+    "is_active"
+  ],
+  "title": "ServiceAccountRead"
+}
+
+
ServiceAccountUpdate
+{
+  "properties": {
+    "role": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/UserRole"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "ServiceAccountUpdate"
+}
+
+
Snapshot
+{
+  "properties": {
+    "expected_revision": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Expected Revision"
+    },
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "staff_only",
+        "public"
+      ],
+      "title": "Visibility"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "expected_revision",
+    "visibility"
+  ],
+  "title": "Snapshot"
+}
+
+
SourceCreate
+{
+  "properties": {
+    "source_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Id"
+    },
+    "name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Name"
+    },
+    "publisher": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Publisher"
+    },
+    "source_type": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Type"
+    },
+    "source_category": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Category"
+    },
+    "source_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Url"
+    },
+    "file_reference": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "File Reference"
+    },
+    "retrieved_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Retrieved At"
+    },
+    "retrieval_method": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Retrieval Method"
+    },
+    "checksum": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Checksum"
+    },
+    "source_owner": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Owner"
+    },
+    "is_official": {
+      "type": "boolean",
+      "title": "Is Official",
+      "default": true
+    },
+    "official_status_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Official Status Note"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    },
+    "staff_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Staff Notes"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "name",
+    "publisher",
+    "source_type",
+    "source_category"
+  ],
+  "title": "SourceCreate",
+  "description": "Request body for registering an official or explicitly labeled source."
+}
+
+
SourceInput
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "label": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Label"
+    },
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "label",
+    "text"
+  ],
+  "title": "SourceInput"
+}
+
+
SourceSnapshot
+{
+  "properties": {
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "public",
+        "staff_only"
+      ],
+      "title": "Visibility"
+    },
+    "meeting_event_ids": {
+      "items": {
+        "type": "string",
+        "format": "uuid"
+      },
+      "type": "array",
+      "maxItems": 50,
+      "title": "Meeting Event Ids"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "visibility"
+  ],
+  "title": "SourceSnapshot"
+}
+
+
SourceType
+{
+  "type": "string",
+  "enum": [
+    "manual_drop",
+    "file_system",
+    "rest_api",
+    "odbc"
+  ],
+  "title": "SourceType"
+}
+
+
StaffRecordsIntake
+{
+  "properties": {
+    "requester": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requester"
+    },
+    "summary": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Summary"
+    },
+    "deadline": {
+      "type": "string",
+      "title": "Deadline"
+    },
+    "deadlineBasis": {
+      "type": "string",
+      "title": "Deadlinebasis",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requester",
+    "summary",
+    "deadline"
+  ],
+  "title": "StaffRecordsIntake",
+  "description": "Existing native create-records-request input; no caller-supplied actor."
+}
+
+
StandardsExplanation
+{
+  "properties": {
+    "question": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Question"
+    },
+    "process_section": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Process Section",
+      "default": ""
+    },
+    "zone_code": {
+      "type": "string",
+      "maxLength": 40,
+      "title": "Zone Code",
+      "default": ""
+    },
+    "rule_types": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "title": "Rule Types"
+    },
+    "observed": {
+      "additionalProperties": {
+        "type": "string"
+      },
+      "type": "object",
+      "title": "Observed"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "question"
+  ],
+  "title": "StandardsExplanation"
+}
+
+
SyncFailureRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "source_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Source Id"
+    },
+    "source_path": {
+      "type": "string",
+      "title": "Source Path"
+    },
+    "error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Message"
+    },
+    "error_class": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Class"
+    },
+    "http_status_code": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Http Status Code"
+    },
+    "retry_count": {
+      "type": "integer",
+      "title": "Retry Count"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "first_failed_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "First Failed At"
+    },
+    "last_retried_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Retried At"
+    },
+    "dismissed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Dismissed At"
+    },
+    "dismissed_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Dismissed By"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "source_id",
+    "source_path",
+    "error_message",
+    "error_class",
+    "http_status_code",
+    "retry_count",
+    "status",
+    "first_failed_at",
+    "last_retried_at",
+    "dismissed_at",
+    "dismissed_by"
+  ],
+  "title": "SyncFailureRead"
+}
+
+
SyncRunLogRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "source_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Source Id"
+    },
+    "started_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Started At"
+    },
+    "finished_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Finished At"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Status"
+    },
+    "records_attempted": {
+      "type": "integer",
+      "title": "Records Attempted"
+    },
+    "records_succeeded": {
+      "type": "integer",
+      "title": "Records Succeeded"
+    },
+    "records_failed": {
+      "type": "integer",
+      "title": "Records Failed"
+    },
+    "error_summary": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Summary"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "source_id",
+    "started_at",
+    "finished_at",
+    "status",
+    "records_attempted",
+    "records_succeeded",
+    "records_failed",
+    "error_summary"
+  ],
+  "title": "SyncRunLogRead"
+}
+
+
SystemStatus
+{
+  "properties": {
+    "version": {
+      "type": "string",
+      "title": "Version"
+    },
+    "database": {
+      "type": "string",
+      "title": "Database"
+    },
+    "ollama": {
+      "type": "string",
+      "title": "Ollama"
+    },
+    "redis": {
+      "type": "string",
+      "title": "Redis"
+    },
+    "user_count": {
+      "type": "integer",
+      "title": "User Count"
+    },
+    "audit_log_count": {
+      "type": "integer",
+      "title": "Audit Log Count"
+    },
+    "suite_session": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Suite Session"
+    }
+  },
+  "type": "object",
+  "required": [
+    "version",
+    "database",
+    "ollama",
+    "redis",
+    "user_count",
+    "audit_log_count"
+  ],
+  "title": "SystemStatus"
+}
+
+
TaggedPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "tagged-pdf",
+      "title": "Action"
+    },
+    "headingLevels": {
+      "items": {
+        "type": "integer",
+        "maximum": 4294967295.0,
+        "minimum": 0.0
+      },
+      "type": "array",
+      "maxItems": 50,
+      "title": "Headinglevels"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "TaggedPlan"
+}
+
+
TestConnectionRequest
+{
+  "properties": {
+    "source_type": {
+      "type": "string",
+      "title": "Source Type"
+    },
+    "host": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Host"
+    },
+    "port": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Port"
+    },
+    "path": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Path"
+    },
+    "username": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Username"
+    },
+    "password": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Password"
+    },
+    "rest_api_config": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Rest Api Config"
+    },
+    "odbc_config": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Odbc Config"
+    }
+  },
+  "type": "object",
+  "required": [
+    "source_type"
+  ],
+  "title": "TestConnectionRequest",
+  "description": "Dedicated schema for test-connection. NOT the create schema.\n\nSecurity: credentials in this request body are never persisted, never\nwritten to audit logs, and never returned in the response."
+}
+
+
TestConnectionResponse
+{
+  "properties": {
+    "success": {
+      "type": "boolean",
+      "title": "Success"
+    },
+    "message": {
+      "type": "string",
+      "title": "Message"
+    },
+    "latency_ms": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Latency Ms"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Status"
+    },
+    "warning": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Warning"
+    },
+    "differing_keys": {
+      "anyOf": [
+        {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Differing Keys"
+    }
+  },
+  "type": "object",
+  "required": [
+    "success",
+    "message"
+  ],
+  "title": "TestConnectionResponse"
+}
+
+
TimelineEventCreate
+{
+  "properties": {
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "internal_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Internal Note"
+    }
+  },
+  "type": "object",
+  "required": [
+    "event_type",
+    "description"
+  ],
+  "title": "TimelineEventCreate"
+}
+
+
TimelineEventRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "actor_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Actor Id"
+    },
+    "actor_role": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Actor Role"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "internal_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Internal Note"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "event_type",
+    "actor_id",
+    "actor_role",
+    "description",
+    "internal_note",
+    "created_at"
+  ],
+  "title": "TimelineEventRead"
+}
+
+
TimelineView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "actor": {
+      "type": "string",
+      "title": "Actor"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "action",
+    "actor",
+    "note",
+    "created_at_unix_seconds"
+  ],
+  "title": "TimelineView"
+}
+
+
TitleCreate
+{
+  "properties": {
+    "title_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Title Id"
+    },
+    "title_number": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title Number"
+    },
+    "title_name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title Name"
+    },
+    "sort_order": {
+      "type": "integer",
+      "title": "Sort Order",
+      "default": 0
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title_number",
+    "title_name"
+  ],
+  "title": "TitleCreate",
+  "description": "Request body for creating a code title."
+}
+
+
TranscriptInput
+{
+  "properties": {
+    "source_label": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Label"
+    },
+    "transcript_text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Transcript Text"
+    },
+    "correction_of_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Correction Of Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_label",
+    "transcript_text"
+  ],
+  "title": "TranscriptInput"
+}
+
+
UserRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "email": {
+      "type": "string",
+      "format": "email",
+      "title": "Email"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active",
+      "default": true
+    },
+    "is_superuser": {
+      "type": "boolean",
+      "title": "Is Superuser",
+      "default": false
+    },
+    "is_verified": {
+      "type": "boolean",
+      "title": "Is Verified",
+      "default": false
+    },
+    "full_name": {
+      "type": "string",
+      "title": "Full Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "last_login": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Login"
+    },
+    "must_change_password": {
+      "type": "boolean",
+      "title": "Must Change Password",
+      "default": false
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "email",
+    "full_name",
+    "role",
+    "created_at",
+    "last_login"
+  ],
+  "title": "UserRead"
+}
+
+
UserRole
+{
+  "type": "string",
+  "enum": [
+    "admin",
+    "staff",
+    "reviewer",
+    "read_only",
+    "liaison",
+    "public"
+  ],
+  "title": "UserRole"
+}
+
+
UserSelfUpdate
+{
+  "properties": {
+    "password": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Password"
+    },
+    "email": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "email"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    },
+    "is_superuser": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Superuser"
+    },
+    "is_verified": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Verified"
+    },
+    "full_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Full Name"
+    }
+  },
+  "type": "object",
+  "title": "UserSelfUpdate",
+  "description": "Schema for user self-update via PATCH /users/me.\n\nExcludes role and department_id. Any payload containing those fields is\nrejected at parse time (HTTP 422). Role and department changes require\nadmin privileges via /admin/users/{id}."
+}
+
+
UserUpdateRequest
+{
+  "properties": {
+    "full_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Full Name"
+    },
+    "role": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Role"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "UserUpdateRequest"
+}
+
+
ValidationError
+{
+  "properties": {
+    "loc": {
+      "items": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "integer"
+          }
+        ]
+      },
+      "type": "array",
+      "title": "Location"
+    },
+    "msg": {
+      "type": "string",
+      "title": "Message"
+    },
+    "type": {
+      "type": "string",
+      "title": "Error Type"
+    },
+    "input": {
+      "title": "Input"
+    },
+    "ctx": {
+      "type": "object",
+      "title": "Context"
+    }
+  },
+  "type": "object",
+  "required": [
+    "loc",
+    "msg",
+    "type"
+  ],
+  "title": "ValidationError"
+}
+
+
Version
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence"
+  ],
+  "title": "Version"
+}
+
+
VoteCorrection
+{
+  "properties": {
+    "vote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Vote"
+    },
+    "reason": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Reason"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "vote",
+    "reason"
+  ],
+  "title": "VoteCorrection"
+}
+
+
VoteInput
+{
+  "properties": {
+    "voter_name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Voter Name"
+    },
+    "vote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Vote"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "voter_name",
+    "vote"
+  ],
+  "title": "VoteInput"
+}
+
+
_ParcelLookupIn
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "query"
+  ],
+  "title": "_ParcelLookupIn"
+}
+
+
townlight_inspections__workflow_models__SourceLink
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "const": "code",
+      "title": "Provider",
+      "default": "code"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "SourceLink"
+}
+
+
townlight_permitting__workflow_models__SourceLink
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "enum": [
+        "code",
+        "zoning"
+      ],
+      "title": "Provider"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "SourceLink"
+}
+
+
townlight_runtime__inspections_bridge__Search
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "const": "code",
+      "title": "Provider"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "query"
+  ],
+  "title": "Search"
+}
+
+
townlight_runtime__notice_bridge__Review
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence",
+    "note"
+  ],
+  "title": "Review"
+}
+
+
townlight_runtime__permitting_bridge__Import
+{
+  "properties": {
+    "bundle": {
+      "$ref": "#/components/schemas/RequirementBundle"
+    },
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "bundle"
+  ],
+  "title": "Import"
+}
+
+
townlight_runtime__permitting_bridge__Search
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "enum": [
+        "code",
+        "zoning"
+      ],
+      "title": "Provider"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "query"
+  ],
+  "title": "Search"
+}
+
+
townlight_runtime__planning_bridge__Import
+{
+  "properties": {
+    "bundle": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Bundle"
+    },
+    "expected_previous_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Previous Revision"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "bundle"
+  ],
+  "title": "Import"
+}
+
+
townlight_runtime__planning_bridge__Search
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Query"
+    },
+    "plan_type": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 40
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Plan Type"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "Search"
+}
+
+
townlight_runtime__zoning_bridge__Review
+{
+  "properties": {
+    "answer": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Answer",
+      "default": ""
+    },
+    "notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Notes",
+      "default": ""
+    },
+    "queue_status": {
+      "type": "string",
+      "enum": [
+        "open",
+        "in_review",
+        "resolved",
+        "closed"
+      ],
+      "title": "Queue Status",
+      "default": "resolved"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "Review"
+}
+
Townlight · AGPL-3.0-only · Source schema evidence only
\ No newline at end of file diff --git a/docs/beta-1/api/core-openapi.json b/docs/beta-1/api/core-openapi.json index ef9aa54..bc8362e 100644 --- a/docs/beta-1/api/core-openapi.json +++ b/docs/beta-1/api/core-openapi.json @@ -2,8 +2,8 @@ "openapi": "3.1.0", "info": { "title": "Townlight Records", - "description": "Townlight Beta 1 documentation view of the installed desktop domain schema. Component API version is unchanged. Exported without lifespan or database access; schema generation is not endpoint acceptance.", - "version": "1.8.0.dev1" + "description": "Prepared source schema for the actual native composition; installed acceptance remains pending. Exported without lifespan, migrations or database/network access.", + "version": "1.8.0.dev2" }, "paths": { "/config/portal-mode": { @@ -513,8 +513,8 @@ }, "/health": { "get": { - "summary": "Runtime Health", - "operationId": "runtime_health_health_get", + "summary": "Health", + "operationId": "health_health_get", "responses": { "200": { "description": "Successful Response", @@ -1166,76 +1166,10047 @@ } } } - }, - "/modules": { - "get": { - "summary": "Runtime Health", - "operationId": "runtime_health_modules_get", - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": {} + } + }, + "components": { + "schemas": { + "ActionItemInput": { + "properties": { + "description": { + "type": "string", + "minLength": 1, + "title": "Description" + }, + "assigned_to": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "source_motion_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Source Motion Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "description" + ], + "title": "ActionItemInput" + }, + "AdaPlan": { + "properties": { + "action": { + "type": "string", + "const": "ada-title-ii", + "title": "Action" + }, + "serviceArea": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Servicearea" + }, + "hasCoordinatorReview": { + "type": "boolean", + "title": "Hascoordinatorreview", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "serviceArea" + ], + "title": "AdaPlan" + }, + "AdminUserCreateRequest": { + "properties": { + "email": { + "type": "string", + "title": "Email" + }, + "password": { + "type": "string", + "title": "Password" + }, + "full_name": { + "type": "string", + "title": "Full Name", + "default": "" + }, + "role": { + "type": "string", + "title": "Role", + "default": "staff" + } + }, + "type": "object", + "required": [ + "email", + "password" + ], + "title": "AdminUserCreateRequest" + }, + "AdminUserCreateResponse": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "email": { + "type": "string", + "title": "Email" + }, + "full_name": { + "type": "string", + "title": "Full Name" + }, + "role": { + "type": "string", + "title": "Role" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + } + }, + "type": "object", + "required": [ + "id", + "email", + "full_name", + "role", + "is_active" + ], + "title": "AdminUserCreateResponse" + }, + "AgendaAssignment": { + "properties": { + "meeting_id": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "meeting_id" + ], + "title": "AgendaAssignment" + }, + "AgendaInput": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "department_name": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Department Name" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "department_name" + ], + "title": "AgendaInput" + }, + "AgendaReviewInput": { + "properties": { + "to_status": { + "type": "string", + "enum": [ + "DRAFTED", + "SUBMITTED", + "DEPT_APPROVED", + "LEGAL_REVIEWED", + "CLERK_ACCEPTED", + "ON_AGENDA", + "IN_PACKET", + "POSTED", + "HEARD", + "DISPOSED", + "ARCHIVED" + ], + "title": "To Status" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "to_status" + ], + "title": "AgendaReviewInput" + }, + "AmendmentInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "policy": { + "$ref": "#/components/schemas/PolicySelection" + }, + "proposal": { + "type": "string", + "maxLength": 20000, + "minLength": 1, + "title": "Proposal" + }, + "responsible_staff": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Responsible Staff" + }, + "status": { + "type": "string", + "enum": [ + "draft", + "review", + "adopted", + "withdrawn" + ], + "title": "Status", + "default": "draft" + }, + "review_note": { + "type": "string", + "maxLength": 5000, + "title": "Review Note", + "default": "" + }, + "adoption_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Adoption Revision" + }, + "note": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "policy", + "proposal", + "responsible_staff", + "note" + ], + "title": "AmendmentInput" + }, + "AnalysisObservation": { + "properties": { + "source": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "title": "Source" + }, + "filename": { + "type": "string", + "maxLength": 160, + "title": "Filename", + "default": "" + }, + "media_type": { + "type": "string", + "maxLength": 80, + "title": "Media Type", + "default": "" + }, + "text": { + "type": "string", + "maxLength": 4000, + "minLength": 1, + "title": "Text" + }, + "adapter": { + "type": "string", + "maxLength": 120, + "title": "Adapter", + "default": "" + }, + "citation_source_ids": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 30, + "title": "Citation Source Ids" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source", + "text" + ], + "title": "AnalysisObservation", + "description": "One draft observation, named with the adapter that actually produced it." + }, + "AnalysisRecord": { + "properties": { + "observations": { + "items": { + "$ref": "#/components/schemas/AnalysisObservation" + }, + "type": "array", + "maxItems": 30, + "title": "Observations" + }, + "cited_sections": { + "items": { + "$ref": "#/components/schemas/CitedSection" + }, + "type": "array", + "maxItems": 30, + "title": "Cited Sections" + }, + "unavailable": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 30, + "title": "Unavailable" + }, + "runtime": { + "additionalProperties": true, + "type": "object", + "title": "Runtime" + }, + "review_required": { + "type": "boolean", + "title": "Review Required", + "default": true + } + }, + "additionalProperties": false, + "type": "object", + "title": "AnalysisRecord", + "description": "The adapter output that accompanies a saved inspection draft." + }, + "ApprovalCommand": { + "properties": { + "action": { + "type": "string", + "const": "approve-records-response", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ApprovalPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "ApprovalCommand" + }, + "ApprovalPayload": { + "properties": { + "approvalNote": { + "type": "string", + "title": "Approvalnote", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "title": "ApprovalPayload" + }, + "ArchiveInput": { + "properties": { + "visibility": { + "type": "string", + "enum": [ + "public", + "closed_session" + ], + "title": "Visibility" + }, + "packet_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Packet Id" + }, + "minutes_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Minutes Id" + }, + "plain_language_summary": { + "type": "string", + "title": "Plain Language Summary", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "visibility" + ], + "title": "ArchiveInput" + }, + "ArtifactPlan": { + "properties": { + "artifact_id": { + "type": "string", + "title": "Artifact Id" + }, + "file_name": { + "type": "string", + "title": "File Name" + }, + "content": { + "type": "string", + "title": "Content" + }, + "sha256": { + "type": "string", + "title": "Sha256" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "artifact_id", + "file_name", + "content", + "sha256", + "created_at_unix_seconds" + ], + "title": "ArtifactPlan" + }, + "AssignCommand": { + "properties": { + "action": { + "type": "string", + "const": "assign-records-request", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/AssignmentPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "AssignCommand" + }, + "AssignmentPayload": { + "properties": { + "assignedTo": { + "type": "string", + "minLength": 1, + "title": "Assignedto" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "assignedTo" + ], + "title": "AssignmentPayload" + }, + "AttachDocument": { + "properties": { + "title": { + "type": "string", + "minLength": 1, + "title": "Title" + }, + "citation": { + "type": "string", + "title": "Citation", + "default": "" + }, + "file": { + "$ref": "#/components/schemas/ManagedFileReceipt" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "file" + ], + "title": "AttachDocument" + }, + "AttachReleaseCopy": { + "properties": { + "status": { + "type": "string", + "enum": [ + "release-ready copy", + "redacted copy" + ], + "title": "Status" + }, + "note": { + "type": "string", + "title": "Note", + "default": "" + }, + "added_by": { + "type": "string", + "title": "Added By", + "default": "" + }, + "file": { + "$ref": "#/components/schemas/ManagedFileReceipt" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "status", + "file" + ], + "title": "AttachReleaseCopy" + }, + "AuditChainVerification": { + "properties": { + "is_valid": { + "type": "boolean", + "title": "Is Valid" + }, + "entries_checked": { + "type": "integer", + "title": "Entries Checked" + }, + "error_message": { + "type": "string", + "title": "Error Message" + } + }, + "type": "object", + "required": [ + "is_valid", + "entries_checked", + "error_message" + ], + "title": "AuditChainVerification" + }, + "AuditLogRead": { + "properties": { + "id": { + "type": "integer", + "title": "Id" + }, + "prev_hash": { + "type": "string", + "title": "Prev Hash" + }, + "entry_hash": { + "type": "string", + "title": "Entry Hash" + }, + "timestamp": { + "type": "string", + "format": "date-time", + "title": "Timestamp" + }, + "user_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "User Id" + }, + "action": { + "type": "string", + "title": "Action" + }, + "resource_type": { + "type": "string", + "title": "Resource Type" + }, + "resource_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Resource Id" + }, + "details": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Details" + }, + "ai_generated": { + "type": "boolean", + "title": "Ai Generated" + } + }, + "type": "object", + "required": [ + "id", + "prev_hash", + "entry_hash", + "timestamp", + "user_id", + "action", + "resource_type", + "resource_id", + "details", + "ai_generated" + ], + "title": "AuditLogRead" + }, + "AuditView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "module_id": { + "type": "string", + "title": "Module Id" + }, + "action": { + "type": "string", + "title": "Action" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + }, + "previous_hash": { + "type": "string", + "title": "Previous Hash" + }, + "entry_hash": { + "type": "string", + "title": "Entry Hash" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "module_id", + "action", + "summary", + "created_at_unix_seconds", + "previous_hash", + "entry_hash" + ], + "title": "AuditView" + }, + "BearerResponse": { + "properties": { + "access_token": { + "type": "string", + "title": "Access Token" + }, + "token_type": { + "type": "string", + "title": "Token Type" + } + }, + "type": "object", + "required": [ + "access_token", + "token_type" + ], + "title": "BearerResponse" + }, + "Body_auth_jwt_login_auth_jwt_login_post": { + "properties": { + "grant_type": { + "anyOf": [ + { + "type": "string", + "pattern": "^password$" + }, + { + "type": "null" + } + ], + "title": "Grant Type" + }, + "username": { + "type": "string", + "title": "Username" + }, + "password": { + "type": "string", + "format": "password", + "title": "Password" + }, + "scope": { + "type": "string", + "title": "Scope", + "default": "" + }, + "client_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Client Id" + }, + "client_secret": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "format": "password", + "title": "Client Secret" + } + }, + "type": "object", + "required": [ + "username", + "password" + ], + "title": "Body_auth_jwt_login_auth_jwt_login_post" + }, + "Body_upload_file_datasources_upload_post": { + "properties": { + "file": { + "type": "string", + "contentMediaType": "application/octet-stream", + "title": "File" + } + }, + "type": "object", + "required": [ + "file" + ], + "title": "Body_upload_file_datasources_upload_post" + }, + "CalculateDeadlineCommand": { + "properties": { + "action": { + "type": "string", + "const": "calculate-records-deadline", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/CalculateDeadlinePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "CalculateDeadlineCommand" + }, + "CalculateDeadlinePayload": { + "properties": { + "deadlineReceivedDate": { + "type": "string", + "title": "Deadlinereceiveddate" + }, + "deadlineRuleName": { + "type": "string", + "minLength": 1, + "title": "Deadlinerulename" + }, + "deadlineDayCount": { + "type": "string", + "title": "Deadlinedaycount" + }, + "deadlineDayType": { + "type": "string", + "title": "Deadlinedaytype" + }, + "deadlineBasis": { + "type": "string", + "minLength": 1, + "title": "Deadlinebasis" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "deadlineReceivedDate", + "deadlineRuleName", + "deadlineDayCount", + "deadlineDayType", + "deadlineBasis" + ], + "title": "CalculateDeadlinePayload" + }, + "ChapterCreate": { + "properties": { + "chapter_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Chapter Id" + }, + "title_id": { + "type": "string", + "minLength": 1, + "title": "Title Id" + }, + "chapter_number": { + "type": "string", + "minLength": 1, + "title": "Chapter Number" + }, + "chapter_name": { + "type": "string", + "minLength": 1, + "title": "Chapter Name" + }, + "sort_order": { + "type": "integer", + "title": "Sort Order", + "default": 0 + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title_id", + "chapter_number", + "chapter_name" + ], + "title": "ChapterCreate", + "description": "Request body for creating a code chapter." + }, + "CitedSection": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "citation": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Citation" + }, + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "version": { + "type": "string", + "maxLength": 80, + "title": "Version", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "citation" + ], + "title": "CitedSection", + "description": "One resolved public Code section; never a caller-supplied quotation." + }, + "CityProfileCreate": { + "properties": { + "city_name": { + "type": "string", + "title": "City Name" + }, + "state": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State" + }, + "county": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "County" + }, + "population_band": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Population Band" + }, + "email_platform": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Email Platform" + }, + "has_dedicated_it": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Has Dedicated It" + }, + "monthly_request_volume": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Monthly Request Volume" + }, + "profile_data": { + "additionalProperties": true, + "type": "object", + "title": "Profile Data", + "default": {} + }, + "gap_map": { + "additionalProperties": true, + "type": "object", + "title": "Gap Map", + "default": {} + } + }, + "type": "object", + "required": [ + "city_name" + ], + "title": "CityProfileCreate" + }, + "CityProfileRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "city_name": { + "type": "string", + "title": "City Name" + }, + "state": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State" + }, + "county": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "County" + }, + "population_band": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Population Band" + }, + "email_platform": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Email Platform" + }, + "has_dedicated_it": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Has Dedicated It" + }, + "monthly_request_volume": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Monthly Request Volume" + }, + "onboarding_status": { + "type": "string", + "title": "Onboarding Status" + }, + "profile_data": { + "additionalProperties": true, + "type": "object", + "title": "Profile Data" + }, + "gap_map": { + "additionalProperties": true, + "type": "object", + "title": "Gap Map" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "city_name", + "state", + "county", + "population_band", + "email_platform", + "has_dedicated_it", + "monthly_request_volume", + "onboarding_status", + "profile_data", + "gap_map", + "created_at", + "updated_at" + ], + "title": "CityProfileRead" + }, + "CityProfileUpdate": { + "properties": { + "city_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "City Name" + }, + "state": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State" + }, + "county": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "County" + }, + "population_band": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Population Band" + }, + "email_platform": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Email Platform" + }, + "has_dedicated_it": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Has Dedicated It" + }, + "monthly_request_volume": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Monthly Request Volume" + }, + "onboarding_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Onboarding Status" + }, + "profile_data": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Profile Data" + }, + "gap_map": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Gap Map" + } + }, + "type": "object", + "title": "CityProfileUpdate" + }, + "ClarificationCommand": { + "properties": { + "action": { + "type": "string", + "const": "request-records-clarification", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ClarificationPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "ClarificationCommand" + }, + "ClarificationPayload": { + "properties": { + "clarificationNote": { + "type": "string", + "minLength": 1, + "title": "Clarificationnote" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "clarificationNote" + ], + "title": "ClarificationPayload" + }, + "Closeout": { + "properties": { + "decision_id": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Decision Id" + }, + "version_id": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Version Id" + }, + "source_id": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Source Id" + }, + "version_label": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Version Label" + }, + "body": { + "type": "string", + "maxLength": 1000000, + "minLength": 1, + "title": "Body" + }, + "effective_start": { + "type": "string", + "format": "date", + "title": "Effective Start" + }, + "effective_end": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective End" + }, + "is_current": { + "type": "boolean", + "title": "Is Current" + }, + "reconciliation_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reconciliation Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "decision_id", + "version_id", + "source_id", + "version_label", + "body", + "effective_start", + "is_current" + ], + "title": "Closeout" + }, + "CodeContext": { + "properties": { + "section_number": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Section Number" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "section_number" + ], + "title": "CodeContext" + }, + "CodeLink": { + "properties": { + "provider": { + "type": "string", + "const": "code", + "title": "Provider", + "default": "code" + }, + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "CodeLink" + }, + "CodeSearch": { + "properties": { + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "CodeSearch" + }, + "CodeSourceSelection": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "CodeSourceSelection" + }, + "CompleteArtifact": { + "properties": { + "export_path": { + "type": "string", + "minLength": 1, + "title": "Export Path" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "export_path" + ], + "title": "CompleteArtifact" + }, + "ConnectionSearch": { + "properties": { + "provider": { + "type": "string", + "enum": [ + "meetings", + "zoning" + ], + "title": "Provider" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "query" + ], + "title": "ConnectionSearch" + }, + "CoverageGapResponse": { + "properties": { + "jurisdictions_without_rules": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Jurisdictions Without Rules" + }, + "departments_without_staff": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array", + "title": "Departments Without Staff" + }, + "uncovered_categories": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Uncovered Categories" + }, + "total_gaps": { + "type": "integer", + "title": "Total Gaps" + } + }, + "type": "object", + "required": [ + "jurisdictions_without_rules", + "departments_without_staff", + "uncovered_categories", + "total_gaps" + ], + "title": "CoverageGapResponse" + }, + "DataSourceAdminRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "source_type": { + "$ref": "#/components/schemas/SourceType" + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "type": "boolean", + "title": "Schedule Enabled", + "default": true + }, + "next_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Next Sync At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "last_ingestion_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Ingestion At" + }, + "last_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Sync At" + }, + "last_sync_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Sync Status" + }, + "last_error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Error Message" + }, + "consecutive_failure_count": { + "type": "integer", + "title": "Consecutive Failure Count", + "default": 0 + }, + "sync_paused": { + "type": "boolean", + "title": "Sync Paused", + "default": false + }, + "health_status": { + "type": "string", + "title": "Health Status", + "default": "healthy" + }, + "active_failure_count": { + "type": "integer", + "title": "Active Failure Count", + "default": 0 + }, + "connector_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Connector Type" + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At" + }, + "connection_config": { + "additionalProperties": true, + "type": "object", + "title": "Connection Config" + } + }, + "type": "object", + "required": [ + "id", + "name", + "source_type", + "is_active", + "created_by", + "created_at", + "last_ingestion_at", + "connection_config" + ], + "title": "DataSourceAdminRead", + "description": "Full datasource shape including connection_config. Returned only by admin-gated endpoints." + }, + "DataSourceCreate": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "source_type": { + "$ref": "#/components/schemas/SourceType" + }, + "connection_config": { + "additionalProperties": true, + "type": "object", + "title": "Connection Config", + "default": {} + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "type": "boolean", + "title": "Schedule Enabled", + "default": true + } + }, + "type": "object", + "required": [ + "name", + "source_type" + ], + "title": "DataSourceCreate" + }, + "DataSourceRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "source_type": { + "$ref": "#/components/schemas/SourceType" + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "type": "boolean", + "title": "Schedule Enabled", + "default": true + }, + "next_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Next Sync At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "last_ingestion_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Ingestion At" + }, + "last_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Sync At" + }, + "last_sync_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Sync Status" + }, + "last_error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Error Message" + }, + "consecutive_failure_count": { + "type": "integer", + "title": "Consecutive Failure Count", + "default": 0 + }, + "sync_paused": { + "type": "boolean", + "title": "Sync Paused", + "default": false + }, + "health_status": { + "type": "string", + "title": "Health Status", + "default": "healthy" + }, + "active_failure_count": { + "type": "integer", + "title": "Active Failure Count", + "default": 0 + }, + "connector_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Connector Type" + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "name", + "source_type", + "is_active", + "created_by", + "created_at", + "last_ingestion_at" + ], + "title": "DataSourceRead", + "description": "Redacted datasource shape — safe for non-admin roles. connection_config omitted." + }, + "DataSourceUpdate": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "connection_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Connection Config" + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Schedule Enabled" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "DataSourceUpdate" + }, + "DeadlineCommand": { + "properties": { + "action": { + "type": "string", + "const": "set-records-deadline", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/DeadlinePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "DeadlineCommand" + }, + "DeadlinePayload": { + "properties": { + "deadline": { + "type": "string", + "title": "Deadline" + }, + "deadlineBasis": { + "type": "string", + "minLength": 1, + "title": "Deadlinebasis" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "deadline", + "deadlineBasis" + ], + "title": "DeadlinePayload" + }, + "Decision": { + "properties": { + "id": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Id" + }, + "outcome": { + "type": "string", + "enum": [ + "adopted", + "not_adopted", + "deferred", + "withdrawn" + ], + "title": "Outcome" + }, + "decided_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Decided At" + }, + "decision_text": { + "type": "string", + "maxLength": 1000000, + "minLength": 1, + "title": "Decision Text" + }, + "supporting_references": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Supporting References" + }, + "supersedes_decision_id": { + "anyOf": [ + { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$" + }, + { + "type": "null" + } + ], + "title": "Supersedes Decision Id" + }, + "reconciliation_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reconciliation Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "outcome", + "decision_text" + ], + "title": "Decision" + }, + "DepartmentCreate": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "code": { + "type": "string", + "title": "Code" + }, + "contact_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Contact Email" + } + }, + "type": "object", + "required": [ + "name", + "code" + ], + "title": "DepartmentCreate" + }, + "DepartmentRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "code": { + "type": "string", + "title": "Code" + }, + "contact_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Contact Email" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "name", + "code", + "contact_email", + "created_at" + ], + "title": "DepartmentRead" + }, + "DepartmentUpdate": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Code" + }, + "contact_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Contact Email" + } + }, + "type": "object", + "title": "DepartmentUpdate" + }, + "DisclosureTemplateCreate": { + "properties": { + "template_type": { + "type": "string", + "title": "Template Type" + }, + "state_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State Code" + }, + "content": { + "type": "string", + "title": "Content" + } + }, + "type": "object", + "required": [ + "template_type", + "content" + ], + "title": "DisclosureTemplateCreate" + }, + "DisclosureTemplateRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "template_type": { + "type": "string", + "title": "Template Type" + }, + "state_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State Code" + }, + "content": { + "type": "string", + "title": "Content" + }, + "version": { + "type": "integer", + "title": "Version" + }, + "updated_by": { + "type": "string", + "format": "uuid", + "title": "Updated By" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "template_type", + "state_code", + "content", + "version", + "updated_by", + "updated_at" + ], + "title": "DisclosureTemplateRead" + }, + "DisclosureTemplateRendered": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "template_type": { + "type": "string", + "title": "Template Type" + }, + "rendered_content": { + "type": "string", + "title": "Rendered Content" + }, + "has_unresolved_variables": { + "type": "boolean", + "title": "Has Unresolved Variables" + } + }, + "type": "object", + "required": [ + "id", + "template_type", + "rendered_content", + "has_unresolved_variables" + ], + "title": "DisclosureTemplateRendered" + }, + "DisclosureTemplateUpdate": { + "properties": { + "content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Content" + }, + "state_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State Code" + } + }, + "type": "object", + "title": "DisclosureTemplateUpdate" + }, + "DocumentChunkRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "chunk_index": { + "type": "integer", + "title": "Chunk Index" + }, + "content_text": { + "type": "string", + "title": "Content Text" + }, + "token_count": { + "type": "integer", + "title": "Token Count" + }, + "page_number": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Page Number" + } + }, + "type": "object", + "required": [ + "id", + "document_id", + "chunk_index", + "content_text", + "token_count", + "page_number" + ], + "title": "DocumentChunkRead" + }, + "DocumentRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "source_id": { + "type": "string", + "format": "uuid", + "title": "Source Id" + }, + "source_path": { + "type": "string", + "title": "Source Path" + }, + "filename": { + "type": "string", + "title": "Filename" + }, + "file_type": { + "type": "string", + "title": "File Type" + }, + "file_hash": { + "type": "string", + "title": "File Hash" + }, + "file_size": { + "type": "integer", + "title": "File Size" + }, + "ingestion_status": { + "$ref": "#/components/schemas/IngestionStatus" + }, + "ingestion_error": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Ingestion Error" + }, + "chunk_count": { + "type": "integer", + "title": "Chunk Count" + }, + "ingested_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Ingested At" + }, + "connector_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Connector Type" + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "source_id", + "source_path", + "filename", + "file_type", + "file_hash", + "file_size", + "ingestion_status", + "ingestion_error", + "chunk_count", + "ingested_at" + ], + "title": "DocumentRead" + }, + "DraftCommand": { + "properties": { + "action": { + "type": "string", + "const": "draft-records-response", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/DraftPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "DraftCommand" + }, + "DraftInput": { + "properties": { + "source_materials": { + "items": { + "$ref": "#/components/schemas/SourceInput" + }, + "type": "array", + "title": "Source Materials" + }, + "sentences": { + "items": { + "$ref": "#/components/schemas/SentenceInput" + }, + "type": "array", + "minItems": 1, + "title": "Sentences" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sentences" + ], + "title": "DraftInput" + }, + "DraftPayload": { + "properties": { + "responseDraft": { + "type": "string", + "minLength": 1, + "title": "Responsedraft" + }, + "citation": { + "type": "string", + "title": "Citation", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "responseDraft" + ], + "title": "DraftPayload" + }, + "ErrorModel": { + "properties": { + "detail": { + "anyOf": [ + { + "type": "string" + }, + { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + ], + "title": "Detail" + } + }, + "type": "object", + "required": [ + "detail" + ], + "title": "ErrorModel" + }, + "Evidence": { + "properties": { + "filename": { + "type": "string", + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$", + "title": "Filename" + }, + "description": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Description" + }, + "media_type": { + "type": "string", + "enum": [ + "text/plain", + "image/jpeg", + "image/png", + "image/webp", + "application/pdf", + "audio/webm", + "audio/ogg", + "audio/wav", + "audio/mpeg", + "audio/mp4" + ], + "title": "Media Type" + }, + "content_base64": { + "type": "string", + "maxLength": 14000000, + "minLength": 1, + "title": "Content Base64" + }, + "sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "filename", + "description", + "media_type", + "content_base64", + "sha256" + ], + "title": "Evidence" + }, + "EvidenceItem": { + "properties": { + "filename": { + "type": "string", + "maxLength": 151, + "minLength": 1, + "title": "Filename" + }, + "media_type": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Media Type" + }, + "description": { + "type": "string", + "maxLength": 2000, + "title": "Description", + "default": "" + }, + "content_base64": { + "type": "string", + "maxLength": 14000000, + "minLength": 1, + "title": "Content Base64" + }, + "sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "filename", + "media_type", + "content_base64", + "sha256" + ], + "title": "EvidenceItem" + }, + "EvidenceItems": { + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/EvidenceItem" + }, + "type": "array", + "maxItems": 10, + "minItems": 1, + "title": "Items" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "items" + ], + "title": "EvidenceItems" + }, + "ExemptionAccuracyReport": { + "properties": { + "category": { + "type": "string", + "title": "Category" + }, + "total_flags": { + "type": "integer", + "title": "Total Flags" + }, + "accepted": { + "type": "integer", + "title": "Accepted" + }, + "rejected": { + "type": "integer", + "title": "Rejected" + }, + "pending": { + "type": "integer", + "title": "Pending" + }, + "acceptance_rate": { + "type": "number", + "title": "Acceptance Rate" + } + }, + "type": "object", + "required": [ + "category", + "total_flags", + "accepted", + "rejected", + "pending", + "acceptance_rate" + ], + "title": "ExemptionAccuracyReport" + }, + "ExemptionDashboard": { + "properties": { + "total_flags": { + "type": "integer", + "title": "Total Flags" + }, + "by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "By Status" + }, + "by_category": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "By Category" + }, + "acceptance_rate": { + "type": "number", + "title": "Acceptance Rate" + }, + "total_rules": { + "type": "integer", + "title": "Total Rules" + }, + "active_rules": { + "type": "integer", + "title": "Active Rules" + } + }, + "type": "object", + "required": [ + "total_flags", + "by_status", + "by_category", + "acceptance_rate", + "total_rules", + "active_rules" + ], + "title": "ExemptionDashboard" + }, + "ExemptionDecisionCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-exemption-decision", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ExemptionDecisionPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "ExemptionDecisionCommand" + }, + "ExemptionDecisionPayload": { + "properties": { + "exemptionSource": { + "type": "string", + "minLength": 1, + "title": "Exemptionsource" + }, + "exemptionKind": { + "type": "string", + "minLength": 1, + "title": "Exemptionkind" + }, + "exemptionFinding": { + "type": "string", + "minLength": 1, + "title": "Exemptionfinding" + }, + "exemptionDecision": { + "type": "string", + "enum": [ + "release", + "redact", + "exempt" + ], + "title": "Exemptiondecision" + }, + "exemptionBasis": { + "type": "string", + "minLength": 1, + "title": "Exemptionbasis" + }, + "exemptionReviewer": { + "type": "string", + "title": "Exemptionreviewer", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "exemptionSource", + "exemptionKind", + "exemptionFinding", + "exemptionDecision", + "exemptionBasis" + ], + "title": "ExemptionDecisionPayload" + }, + "ExemptionDecisionView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "source": { + "type": "string", + "title": "Source" + }, + "kind": { + "type": "string", + "title": "Kind" + }, + "finding": { + "type": "string", + "title": "Finding" + }, + "decision": { + "type": "string", + "enum": [ + "release", + "redact", + "exempt" + ], + "title": "Decision" + }, + "basis": { + "type": "string", + "title": "Basis" + }, + "reviewer": { + "type": "string", + "title": "Reviewer" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "source", + "kind", + "finding", + "decision", + "basis", + "reviewer", + "created_at_unix_seconds" + ], + "title": "ExemptionDecisionView" + }, + "ExemptionFlagRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "chunk_id": { + "type": "string", + "format": "uuid", + "title": "Chunk Id" + }, + "rule_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Rule Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "category": { + "type": "string", + "title": "Category" + }, + "matched_text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Matched Text" + }, + "confidence": { + "type": "number", + "title": "Confidence" + }, + "status": { + "$ref": "#/components/schemas/FlagStatus" + }, + "reviewed_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Reviewed By" + }, + "reviewed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Reviewed At" + }, + "review_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Reason" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "chunk_id", + "rule_id", + "request_id", + "category", + "matched_text", + "confidence", + "status", + "reviewed_by", + "reviewed_at", + "review_reason", + "created_at" + ], + "title": "ExemptionFlagRead" + }, + "ExemptionFlagReview": { + "properties": { + "status": { + "$ref": "#/components/schemas/FlagStatus" + }, + "review_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Reason" + } + }, + "type": "object", + "required": [ + "status" + ], + "title": "ExemptionFlagReview" + }, + "ExemptionNoteCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-exemption-review", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ExemptionNotePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "ExemptionNoteCommand" + }, + "ExemptionNotePayload": { + "properties": { + "exemptionNote": { + "type": "string", + "minLength": 1, + "title": "Exemptionnote" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "exemptionNote" + ], + "title": "ExemptionNotePayload" + }, + "ExemptionRuleCreate": { + "properties": { + "state_code": { + "type": "string", + "title": "State Code" + }, + "category": { + "type": "string", + "title": "Category" + }, + "rule_type": { + "$ref": "#/components/schemas/RuleType" + }, + "rule_definition": { + "type": "string", + "title": "Rule Definition" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "enabled": { + "type": "boolean", + "title": "Enabled", + "default": true + } + }, + "type": "object", + "required": [ + "state_code", + "category", + "rule_type", + "rule_definition" + ], + "title": "ExemptionRuleCreate" + }, + "ExemptionRuleRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "state_code": { + "type": "string", + "title": "State Code" + }, + "category": { + "type": "string", + "title": "Category" + }, + "rule_type": { + "$ref": "#/components/schemas/RuleType" + }, + "rule_definition": { + "type": "string", + "title": "Rule Definition" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "enabled": { + "type": "boolean", + "title": "Enabled" + }, + "version": { + "type": "integer", + "title": "Version", + "default": 1 + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "state_code", + "category", + "rule_type", + "rule_definition", + "description", + "enabled", + "created_by", + "created_at" + ], + "title": "ExemptionRuleRead" + }, + "ExemptionRuleUpdate": { + "properties": { + "rule_definition": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Rule Definition" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "enabled": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Enabled" + } + }, + "type": "object", + "title": "ExemptionRuleUpdate" + }, + "ExportReceipt": { + "properties": { + "export_path": { + "type": "string", + "maxLength": 32768, + "minLength": 1, + "title": "Export Path" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "export_path" + ], + "title": "ExportReceipt" + }, + "FeeEstimateCommand": { + "properties": { + "action": { + "type": "string", + "const": "estimate-records-fee", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/FeeEstimatePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "FeeEstimateCommand" + }, + "FeeEstimatePayload": { + "properties": { + "feeEstimate": { + "type": "string", + "minLength": 1, + "title": "Feeestimate" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "feeEstimate" + ], + "title": "FeeEstimatePayload" + }, + "FeeEstimateRequest": { + "properties": { + "page_count": { + "type": "integer", + "title": "Page Count" + }, + "fee_schedule_id": { + "type": "string", + "format": "uuid", + "title": "Fee Schedule Id" + } + }, + "type": "object", + "required": [ + "page_count", + "fee_schedule_id" + ], + "title": "FeeEstimateRequest" + }, + "FeeEstimateResponse": { + "properties": { + "page_count": { + "type": "integer", + "title": "Page Count" + }, + "unit_price": { + "type": "number", + "title": "Unit Price" + }, + "total": { + "type": "number", + "title": "Total" + }, + "fee_type": { + "type": "string", + "title": "Fee Type" + }, + "description": { + "type": "string", + "title": "Description" + } + }, + "type": "object", + "required": [ + "page_count", + "unit_price", + "total", + "fee_type", + "description" + ], + "title": "FeeEstimateResponse" + }, + "FeeLineCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-fee-line", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/FeeLinePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "FeeLineCommand" + }, + "FeeLineItemCreate": { + "properties": { + "description": { + "type": "string", + "title": "Description" + }, + "quantity": { + "type": "integer", + "title": "Quantity", + "default": 1 + }, + "unit_price": { + "type": "number", + "title": "Unit Price" + }, + "fee_schedule_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Fee Schedule Id" + } + }, + "type": "object", + "required": [ + "description", + "unit_price" + ], + "title": "FeeLineItemCreate" + }, + "FeeLineItemRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "fee_schedule_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Fee Schedule Id" + }, + "description": { + "type": "string", + "title": "Description" + }, + "quantity": { + "type": "integer", + "title": "Quantity" + }, + "unit_price": { + "type": "number", + "title": "Unit Price" + }, + "total": { + "type": "number", + "title": "Total" + }, + "status": { + "type": "string", + "title": "Status" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "fee_schedule_id", + "description", + "quantity", + "unit_price", + "total", + "status", + "created_at" + ], + "title": "FeeLineItemRead" + }, + "FeeLinePayload": { + "properties": { + "feeLineDescription": { + "type": "string", + "minLength": 1, + "title": "Feelinedescription" + }, + "feeScheduleBasis": { + "type": "string", + "minLength": 1, + "title": "Feeschedulebasis" + }, + "feeLineAmount": { + "type": "string", + "title": "Feelineamount" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "feeLineDescription", + "feeScheduleBasis", + "feeLineAmount" + ], + "title": "FeeLinePayload" + }, + "FeeLineView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "description": { + "type": "string", + "title": "Description" + }, + "schedule_basis": { + "type": "string", + "title": "Schedule Basis" + }, + "amount_cents": { + "type": "integer", + "title": "Amount Cents" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "description", + "schedule_basis", + "amount_cents", + "created_at_unix_seconds" + ], + "title": "FeeLineView" + }, + "FeeScheduleCreate": { + "properties": { + "jurisdiction": { + "type": "string", + "title": "Jurisdiction" + }, + "fee_type": { + "type": "string", + "title": "Fee Type" + }, + "amount": { + "type": "number", + "title": "Amount" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "effective_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective Date" + } + }, + "type": "object", + "required": [ + "jurisdiction", + "fee_type", + "amount" + ], + "title": "FeeScheduleCreate" + }, + "FeeScheduleRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "jurisdiction": { + "type": "string", + "title": "Jurisdiction" + }, + "fee_type": { + "type": "string", + "title": "Fee Type" + }, + "amount": { + "type": "number", + "title": "Amount" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "effective_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective Date" + }, + "created_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "jurisdiction", + "fee_type", + "amount", + "description", + "effective_date", + "created_by", + "created_at" + ], + "title": "FeeScheduleRead" + }, + "FeeScheduleUpdate": { + "properties": { + "fee_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Fee Type" + }, + "amount": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Amount" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "effective_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective Date" + } + }, + "type": "object", + "title": "FeeScheduleUpdate" + }, + "FeeWaiverCommand": { + "properties": { + "action": { + "type": "string", + "const": "waive-records-fee", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/FeeWaiverPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "FeeWaiverCommand" + }, + "FeeWaiverCreateRequest": { + "properties": { + "waiver_type": { + "type": "string", + "title": "Waiver Type" + }, + "reason": { + "type": "string", + "title": "Reason" + } + }, + "type": "object", + "required": [ + "waiver_type", + "reason" + ], + "title": "FeeWaiverCreateRequest" + }, + "FeeWaiverPayload": { + "properties": { + "feeWaiverReason": { + "type": "string", + "minLength": 1, + "title": "Feewaiverreason" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "feeWaiverReason" + ], + "title": "FeeWaiverPayload" + }, + "FeeWaiverReadResponse": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "waiver_type": { + "type": "string", + "title": "Waiver Type" + }, + "reason": { + "type": "string", + "title": "Reason" + }, + "status": { + "type": "string", + "title": "Status" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + }, + "created_at": { + "type": "string", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "waiver_type", + "reason", + "status", + "created_at" + ], + "title": "FeeWaiverReadResponse" + }, + "FeeWaiverReviewRequest": { + "properties": { + "status": { + "type": "string", + "title": "Status" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + } + }, + "type": "object", + "required": [ + "status" + ], + "title": "FeeWaiverReviewRequest" + }, + "FinishCommand": { + "properties": { + "action": { + "type": "string", + "enum": [ + "fulfill-records-request", + "close-records-request" + ], + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/NativePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "FinishCommand" + }, + "FlagStatus": { + "type": "string", + "enum": [ + "flagged", + "reviewed", + "accepted", + "rejected" + ], + "title": "FlagStatus" + }, + "FormPlan": { + "properties": { + "action": { + "type": "string", + "const": "form-plan", + "title": "Action" + }, + "formName": { + "type": "string", + "maxLength": 500, + "title": "Formname", + "default": "" + }, + "fields": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 50, + "title": "Fields" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "FormPlan" + }, + "GeneratedDraft": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "model": { + "type": "string", + "minLength": 1, + "title": "Model" + }, + "previous_response_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Previous Response Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text", + "model", + "previous_response_sha256" + ], + "title": "GeneratedDraft" + }, + "HTTPValidationError": { + "properties": { + "detail": { + "items": { + "$ref": "#/components/schemas/ValidationError" + }, + "type": "array", + "title": "Detail" + } + }, + "type": "object", + "title": "HTTPValidationError" + }, + "Handoff": { + "properties": { + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "request_id" + ], + "title": "Handoff" + }, + "ImportBundleCreate": { + "properties": { + "job_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Job Id" + }, + "connector_type": { + "type": "string", + "minLength": 1, + "title": "Connector Type" + }, + "source": { + "$ref": "#/components/schemas/SourceCreate" + }, + "sources": { + "items": { + "$ref": "#/components/schemas/SourceCreate" + }, + "type": "array", + "title": "Sources" + }, + "titles": { + "items": { + "$ref": "#/components/schemas/TitleCreate" + }, + "type": "array", + "title": "Titles" + }, + "chapters": { + "items": { + "$ref": "#/components/schemas/ChapterCreate" + }, + "type": "array", + "title": "Chapters" + }, + "sections": { + "items": { + "$ref": "#/components/schemas/SectionCreate" + }, + "type": "array", + "title": "Sections" + }, + "versions": { + "items": { + "$ref": "#/components/schemas/SectionVersionCreate" + }, + "type": "array", + "title": "Versions" + }, + "provenance": { + "additionalProperties": true, + "type": "object", + "title": "Provenance" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "connector_type", + "source" + ], + "title": "ImportBundleCreate", + "description": "Request body for local fixture/file-drop import jobs." + }, + "InclusionStatus": { + "type": "string", + "enum": [ + "included", + "excluded", + "pending" + ], + "title": "InclusionStatus" + }, + "IngestionStats": { + "properties": { + "total_sources": { + "type": "integer", + "title": "Total Sources" + }, + "active_sources": { + "type": "integer", + "title": "Active Sources" + }, + "total_documents": { + "type": "integer", + "title": "Total Documents" + }, + "documents_by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Documents By Status" + }, + "total_chunks": { + "type": "integer", + "title": "Total Chunks" + } + }, + "type": "object", + "required": [ + "total_sources", + "active_sources", + "total_documents", + "documents_by_status", + "total_chunks" + ], + "title": "IngestionStats" + }, + "IngestionStatus": { + "type": "string", + "enum": [ + "pending", + "processing", + "completed", + "failed" + ], + "title": "IngestionStatus" + }, + "InitiativeInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "policy": { + "$ref": "#/components/schemas/PolicySelection" + }, + "responsible_staff": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Responsible Staff" + }, + "target": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "title": "Target" + }, + "unit": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Unit" + }, + "due_on": { + "type": "string", + "format": "date", + "title": "Due On" + }, + "status": { + "type": "string", + "enum": [ + "planned", + "active", + "completed", + "cancelled" + ], + "title": "Status", + "default": "planned" + }, + "milestones": { + "items": { + "$ref": "#/components/schemas/Milestone" + }, + "type": "array", + "maxItems": 100, + "title": "Milestones" + }, + "measurements": { + "items": { + "$ref": "#/components/schemas/Measurement" + }, + "type": "array", + "maxItems": 1000, + "title": "Measurements" + }, + "note": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "policy", + "responsible_staff", + "target", + "unit", + "due_on", + "note" + ], + "title": "InitiativeInput" + }, + "InspectionInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "property_reference": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Property Reference" + }, + "inspection_reference": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Inspection Reference" + }, + "dataset_kind": { + "type": "string", + "enum": [ + "municipal", + "fictional" + ], + "title": "Dataset Kind" + }, + "inspector_notes": { + "type": "string", + "maxLength": 10000, + "minLength": 1, + "title": "Inspector Notes" + }, + "photo_observations": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 30, + "title": "Photo Observations" + }, + "voice_notes": { + "type": "string", + "maxLength": 10000, + "title": "Voice Notes", + "default": "" + }, + "evidence": { + "items": { + "$ref": "#/components/schemas/Evidence" + }, + "type": "array", + "maxItems": 10, + "title": "Evidence" + }, + "linked_sources": { + "items": { + "$ref": "#/components/schemas/townlight_inspections__workflow_models__SourceLink" + }, + "type": "array", + "maxItems": 30, + "title": "Linked Sources" + }, + "assigned_to": { + "type": "string", + "maxLength": 255, + "title": "Assigned To", + "default": "" + }, + "staff_notes": { + "type": "string", + "maxLength": 10000, + "title": "Staff Notes", + "default": "" + }, + "notice_draft": { + "type": "string", + "maxLength": 10000, + "title": "Notice Draft", + "default": "" + }, + "review_state": { + "type": "string", + "enum": [ + "draft", + "follow_up", + "reviewed" + ], + "title": "Review State", + "default": "draft" + }, + "review_notes": { + "type": "string", + "maxLength": 4000, + "title": "Review Notes", + "default": "" + }, + "public_summary": { + "type": "string", + "maxLength": 10000, + "title": "Public Summary", + "default": "" + }, + "analysis": { + "anyOf": [ + { + "$ref": "#/components/schemas/AnalysisRecord" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "property_reference", + "inspection_reference", + "dataset_kind", + "inspector_notes" + ], + "title": "InspectionInput" + }, + "IntakeInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "project_name": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Project Name" + }, + "project_description": { + "type": "string", + "maxLength": 10000, + "minLength": 1, + "title": "Project Description" + }, + "location": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Location" + }, + "applicant_contact": { + "type": "string", + "maxLength": 2000, + "title": "Applicant Contact", + "default": "" + }, + "requirement_revision": { + "type": "string", + "format": "uuid", + "title": "Requirement Revision" + }, + "materials": { + "items": { + "$ref": "#/components/schemas/MaterialReview" + }, + "type": "array", + "maxItems": 100, + "minItems": 1, + "title": "Materials" + }, + "linked_sources": { + "items": { + "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink" + }, + "type": "array", + "maxItems": 30, + "title": "Linked Sources" + }, + "staff_notes": { + "type": "string", + "maxLength": 10000, + "title": "Staff Notes", + "default": "" + }, + "assigned_to": { + "type": "string", + "maxLength": 255, + "title": "Assigned To", + "default": "" + }, + "review_state": { + "type": "string", + "enum": [ + "draft", + "follow_up", + "reviewed" + ], + "title": "Review State", + "default": "draft" + }, + "review_notes": { + "type": "string", + "maxLength": 4000, + "title": "Review Notes", + "default": "" + }, + "public_summary": { + "type": "string", + "maxLength": 10000, + "title": "Public Summary", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "project_name", + "project_description", + "location", + "requirement_revision", + "materials" + ], + "title": "IntakeInput" + }, + "InterpretationNoteCreate": { + "properties": { + "note_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Note Id" + }, + "note_text": { + "type": "string", + "minLength": 1, + "title": "Note Text" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "note_text" + ], + "title": "InterpretationNoteCreate", + "description": "Request body for staff-only interpretation notes." + }, + "InterviewRequest": { + "properties": { + "last_answer": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Answer" + }, + "last_field": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Field" + }, + "skipped_fields": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Skipped Fields" + } + }, + "type": "object", + "title": "InterviewRequest" + }, + "InterviewResponse": { + "properties": { + "question": { + "type": "string", + "title": "Question" + }, + "target_field": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Target Field" + }, + "all_complete": { + "type": "boolean", + "title": "All Complete" + }, + "completed_fields": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Completed Fields" + }, + "onboarding_status": { + "type": "string", + "title": "Onboarding Status" + }, + "skipped_fields": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Skipped Fields" + } + }, + "type": "object", + "required": [ + "question", + "target_field", + "all_complete", + "completed_fields", + "onboarding_status", + "skipped_fields" + ], + "title": "InterviewResponse" + }, + "ManagedFileReceipt": { + "properties": { + "original_path": { + "type": "string", + "minLength": 1, + "title": "Original Path" + }, + "stored_path": { + "type": "string", + "minLength": 1, + "title": "Stored Path" + }, + "file_name": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "File Name" + }, + "sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Sha256" + }, + "size_bytes": { + "type": "integer", + "maximum": 2147483647.0, + "minimum": 0.0, + "title": "Size Bytes" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "original_path", + "stored_path", + "file_name", + "sha256", + "size_bytes" + ], + "title": "ManagedFileReceipt" + }, + "ManagedSource": { + "properties": { + "original_path": { + "type": "string", + "title": "Original Path" + }, + "stored_path": { + "type": "string", + "title": "Stored Path" + }, + "file_name": { + "type": "string", + "title": "File Name" + }, + "sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Sha256" + }, + "size_bytes": { + "type": "integer", + "minimum": 0.0, + "title": "Size Bytes" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "original_path", + "stored_path", + "file_name", + "sha256", + "size_bytes" + ], + "title": "ManagedSource" + }, + "Material": { + "properties": { + "material_id": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]{1,80}$", + "title": "Material Id" + }, + "description": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Description" + }, + "citation": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Citation" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "material_id", + "description", + "citation" + ], + "title": "Material" + }, + "MaterialReview": { + "properties": { + "material_id": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Material Id" + }, + "status": { + "type": "string", + "enum": [ + "not_reviewed", + "provided", + "missing", + "unclear" + ], + "title": "Status", + "default": "not_reviewed" + }, + "note": { + "type": "string", + "maxLength": 2000, + "title": "Note", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "material_id" + ], + "title": "MaterialReview" + }, + "Measurement": { + "properties": { + "recorded_on": { + "type": "string", + "format": "date", + "title": "Recorded On" + }, + "value": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "title": "Value" + }, + "evidence": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Evidence" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "recorded_on", + "value", + "evidence" + ], + "title": "Measurement" + }, + "MediaAnalysis": { + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/EvidenceItem" + }, + "type": "array", + "maxItems": 10, + "minItems": 1, + "title": "Items" + }, + "code_links": { + "items": { + "$ref": "#/components/schemas/CodeLink" + }, + "type": "array", + "maxItems": 30, + "title": "Code Links" + }, + "inspector_supplied_text": { + "type": "string", + "maxLength": 10000, + "title": "Inspector Supplied Text", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "items" + ], + "title": "MediaAnalysis" + }, + "MeetingInput": { + "properties": { + "title": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Title" + }, + "scheduled_start": { + "type": "string", + "format": "date-time", + "title": "Scheduled Start" + }, + "location": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Location" + }, + "meeting_type": { + "type": "string", + "enum": [ + "regular", + "special", + "emergency", + "closed_session", + "executive" + ], + "title": "Meeting Type", + "default": "regular" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "scheduled_start", + "location" + ], + "title": "MeetingInput" + }, + "MeetingLink": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + }, + "relation": { + "type": "string", + "enum": [ + "hearing", + "context", + "precedent" + ], + "title": "Relation" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256", + "relation" + ], + "title": "MeetingLink" + }, + "MeetingSearch": { + "properties": { + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "MeetingSearch" + }, + "MeetingStageInput": { + "properties": { + "to_status": { + "type": "string", + "enum": [ + "SCHEDULED", + "NOTICED", + "PACKET_POSTED", + "IN_PROGRESS", + "RECESSED", + "ADJOURNED", + "TRANSCRIPT_READY", + "MINUTES_DRAFTED", + "MINUTES_POSTED", + "MINUTES_ADOPTED", + "MINUTES_SIGNED", + "ARCHIVED", + "CANCELLED" + ], + "title": "To Status" + }, + "statutory_basis": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Statutory Basis" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "to_status" + ], + "title": "MeetingStageInput" + }, + "MeetingsSearch": { + "properties": { + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "MeetingsSearch" + }, + "MeetingsSourceSelection": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "MeetingsSourceSelection" + }, + "MessageCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-message", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/MessagePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "MessageCommand" + }, + "MessageCreate": { + "properties": { + "message_text": { + "type": "string", + "title": "Message Text" + }, + "is_internal": { + "type": "boolean", + "title": "Is Internal", + "default": false + } + }, + "type": "object", + "required": [ + "message_text" + ], + "title": "MessageCreate" + }, + "MessagePayload": { + "properties": { + "requestMessageBody": { + "type": "string", + "minLength": 1, + "title": "Requestmessagebody" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requestMessageBody" + ], + "title": "MessagePayload" + }, + "MessageRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "sender_type": { + "type": "string", + "title": "Sender Type" + }, + "sender_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Sender Id" + }, + "message_text": { + "type": "string", + "title": "Message Text" + }, + "is_internal": { + "type": "boolean", + "title": "Is Internal" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "sender_type", + "sender_id", + "message_text", + "is_internal", + "created_at" + ], + "title": "MessageRead" + }, + "MessageView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "author": { + "type": "string", + "title": "Author" + }, + "author_role": { + "type": "string", + "title": "Author Role" + }, + "body": { + "type": "string", + "title": "Body" + }, + "visibility": { + "type": "string", + "title": "Visibility" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "author", + "author_role", + "body", + "visibility", + "created_at_unix_seconds" + ], + "title": "MessageView" + }, + "Milestone": { + "properties": { + "title": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Title" + }, + "due_on": { + "type": "string", + "format": "date", + "title": "Due On" + }, + "completed_on": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Completed On" + }, + "evidence": { + "type": "string", + "maxLength": 2000, + "title": "Evidence", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "due_on" + ], + "title": "Milestone" + }, + "MinutesDecision": { + "properties": { + "action": { + "type": "string", + "enum": [ + "post", + "adopt", + "sign" + ], + "title": "Action" + }, + "note": { + "type": "string", + "title": "Note", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "MinutesDecision" + }, + "ModelRegistryCreate": { + "properties": { + "model_name": { + "type": "string", + "title": "Model Name" + }, + "model_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Version" + }, + "parameter_count": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parameter Count" + }, + "license": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License" + }, + "model_card_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Card Url" + }, + "is_active": { + "type": "boolean", + "title": "Is Active", + "default": false + }, + "context_window_size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Context Window Size" + }, + "supports_ner": { + "type": "boolean", + "title": "Supports Ner", + "default": false + }, + "supports_vision": { + "type": "boolean", + "title": "Supports Vision", + "default": false + } + }, + "type": "object", + "required": [ + "model_name" + ], + "title": "ModelRegistryCreate", + "description": "Schema for creating a new model_registry record (POST body)." + }, + "ModelRegistryRead": { + "properties": { + "id": { + "type": "integer", + "title": "Id" + }, + "model_name": { + "type": "string", + "title": "Model Name" + }, + "model_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Version" + }, + "parameter_count": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parameter Count" + }, + "license": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License" + }, + "model_card_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Card Url" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "added_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Added At" + }, + "context_window_size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Context Window Size" + }, + "supports_ner": { + "type": "boolean", + "title": "Supports Ner" + }, + "supports_vision": { + "type": "boolean", + "title": "Supports Vision" + } + }, + "type": "object", + "required": [ + "id", + "model_name", + "is_active", + "supports_ner", + "supports_vision" + ], + "title": "ModelRegistryRead", + "description": "Schema for returning a model_registry record (GET response).\n\n``from_attributes=True`` allows construction directly from an ORM instance." + }, + "ModelRegistryUpdate": { + "properties": { + "model_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Name" + }, + "model_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Version" + }, + "parameter_count": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parameter Count" + }, + "license": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License" + }, + "model_card_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Card Url" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + }, + "context_window_size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Context Window Size" + }, + "supports_ner": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Supports Ner" + }, + "supports_vision": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Supports Vision" + } + }, + "type": "object", + "title": "ModelRegistryUpdate", + "description": "Schema for partially updating a model_registry record (PATCH body).\n\nEvery field is optional so callers can send only the fields they want to\nchange." + }, + "MotionCorrection": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "reason": { + "type": "string", + "minLength": 1, + "title": "Reason" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text", + "reason" + ], + "title": "MotionCorrection" + }, + "MotionInput": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "seconded_by": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Seconded By" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text" + ], + "title": "MotionInput" + }, + "NativePayload": { + "properties": {}, + "additionalProperties": false, + "type": "object", + "title": "NativePayload" + }, + "NativeRequestRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "requester_name": { + "type": "string", + "title": "Requester Name" + }, + "requester_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Email" + }, + "requester_phone": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Phone" + }, + "requester_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Type" + }, + "date_received": { + "type": "string", + "format": "date-time", + "title": "Date Received" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "description": { + "type": "string", + "title": "Description" + }, + "status": { + "$ref": "#/components/schemas/RequestStatus" + }, + "assigned_to": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "created_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "response_draft": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Response Draft" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + }, + "estimated_fee": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Estimated Fee" + }, + "fee_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Fee Status" + }, + "fee_waiver_requested": { + "type": "boolean", + "title": "Fee Waiver Requested", + "default": false + }, + "priority": { + "type": "string", + "title": "Priority", + "default": "normal" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + }, + "closed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Closed At" + }, + "closure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Closure Reason" + }, + "desktop_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Desktop Id" + }, + "public_tracking_number": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Public Tracking Number" + }, + "submitted_via": { + "type": "string", + "title": "Submitted Via" + }, + "deadline_label": { + "type": "string", + "title": "Deadline Label" + }, + "deadline_basis": { + "type": "string", + "title": "Deadline Basis" + }, + "deadline_reviewed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Deadline Reviewed At" + } + }, + "type": "object", + "required": [ + "id", + "requester_name", + "requester_email", + "date_received", + "statutory_deadline", + "description", + "status", + "assigned_to", + "created_by", + "created_at", + "response_draft", + "review_notes", + "desktop_id", + "public_tracking_number", + "submitted_via", + "deadline_label", + "deadline_basis", + "deadline_reviewed_at" + ], + "title": "NativeRequestRead" + }, + "NoticeDocumentInput": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text" + ], + "title": "NoticeDocumentInput" + }, + "NoticeDraft": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "body": { + "type": "string", + "maxLength": 100000, + "minLength": 1, + "title": "Body" + }, + "notice_type": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Notice Type" + }, + "statutory_basis": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Statutory Basis" + }, + "event_date": { + "type": "string", + "format": "date", + "title": "Event Date" + }, + "lead_days": { + "type": "integer", + "maximum": 365.0, + "minimum": 0.0, + "title": "Lead Days" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "body", + "notice_type", + "statutory_basis", + "event_date", + "lead_days" + ], + "title": "NoticeDraft" + }, + "NoticeInput": { + "properties": { + "notice_type": { + "type": "string", + "enum": [ + "regular", + "special", + "emergency", + "closed_session", + "executive" + ], + "title": "Notice Type" + }, + "posted_at": { + "type": "string", + "format": "date-time", + "title": "Posted At" + }, + "minimum_notice_hours": { + "type": "integer", + "minimum": 0.0, + "title": "Minimum Notice Hours" + }, + "statutory_basis": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Statutory Basis" + }, + "approved_by": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Approved By" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "notice_type", + "posted_at", + "minimum_notice_hours" + ], + "title": "NoticeInput" + }, + "NoticeProofInput": { + "properties": { + "location": { + "type": "string", + "minLength": 1, + "title": "Location" + }, + "note": { + "type": "string", + "title": "Note", + "default": "" + }, + "document_delivery_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Document Delivery Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "location" + ], + "title": "NoticeProofInput" + }, + "NotificationLogRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "template_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Template Id" + }, + "recipient_email": { + "type": "string", + "title": "Recipient Email" + }, + "request_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Request Id" + }, + "channel": { + "type": "string", + "title": "Channel" + }, + "status": { + "type": "string", + "title": "Status" + }, + "sent_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Sent At" + }, + "error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Message" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "template_id", + "recipient_email", + "request_id", + "channel", + "status", + "sent_at", + "error_message", + "created_at" + ], + "title": "NotificationLogRead" + }, + "NotificationTemplateCreate": { + "properties": { + "event_type": { + "type": "string", + "title": "Event Type" + }, + "channel": { + "type": "string", + "title": "Channel", + "default": "email" + }, + "subject_template": { + "type": "string", + "title": "Subject Template" + }, + "body_template": { + "type": "string", + "title": "Body Template" + } + }, + "type": "object", + "required": [ + "event_type", + "subject_template", + "body_template" + ], + "title": "NotificationTemplateCreate" + }, + "NotificationTemplateRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "event_type": { + "type": "string", + "title": "Event Type" + }, + "channel": { + "type": "string", + "title": "Channel" + }, + "subject_template": { + "type": "string", + "title": "Subject Template" + }, + "body_template": { + "type": "string", + "title": "Body Template" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "event_type", + "channel", + "subject_template", + "body_template", + "is_active", + "created_at" + ], + "title": "NotificationTemplateRead" + }, + "NotificationTemplateUpdate": { + "properties": { + "subject_template": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Subject Template" + }, + "body_template": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Body Template" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "NotificationTemplateUpdate" + }, + "NotificationView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "notification_id": { + "type": "string", + "title": "Notification Id" + }, + "module_id": { + "type": "string", + "title": "Module Id" + }, + "record_id": { + "type": "string", + "title": "Record Id" + }, + "audience": { + "type": "string", + "title": "Audience" + }, + "channel": { + "type": "string", + "title": "Channel" + }, + "subject": { + "type": "string", + "title": "Subject" + }, + "body": { + "type": "string", + "title": "Body" + }, + "status": { + "type": "string", + "title": "Status" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + }, + "sent_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Sent At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "notification_id", + "module_id", + "record_id", + "audience", + "channel", + "subject", + "body", + "status", + "created_at_unix_seconds", + "sent_at_unix_seconds" + ], + "title": "NotificationView" + }, + "OllamaModelInfo": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Size" + }, + "details": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Details" + } + }, + "type": "object", + "required": [ + "name" + ], + "title": "OllamaModelInfo" + }, + "OllamaStatus": { + "properties": { + "status": { + "type": "string", + "title": "Status" + }, + "models": { + "items": { + "$ref": "#/components/schemas/OllamaModelInfo" + }, + "type": "array", + "title": "Models" + } + }, + "type": "object", + "required": [ + "status", + "models" + ], + "title": "OllamaStatus" + }, + "OperationalMetrics": { + "properties": { + "average_response_time_days": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Average Response Time Days" + }, + "median_response_time_days": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Median Response Time Days" + }, + "requests_by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Requests By Status" + }, + "requests_by_department": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Requests By Department" + }, + "deadline_compliance_rate": { + "type": "number", + "title": "Deadline Compliance Rate" + }, + "total_open": { + "type": "integer", + "title": "Total Open" + }, + "total_closed": { + "type": "integer", + "title": "Total Closed" + }, + "total_overdue": { + "type": "integer", + "title": "Total Overdue" + }, + "clarification_frequency": { + "type": "number", + "title": "Clarification Frequency" + }, + "top_request_topics": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Top Request Topics" + } + }, + "type": "object", + "required": [ + "average_response_time_days", + "median_response_time_days", + "requests_by_status", + "requests_by_department", + "deadline_compliance_rate", + "total_open", + "total_closed", + "total_overdue", + "clarification_frequency", + "top_request_topics" + ], + "title": "OperationalMetrics" + }, + "Outline": { + "properties": { + "title": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Title" + }, + "question_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "maxItems": 50, + "minItems": 1, + "title": "Question Ids" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "question_ids" + ], + "title": "Outline" + }, + "Packet": { + "properties": { + "expected_revision": { + "type": "string", + "format": "uuid", + "title": "Expected Revision" + }, + "visibility": { + "type": "string", + "enum": [ + "staff_only", + "records_copy" + ], + "title": "Visibility" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "expected_revision", + "visibility" + ], + "title": "Packet" + }, + "PacketInput": { + "properties": { + "agenda_item_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "title": "Agenda Item Ids" + }, + "source_files": { + "items": { + "$ref": "#/components/schemas/ManagedSource" + }, + "type": "array", + "title": "Source Files" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "agenda_item_ids" + ], + "title": "PacketInput" + }, + "Pathway": { + "properties": { + "project_type": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Project Type" + }, + "proposal": { + "type": "string", + "maxLength": 4000, + "title": "Proposal", + "default": "" + }, + "location_context": { + "type": "string", + "maxLength": 1000, + "title": "Location Context", + "default": "" + }, + "requirement_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Requirement Revision" + }, + "fee_link": { + "anyOf": [ + { + "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "project_type" + ], + "title": "Pathway" + }, + "PathwayStep": { + "properties": { + "step": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Step" + }, + "citation": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Citation" + }, + "typical_time": { + "type": "string", + "maxLength": 1000, + "title": "Typical Time", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "step", + "citation" + ], + "title": "PathwayStep" + }, + "PlainLanguageSummaryCreate": { + "properties": { + "summary_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Summary Id" + }, + "section_version_id": { + "type": "string", + "minLength": 1, + "title": "Section Version Id" + }, + "summary_text": { + "type": "string", + "minLength": 1, + "title": "Summary Text" + }, + "language_code": { + "type": "string", + "title": "Language Code", + "default": "en" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "section_version_id", + "summary_text" + ], + "title": "PlainLanguageSummaryCreate", + "description": "Request body for staff-drafted plain-language summaries." + }, + "PolicySelection": { + "properties": { + "plan_id": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Plan Id" + }, + "revision_id": { + "type": "string", + "maxLength": 36, + "minLength": 36, + "title": "Revision Id" + }, + "policy_id": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Policy Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "plan_id", + "revision_id", + "policy_id" + ], + "title": "PolicySelection" + }, + "PortalModeResponse": { + "properties": { + "mode": { + "type": "string", + "enum": [ + "public", + "private" + ], + "title": "Mode", + "description": "Active portal posture for this deployment. ``public`` = minimal resident surface (landing + authenticated records-request submission + resident registration) reachable without staff auth. ``private`` = staff-only; no public routes, no resident self-registration." + } + }, + "type": "object", + "required": [ + "mode" + ], + "title": "PortalModeResponse", + "description": "T5D — schema for ``GET /config/portal-mode``.\n\nExposed to the frontend on boot so it can branch routing without a\nuser-identity lookup. The payload is intentionally the single field\nbelow — no staff config, no user state, no schema version." + }, + "PrepareArtifact": { + "properties": { + "kind": { + "type": "string", + "enum": [ + "response", + "release-package" + ], + "title": "Kind" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "kind" + ], + "title": "PrepareArtifact" + }, + "Proof": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + }, + "filename": { + "type": "string", + "maxLength": 150, + "minLength": 1, + "title": "Filename" + }, + "content_base64": { + "type": "string", + "maxLength": 7000000, + "minLength": 1, + "title": "Content Base64" + }, + "location": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Location" + }, + "published_at": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Published At" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence", + "filename", + "content_base64", + "location", + "published_at" + ], + "title": "Proof" + }, + "Proposal": { + "properties": { + "id": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Id" + }, + "version_id": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Version Id" + }, + "meeting_id": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "ordinance_number": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Ordinance Number" + }, + "proposed_text": { + "type": "string", + "maxLength": 1000000, + "minLength": 1, + "title": "Proposed Text" + }, + "supersedes_id": { + "anyOf": [ + { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$" + }, + { + "type": "null" + } + ], + "title": "Supersedes Id" + }, + "reconciliation_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reconciliation Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "version_id", + "meeting_id", + "title", + "ordinance_number", + "proposed_text" + ], + "title": "Proposal" + }, + "PublicExplore": { + "properties": { + "goal": { + "type": "string", + "maxLength": 500, + "title": "Goal", + "default": "" + }, + "topic": { + "type": "string", + "maxLength": 160, + "title": "Topic", + "default": "" + }, + "neighborhood": { + "type": "string", + "maxLength": 255, + "title": "Neighborhood", + "default": "" + }, + "plan_type": { + "type": "string", + "maxLength": 120, + "title": "Plan Type", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "title": "PublicExplore" + }, + "PublicIntake": { + "properties": { + "requester": { + "type": "string", + "minLength": 1, + "title": "Requester" + }, + "requesterContact": { + "type": "string", + "minLength": 1, + "title": "Requestercontact" + }, + "summary": { + "type": "string", + "minLength": 1, + "title": "Summary" + }, + "deadline": { + "type": "string", + "title": "Deadline", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requester", + "requesterContact", + "summary" + ], + "title": "PublicIntake" + }, + "PublicLookup": { + "properties": { + "trackingNumber": { + "type": "string", + "minLength": 1, + "title": "Trackingnumber" + }, + "requesterContact": { + "type": "string", + "minLength": 1, + "title": "Requestercontact" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "trackingNumber", + "requesterContact" + ], + "title": "PublicLookup" + }, + "PublicMessage": { + "properties": { + "trackingNumber": { + "type": "string", + "minLength": 1, + "title": "Trackingnumber" + }, + "requesterContact": { + "type": "string", + "minLength": 1, + "title": "Requestercontact" + }, + "publicRequestMessage": { + "type": "string", + "minLength": 1, + "title": "Publicrequestmessage" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "trackingNumber", + "requesterContact", + "publicRequestMessage" + ], + "title": "PublicMessage" + }, + "PublicStatusView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "label": { + "type": "string", + "title": "Label" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "status": { + "type": "string", + "title": "Status" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "label", + "summary", + "status", + "created_at_unix_seconds" + ], + "title": "PublicStatusView" + }, + "PublicationView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "source_module": { + "type": "string", + "title": "Source Module" + }, + "source_record_id": { + "type": "string", + "title": "Source Record Id" + }, + "record_type": { + "type": "string", + "title": "Record Type" + }, + "public_payload": { + "type": "string", + "title": "Public Payload" + }, + "payload_hash": { + "type": "string", + "title": "Payload Hash" + }, + "published_at_unix_seconds": { + "type": "integer", + "title": "Published At Unix Seconds" + }, + "retracted_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Retracted At Unix Seconds" + }, + "retracted_by": { + "type": "string", + "title": "Retracted By", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "source_module", + "source_record_id", + "record_type", + "public_payload", + "payload_hash", + "published_at_unix_seconds" + ], + "title": "PublicationView" + }, + "PublishingPlan": { + "properties": { + "action": { + "type": "string", + "const": "publishing-workflow", + "title": "Action" + }, + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "hasReview": { + "type": "boolean", + "title": "Hasreview", + "default": false + }, + "hasPlainLanguage": { + "type": "boolean", + "title": "Hasplainlanguage", + "default": false + }, + "hasTranslationReview": { + "type": "boolean", + "title": "Hastranslationreview", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "PublishingPlan" + }, + "Question": { + "properties": { + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + }, + "question": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Question" + }, + "kind": { + "type": "string", + "enum": [ + "use", + "dimension" + ], + "title": "Kind" + }, + "key": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Key" + }, + "audience": { + "type": "string", + "enum": [ + "resident", + "staff" + ], + "title": "Audience", + "default": "resident" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "jurisdiction", + "query", + "question", + "kind", + "key" + ], + "title": "Question" + }, + "QuestionAnswerRequest": { + "properties": { + "question": { + "type": "string", + "minLength": 1, + "title": "Question" + }, + "section_number": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Section Number" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "question" + ], + "title": "QuestionAnswerRequest", + "description": "Request body for citation-grounded code Q&A." + }, + "RecordsDocumentView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "attachment_id": { + "type": "string", + "title": "Attachment Id" + }, + "title": { + "type": "string", + "title": "Title" + }, + "original_path": { + "type": "string", + "title": "Original Path" + }, + "stored_path": { + "type": "string", + "title": "Stored Path" + }, + "citation": { + "type": "string", + "title": "Citation" + }, + "sha256": { + "type": "string", + "title": "Sha256" + }, + "size_bytes": { + "type": "integer", + "title": "Size Bytes" + }, + "status": { + "type": "string", + "title": "Status" + }, + "added_by": { + "type": "string", + "title": "Added By" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + }, + "release_original_path": { + "type": "string", + "title": "Release Original Path", + "default": "" + }, + "release_stored_path": { + "type": "string", + "title": "Release Stored Path", + "default": "" + }, + "release_file_name": { + "type": "string", + "title": "Release File Name", + "default": "" + }, + "release_sha256": { + "type": "string", + "title": "Release Sha256", + "default": "" + }, + "release_size_bytes": { + "type": "integer", + "title": "Release Size Bytes", + "default": 0 + }, + "release_status": { + "type": "string", + "title": "Release Status", + "default": "" + }, + "release_note": { + "type": "string", + "title": "Release Note", + "default": "" + }, + "release_added_by": { + "type": "string", + "title": "Release Added By", + "default": "" + }, + "release_added_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Release Added At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "attachment_id", + "title", + "original_path", + "stored_path", + "citation", + "sha256", + "size_bytes", + "status", + "added_by", + "created_at_unix_seconds" + ], + "title": "RecordsDocumentView" + }, + "RecordsOperationRead": { + "properties": { + "action": { + "type": "string", + "title": "Action" + }, + "message": { + "type": "string", + "title": "Message" + }, + "request": { + "$ref": "#/components/schemas/RecordsView" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "message", + "request" + ], + "title": "RecordsOperationRead" + }, + "RecordsStateRead": { + "properties": { + "demo_fixture": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Demo Fixture" + }, + "records_requests": { + "items": { + "$ref": "#/components/schemas/RecordsView" + }, + "type": "array", + "title": "Records Requests" + }, + "notification_events": { + "items": { + "$ref": "#/components/schemas/NotificationView" + }, + "type": "array", + "title": "Notification Events" + }, + "publication_events": { + "items": { + "$ref": "#/components/schemas/PublicationView" + }, + "type": "array", + "title": "Publication Events" + }, + "audit_entries": { + "items": { + "$ref": "#/components/schemas/AuditView" + }, + "type": "array", + "title": "Audit Entries" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "records_requests" + ], + "title": "RecordsStateRead" + }, + "RecordsView": { + "properties": { + "request_id": { + "type": "string", + "title": "Request Id" + }, + "id": { + "type": "string", + "title": "Id" + }, + "public_tracking_number": { + "type": "string", + "title": "Public Tracking Number" + }, + "requester": { + "type": "string", + "title": "Requester" + }, + "requester_contact": { + "type": "string", + "title": "Requester Contact" + }, + "submitted_via": { + "type": "string", + "title": "Submitted Via" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "deadline": { + "type": "string", + "title": "Deadline" + }, + "deadline_basis": { + "type": "string", + "title": "Deadline Basis" + }, + "status": { + "type": "string", + "title": "Status" + }, + "assigned_to": { + "type": "string", + "title": "Assigned To" + }, + "clarification_notes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Clarification Notes" + }, + "search_notes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Search Notes" + }, + "search_sessions": { + "items": { + "$ref": "#/components/schemas/SearchReceiptView" + }, + "type": "array", + "title": "Search Sessions" + }, + "exemption_reviews": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Exemption Reviews" + }, + "exemption_decisions": { + "items": { + "$ref": "#/components/schemas/ExemptionDecisionView" + }, + "type": "array", + "title": "Exemption Decisions" + }, + "fee_estimate": { + "type": "string", + "title": "Fee Estimate" + }, + "fee_line_items": { + "items": { + "$ref": "#/components/schemas/FeeLineView" + }, + "type": "array", + "title": "Fee Line Items" + }, + "fee_waiver_reason": { + "type": "string", + "title": "Fee Waiver Reason" + }, + "citations": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Citations" + }, + "response_draft": { + "type": "string", + "title": "Response Draft" + }, + "approval_notes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Approval Notes" + }, + "exports": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Exports" + }, + "documents": { + "items": { + "$ref": "#/components/schemas/RecordsDocumentView" + }, + "type": "array", + "title": "Documents" + }, + "release_packages": { + "items": { + "$ref": "#/components/schemas/ReleasePackageView" + }, + "type": "array", + "title": "Release Packages" + }, + "timeline": { + "items": { + "$ref": "#/components/schemas/TimelineView" + }, + "type": "array", + "title": "Timeline" + }, + "public_status_events": { + "items": { + "$ref": "#/components/schemas/PublicStatusView" + }, + "type": "array", + "title": "Public Status Events" + }, + "messages": { + "items": { + "$ref": "#/components/schemas/MessageView" + }, + "type": "array", + "title": "Messages" + }, + "deadline_reviewed_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Deadline Reviewed At Unix Seconds" + }, + "approved_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Approved At Unix Seconds" + }, + "fulfilled_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Fulfilled At Unix Seconds" + }, + "closed_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Closed At Unix Seconds" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "request_id", + "id", + "public_tracking_number", + "requester", + "requester_contact", + "submitted_via", + "summary", + "deadline", + "deadline_basis", + "status", + "assigned_to", + "clarification_notes", + "search_notes", + "search_sessions", + "exemption_reviews", + "exemption_decisions", + "fee_estimate", + "fee_line_items", + "fee_waiver_reason", + "citations", + "response_draft", + "approval_notes", + "exports", + "timeline", + "public_status_events", + "messages", + "deadline_reviewed_at_unix_seconds", + "approved_at_unix_seconds", + "fulfilled_at_unix_seconds", + "closed_at_unix_seconds", + "created_at_unix_seconds" + ], + "title": "RecordsView" + }, + "ReleasePackageView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "export_path": { + "type": "string", + "title": "Export Path" + }, + "package_hash": { + "type": "string", + "title": "Package Hash" + }, + "document_count": { + "type": "integer", + "title": "Document Count" + }, + "release_artifact_count": { + "type": "integer", + "title": "Release Artifact Count" + }, + "search_session_count": { + "type": "integer", + "title": "Search Session Count" + }, + "release_count": { + "type": "integer", + "title": "Release Count" + }, + "redacted_count": { + "type": "integer", + "title": "Redacted Count" + }, + "exempt_count": { + "type": "integer", + "title": "Exempt Count" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "export_path", + "package_hash", + "document_count", + "release_artifact_count", + "search_session_count", + "release_count", + "redacted_count", + "exempt_count", + "created_at_unix_seconds" + ], + "title": "ReleasePackageView" + }, + "RepeatLookup": { + "properties": { + "property_reference": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Property Reference" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "property_reference" + ], + "title": "RepeatLookup" + }, + "RequestCreate": { + "properties": { + "requester_name": { + "type": "string", + "maxLength": 255, + "title": "Requester Name" + }, + "requester_email": { + "anyOf": [ + { + "type": "string", + "maxLength": 255 + }, + { + "type": "null" + } + ], + "title": "Requester Email" + }, + "requester_phone": { + "anyOf": [ + { + "type": "string", + "maxLength": 50 + }, + { + "type": "null" + } + ], + "title": "Requester Phone" + }, + "requester_type": { + "anyOf": [ + { + "type": "string", + "maxLength": 100 + }, + { + "type": "null" + } + ], + "title": "Requester Type" + }, + "description": { + "type": "string", + "maxLength": 10000, + "title": "Description" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "priority": { + "type": "string", + "title": "Priority", + "default": "normal" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string", + "pattern": "^(narrow|moderate|broad)$" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + } + }, + "type": "object", + "required": [ + "requester_name", + "description" + ], + "title": "RequestCreate" + }, + "RequestDocumentAdd": { + "properties": { + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "relevance_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Relevance Note" + } + }, + "type": "object", + "required": [ + "document_id" + ], + "title": "RequestDocumentAdd" + }, + "RequestDocumentRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "relevance_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Relevance Note" + }, + "exemption_flags": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Exemption Flags" + }, + "inclusion_status": { + "$ref": "#/components/schemas/InclusionStatus" + }, + "attached_at": { + "type": "string", + "format": "date-time", + "title": "Attached At" + }, + "attached_by": { + "type": "string", + "format": "uuid", + "title": "Attached By" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "document_id", + "relevance_note", + "exemption_flags", + "inclusion_status", + "attached_at", + "attached_by" + ], + "title": "RequestDocumentRead" + }, + "RequestRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "requester_name": { + "type": "string", + "title": "Requester Name" + }, + "requester_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Email" + }, + "requester_phone": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Phone" + }, + "requester_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Type" + }, + "date_received": { + "type": "string", + "format": "date-time", + "title": "Date Received" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "description": { + "type": "string", + "title": "Description" + }, + "status": { + "$ref": "#/components/schemas/RequestStatus" + }, + "assigned_to": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "created_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "response_draft": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Response Draft" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + }, + "estimated_fee": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Estimated Fee" + }, + "fee_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Fee Status" + }, + "fee_waiver_requested": { + "type": "boolean", + "title": "Fee Waiver Requested", + "default": false + }, + "priority": { + "type": "string", + "title": "Priority", + "default": "normal" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + }, + "closed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Closed At" + }, + "closure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Closure Reason" + } + }, + "type": "object", + "required": [ + "id", + "requester_name", + "requester_email", + "date_received", + "statutory_deadline", + "description", + "status", + "assigned_to", + "created_by", + "created_at", + "response_draft", + "review_notes" + ], + "title": "RequestRead" + }, + "RequestStats": { + "properties": { + "total_requests": { + "type": "integer", + "title": "Total Requests" + }, + "by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "By Status" + }, + "approaching_deadline": { + "type": "integer", + "title": "Approaching Deadline" + }, + "overdue": { + "type": "integer", + "title": "Overdue" + } + }, + "type": "object", + "required": [ + "total_requests", + "by_status", + "approaching_deadline", + "overdue" + ], + "title": "RequestStats" + }, + "RequestStatus": { + "type": "string", + "enum": [ + "received", + "clarification_needed", + "assigned", + "searching", + "in_review", + "ready_for_release", + "drafted", + "approved", + "fulfilled", + "closed" + ], + "title": "RequestStatus" + }, + "RequestUpdate": { + "properties": { + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "status": { + "anyOf": [ + { + "$ref": "#/components/schemas/RequestStatus" + }, + { + "type": "null" + } + ] + }, + "assigned_to": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "response_draft": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Response Draft" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + } + }, + "type": "object", + "title": "RequestUpdate" + }, + "RequirementBundle": { + "properties": { + "requirement_id": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]{1,100}$", + "title": "Requirement Id" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "project_type": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Project Type" + }, + "source_reference": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Source Reference" + }, + "source_date": { + "type": "string", + "format": "date", + "title": "Source Date" + }, + "effective_on": { + "type": "string", + "format": "date", + "title": "Effective On" + }, + "dataset_kind": { + "type": "string", + "enum": [ + "municipal", + "fictional" + ], + "title": "Dataset Kind" + }, + "filename": { + "type": "string", + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$", + "title": "Filename" + }, + "content_base64": { + "type": "string", + "maxLength": 14000000, + "minLength": 1, + "title": "Content Base64" + }, + "sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Sha256" + }, + "materials": { + "items": { + "$ref": "#/components/schemas/Material" + }, + "type": "array", + "maxItems": 100, + "minItems": 1, + "title": "Materials" + }, + "pathway": { + "items": { + "$ref": "#/components/schemas/PathwayStep" + }, + "type": "array", + "maxItems": 100, + "title": "Pathway" + }, + "fee_link": { + "anyOf": [ + { + "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink" + }, + { + "type": "null" + } + ] + }, + "staff_note": { + "type": "string", + "maxLength": 4000, + "title": "Staff Note", + "default": "" + }, + "change_note": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Change Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requirement_id", + "title", + "jurisdiction", + "project_type", + "source_reference", + "source_date", + "effective_on", + "dataset_kind", + "filename", + "content_base64", + "sha256", + "materials", + "change_note" + ], + "title": "RequirementBundle" + }, + "ResponseLetterCreate": { + "properties": { + "template_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Template Id" + } + }, + "type": "object", + "title": "ResponseLetterCreate" + }, + "ResponseLetterRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "template_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Template Id" + }, + "generated_content": { + "type": "string", + "title": "Generated Content" + }, + "edited_content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Edited Content" + }, + "status": { + "type": "string", + "title": "Status" + }, + "generated_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Generated By" + }, + "approved_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Approved By" + }, + "sent_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Sent At" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "template_id", + "generated_content", + "edited_content", + "status", + "generated_by", + "approved_by", + "sent_at", + "created_at" + ], + "title": "ResponseLetterRead" + }, + "ResponseLetterUpdate": { + "properties": { + "edited_content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Edited Content" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + } + }, + "type": "object", + "title": "ResponseLetterUpdate" + }, + "ReviewInput": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "body": { + "type": "string", + "maxLength": 5000, + "title": "Body", + "default": "" + }, + "hasAltText": { + "type": "boolean", + "title": "Hasalttext", + "default": false + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "en" + } + }, + "additionalProperties": false, + "type": "object", + "title": "ReviewInput" + }, + "Revision": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + }, + "document": { + "$ref": "#/components/schemas/NoticeDraft" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence", + "document" + ], + "title": "Revision" + }, + "RewriteInput": { + "properties": { + "action": { + "type": "string", + "enum": [ + "plain-language", + "language-variant" + ], + "title": "Action" + }, + "text": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Text" + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "text" + ], + "title": "RewriteInput" + }, + "RewriteResult": { + "properties": { + "action": { + "type": "string", + "enum": [ + "plain-language", + "language-variant" + ], + "title": "Action" + }, + "text": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Text" + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "" + }, + "outcome": { + "type": "string", + "enum": [ + "generated", + "unavailable" + ], + "title": "Outcome" + }, + "generated": { + "anyOf": [ + { + "type": "string", + "maxLength": 100000 + }, + { + "type": "null" + } + ], + "title": "Generated" + }, + "model": { + "anyOf": [ + { + "type": "string", + "maxLength": 200 + }, + { + "type": "null" + } + ], + "title": "Model" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "text", + "outcome" + ], + "title": "RewriteResult" + }, + "Rule": { + "properties": { + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "zone_code": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Zone Code" + }, + "key": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Key" + }, + "section_number": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Section Number" + }, + "kind": { + "type": "string", + "enum": [ + "use", + "dimension" + ], + "title": "Kind" + }, + "value": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Value" + }, + "overlay_code": { + "anyOf": [ + { + "type": "string", + "maxLength": 255 + }, + { + "type": "null" + } + ], + "title": "Overlay Code" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "jurisdiction", + "zone_code", + "key", + "section_number", + "kind", + "value" + ], + "title": "Rule" + }, + "RuleTestMatch": { + "properties": { + "matched_text": { + "type": "string", + "title": "Matched Text" + }, + "start": { + "type": "integer", + "title": "Start" + }, + "end": { + "type": "integer", + "title": "End" + } + }, + "type": "object", + "required": [ + "matched_text", + "start", + "end" + ], + "title": "RuleTestMatch" + }, + "RuleTestRequest": { + "properties": { + "sample_text": { + "type": "string", + "title": "Sample Text" + } + }, + "type": "object", + "required": [ + "sample_text" + ], + "title": "RuleTestRequest" + }, + "RuleTestResponse": { + "properties": { + "rule_id": { + "type": "string", + "format": "uuid", + "title": "Rule Id" + }, + "rule_type": { + "type": "string", + "title": "Rule Type" + }, + "matched": { + "type": "boolean", + "title": "Matched" + }, + "matches": { + "items": { + "$ref": "#/components/schemas/RuleTestMatch" + }, + "type": "array", + "title": "Matches" + } + }, + "type": "object", + "required": [ + "rule_id", + "rule_type", + "matched", + "matches" + ], + "title": "RuleTestResponse" + }, + "RuleType": { + "type": "string", + "enum": [ + "regex", + "keyword", + "llm_prompt" + ], + "title": "RuleType" + }, + "SaveReview": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "body": { + "type": "string", + "maxLength": 5000, + "title": "Body", + "default": "" + }, + "hasAltText": { + "type": "boolean", + "title": "Hasalttext", + "default": false + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "en" + }, + "ai_analysis": { + "anyOf": [ + { + "type": "string", + "maxLength": 100000 + }, + { + "type": "null" + } + ], + "title": "Ai Analysis" + }, + "ai_analysis_model": { + "anyOf": [ + { + "type": "string", + "maxLength": 200 + }, + { + "type": "null" + } + ], + "title": "Ai Analysis Model" + }, + "ai_outcome": { + "type": "string", + "enum": [ + "generated", + "unavailable", + "failed" + ], + "title": "Ai Outcome" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "ai_outcome" + ], + "title": "SaveReview" + }, + "SearchFilterOptions": { + "properties": { + "file_types": { + "items": { + "type": "string" + }, + "type": "array", + "title": "File Types" + }, + "source_names": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Source Names" + }, + "departments": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array", + "title": "Departments", + "default": [] + }, + "date_range": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Date Range" + } + }, + "type": "object", + "required": [ + "file_types", + "source_names" + ], + "title": "SearchFilterOptions" + }, + "SearchInput": { + "properties": { + "query": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "SearchInput" + }, + "SearchNoteCommand": { + "properties": { + "action": { + "type": "string", + "const": "record-records-search", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/SearchNotePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "SearchNoteCommand" + }, + "SearchNotePayload": { + "properties": { + "sourceNote": { + "type": "string", + "minLength": 1, + "title": "Sourcenote" + }, + "citation": { + "type": "string", + "title": "Citation", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sourceNote" + ], + "title": "SearchNotePayload" + }, + "SearchReceiptCommand": { + "properties": { + "action": { + "type": "string", + "const": "record-records-search-session", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/SearchReceiptPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "SearchReceiptCommand" + }, + "SearchReceiptPayload": { + "properties": { + "searchQuery": { + "type": "string", + "minLength": 1, + "title": "Searchquery" + }, + "searchLocations": { + "type": "string", + "minLength": 1, + "title": "Searchlocations" + }, + "searchResultTitle": { + "type": "string", + "minLength": 1, + "title": "Searchresulttitle" + }, + "searchResultCitation": { + "type": "string", + "minLength": 1, + "title": "Searchresultcitation" + }, + "searchResultSummary": { + "type": "string", + "minLength": 1, + "title": "Searchresultsummary" + }, + "searchResultStatus": { + "type": "string", + "title": "Searchresultstatus", + "default": "" + }, + "searchReviewer": { + "type": "string", + "title": "Searchreviewer", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "searchQuery", + "searchLocations", + "searchResultTitle", + "searchResultCitation", + "searchResultSummary" + ], + "title": "SearchReceiptPayload" + }, + "SearchReceiptView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "query": { + "type": "string", + "title": "Query" + }, + "locations": { + "type": "string", + "title": "Locations" + }, + "reviewer": { + "type": "string", + "title": "Reviewer" + }, + "results": { + "items": { + "$ref": "#/components/schemas/SearchResultView" + }, + "type": "array", + "title": "Results" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "query", + "locations", + "reviewer", + "results", + "created_at_unix_seconds" + ], + "title": "SearchReceiptView" + }, + "SearchRequest": { + "properties": { + "query": { + "type": "string", + "title": "Query" + }, + "session_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Session Id" + }, + "filters": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Filters" + }, + "limit": { + "type": "integer", + "maximum": 50.0, + "title": "Limit", + "default": 10 + }, + "synthesize": { + "type": "boolean", + "title": "Synthesize", + "default": false + } + }, + "type": "object", + "required": [ + "query" + ], + "title": "SearchRequest" + }, + "SearchResponse": { + "properties": { + "query_id": { + "type": "string", + "format": "uuid", + "title": "Query Id" + }, + "session_id": { + "type": "string", + "format": "uuid", + "title": "Session Id" + }, + "query_text": { + "type": "string", + "title": "Query Text" + }, + "results": { + "items": { + "$ref": "#/components/schemas/SearchResultItem" + }, + "type": "array", + "title": "Results" + }, + "results_count": { + "type": "integer", + "title": "Results Count" + }, + "synthesized_answer": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Synthesized Answer" + }, + "ai_generated": { + "type": "boolean", + "title": "Ai Generated", + "default": false + } + }, + "type": "object", + "required": [ + "query_id", + "session_id", + "query_text", + "results", + "results_count" + ], + "title": "SearchResponse" + }, + "SearchResultItem": { + "properties": { + "chunk_id": { + "type": "string", + "format": "uuid", + "title": "Chunk Id" + }, + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "filename": { + "type": "string", + "title": "Filename" + }, + "file_type": { + "type": "string", + "title": "File Type" + }, + "source_path": { + "type": "string", + "title": "Source Path" + }, + "page_number": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Page Number" + }, + "content_text": { + "type": "string", + "title": "Content Text" + }, + "similarity_score": { + "type": "number", + "title": "Similarity Score" + }, + "rank": { + "type": "integer", + "title": "Rank" + } + }, + "type": "object", + "required": [ + "chunk_id", + "document_id", + "filename", + "file_type", + "source_path", + "page_number", + "content_text", + "similarity_score", + "rank" + ], + "title": "SearchResultItem" + }, + "SearchResultView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "title": { + "type": "string", + "title": "Title" + }, + "citation": { + "type": "string", + "title": "Citation" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "status": { + "type": "string", + "title": "Status" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "title", + "citation", + "summary", + "status" + ], + "title": "SearchResultView" + }, + "SearchSessionRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "user_id": { + "type": "string", + "format": "uuid", + "title": "User Id" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "queries": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array", + "title": "Queries", + "default": [] + } + }, + "type": "object", + "required": [ + "id", + "user_id", + "created_at" + ], + "title": "SearchSessionRead" + }, + "SectionCreate": { + "properties": { + "section_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Section Id" + }, + "chapter_id": { + "type": "string", + "minLength": 1, + "title": "Chapter Id" + }, + "section_number": { + "type": "string", + "minLength": 1, + "title": "Section Number" + }, + "section_heading": { + "type": "string", + "minLength": 1, + "title": "Section Heading" + }, + "parent_section_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parent Section Id" + }, + "sort_order": { + "type": "integer", + "title": "Sort Order", + "default": 0 + }, + "administrative_regulation_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Administrative Regulation Refs" + }, + "resolution_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Resolution Refs" + }, + "policy_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Policy Refs" + }, + "approved_summary_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Approved Summary Refs" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "chapter_id", + "section_number", + "section_heading" + ], + "title": "SectionCreate", + "description": "Request body for creating a code section or subsection." + }, + "SectionVersionCreate": { + "properties": { + "version_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Version Id" + }, + "section_id": { + "type": "string", + "minLength": 1, + "title": "Section Id" + }, + "source_id": { + "type": "string", + "minLength": 1, + "title": "Source Id" + }, + "version_label": { + "type": "string", + "minLength": 1, + "title": "Version Label" + }, + "body": { + "type": "string", + "minLength": 1, + "title": "Body" + }, + "effective_start": { + "type": "string", + "format": "date", + "title": "Effective Start" + }, + "effective_end": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective End" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + }, + "is_current": { + "type": "boolean", + "title": "Is Current", + "default": false + }, + "adoption_event_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Adoption Event Id" + }, + "amendment_event_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Amendment Event Id" + }, + "amendment_summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Amendment Summary" + }, + "prior_version_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Prior Version Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "section_id", + "source_id", + "version_label", + "body", + "effective_start" + ], + "title": "SectionVersionCreate", + "description": "Request body for adding an immutable section version." + }, + "Selection": { + "properties": { + "recording_id": { + "type": "string", + "format": "uuid", + "title": "Recording Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "recording_id", + "expected_sha256" + ], + "title": "Selection" + }, + "SentenceInput": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "citations": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Citations" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text" + ], + "title": "SentenceInput" + }, + "ServiceAccountCreate": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole", + "default": "read_only" + } + }, + "type": "object", + "required": [ + "name" + ], + "title": "ServiceAccountCreate" + }, + "ServiceAccountCreated": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "api_key": { + "type": "string", + "title": "Api Key" + } + }, + "type": "object", + "required": [ + "id", + "name", + "role", + "created_by", + "created_at", + "is_active", + "api_key" + ], + "title": "ServiceAccountCreated", + "description": "Returned only on creation — includes the plaintext API key (shown once)." + }, + "ServiceAccountRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + } + }, + "type": "object", + "required": [ + "id", + "name", + "role", + "created_by", + "created_at", + "is_active" + ], + "title": "ServiceAccountRead" + }, + "ServiceAccountUpdate": { + "properties": { + "role": { + "anyOf": [ + { + "$ref": "#/components/schemas/UserRole" + }, + { + "type": "null" + } + ] + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "ServiceAccountUpdate" + }, + "Snapshot": { + "properties": { + "expected_revision": { + "type": "string", + "format": "uuid", + "title": "Expected Revision" + }, + "visibility": { + "type": "string", + "enum": [ + "staff_only", + "public" + ], + "title": "Visibility" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "expected_revision", + "visibility" + ], + "title": "Snapshot" + }, + "SourceCreate": { + "properties": { + "source_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Id" + }, + "name": { + "type": "string", + "minLength": 1, + "title": "Name" + }, + "publisher": { + "type": "string", + "minLength": 1, + "title": "Publisher" + }, + "source_type": { + "type": "string", + "minLength": 1, + "title": "Source Type" + }, + "source_category": { + "type": "string", + "minLength": 1, + "title": "Source Category" + }, + "source_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Url" + }, + "file_reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "File Reference" + }, + "retrieved_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Retrieved At" + }, + "retrieval_method": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Retrieval Method" + }, + "checksum": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Checksum" + }, + "source_owner": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Owner" + }, + "is_official": { + "type": "boolean", + "title": "Is Official", + "default": true + }, + "official_status_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" } - } + ], + "title": "Official Status Note" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + }, + "staff_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Staff Notes" } - } - } - }, - "/ready": { - "get": { - "summary": "Domain Ready", - "operationId": "domain_ready_ready_get", - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": {} + }, + "additionalProperties": false, + "type": "object", + "required": [ + "name", + "publisher", + "source_type", + "source_category" + ], + "title": "SourceCreate", + "description": "Request body for registering an official or explicitly labeled source." + }, + "SourceInput": { + "properties": { + "source_id": { + "type": "string", + "minLength": 1, + "title": "Source Id" + }, + "label": { + "type": "string", + "minLength": 1, + "title": "Label" + }, + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "label", + "text" + ], + "title": "SourceInput" + }, + "SourceSnapshot": { + "properties": { + "visibility": { + "type": "string", + "enum": [ + "public", + "staff_only" + ], + "title": "Visibility" + }, + "meeting_event_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "maxItems": 50, + "title": "Meeting Event Ids" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "visibility" + ], + "title": "SourceSnapshot" + }, + "SourceType": { + "type": "string", + "enum": [ + "manual_drop", + "file_system", + "rest_api", + "odbc" + ], + "title": "SourceType" + }, + "StaffRecordsIntake": { + "properties": { + "requester": { + "type": "string", + "minLength": 1, + "title": "Requester" + }, + "summary": { + "type": "string", + "minLength": 1, + "title": "Summary" + }, + "deadline": { + "type": "string", + "title": "Deadline" + }, + "deadlineBasis": { + "type": "string", + "title": "Deadlinebasis", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requester", + "summary", + "deadline" + ], + "title": "StaffRecordsIntake", + "description": "Existing native create-records-request input; no caller-supplied actor." + }, + "StandardsExplanation": { + "properties": { + "question": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Question" + }, + "process_section": { + "type": "string", + "maxLength": 255, + "title": "Process Section", + "default": "" + }, + "zone_code": { + "type": "string", + "maxLength": 40, + "title": "Zone Code", + "default": "" + }, + "rule_types": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 10, + "title": "Rule Types" + }, + "observed": { + "additionalProperties": { + "type": "string" + }, + "type": "object", + "title": "Observed" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "question" + ], + "title": "StandardsExplanation" + }, + "SyncFailureRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "source_id": { + "type": "string", + "format": "uuid", + "title": "Source Id" + }, + "source_path": { + "type": "string", + "title": "Source Path" + }, + "error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Message" + }, + "error_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Class" + }, + "http_status_code": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Http Status Code" + }, + "retry_count": { + "type": "integer", + "title": "Retry Count" + }, + "status": { + "type": "string", + "title": "Status" + }, + "first_failed_at": { + "type": "string", + "format": "date-time", + "title": "First Failed At" + }, + "last_retried_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Retried At" + }, + "dismissed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Dismissed At" + }, + "dismissed_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Dismissed By" + } + }, + "type": "object", + "required": [ + "id", + "source_id", + "source_path", + "error_message", + "error_class", + "http_status_code", + "retry_count", + "status", + "first_failed_at", + "last_retried_at", + "dismissed_at", + "dismissed_by" + ], + "title": "SyncFailureRead" + }, + "SyncRunLogRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "source_id": { + "type": "string", + "format": "uuid", + "title": "Source Id" + }, + "started_at": { + "type": "string", + "format": "date-time", + "title": "Started At" + }, + "finished_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Finished At" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + }, + "records_attempted": { + "type": "integer", + "title": "Records Attempted" + }, + "records_succeeded": { + "type": "integer", + "title": "Records Succeeded" + }, + "records_failed": { + "type": "integer", + "title": "Records Failed" + }, + "error_summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Summary" + } + }, + "type": "object", + "required": [ + "id", + "source_id", + "started_at", + "finished_at", + "status", + "records_attempted", + "records_succeeded", + "records_failed", + "error_summary" + ], + "title": "SyncRunLogRead" + }, + "SystemStatus": { + "properties": { + "version": { + "type": "string", + "title": "Version" + }, + "database": { + "type": "string", + "title": "Database" + }, + "ollama": { + "type": "string", + "title": "Ollama" + }, + "redis": { + "type": "string", + "title": "Redis" + }, + "user_count": { + "type": "integer", + "title": "User Count" + }, + "audit_log_count": { + "type": "integer", + "title": "Audit Log Count" + }, + "suite_session": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" } - } + ], + "title": "Suite Session" } - } - } - } - }, - "components": { - "schemas": { - "AdaPlan": { + }, + "type": "object", + "required": [ + "version", + "database", + "ollama", + "redis", + "user_count", + "audit_log_count" + ], + "title": "SystemStatus" + }, + "TaggedPlan": { "properties": { "action": { "type": "string", - "const": "ada-title-ii", + "const": "tagged-pdf", "title": "Action" }, - "serviceArea": { - "type": "string", - "maxLength": 500, - "minLength": 1, - "title": "Servicearea" - }, - "hasCoordinatorReview": { - "type": "boolean", - "title": "Hascoordinatorreview", - "default": false + "headingLevels": { + "items": { + "type": "integer", + "maximum": 4294967295.0, + "minimum": 0.0 + }, + "type": "array", + "maxItems": 50, + "title": "Headinglevels" } }, "additionalProperties": false, "type": "object", "required": [ - "action", - "serviceArea" + "action" ], - "title": "AdaPlan" + "title": "TaggedPlan" }, - "CityProfileCreate": { + "TestConnectionRequest": { "properties": { - "city_name": { + "source_type": { "type": "string", - "title": "City Name" + "title": "Source Type" }, - "state": { + "host": { "anyOf": [ { "type": "string" @@ -1244,20 +11215,20 @@ "type": "null" } ], - "title": "State" + "title": "Host" }, - "county": { + "port": { "anyOf": [ { - "type": "string" + "type": "integer" }, { "type": "null" } ], - "title": "County" + "title": "Port" }, - "population_band": { + "path": { "anyOf": [ { "type": "string" @@ -1266,9 +11237,9 @@ "type": "null" } ], - "title": "Population Band" + "title": "Path" }, - "email_platform": { + "username": { "anyOf": [ { "type": "string" @@ -1277,72 +11248,73 @@ "type": "null" } ], - "title": "Email Platform" + "title": "Username" }, - "has_dedicated_it": { + "password": { "anyOf": [ { - "type": "boolean" + "type": "string" }, { "type": "null" } ], - "title": "Has Dedicated It" + "title": "Password" }, - "monthly_request_volume": { + "rest_api_config": { "anyOf": [ { - "type": "string" + "additionalProperties": true, + "type": "object" }, { "type": "null" } ], - "title": "Monthly Request Volume" - }, - "profile_data": { - "additionalProperties": true, - "type": "object", - "title": "Profile Data", - "default": {} + "title": "Rest Api Config" }, - "gap_map": { - "additionalProperties": true, - "type": "object", - "title": "Gap Map", - "default": {} + "odbc_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Odbc Config" } }, "type": "object", "required": [ - "city_name" + "source_type" ], - "title": "CityProfileCreate" + "title": "TestConnectionRequest", + "description": "Dedicated schema for test-connection. NOT the create schema.\n\nSecurity: credentials in this request body are never persisted, never\nwritten to audit logs, and never returned in the response." }, - "CityProfileRead": { + "TestConnectionResponse": { "properties": { - "id": { - "type": "string", - "format": "uuid", - "title": "Id" + "success": { + "type": "boolean", + "title": "Success" }, - "city_name": { + "message": { "type": "string", - "title": "City Name" + "title": "Message" }, - "state": { + "latency_ms": { "anyOf": [ { - "type": "string" + "type": "integer" }, { "type": "null" } ], - "title": "State" + "title": "Latency Ms" }, - "county": { + "status": { "anyOf": [ { "type": "string" @@ -1351,9 +11323,9 @@ "type": "null" } ], - "title": "County" + "title": "Status" }, - "population_band": { + "warning": { "anyOf": [ { "type": "string" @@ -1362,9 +11334,41 @@ "type": "null" } ], - "title": "Population Band" + "title": "Warning" }, - "email_platform": { + "differing_keys": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Differing Keys" + } + }, + "type": "object", + "required": [ + "success", + "message" + ], + "title": "TestConnectionResponse" + }, + "TimelineEventCreate": { + "properties": { + "event_type": { + "type": "string", + "title": "Event Type" + }, + "description": { + "type": "string", + "title": "Description" + }, + "internal_note": { "anyOf": [ { "type": "string" @@ -1373,20 +11377,45 @@ "type": "null" } ], - "title": "Email Platform" + "title": "Internal Note" + } + }, + "type": "object", + "required": [ + "event_type", + "description" + ], + "title": "TimelineEventCreate" + }, + "TimelineEventRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" }, - "has_dedicated_it": { + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "event_type": { + "type": "string", + "title": "Event Type" + }, + "actor_id": { "anyOf": [ { - "type": "boolean" + "type": "string", + "format": "uuid" }, { "type": "null" } ], - "title": "Has Dedicated It" + "title": "Actor Id" }, - "monthly_request_volume": { + "actor_role": { "anyOf": [ { "type": "string" @@ -1395,54 +11424,79 @@ "type": "null" } ], - "title": "Monthly Request Volume" + "title": "Actor Role" }, - "onboarding_status": { + "description": { "type": "string", - "title": "Onboarding Status" - }, - "profile_data": { - "additionalProperties": true, - "type": "object", - "title": "Profile Data" + "title": "Description" }, - "gap_map": { - "additionalProperties": true, - "type": "object", - "title": "Gap Map" + "internal_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Internal Note" }, "created_at": { "type": "string", "format": "date-time", "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "event_type", + "actor_id", + "actor_role", + "description", + "internal_note", + "created_at" + ], + "title": "TimelineEventRead" + }, + "TimelineView": { + "properties": { + "id": { + "type": "string", + "title": "Id" }, - "updated_at": { + "action": { "type": "string", - "format": "date-time", - "title": "Updated At" + "title": "Action" + }, + "actor": { + "type": "string", + "title": "Actor" + }, + "note": { + "type": "string", + "title": "Note" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" } }, + "additionalProperties": false, "type": "object", "required": [ "id", - "city_name", - "state", - "county", - "population_band", - "email_platform", - "has_dedicated_it", - "monthly_request_volume", - "onboarding_status", - "profile_data", - "gap_map", - "created_at", - "updated_at" + "action", + "actor", + "note", + "created_at_unix_seconds" ], - "title": "CityProfileRead" + "title": "TimelineView" }, - "CityProfileUpdate": { + "TitleCreate": { "properties": { - "city_name": { + "title_id": { "anyOf": [ { "type": "string" @@ -1451,124 +11505,217 @@ "type": "null" } ], - "title": "City Name" + "title": "Title Id" + }, + "title_number": { + "type": "string", + "minLength": 1, + "title": "Title Number" + }, + "title_name": { + "type": "string", + "minLength": 1, + "title": "Title Name" + }, + "sort_order": { + "type": "integer", + "title": "Sort Order", + "default": 0 + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title_number", + "title_name" + ], + "title": "TitleCreate", + "description": "Request body for creating a code title." + }, + "TranscriptInput": { + "properties": { + "source_label": { + "type": "string", + "minLength": 1, + "title": "Source Label" + }, + "transcript_text": { + "type": "string", + "minLength": 1, + "title": "Transcript Text" + }, + "correction_of_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Correction Of Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_label", + "transcript_text" + ], + "title": "TranscriptInput" + }, + "UserRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "email": { + "type": "string", + "format": "email", + "title": "Email" + }, + "is_active": { + "type": "boolean", + "title": "Is Active", + "default": true + }, + "is_superuser": { + "type": "boolean", + "title": "Is Superuser", + "default": false }, - "state": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "State" + "is_verified": { + "type": "boolean", + "title": "Is Verified", + "default": false }, - "county": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "County" + "full_name": { + "type": "string", + "title": "Full Name" }, - "population_band": { + "role": { + "$ref": "#/components/schemas/UserRole" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "last_login": { "anyOf": [ { - "type": "string" + "type": "string", + "format": "date-time" }, { "type": "null" } ], - "title": "Population Band" + "title": "Last Login" }, - "email_platform": { + "must_change_password": { + "type": "boolean", + "title": "Must Change Password", + "default": false + }, + "department_id": { "anyOf": [ { - "type": "string" + "type": "string", + "format": "uuid" }, { "type": "null" } ], - "title": "Email Platform" - }, - "has_dedicated_it": { + "title": "Department Id" + } + }, + "type": "object", + "required": [ + "id", + "email", + "full_name", + "role", + "created_at", + "last_login" + ], + "title": "UserRead" + }, + "UserRole": { + "type": "string", + "enum": [ + "admin", + "staff", + "reviewer", + "read_only", + "liaison", + "public" + ], + "title": "UserRole" + }, + "UserSelfUpdate": { + "properties": { + "password": { "anyOf": [ { - "type": "boolean" + "type": "string" }, { "type": "null" } ], - "title": "Has Dedicated It" + "title": "Password" }, - "monthly_request_volume": { + "email": { "anyOf": [ { - "type": "string" + "type": "string", + "format": "email" }, { "type": "null" } ], - "title": "Monthly Request Volume" + "title": "Email" }, - "onboarding_status": { + "is_active": { "anyOf": [ { - "type": "string" + "type": "boolean" }, { "type": "null" } ], - "title": "Onboarding Status" + "title": "Is Active" }, - "profile_data": { + "is_superuser": { "anyOf": [ { - "additionalProperties": true, - "type": "object" + "type": "boolean" }, { "type": "null" } ], - "title": "Profile Data" + "title": "Is Superuser" }, - "gap_map": { + "is_verified": { "anyOf": [ { - "additionalProperties": true, - "type": "object" + "type": "boolean" }, { "type": "null" } ], - "title": "Gap Map" - } - }, - "type": "object", - "title": "CityProfileUpdate" - }, - "DepartmentCreate": { - "properties": { - "name": { - "type": "string", - "title": "Name" - }, - "code": { - "type": "string", - "title": "Code" + "title": "Is Verified" }, - "contact_email": { + "full_name": { "anyOf": [ { "type": "string" @@ -1577,32 +11724,16 @@ "type": "null" } ], - "title": "Contact Email" + "title": "Full Name" } }, "type": "object", - "required": [ - "name", - "code" - ], - "title": "DepartmentCreate" + "title": "UserSelfUpdate", + "description": "Schema for user self-update via PATCH /users/me.\n\nExcludes role and department_id. Any payload containing those fields is\nrejected at parse time (HTTP 422). Role and department changes require\nadmin privileges via /admin/users/{id}." }, - "DepartmentRead": { + "UserUpdateRequest": { "properties": { - "id": { - "type": "string", - "format": "uuid", - "title": "Id" - }, - "name": { - "type": "string", - "title": "Name" - }, - "code": { - "type": "string", - "title": "Code" - }, - "contact_email": { + "full_name": { "anyOf": [ { "type": "string" @@ -1611,27 +11742,9 @@ "type": "null" } ], - "title": "Contact Email" + "title": "Full Name" }, - "created_at": { - "type": "string", - "format": "date-time", - "title": "Created At" - } - }, - "type": "object", - "required": [ - "id", - "name", - "code", - "contact_email", - "created_at" - ], - "title": "DepartmentRead" - }, - "DepartmentUpdate": { - "properties": { - "name": { + "role": { "anyOf": [ { "type": "string" @@ -1640,345 +11753,355 @@ "type": "null" } ], - "title": "Name" + "title": "Role" }, - "code": { + "department_id": { "anyOf": [ { - "type": "string" + "type": "string", + "format": "uuid" }, { "type": "null" } ], - "title": "Code" + "title": "Department Id" }, - "contact_email": { + "is_active": { "anyOf": [ { - "type": "string" + "type": "boolean" }, { "type": "null" } ], - "title": "Contact Email" - } - }, - "type": "object", - "title": "DepartmentUpdate" - }, - "ExportReceipt": { - "properties": { - "export_path": { - "type": "string", - "maxLength": 32768, - "minLength": 1, - "title": "Export Path" + "title": "Is Active" } }, - "additionalProperties": false, "type": "object", - "required": [ - "export_path" - ], - "title": "ExportReceipt" + "title": "UserUpdateRequest" }, - "FormPlan": { + "ValidationError": { "properties": { - "action": { + "loc": { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "integer" + } + ] + }, + "type": "array", + "title": "Location" + }, + "msg": { "type": "string", - "const": "form-plan", - "title": "Action" + "title": "Message" }, - "formName": { + "type": { "type": "string", - "maxLength": 500, - "title": "Formname", - "default": "" + "title": "Error Type" }, - "fields": { - "items": { - "type": "string" - }, - "type": "array", - "maxItems": 50, - "title": "Fields" + "input": { + "title": "Input" + }, + "ctx": { + "type": "object", + "title": "Context" } }, - "additionalProperties": false, "type": "object", "required": [ - "action" + "loc", + "msg", + "type" ], - "title": "FormPlan" + "title": "ValidationError" }, - "HTTPValidationError": { + "Version": { "properties": { - "detail": { - "items": { - "$ref": "#/components/schemas/ValidationError" - }, - "type": "array", - "title": "Detail" + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" } }, + "additionalProperties": false, "type": "object", - "title": "HTTPValidationError" + "required": [ + "sequence" + ], + "title": "Version" }, - "PortalModeResponse": { + "VoteCorrection": { "properties": { - "mode": { + "vote": { "type": "string", - "enum": [ - "public", - "private" - ], - "title": "Mode", - "description": "Active portal posture for this deployment. ``public`` = minimal resident surface (landing + authenticated records-request submission + resident registration) reachable without staff auth. ``private`` = staff-only; no public routes, no resident self-registration." + "minLength": 1, + "title": "Vote" + }, + "reason": { + "type": "string", + "minLength": 1, + "title": "Reason" } }, + "additionalProperties": false, "type": "object", "required": [ - "mode" + "vote", + "reason" ], - "title": "PortalModeResponse", - "description": "T5D \u2014 schema for ``GET /config/portal-mode``.\n\nExposed to the frontend on boot so it can branch routing without a\nuser-identity lookup. The payload is intentionally the single field\nbelow \u2014 no staff config, no user state, no schema version." + "title": "VoteCorrection" }, - "PublishingPlan": { + "VoteInput": { "properties": { - "action": { - "type": "string", - "const": "publishing-workflow", - "title": "Action" - }, - "title": { + "voter_name": { "type": "string", - "maxLength": 500, - "title": "Title", - "default": "" - }, - "hasReview": { - "type": "boolean", - "title": "Hasreview", - "default": false - }, - "hasPlainLanguage": { - "type": "boolean", - "title": "Hasplainlanguage", - "default": false + "minLength": 1, + "title": "Voter Name" }, - "hasTranslationReview": { - "type": "boolean", - "title": "Hastranslationreview", - "default": false + "vote": { + "type": "string", + "minLength": 1, + "title": "Vote" } }, "additionalProperties": false, "type": "object", "required": [ - "action" + "voter_name", + "vote" ], - "title": "PublishingPlan" + "title": "VoteInput" }, - "ReviewInput": { + "_ParcelLookupIn": { "properties": { - "title": { - "type": "string", - "maxLength": 500, - "title": "Title", - "default": "" - }, - "body": { + "jurisdiction": { "type": "string", - "maxLength": 5000, - "title": "Body", - "default": "" - }, - "hasAltText": { - "type": "boolean", - "title": "Hasalttext", - "default": false + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" }, - "language": { + "query": { "type": "string", - "maxLength": 80, - "title": "Language", - "default": "en" + "maxLength": 500, + "minLength": 1, + "title": "Query" } }, "additionalProperties": false, "type": "object", - "title": "ReviewInput" + "required": [ + "jurisdiction", + "query" + ], + "title": "_ParcelLookupIn" }, - "RewriteInput": { + "townlight_inspections__workflow_models__SourceLink": { "properties": { - "action": { + "provider": { "type": "string", - "enum": [ - "plain-language", - "language-variant" - ], - "title": "Action" + "const": "code", + "title": "Provider", + "default": "code" }, - "text": { + "source_id": { "type": "string", - "maxLength": 5000, + "maxLength": 500, "minLength": 1, - "title": "Text" + "title": "Source Id" }, - "language": { + "expected_sha256": { "type": "string", - "maxLength": 80, - "title": "Language", - "default": "" + "pattern": "^[a-f0-9]{64}$", + "title": "Expected Sha256" } }, "additionalProperties": false, "type": "object", "required": [ - "action", - "text" + "source_id", + "expected_sha256" ], - "title": "RewriteInput" + "title": "SourceLink" }, - "RewriteResult": { + "townlight_permitting__workflow_models__SourceLink": { "properties": { - "action": { + "provider": { "type": "string", "enum": [ - "plain-language", - "language-variant" + "code", + "zoning" ], - "title": "Action" + "title": "Provider" }, - "text": { + "source_id": { "type": "string", - "maxLength": 5000, + "maxLength": 500, "minLength": 1, - "title": "Text" + "title": "Source Id" }, - "language": { + "expected_sha256": { "type": "string", - "maxLength": 80, - "title": "Language", - "default": "" + "pattern": "^[a-f0-9]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "source_id", + "expected_sha256" + ], + "title": "SourceLink" + }, + "townlight_runtime__inspections_bridge__Search": { + "properties": { + "provider": { + "type": "string", + "const": "code", + "title": "Provider" }, - "outcome": { + "query": { "type": "string", - "enum": [ - "generated", - "unavailable" - ], - "title": "Outcome" + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "query" + ], + "title": "Search" + }, + "townlight_runtime__notice_bridge__Review": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" }, - "generated": { - "anyOf": [ - { - "type": "string", - "maxLength": 100000 - }, - { - "type": "null" - } - ], - "title": "Generated" + "note": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence", + "note" + ], + "title": "Review" + }, + "townlight_runtime__permitting_bridge__Import": { + "properties": { + "bundle": { + "$ref": "#/components/schemas/RequirementBundle" }, - "model": { + "expected_revision": { "anyOf": [ { "type": "string", - "maxLength": 200 + "format": "uuid" }, { "type": "null" } ], - "title": "Model" + "title": "Expected Revision" } }, "additionalProperties": false, "type": "object", "required": [ - "action", - "text", - "outcome" + "bundle" ], - "title": "RewriteResult" + "title": "Import" }, - "SaveReview": { + "townlight_runtime__permitting_bridge__Search": { "properties": { - "title": { - "type": "string", - "maxLength": 500, - "title": "Title", - "default": "" - }, - "body": { + "provider": { "type": "string", - "maxLength": 5000, - "title": "Body", - "default": "" - }, - "hasAltText": { - "type": "boolean", - "title": "Hasalttext", - "default": false + "enum": [ + "code", + "zoning" + ], + "title": "Provider" }, - "language": { + "query": { "type": "string", - "maxLength": 80, - "title": "Language", - "default": "en" - }, - "ai_analysis": { - "anyOf": [ - { - "type": "string", - "maxLength": 100000 - }, - { - "type": "null" - } - ], - "title": "Ai Analysis" + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "query" + ], + "title": "Search" + }, + "townlight_runtime__planning_bridge__Import": { + "properties": { + "bundle": { + "additionalProperties": true, + "type": "object", + "title": "Bundle" }, - "ai_analysis_model": { + "expected_previous_revision": { "anyOf": [ { "type": "string", - "maxLength": 200 + "maxLength": 36, + "minLength": 36 }, { "type": "null" } ], - "title": "Ai Analysis Model" - }, - "ai_outcome": { - "type": "string", - "enum": [ - "generated", - "unavailable", - "failed" - ], - "title": "Ai Outcome" + "title": "Expected Previous Revision" } }, "additionalProperties": false, "type": "object", "required": [ - "ai_outcome" + "bundle" ], - "title": "SaveReview" + "title": "Import" }, - "SearchInput": { + "townlight_runtime__planning_bridge__Search": { "properties": { "query": { "type": "string", - "maxLength": 5000, + "maxLength": 2000, "minLength": 1, "title": "Query" + }, + "plan_type": { + "anyOf": [ + { + "type": "string", + "maxLength": 40 + }, + { + "type": "null" + } + ], + "title": "Plan Type" } }, "additionalProperties": false, @@ -1986,72 +12109,37 @@ "required": [ "query" ], - "title": "SearchInput" + "title": "Search" }, - "TaggedPlan": { + "townlight_runtime__zoning_bridge__Review": { "properties": { - "action": { + "answer": { "type": "string", - "const": "tagged-pdf", - "title": "Action" - }, - "headingLevels": { - "items": { - "type": "integer", - "maximum": 4294967295.0, - "minimum": 0.0 - }, - "type": "array", - "maxItems": 50, - "title": "Headinglevels" - } - }, - "additionalProperties": false, - "type": "object", - "required": [ - "action" - ], - "title": "TaggedPlan" - }, - "ValidationError": { - "properties": { - "loc": { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "integer" - } - ] - }, - "type": "array", - "title": "Location" + "maxLength": 10000, + "title": "Answer", + "default": "" }, - "msg": { + "notes": { "type": "string", - "title": "Message" + "maxLength": 10000, + "title": "Notes", + "default": "" }, - "type": { + "queue_status": { "type": "string", - "title": "Error Type" - }, - "input": { - "title": "Input" - }, - "ctx": { - "type": "object", - "title": "Context" + "enum": [ + "open", + "in_review", + "resolved", + "closed" + ], + "title": "Queue Status", + "default": "resolved" } }, + "additionalProperties": false, "type": "object", - "required": [ - "loc", - "msg", - "type" - ], - "title": "ValidationError" + "title": "Review" } }, "securitySchemes": { @@ -2066,5 +12154,9 @@ } } }, - "x-townlight-boundary": "Effective outer runtime plus selected mounted inner-domain paths; outer /health wins" -} \ No newline at end of file + "x-townlight-component": { + "view": "core", + "identity": "Townlight Core 1.3.0.dev2", + "evidence": "source-schema-only" + } +} diff --git a/docs/beta-1/api/core.html b/docs/beta-1/api/core.html index a2d38aa..07dc8dd 100644 --- a/docs/beta-1/api/core.html +++ b/docs/beta-1/api/core.html @@ -1,5 +1,4 @@ -Townlight -Core API Reference | Townlight Beta 1
townlightTownlight Beta 1
-
Townlight Beta 1

Townlight -Core API -Reference

Staff guide and technical reference

Documentation edition 30 October 2026
Existing component versions retained
Signed suite installer 1.6.0.1
Private beta documentation companion

API -reference scope

-

This is the Townlight Beta 1 technical contract for -Core. The desktop-domain entries below come from the installed -candidate’s generated OpenAPI schema. Export did not start a server, -enter application lifespan, run migrations or contact a database. It is -schema evidence, not proof of every endpoint’s runtime behavior. The -acceptance section of the operating manual identifies exercised -paths.

-

The complete filtered OpenAPI JSON -preserves request bodies, parameters, response declarations, constraints -and referenced schemas. An empty response schema means that this -application did not declare a structured response model; do not infer a -stronger contract from a green HTTP status. HTTP authorization enforced -inside dependencies is still required when an automatically generated -header parameter says optional.

-

Origins and authentication

-

The canonical native domain transport uses -http://127.0.0.1:15480. The native shell supplies -X-Townlight-Session and maps it to a persisted SQL -identity; browser code must not invent an actor or role. A trusted local -integration must protect that proof as a credential and revalidate -current authority. Standalone /auth/jwt/login uses the -existing bearer-token flow; that token is not interchangeable with -native proof. Public routes have their own permission and deployment -gates. Do not bind the native domain runtime to a non-loopback -interface.

-

Station defaults to explicit loopback port 8756. Its -service revalidates Townlight authority. Its browser exchanges a one-use -60-second ticket for a 900-second HttpOnly SameSite Strict operator -cookie. Browser mutations require the exact Origin and -X-Station-UI: 1. Native session proof must not be put in a -URL or shipped to an MCP client.

-

Failure and retry contract

-

401 means missing/expired identity; 403 -means permission or origin denial; 404 means a missing or -unavailable resource; 409 commonly means revision, -source-hash, lifecycle or idempotency conflict; 422 means -invalid input; 429 means a bounded rate/capacity refusal; -503 means an unavailable dependency, configuration or -schema. Individual routes may use only a subset and source-derived -checks can add errors absent from generated response declarations. -Preserve edits, read the detail and inspect current state before -retrying a write. Neither a retry nor an idempotency key authorizes a -changed payload.

-

Effective installed -runtime contract

-

The inner domain export in -reference/desktop-domain-openapi.json has 243 paths and 245 -schemas. The installed host is a second FastAPI application: it -registers GET /health, GET /modules -and GET /ready before mounting that domain application -at /. Its /health therefore -overrides the inner app.main.health at the -installed origin. The effective composition has 245 unique URI paths. -The filtered downloads for Suite, Core and Records compose those real -outer routes over their inner-domain selection; the original inner and -outer exports remain separate evidence files.

- ---- - - - - - - - - - - - - - - - - - - - - -
Outer operationActual response and use
GET /healthRuntime status (ok or -degraded), service/version, product profile, module checks, -database check and local_only. HTTP 200 when healthy, -otherwise 503. This is not the inner app’s simple status/version -handler.
GET /modulesThe same runtime health payload and HTTP status as -/health; not a second independent readiness proof.
GET /readystatus (ready or not-ready) -and reason; HTTP 200/503 after the applicable activation, -schema and provider checks. Use this for domain readiness.
-

For example, a ready result has shape -{"status":"ready","reason":"<actual profile-specific readiness reason>"}; -an inactive domain returns -{"status":"not-ready","reason":"domain-inactive"} with 503. -These are source-derived shapes, not new execution receipts. Read the -actual reason rather than treating a listening process or -/health alone as canonical readiness.

-

The native origin remains http://127.0.0.1:15480. -Station’s separately paired suite process can use another explicitly -configured loopback port; its Station origin and the Station service’s -suite origin must agree. The Station operating guide supplies that setup -without disabling normal activation.

-

Installed desktop HTTP -operations

-

GET /config/portal-mode

-

Get the deployment’s current portal posture.

-

Operation ID: get_portal_mode_config_portal_mode_get. -Tags: public.

- - - - - - - - - - - - - - - -
Declared statusDescriptionResponse model
200Successful Responseapplication/json: PortalModeResponse
-

GET /city-profile

-

Get City Profile

-

Operation ID: get_city_profile_city_profile_get. Tags: -city-profile.

- ----- - - - - - - - - - - - - - - -
Declared statusDescriptionResponse model
200Successful Responseapplication/json: CityProfileRead or null
-

POST /city-profile

-

Create City Profile

-

Operation ID: create_city_profile_city_profile_post. -Tags: city-profile.

-

Request body: application/json; required. Model: -CityProfileCreate.

- - - - - - - - - - - - - - - - - - - - -
Declared statusDescriptionResponse model
201Successful Responseapplication/json: CityProfileRead
422Validation Errorapplication/json: HTTPValidationError
-

PATCH /city-profile

-

Update City Profile

-

Operation ID: update_city_profile_city_profile_patch. -Tags: city-profile.

-

Request body: application/json; required. Model: -CityProfileUpdate.

- - - - - - - - - - - - - - - - - - - - -
Declared statusDescriptionResponse model
200Successful Responseapplication/json: CityProfileRead
422Validation Errorapplication/json: HTTPValidationError
-

GET /catalog/domains

-

List Domains

-

Operation ID: list_domains_catalog_domains_get. Tags: -catalog.

- - - - - - - - - - - - - - - -
Declared statusDescriptionResponse model
200Successful Responseapplication/json: Unspecified JSON shape
-

GET /catalog/systems

-

List Systems

-

Operation ID: list_systems_catalog_systems_get. Tags: -catalog.

- - - - - - - - - - - - - - - - - -
ParameterLocationRequiredType and constraints
domainqueryno at schema levelstring or null
- - - - - - - - - - - - - - - - - - - - -
Declared statusDescriptionResponse model
200Successful Responseapplication/json: Unspecified JSON shape
422Validation Errorapplication/json: HTTPValidationError
-

GET /catalog/connectors

-

List Connectors

-

Operation ID: list_connectors_catalog_connectors_get. -Tags: catalog.

- - - - - - - - - - - - - - - - - -
ParameterLocationRequiredType and constraints
domainqueryyesstring
- - - - - - - - - - - - - - - - - - - - -
Declared statusDescriptionResponse model
200Successful Responseapplication/json: Unspecified JSON shape
422Validation Errorapplication/json: HTTPValidationError
-

POST /catalog/load

-

Trigger Catalog Load

-

Operation ID: trigger_catalog_load_catalog_load_post. -Tags: catalog.

- - - - - - - - - - - - - - - -
Declared statusDescriptionResponse model
200Successful Responseapplication/json: Unspecified JSON shape
-

GET /departments/

-

List Departments

-

Operation ID: list_departments_departments__get. Tags: -departments.

- ----- - - - - - - - - - - - - - - -
Declared statusDescriptionResponse model
200Successful Responseapplication/json: array of DepartmentRead
-

POST /departments/

-

Create Department

-

Operation ID: create_department_departments__post. Tags: -departments.

-

Request body: application/json; required. Model: -DepartmentCreate.

- - - - - - - - - - - - - - - - - - - - -
Declared statusDescriptionResponse model
201Successful Responseapplication/json: DepartmentRead
422Validation Errorapplication/json: HTTPValidationError
-

GET /departments/{dept_id}

-

Get Department

-

Operation ID: get_department_departments__dept_id__get. -Tags: departments.

- - - - - - - - - - - - - - - - - -
ParameterLocationRequiredType and constraints
dept_idpathyesstring; format=uuid
- - - - - - - - - - - - - - - - - - - - -
Declared statusDescriptionResponse model
200Successful Responseapplication/json: DepartmentRead
422Validation Errorapplication/json: HTTPValidationError
-

PATCH /departments/{dept_id}

-

Update Department

-

Operation ID: -update_department_departments__dept_id__patch. Tags: -departments.

- - - - - - - - - - - - - - - - - -
ParameterLocationRequiredType and constraints
dept_idpathyesstring; format=uuid
-

Request body: application/json; required. Model: -DepartmentUpdate.

- - - - - - - - - - - - - - - - - - - - -
Declared statusDescriptionResponse model
200Successful Responseapplication/json: DepartmentRead
422Validation Errorapplication/json: HTTPValidationError
-

DELETE /departments/{dept_id}

-

Delete Department

-

Operation ID: -delete_department_departments__dept_id__delete. Tags: -departments.

- - - - - - - - - - - - - - - - - -
ParameterLocationRequiredType and constraints
dept_idpathyesstring; format=uuid
- - - - - - - - - - - - - - - - - - - - -
Declared statusDescriptionResponse model
204Successful ResponseNo content model declared
422Validation Errorapplication/json: HTTPValidationError
-

GET /health

-

Runtime Health

-

Operation ID: runtime_health_health_get. Tags: .

- - - - - - - - - - - - - - - -
Declared statusDescriptionResponse model
200Successful Responseapplication/json: Unspecified JSON shape
-

GET /desktop/v1/access/state

-

Access State

-

Operation ID: access_state_desktop_v1_access_state_get. -Tags: native-access.

- - - - - - - - - - - - - - - - - -
ParameterLocationRequiredType and constraints
X-Townlight-Sessionheaderno at schema levelstring or null
- - - - - - - - - - - - - - - - - - - - -
Declared statusDescriptionResponse model
200Successful Responseapplication/json: Unspecified JSON shape
422Validation Errorapplication/json: HTTPValidationError
-

POST -/desktop/v1/access/review-context

-

Review Context

-

Operation ID: -review_context_desktop_v1_access_review_context_post. Tags: -native-access.

- - - - - - - - - - - - - - - - - -
ParameterLocationRequiredType and constraints
X-Townlight-Sessionheaderno at schema levelstring or null
-

Request body: application/json; required. Model: -ReviewInput.

- - - - - - - - - - - - - - - - - - - - -
Declared statusDescriptionResponse model
200Successful Responseapplication/json: Unspecified JSON shape
422Validation Errorapplication/json: HTTPValidationError
-

POST -/desktop/v1/access/reviews

-

Save Review

-

Operation ID: -save_review_desktop_v1_access_reviews_post. Tags: -native-access.

- - - - - - - - - - - - - - - - - -
ParameterLocationRequiredType and constraints
X-Townlight-Sessionheaderno at schema levelstring or null
-

Request body: application/json; required. Model: -SaveReview.

- - - - - - - - - - - - - - - - - - - - -
Declared statusDescriptionResponse model
200Successful Responseapplication/json: Unspecified JSON shape
422Validation Errorapplication/json: HTTPValidationError
-

POST -/desktop/v1/access/reviews/{review_id}/delete

-

Delete Review

-

Operation ID: -delete_review_desktop_v1_access_reviews__review_id__delete_post. -Tags: native-access.

- - - - - - - - - - - - - - - - - - - - - - - -
ParameterLocationRequiredType and constraints
review_idpathyesstring; format=uuid
X-Townlight-Sessionheaderno at schema levelstring or null
- - - - - - - - - - - - - - - - - - - - -
Declared statusDescriptionResponse model
200Successful Responseapplication/json: Unspecified JSON shape
422Validation Errorapplication/json: HTTPValidationError
-

POST /desktop/v1/access/tools

-

Tool

-

Operation ID: tool_desktop_v1_access_tools_post. Tags: -native-access.

- - - - - - - - - - - - - - - - - -
ParameterLocationRequiredType and constraints
X-Townlight-Sessionheaderno at schema levelstring or null
-

Request body: application/json; required. Model: -object.

- - - - - - - - - - - - - - - - - - - - -
Declared statusDescriptionResponse model
200Successful Responseapplication/json: Unspecified JSON shape
422Validation Errorapplication/json: HTTPValidationError
-

POST -/desktop/v1/access/rewrite-context

-

Rewrite Context

-

Operation ID: -rewrite_context_desktop_v1_access_rewrite_context_post. -Tags: native-access.

- - - - - - - - - - - - - - - - - -
ParameterLocationRequiredType and constraints
X-Townlight-Sessionheaderno at schema levelstring or null
-

Request body: application/json; required. Model: -RewriteInput.

- - - - - - - - - - - - - - - - - - - - -
Declared statusDescriptionResponse model
200Successful Responseapplication/json: Unspecified JSON shape
422Validation Errorapplication/json: HTTPValidationError
-

POST -/desktop/v1/access/rewrite-result

-

Rewrite Result

-

Operation ID: -rewrite_result_desktop_v1_access_rewrite_result_post. Tags: -native-access.

- - - - - - - - - - - - - - - - - -
ParameterLocationRequiredType and constraints
X-Townlight-Sessionheaderno at schema levelstring or null
-

Request body: application/json; required. Model: -RewriteResult.

- - - - - - - - - - - - - - - - - - - - -
Declared statusDescriptionResponse model
200Successful Responseapplication/json: Unspecified JSON shape
422Validation Errorapplication/json: HTTPValidationError
-

POST -/desktop/v1/access/reviews/{review_id}/export

-

Prepare Export

-

Operation ID: -prepare_export_desktop_v1_access_reviews__review_id__export_post. -Tags: native-access.

- - - - - - - - - - - - - - - - - - - - - - - -
ParameterLocationRequiredType and constraints
review_idpathyesstring; format=uuid
X-Townlight-Sessionheaderno at schema levelstring or null
- - - - - - - - - - - - - - - - - - - - -
Declared statusDescriptionResponse model
200Successful Responseapplication/json: Unspecified JSON shape
422Validation Errorapplication/json: HTTPValidationError
-

POST -/desktop/v1/access/exports/{artifact_id}/complete

-

Complete Export

-

Operation ID: -complete_export_desktop_v1_access_exports__artifact_id__complete_post. -Tags: native-access.

- - - - - - - - - - - - - - - - - - - - - - - -
ParameterLocationRequiredType and constraints
artifact_idpathyesstring; format=uuid
X-Townlight-Sessionheaderno at schema levelstring or null
-

Request body: application/json; required. Model: -ExportReceipt.

- - - - - - - - - - - - - - - - - - - - -
Declared statusDescriptionResponse model
200Successful Responseapplication/json: Unspecified JSON shape
422Validation Errorapplication/json: HTTPValidationError
-

GET /desktop/v1/suite/state

-

Suite State

-

Operation ID: suite_state_desktop_v1_suite_state_get. -Tags: native-records-snapshot.

- - - - - - - - - - - - - - - - - -
ParameterLocationRequiredType and constraints
X-Townlight-Sessionheaderno at schema levelstring or null
- - - - - - - - - - - - - - - - - - - - -
Declared statusDescriptionResponse model
200Successful Responseapplication/json: Unspecified JSON shape
422Validation Errorapplication/json: HTTPValidationError
-

POST /desktop/v1/suite/search

-

Search

-

Operation ID: search_desktop_v1_suite_search_post. Tags: -native-records-snapshot.

- - - - - - - - - - - - - - - - - -
ParameterLocationRequiredType and constraints
X-Townlight-Sessionheaderno at schema levelstring or null
-

Request body: application/json; required. Model: -SearchInput.

- - - - - - - - - - - - - - - - - - - - -
Declared statusDescriptionResponse model
200Successful Responseapplication/json: Unspecified JSON shape
422Validation Errorapplication/json: HTTPValidationError
-

GET /modules

-

Runtime Health

-

Operation ID: runtime_health_modules_get. Tags: .

- - - - - - - - - - - - - - - -
Declared statusDescriptionResponse model
200Successful Responseapplication/json: Unspecified JSON shape
-

GET /ready

-

Domain Ready

-

Operation ID: domain_ready_ready_get. Tags: .

- - - - - - - - - - - - - - - -
Declared statusDescriptionResponse model
200Successful Responseapplication/json: Unspecified JSON shape
-

Request and response data -dictionary

-

Fields below retain the actual schema requirements and constraints. -null and omitted are distinct where a model distinguishes -them. Additional-property rules apply per schema. Full discriminators, -nested definitions and defaults are retained in the JSON.

-

AdaPlan

-

Additional properties: false.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldRequiredType and constraintsDefault or description
actionyesstring; value ada-title-ii
serviceAreayesstring; minLength=1; maxLength=500
hasCoordinatorReviewnobooleandefault false.
-

CityProfileCreate

-

Additional properties: not explicitly declared.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldRequiredType and constraintsDefault or description
city_nameyesstring
statenostring or null
countynostring or null
population_bandnostring or null
email_platformnostring or null
has_dedicated_itnoboolean or null
monthly_request_volumenostring or null
profile_datanoobjectdefault {}.
gap_mapnoobjectdefault {}.
-

CityProfileRead

-

Additional properties: not explicitly declared.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldRequiredType and constraintsDefault or description
idyesstring; format=uuid
city_nameyesstring
stateyesstring or null
countyyesstring or null
population_bandyesstring or null
email_platformyesstring or null
has_dedicated_ityesboolean or null
monthly_request_volumeyesstring or null
onboarding_statusyesstring
profile_datayesobject
gap_mapyesobject
created_atyesstring; format=date-time
updated_atyesstring; format=date-time
-

CityProfileUpdate

-

Additional properties: not explicitly declared.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldRequiredType and constraintsDefault or description
city_namenostring or null
statenostring or null
countynostring or null
population_bandnostring or null
email_platformnostring or null
has_dedicated_itnoboolean or null
monthly_request_volumenostring or null
onboarding_statusnostring or null
profile_datanoobject or null
gap_mapnoobject or null
-

DepartmentCreate

-

Additional properties: not explicitly declared.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldRequiredType and constraintsDefault or description
nameyesstring
codeyesstring
contact_emailnostring or null
-

DepartmentRead

-

Additional properties: not explicitly declared.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldRequiredType and constraintsDefault or description
idyesstring; format=uuid
nameyesstring
codeyesstring
contact_emailyesstring or null
created_atyesstring; format=date-time
-

DepartmentUpdate

-

Additional properties: not explicitly declared.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldRequiredType and constraintsDefault or description
namenostring or null
codenostring or null
contact_emailnostring or null
-

ExportReceipt

-

Additional properties: false.

- - - - - - - - - - - - - - - - - -
FieldRequiredType and constraintsDefault or description
export_pathyesstring; minLength=1; maxLength=32768
-

FormPlan

-

Additional properties: false.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldRequiredType and constraintsDefault or description
actionyesstring; value form-plan
formNamenostring; maxLength=500default ““.
fieldsnoarray of string; maxItems=50
-

HTTPValidationError

-

Additional properties: not explicitly declared.

- - - - - - - - - - - - - - - - - -
FieldRequiredType and constraintsDefault or description
detailnoarray of ValidationError
-

PortalModeResponse

-

T5D — schema for GET /config/portal-mode.

-

Exposed to the frontend on boot so it can branch routing without a -user-identity lookup. The payload is intentionally the single field -below — no staff config, no user state, no schema version.

-

Additional properties: not explicitly declared.

- ------ - - - - - - - - - - - - - - - - -
FieldRequiredType and constraintsDefault or description
modeyesstring; values public, privateActive portal posture for this deployment. public = -minimal resident surface (landing + authenticated records-request -submission + resident registration) reachable without staff auth. -private = staff-only; no public routes, no resident -self-registration.
-

PublishingPlan

-

Additional properties: false.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldRequiredType and constraintsDefault or description
actionyesstring; value publishing-workflow
titlenostring; maxLength=500default ““.
hasReviewnobooleandefault false.
hasPlainLanguagenobooleandefault false.
hasTranslationReviewnobooleandefault false.
-

ReviewInput

-

Additional properties: false.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldRequiredType and constraintsDefault or description
titlenostring; maxLength=500default ““.
bodynostring; maxLength=5000default ““.
hasAltTextnobooleandefault false.
languagenostring; maxLength=80default “en”.
-

RewriteInput

-

Additional properties: false.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldRequiredType and constraintsDefault or description
actionyesstring; values plain-language, language-variant
textyesstring; minLength=1; maxLength=5000
languagenostring; maxLength=80default ““.
-

RewriteResult

-

Additional properties: false.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldRequiredType and constraintsDefault or description
actionyesstring; values plain-language, language-variant
textyesstring; minLength=1; maxLength=5000
languagenostring; maxLength=80default ““.
outcomeyesstring; values generated, unavailable
generatednostring; maxLength=100000 or null
modelnostring; maxLength=200 or null
-

SaveReview

-

Additional properties: false.

- ------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldRequiredType and constraintsDefault or description
titlenostring; maxLength=500default ““.
bodynostring; maxLength=5000default ““.
hasAltTextnobooleandefault false.
languagenostring; maxLength=80default “en”.
ai_analysisnostring; maxLength=100000 or null
ai_analysis_modelnostring; maxLength=200 or null
ai_outcomeyesstring; values generated, unavailable, failed
-

SearchInput

-

Additional properties: false.

- - - - - - - - - - - - - - - - - -
FieldRequiredType and constraintsDefault or description
queryyesstring; minLength=1; maxLength=5000
-

TaggedPlan

-

Additional properties: false.

- ------ - - - - - - - - - - - - - - - - - - - - - - -
FieldRequiredType and constraintsDefault or description
actionyesstring; value tagged-pdf
headingLevelsnoarray of integer; minimum=0.0; maximum=4294967295.0; -maxItems=50
-

ValidationError

-

Additional properties: not explicitly declared.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FieldRequiredType and constraintsDefault or description
locyesarray of string or integer
msgyesstring
typeyesstring
inputnoobject
ctxnoobject
-

Source route and -validation supplement

-

These declarations are extracted from the immutable candidate source. -Package standalone routes are a different deployment -surface from the mounted installed domain. They are listed to -document existing code, not to claim they all have installed or city -acceptance. A source declaration without a resolved include-router mount -is identified as such. Full signatures, direct HTTP refusals and schema -fields are retained in the source inventory.

-

router.py

-

Candidate source: -installed-owned-source/townlight_core/llm/registry/router.py.

-

GET /admin/models — handler -list_models, line 46. Declared router prefix included.

-
list_models(session: AsyncSession=Depends(get_session))
-

GET /admin/models/{model_id} — handler -get_model, line 53. Declared router prefix included.

-
get_model(model_id: int, session: AsyncSession=Depends(get_session))
-

Direct handler refusals: -HTTPException(status_code=404, detail=f'Model {model_id} not found').

-

POST /admin/models — handler -create_model, line 61. Declared router prefix included.

-
create_model(payload: ModelRegistryCreate, session: AsyncSession=Depends(get_session))
-

PATCH /admin/models/{model_id} — -handler update_model, line 73. Declared router prefix -included.

-
update_model(model_id: int, payload: ModelRegistryUpdate, session: AsyncSession=Depends(get_session))
-

Direct handler refusals: -HTTPException(status_code=404, detail=f'Model {model_id} not found').

-

DELETE /admin/models/{model_id} — -handler delete_model, line 89. Declared router prefix -included.

-
delete_model(model_id: int, session: AsyncSession=Depends(get_session))
-

Direct handler refusals: -HTTPException(status_code=404, detail=f'Model {model_id} not found').

-

services.py

-

Candidate source: -installed-owned-source/townlight_runtime/services.py.

-

GET /health — handler -runtime_health, line 439. Declared router prefix -included.

-
runtime_health()
-

GET /modules — handler -runtime_health, line 439. Declared router prefix -included.

-
runtime_health()
-

GET /ready — handler -domain_ready, line 444. Declared router prefix -included.

-
domain_ready()
-

Alphabetical contract index

-
    -
  • AdaPlan — request/response data -dictionary.

  • -
  • CityProfileCreate — request/response data -dictionary.

  • -
  • CityProfileRead — request/response data -dictionary.

  • -
  • CityProfileUpdate — request/response data -dictionary.

  • -
  • DepartmentCreate — request/response data -dictionary.

  • -
  • DepartmentRead — request/response data -dictionary.

  • -
  • DepartmentUpdate — request/response data -dictionary.

  • -
  • ExportReceipt — request/response data -dictionary.

  • -
  • FormPlan — request/response data -dictionary.

  • -
  • HTTPValidationError — request/response data -dictionary.

  • -
  • PortalModeResponse — request/response data -dictionary.

  • -
  • PublishingPlan — request/response data -dictionary.

  • -
  • ReviewInput — request/response data -dictionary.

  • -
  • RewriteInput — request/response data -dictionary.

  • -
  • RewriteResult — request/response data -dictionary.

  • -
  • SaveReview — request/response data -dictionary.

  • -
  • SearchInput — request/response data -dictionary.

  • -
  • TaggedPlan — request/response data -dictionary.

  • -
  • ValidationError — request/response data -dictionary.

  • -
  • Authentication: Origins and authentication.

  • -
  • Conflicts and retry: Failure and retry contract.

  • -
  • Fields and validation: Request and response data -dictionary.

  • -
  • HTTP operations: Installed desktop HTTP operations.

  • -
  • Standalone boundaries: Source route and validation -supplement.

  • -
- \ No newline at end of file + +pre{white-space:pre-wrap;overflow-wrap:anywhere}summary{cursor:pointer;padding:.6rem;font-weight:600}details{margin:.5rem 0}
Townlight

Townlight Core API reference

+

Prepared source candidate, November 2, 2026. New signed Windows installed acceptance and publication remain pending.

+

Townlight Core 1.3.0.dev2. The HTTP host is Townlight Records 1.8.0.dev2. Component package versions and the host API version are separate identities.

+

Generated from the actual native inspections-preview composition without application lifespan, migrations or database/network access. It describes route and validation contracts; it does not establish endpoint behavior, individual authorization or installed acceptance. Standalone product applications have separate deployment boundaries.

+

Machine-readable OpenAPI schema · Operating manual and limits

+

HTTP operations

+
GET /catalog/connectors +
{
+  "tags": [
+    "catalog"
+  ],
+  "summary": "List Connectors",
+  "operationId": "list_connectors_catalog_connectors_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "domain",
+      "in": "query",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Domain"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /catalog/domains +
{
+  "tags": [
+    "catalog"
+  ],
+  "summary": "List Domains",
+  "operationId": "list_domains_catalog_domains_get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
POST /catalog/load +
{
+  "tags": [
+    "catalog"
+  ],
+  "summary": "Trigger Catalog Load",
+  "operationId": "trigger_catalog_load_catalog_load_post",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
GET /catalog/systems +
{
+  "tags": [
+    "catalog"
+  ],
+  "summary": "List Systems",
+  "operationId": "list_systems_catalog_systems_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "domain",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Domain"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /city-profile +
{
+  "tags": [
+    "city-profile"
+  ],
+  "summary": "Get City Profile",
+  "operationId": "get_city_profile_city_profile_get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "anyOf": [
+              {
+                "$ref": "#/components/schemas/CityProfileRead"
+              },
+              {
+                "type": "null"
+              }
+            ],
+            "title": "Response Get City Profile City Profile Get"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
POST /city-profile +
{
+  "tags": [
+    "city-profile"
+  ],
+  "summary": "Create City Profile",
+  "operationId": "create_city_profile_city_profile_post",
+  "requestBody": {
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/CityProfileCreate"
+        }
+      }
+    },
+    "required": true
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/CityProfileRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
PATCH /city-profile +
{
+  "tags": [
+    "city-profile"
+  ],
+  "summary": "Update City Profile",
+  "operationId": "update_city_profile_city_profile_patch",
+  "requestBody": {
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/CityProfileUpdate"
+        }
+      }
+    },
+    "required": true
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/CityProfileRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
GET /config/portal-mode +
{
+  "tags": [
+    "public"
+  ],
+  "summary": "Get the deployment's current portal posture.",
+  "operationId": "get_portal_mode_config_portal_mode_get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/PortalModeResponse"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /departments/ +
{
+  "tags": [
+    "departments"
+  ],
+  "summary": "List Departments",
+  "operationId": "list_departments_departments__get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "items": {
+              "$ref": "#/components/schemas/DepartmentRead"
+            },
+            "type": "array",
+            "title": "Response List Departments Departments  Get"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
POST /departments/ +
{
+  "tags": [
+    "departments"
+  ],
+  "summary": "Create Department",
+  "operationId": "create_department_departments__post",
+  "requestBody": {
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/DepartmentCreate"
+        }
+      }
+    },
+    "required": true
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/DepartmentRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
GET /departments/{dept_id} +
{
+  "tags": [
+    "departments"
+  ],
+  "summary": "Get Department",
+  "operationId": "get_department_departments__dept_id__get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "dept_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Dept Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/DepartmentRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
PATCH /departments/{dept_id} +
{
+  "tags": [
+    "departments"
+  ],
+  "summary": "Update Department",
+  "operationId": "update_department_departments__dept_id__patch",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "dept_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Dept Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/DepartmentUpdate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/DepartmentRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
DELETE /departments/{dept_id} +
{
+  "tags": [
+    "departments"
+  ],
+  "summary": "Delete Department",
+  "operationId": "delete_department_departments__dept_id__delete",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "dept_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Dept Id"
+      }
+    }
+  ],
+  "responses": {
+    "204": {
+      "description": "Successful Response"
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/access/exports/{artifact_id}/complete +
{
+  "tags": [
+    "native-access"
+  ],
+  "summary": "Complete Export",
+  "operationId": "complete_export_desktop_v1_access_exports__artifact_id__complete_post",
+  "parameters": [
+    {
+      "name": "artifact_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Artifact Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/ExportReceipt"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/access/review-context +
{
+  "tags": [
+    "native-access"
+  ],
+  "summary": "Review Context",
+  "operationId": "review_context_desktop_v1_access_review_context_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/ReviewInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/access/reviews +
{
+  "tags": [
+    "native-access"
+  ],
+  "summary": "Save Review",
+  "operationId": "save_review_desktop_v1_access_reviews_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/SaveReview"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/access/reviews/{review_id}/delete +
{
+  "tags": [
+    "native-access"
+  ],
+  "summary": "Delete Review",
+  "operationId": "delete_review_desktop_v1_access_reviews__review_id__delete_post",
+  "parameters": [
+    {
+      "name": "review_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Review Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/access/reviews/{review_id}/export +
{
+  "tags": [
+    "native-access"
+  ],
+  "summary": "Prepare Export",
+  "operationId": "prepare_export_desktop_v1_access_reviews__review_id__export_post",
+  "parameters": [
+    {
+      "name": "review_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Review Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/access/rewrite-context +
{
+  "tags": [
+    "native-access"
+  ],
+  "summary": "Rewrite Context",
+  "operationId": "rewrite_context_desktop_v1_access_rewrite_context_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/RewriteInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/access/rewrite-result +
{
+  "tags": [
+    "native-access"
+  ],
+  "summary": "Rewrite Result",
+  "operationId": "rewrite_result_desktop_v1_access_rewrite_result_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/RewriteResult"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/access/state +
{
+  "tags": [
+    "native-access"
+  ],
+  "summary": "Access State",
+  "operationId": "access_state_desktop_v1_access_state_get",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/access/tools +
{
+  "tags": [
+    "native-access"
+  ],
+  "summary": "Tool",
+  "operationId": "tool_desktop_v1_access_tools_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "oneOf": [
+            {
+              "$ref": "#/components/schemas/FormPlan"
+            },
+            {
+              "$ref": "#/components/schemas/PublishingPlan"
+            },
+            {
+              "$ref": "#/components/schemas/AdaPlan"
+            },
+            {
+              "$ref": "#/components/schemas/TaggedPlan"
+            }
+          ],
+          "discriminator": {
+            "propertyName": "action",
+            "mapping": {
+              "form-plan": "#/components/schemas/FormPlan",
+              "publishing-workflow": "#/components/schemas/PublishingPlan",
+              "ada-title-ii": "#/components/schemas/AdaPlan",
+              "tagged-pdf": "#/components/schemas/TaggedPlan"
+            }
+          },
+          "title": "Data"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/suite/search +
{
+  "tags": [
+    "native-records-snapshot"
+  ],
+  "summary": "Search",
+  "operationId": "search_desktop_v1_suite_search_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/SearchInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/suite/state +
{
+  "tags": [
+    "native-records-snapshot"
+  ],
+  "summary": "Suite State",
+  "operationId": "suite_state_desktop_v1_suite_state_get",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /health +
{
+  "summary": "Health",
+  "operationId": "health_health_get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    }
+  }
+}
+

Request and response data dictionary

+

Each schema includes the actual required fields, types, constraints and descriptions. References resolve against the machine-readable document.

+
ActionItemInput
+{
+  "properties": {
+    "description": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Description"
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "source_motion_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Motion Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "description"
+  ],
+  "title": "ActionItemInput"
+}
+
+
AdaPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "ada-title-ii",
+      "title": "Action"
+    },
+    "serviceArea": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Servicearea"
+    },
+    "hasCoordinatorReview": {
+      "type": "boolean",
+      "title": "Hascoordinatorreview",
+      "default": false
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "serviceArea"
+  ],
+  "title": "AdaPlan"
+}
+
+
AdminUserCreateRequest
+{
+  "properties": {
+    "email": {
+      "type": "string",
+      "title": "Email"
+    },
+    "password": {
+      "type": "string",
+      "title": "Password"
+    },
+    "full_name": {
+      "type": "string",
+      "title": "Full Name",
+      "default": ""
+    },
+    "role": {
+      "type": "string",
+      "title": "Role",
+      "default": "staff"
+    }
+  },
+  "type": "object",
+  "required": [
+    "email",
+    "password"
+  ],
+  "title": "AdminUserCreateRequest"
+}
+
+
AdminUserCreateResponse
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "email": {
+      "type": "string",
+      "title": "Email"
+    },
+    "full_name": {
+      "type": "string",
+      "title": "Full Name"
+    },
+    "role": {
+      "type": "string",
+      "title": "Role"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "email",
+    "full_name",
+    "role",
+    "is_active"
+  ],
+  "title": "AdminUserCreateResponse"
+}
+
+
AgendaAssignment
+{
+  "properties": {
+    "meeting_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Meeting Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "meeting_id"
+  ],
+  "title": "AgendaAssignment"
+}
+
+
AgendaInput
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "department_name": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Department Name"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "department_name"
+  ],
+  "title": "AgendaInput"
+}
+
+
AgendaReviewInput
+{
+  "properties": {
+    "to_status": {
+      "type": "string",
+      "enum": [
+        "DRAFTED",
+        "SUBMITTED",
+        "DEPT_APPROVED",
+        "LEGAL_REVIEWED",
+        "CLERK_ACCEPTED",
+        "ON_AGENDA",
+        "IN_PACKET",
+        "POSTED",
+        "HEARD",
+        "DISPOSED",
+        "ARCHIVED"
+      ],
+      "title": "To Status"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "to_status"
+  ],
+  "title": "AgendaReviewInput"
+}
+
+
AmendmentInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "policy": {
+      "$ref": "#/components/schemas/PolicySelection"
+    },
+    "proposal": {
+      "type": "string",
+      "maxLength": 20000,
+      "minLength": 1,
+      "title": "Proposal"
+    },
+    "responsible_staff": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Responsible Staff"
+    },
+    "status": {
+      "type": "string",
+      "enum": [
+        "draft",
+        "review",
+        "adopted",
+        "withdrawn"
+      ],
+      "title": "Status",
+      "default": "draft"
+    },
+    "review_note": {
+      "type": "string",
+      "maxLength": 5000,
+      "title": "Review Note",
+      "default": ""
+    },
+    "adoption_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Adoption Revision"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "policy",
+    "proposal",
+    "responsible_staff",
+    "note"
+  ],
+  "title": "AmendmentInput"
+}
+
+
AnalysisObservation
+{
+  "properties": {
+    "source": {
+      "type": "string",
+      "maxLength": 64,
+      "minLength": 1,
+      "title": "Source"
+    },
+    "filename": {
+      "type": "string",
+      "maxLength": 160,
+      "title": "Filename",
+      "default": ""
+    },
+    "media_type": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Media Type",
+      "default": ""
+    },
+    "text": {
+      "type": "string",
+      "maxLength": 4000,
+      "minLength": 1,
+      "title": "Text"
+    },
+    "adapter": {
+      "type": "string",
+      "maxLength": 120,
+      "title": "Adapter",
+      "default": ""
+    },
+    "citation_source_ids": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Citation Source Ids"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source",
+    "text"
+  ],
+  "title": "AnalysisObservation",
+  "description": "One draft observation, named with the adapter that actually produced it."
+}
+
+
AnalysisRecord
+{
+  "properties": {
+    "observations": {
+      "items": {
+        "$ref": "#/components/schemas/AnalysisObservation"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Observations"
+    },
+    "cited_sections": {
+      "items": {
+        "$ref": "#/components/schemas/CitedSection"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Cited Sections"
+    },
+    "unavailable": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Unavailable"
+    },
+    "runtime": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Runtime"
+    },
+    "review_required": {
+      "type": "boolean",
+      "title": "Review Required",
+      "default": true
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "AnalysisRecord",
+  "description": "The adapter output that accompanies a saved inspection draft."
+}
+
+
ApprovalCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "approve-records-response",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ApprovalPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "ApprovalCommand"
+}
+
+
ApprovalPayload
+{
+  "properties": {
+    "approvalNote": {
+      "type": "string",
+      "title": "Approvalnote",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "ApprovalPayload"
+}
+
+
ArchiveInput
+{
+  "properties": {
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "public",
+        "closed_session"
+      ],
+      "title": "Visibility"
+    },
+    "packet_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Packet Id"
+    },
+    "minutes_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Minutes Id"
+    },
+    "plain_language_summary": {
+      "type": "string",
+      "title": "Plain Language Summary",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "visibility"
+  ],
+  "title": "ArchiveInput"
+}
+
+
ArtifactPlan
+{
+  "properties": {
+    "artifact_id": {
+      "type": "string",
+      "title": "Artifact Id"
+    },
+    "file_name": {
+      "type": "string",
+      "title": "File Name"
+    },
+    "content": {
+      "type": "string",
+      "title": "Content"
+    },
+    "sha256": {
+      "type": "string",
+      "title": "Sha256"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "artifact_id",
+    "file_name",
+    "content",
+    "sha256",
+    "created_at_unix_seconds"
+  ],
+  "title": "ArtifactPlan"
+}
+
+
AssignCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "assign-records-request",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/AssignmentPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "AssignCommand"
+}
+
+
AssignmentPayload
+{
+  "properties": {
+    "assignedTo": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Assignedto"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "assignedTo"
+  ],
+  "title": "AssignmentPayload"
+}
+
+
AttachDocument
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation",
+      "default": ""
+    },
+    "file": {
+      "$ref": "#/components/schemas/ManagedFileReceipt"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "file"
+  ],
+  "title": "AttachDocument"
+}
+
+
AttachReleaseCopy
+{
+  "properties": {
+    "status": {
+      "type": "string",
+      "enum": [
+        "release-ready copy",
+        "redacted copy"
+      ],
+      "title": "Status"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note",
+      "default": ""
+    },
+    "added_by": {
+      "type": "string",
+      "title": "Added By",
+      "default": ""
+    },
+    "file": {
+      "$ref": "#/components/schemas/ManagedFileReceipt"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "status",
+    "file"
+  ],
+  "title": "AttachReleaseCopy"
+}
+
+
AuditChainVerification
+{
+  "properties": {
+    "is_valid": {
+      "type": "boolean",
+      "title": "Is Valid"
+    },
+    "entries_checked": {
+      "type": "integer",
+      "title": "Entries Checked"
+    },
+    "error_message": {
+      "type": "string",
+      "title": "Error Message"
+    }
+  },
+  "type": "object",
+  "required": [
+    "is_valid",
+    "entries_checked",
+    "error_message"
+  ],
+  "title": "AuditChainVerification"
+}
+
+
AuditLogRead
+{
+  "properties": {
+    "id": {
+      "type": "integer",
+      "title": "Id"
+    },
+    "prev_hash": {
+      "type": "string",
+      "title": "Prev Hash"
+    },
+    "entry_hash": {
+      "type": "string",
+      "title": "Entry Hash"
+    },
+    "timestamp": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Timestamp"
+    },
+    "user_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "User Id"
+    },
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "resource_type": {
+      "type": "string",
+      "title": "Resource Type"
+    },
+    "resource_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Resource Id"
+    },
+    "details": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Details"
+    },
+    "ai_generated": {
+      "type": "boolean",
+      "title": "Ai Generated"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "prev_hash",
+    "entry_hash",
+    "timestamp",
+    "user_id",
+    "action",
+    "resource_type",
+    "resource_id",
+    "details",
+    "ai_generated"
+  ],
+  "title": "AuditLogRead"
+}
+
+
AuditView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "module_id": {
+      "type": "string",
+      "title": "Module Id"
+    },
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    },
+    "previous_hash": {
+      "type": "string",
+      "title": "Previous Hash"
+    },
+    "entry_hash": {
+      "type": "string",
+      "title": "Entry Hash"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "module_id",
+    "action",
+    "summary",
+    "created_at_unix_seconds",
+    "previous_hash",
+    "entry_hash"
+  ],
+  "title": "AuditView"
+}
+
+
BearerResponse
+{
+  "properties": {
+    "access_token": {
+      "type": "string",
+      "title": "Access Token"
+    },
+    "token_type": {
+      "type": "string",
+      "title": "Token Type"
+    }
+  },
+  "type": "object",
+  "required": [
+    "access_token",
+    "token_type"
+  ],
+  "title": "BearerResponse"
+}
+
+
Body_auth_jwt_login_auth_jwt_login_post
+{
+  "properties": {
+    "grant_type": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^password$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Grant Type"
+    },
+    "username": {
+      "type": "string",
+      "title": "Username"
+    },
+    "password": {
+      "type": "string",
+      "format": "password",
+      "title": "Password"
+    },
+    "scope": {
+      "type": "string",
+      "title": "Scope",
+      "default": ""
+    },
+    "client_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Client Id"
+    },
+    "client_secret": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "format": "password",
+      "title": "Client Secret"
+    }
+  },
+  "type": "object",
+  "required": [
+    "username",
+    "password"
+  ],
+  "title": "Body_auth_jwt_login_auth_jwt_login_post"
+}
+
+
Body_upload_file_datasources_upload_post
+{
+  "properties": {
+    "file": {
+      "type": "string",
+      "contentMediaType": "application/octet-stream",
+      "title": "File"
+    }
+  },
+  "type": "object",
+  "required": [
+    "file"
+  ],
+  "title": "Body_upload_file_datasources_upload_post"
+}
+
+
CalculateDeadlineCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "calculate-records-deadline",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/CalculateDeadlinePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "CalculateDeadlineCommand"
+}
+
+
CalculateDeadlinePayload
+{
+  "properties": {
+    "deadlineReceivedDate": {
+      "type": "string",
+      "title": "Deadlinereceiveddate"
+    },
+    "deadlineRuleName": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Deadlinerulename"
+    },
+    "deadlineDayCount": {
+      "type": "string",
+      "title": "Deadlinedaycount"
+    },
+    "deadlineDayType": {
+      "type": "string",
+      "title": "Deadlinedaytype"
+    },
+    "deadlineBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Deadlinebasis"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "deadlineReceivedDate",
+    "deadlineRuleName",
+    "deadlineDayCount",
+    "deadlineDayType",
+    "deadlineBasis"
+  ],
+  "title": "CalculateDeadlinePayload"
+}
+
+
ChapterCreate
+{
+  "properties": {
+    "chapter_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Chapter Id"
+    },
+    "title_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title Id"
+    },
+    "chapter_number": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Chapter Number"
+    },
+    "chapter_name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Chapter Name"
+    },
+    "sort_order": {
+      "type": "integer",
+      "title": "Sort Order",
+      "default": 0
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title_id",
+    "chapter_number",
+    "chapter_name"
+  ],
+  "title": "ChapterCreate",
+  "description": "Request body for creating a code chapter."
+}
+
+
CitedSection
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "citation": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Citation"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "version": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Version",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "citation"
+  ],
+  "title": "CitedSection",
+  "description": "One resolved public Code section; never a caller-supplied quotation."
+}
+
+
CityProfileCreate
+{
+  "properties": {
+    "city_name": {
+      "type": "string",
+      "title": "City Name"
+    },
+    "state": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State"
+    },
+    "county": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "County"
+    },
+    "population_band": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Population Band"
+    },
+    "email_platform": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email Platform"
+    },
+    "has_dedicated_it": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Has Dedicated It"
+    },
+    "monthly_request_volume": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Monthly Request Volume"
+    },
+    "profile_data": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Profile Data",
+      "default": {}
+    },
+    "gap_map": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Gap Map",
+      "default": {}
+    }
+  },
+  "type": "object",
+  "required": [
+    "city_name"
+  ],
+  "title": "CityProfileCreate"
+}
+
+
CityProfileRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "city_name": {
+      "type": "string",
+      "title": "City Name"
+    },
+    "state": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State"
+    },
+    "county": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "County"
+    },
+    "population_band": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Population Band"
+    },
+    "email_platform": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email Platform"
+    },
+    "has_dedicated_it": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Has Dedicated It"
+    },
+    "monthly_request_volume": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Monthly Request Volume"
+    },
+    "onboarding_status": {
+      "type": "string",
+      "title": "Onboarding Status"
+    },
+    "profile_data": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Profile Data"
+    },
+    "gap_map": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Gap Map"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "updated_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "city_name",
+    "state",
+    "county",
+    "population_band",
+    "email_platform",
+    "has_dedicated_it",
+    "monthly_request_volume",
+    "onboarding_status",
+    "profile_data",
+    "gap_map",
+    "created_at",
+    "updated_at"
+  ],
+  "title": "CityProfileRead"
+}
+
+
CityProfileUpdate
+{
+  "properties": {
+    "city_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "City Name"
+    },
+    "state": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State"
+    },
+    "county": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "County"
+    },
+    "population_band": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Population Band"
+    },
+    "email_platform": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email Platform"
+    },
+    "has_dedicated_it": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Has Dedicated It"
+    },
+    "monthly_request_volume": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Monthly Request Volume"
+    },
+    "onboarding_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Onboarding Status"
+    },
+    "profile_data": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Profile Data"
+    },
+    "gap_map": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Gap Map"
+    }
+  },
+  "type": "object",
+  "title": "CityProfileUpdate"
+}
+
+
ClarificationCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "request-records-clarification",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ClarificationPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "ClarificationCommand"
+}
+
+
ClarificationPayload
+{
+  "properties": {
+    "clarificationNote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Clarificationnote"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "clarificationNote"
+  ],
+  "title": "ClarificationPayload"
+}
+
+
Closeout
+{
+  "properties": {
+    "decision_id": {
+      "type": "string",
+      "pattern": "^[A-Za-z0-9_-]{1,64}$",
+      "title": "Decision Id"
+    },
+    "version_id": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Version Id"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "version_label": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Version Label"
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 1000000,
+      "minLength": 1,
+      "title": "Body"
+    },
+    "effective_start": {
+      "type": "string",
+      "format": "date",
+      "title": "Effective Start"
+    },
+    "effective_end": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective End"
+    },
+    "is_current": {
+      "type": "boolean",
+      "title": "Is Current"
+    },
+    "reconciliation_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reconciliation Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "decision_id",
+    "version_id",
+    "source_id",
+    "version_label",
+    "body",
+    "effective_start",
+    "is_current"
+  ],
+  "title": "Closeout"
+}
+
+
CodeContext
+{
+  "properties": {
+    "section_number": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Section Number"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "section_number"
+  ],
+  "title": "CodeContext"
+}
+
+
CodeLink
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "const": "code",
+      "title": "Provider",
+      "default": "code"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "CodeLink"
+}
+
+
CodeSearch
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "CodeSearch"
+}
+
+
CodeSourceSelection
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 200,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "CodeSourceSelection"
+}
+
+
CompleteArtifact
+{
+  "properties": {
+    "export_path": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Export Path"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "export_path"
+  ],
+  "title": "CompleteArtifact"
+}
+
+
ConnectionSearch
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "enum": [
+        "meetings",
+        "zoning"
+      ],
+      "title": "Provider"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "query"
+  ],
+  "title": "ConnectionSearch"
+}
+
+
CoverageGapResponse
+{
+  "properties": {
+    "jurisdictions_without_rules": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Jurisdictions Without Rules"
+    },
+    "departments_without_staff": {
+      "items": {
+        "additionalProperties": true,
+        "type": "object"
+      },
+      "type": "array",
+      "title": "Departments Without Staff"
+    },
+    "uncovered_categories": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Uncovered Categories"
+    },
+    "total_gaps": {
+      "type": "integer",
+      "title": "Total Gaps"
+    }
+  },
+  "type": "object",
+  "required": [
+    "jurisdictions_without_rules",
+    "departments_without_staff",
+    "uncovered_categories",
+    "total_gaps"
+  ],
+  "title": "CoverageGapResponse"
+}
+
+
DataSourceAdminRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "source_type": {
+      "$ref": "#/components/schemas/SourceType"
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "type": "boolean",
+      "title": "Schedule Enabled",
+      "default": true
+    },
+    "next_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Next Sync At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "last_ingestion_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Ingestion At"
+    },
+    "last_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync At"
+    },
+    "last_sync_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync Status"
+    },
+    "last_error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Error Message"
+    },
+    "consecutive_failure_count": {
+      "type": "integer",
+      "title": "Consecutive Failure Count",
+      "default": 0
+    },
+    "sync_paused": {
+      "type": "boolean",
+      "title": "Sync Paused",
+      "default": false
+    },
+    "health_status": {
+      "type": "string",
+      "title": "Health Status",
+      "default": "healthy"
+    },
+    "active_failure_count": {
+      "type": "integer",
+      "title": "Active Failure Count",
+      "default": 0
+    },
+    "connector_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connector Type"
+    },
+    "updated_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Updated At"
+    },
+    "connection_config": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Connection Config"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "source_type",
+    "is_active",
+    "created_by",
+    "created_at",
+    "last_ingestion_at",
+    "connection_config"
+  ],
+  "title": "DataSourceAdminRead",
+  "description": "Full datasource shape including connection_config. Returned only by admin-gated endpoints."
+}
+
+
DataSourceCreate
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "source_type": {
+      "$ref": "#/components/schemas/SourceType"
+    },
+    "connection_config": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Connection Config",
+      "default": {}
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "type": "boolean",
+      "title": "Schedule Enabled",
+      "default": true
+    }
+  },
+  "type": "object",
+  "required": [
+    "name",
+    "source_type"
+  ],
+  "title": "DataSourceCreate"
+}
+
+
DataSourceRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "source_type": {
+      "$ref": "#/components/schemas/SourceType"
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "type": "boolean",
+      "title": "Schedule Enabled",
+      "default": true
+    },
+    "next_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Next Sync At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "last_ingestion_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Ingestion At"
+    },
+    "last_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync At"
+    },
+    "last_sync_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync Status"
+    },
+    "last_error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Error Message"
+    },
+    "consecutive_failure_count": {
+      "type": "integer",
+      "title": "Consecutive Failure Count",
+      "default": 0
+    },
+    "sync_paused": {
+      "type": "boolean",
+      "title": "Sync Paused",
+      "default": false
+    },
+    "health_status": {
+      "type": "string",
+      "title": "Health Status",
+      "default": "healthy"
+    },
+    "active_failure_count": {
+      "type": "integer",
+      "title": "Active Failure Count",
+      "default": 0
+    },
+    "connector_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connector Type"
+    },
+    "updated_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "source_type",
+    "is_active",
+    "created_by",
+    "created_at",
+    "last_ingestion_at"
+  ],
+  "title": "DataSourceRead",
+  "description": "Redacted datasource shape — safe for non-admin roles. connection_config omitted."
+}
+
+
DataSourceUpdate
+{
+  "properties": {
+    "name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Name"
+    },
+    "connection_config": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connection Config"
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Schedule Enabled"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "DataSourceUpdate"
+}
+
+
DeadlineCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "set-records-deadline",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/DeadlinePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "DeadlineCommand"
+}
+
+
DeadlinePayload
+{
+  "properties": {
+    "deadline": {
+      "type": "string",
+      "title": "Deadline"
+    },
+    "deadlineBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Deadlinebasis"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "deadline",
+    "deadlineBasis"
+  ],
+  "title": "DeadlinePayload"
+}
+
+
Decision
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "pattern": "^[A-Za-z0-9_-]{1,64}$",
+      "title": "Id"
+    },
+    "outcome": {
+      "type": "string",
+      "enum": [
+        "adopted",
+        "not_adopted",
+        "deferred",
+        "withdrawn"
+      ],
+      "title": "Outcome"
+    },
+    "decided_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Decided At"
+    },
+    "decision_text": {
+      "type": "string",
+      "maxLength": 1000000,
+      "minLength": 1,
+      "title": "Decision Text"
+    },
+    "supporting_references": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Supporting References"
+    },
+    "supersedes_decision_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^[A-Za-z0-9_-]{1,64}$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supersedes Decision Id"
+    },
+    "reconciliation_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reconciliation Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "outcome",
+    "decision_text"
+  ],
+  "title": "Decision"
+}
+
+
DepartmentCreate
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "code": {
+      "type": "string",
+      "title": "Code"
+    },
+    "contact_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Contact Email"
+    }
+  },
+  "type": "object",
+  "required": [
+    "name",
+    "code"
+  ],
+  "title": "DepartmentCreate"
+}
+
+
DepartmentRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "code": {
+      "type": "string",
+      "title": "Code"
+    },
+    "contact_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Contact Email"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "code",
+    "contact_email",
+    "created_at"
+  ],
+  "title": "DepartmentRead"
+}
+
+
DepartmentUpdate
+{
+  "properties": {
+    "name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Name"
+    },
+    "code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Code"
+    },
+    "contact_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Contact Email"
+    }
+  },
+  "type": "object",
+  "title": "DepartmentUpdate"
+}
+
+
DisclosureTemplateCreate
+{
+  "properties": {
+    "template_type": {
+      "type": "string",
+      "title": "Template Type"
+    },
+    "state_code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State Code"
+    },
+    "content": {
+      "type": "string",
+      "title": "Content"
+    }
+  },
+  "type": "object",
+  "required": [
+    "template_type",
+    "content"
+  ],
+  "title": "DisclosureTemplateCreate"
+}
+
+
DisclosureTemplateRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "template_type": {
+      "type": "string",
+      "title": "Template Type"
+    },
+    "state_code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State Code"
+    },
+    "content": {
+      "type": "string",
+      "title": "Content"
+    },
+    "version": {
+      "type": "integer",
+      "title": "Version"
+    },
+    "updated_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Updated By"
+    },
+    "updated_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "template_type",
+    "state_code",
+    "content",
+    "version",
+    "updated_by",
+    "updated_at"
+  ],
+  "title": "DisclosureTemplateRead"
+}
+
+
DisclosureTemplateRendered
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "template_type": {
+      "type": "string",
+      "title": "Template Type"
+    },
+    "rendered_content": {
+      "type": "string",
+      "title": "Rendered Content"
+    },
+    "has_unresolved_variables": {
+      "type": "boolean",
+      "title": "Has Unresolved Variables"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "template_type",
+    "rendered_content",
+    "has_unresolved_variables"
+  ],
+  "title": "DisclosureTemplateRendered"
+}
+
+
DisclosureTemplateUpdate
+{
+  "properties": {
+    "content": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Content"
+    },
+    "state_code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State Code"
+    }
+  },
+  "type": "object",
+  "title": "DisclosureTemplateUpdate"
+}
+
+
DocumentChunkRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "chunk_index": {
+      "type": "integer",
+      "title": "Chunk Index"
+    },
+    "content_text": {
+      "type": "string",
+      "title": "Content Text"
+    },
+    "token_count": {
+      "type": "integer",
+      "title": "Token Count"
+    },
+    "page_number": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Page Number"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "document_id",
+    "chunk_index",
+    "content_text",
+    "token_count",
+    "page_number"
+  ],
+  "title": "DocumentChunkRead"
+}
+
+
DocumentRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "source_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Source Id"
+    },
+    "source_path": {
+      "type": "string",
+      "title": "Source Path"
+    },
+    "filename": {
+      "type": "string",
+      "title": "Filename"
+    },
+    "file_type": {
+      "type": "string",
+      "title": "File Type"
+    },
+    "file_hash": {
+      "type": "string",
+      "title": "File Hash"
+    },
+    "file_size": {
+      "type": "integer",
+      "title": "File Size"
+    },
+    "ingestion_status": {
+      "$ref": "#/components/schemas/IngestionStatus"
+    },
+    "ingestion_error": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ingestion Error"
+    },
+    "chunk_count": {
+      "type": "integer",
+      "title": "Chunk Count"
+    },
+    "ingested_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ingested At"
+    },
+    "connector_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connector Type"
+    },
+    "updated_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "source_id",
+    "source_path",
+    "filename",
+    "file_type",
+    "file_hash",
+    "file_size",
+    "ingestion_status",
+    "ingestion_error",
+    "chunk_count",
+    "ingested_at"
+  ],
+  "title": "DocumentRead"
+}
+
+
DraftCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "draft-records-response",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/DraftPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "DraftCommand"
+}
+
+
DraftInput
+{
+  "properties": {
+    "source_materials": {
+      "items": {
+        "$ref": "#/components/schemas/SourceInput"
+      },
+      "type": "array",
+      "title": "Source Materials"
+    },
+    "sentences": {
+      "items": {
+        "$ref": "#/components/schemas/SentenceInput"
+      },
+      "type": "array",
+      "minItems": 1,
+      "title": "Sentences"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sentences"
+  ],
+  "title": "DraftInput"
+}
+
+
DraftPayload
+{
+  "properties": {
+    "responseDraft": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Responsedraft"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "responseDraft"
+  ],
+  "title": "DraftPayload"
+}
+
+
ErrorModel
+{
+  "properties": {
+    "detail": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "additionalProperties": {
+            "type": "string"
+          },
+          "type": "object"
+        }
+      ],
+      "title": "Detail"
+    }
+  },
+  "type": "object",
+  "required": [
+    "detail"
+  ],
+  "title": "ErrorModel"
+}
+
+
Evidence
+{
+  "properties": {
+    "filename": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$",
+      "title": "Filename"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Description"
+    },
+    "media_type": {
+      "type": "string",
+      "enum": [
+        "text/plain",
+        "image/jpeg",
+        "image/png",
+        "image/webp",
+        "application/pdf",
+        "audio/webm",
+        "audio/ogg",
+        "audio/wav",
+        "audio/mpeg",
+        "audio/mp4"
+      ],
+      "title": "Media Type"
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 14000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "filename",
+    "description",
+    "media_type",
+    "content_base64",
+    "sha256"
+  ],
+  "title": "Evidence"
+}
+
+
EvidenceItem
+{
+  "properties": {
+    "filename": {
+      "type": "string",
+      "maxLength": 151,
+      "minLength": 1,
+      "title": "Filename"
+    },
+    "media_type": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Media Type"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Description",
+      "default": ""
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 14000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "filename",
+    "media_type",
+    "content_base64",
+    "sha256"
+  ],
+  "title": "EvidenceItem"
+}
+
+
EvidenceItems
+{
+  "properties": {
+    "items": {
+      "items": {
+        "$ref": "#/components/schemas/EvidenceItem"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "minItems": 1,
+      "title": "Items"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "items"
+  ],
+  "title": "EvidenceItems"
+}
+
+
ExemptionAccuracyReport
+{
+  "properties": {
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "total_flags": {
+      "type": "integer",
+      "title": "Total Flags"
+    },
+    "accepted": {
+      "type": "integer",
+      "title": "Accepted"
+    },
+    "rejected": {
+      "type": "integer",
+      "title": "Rejected"
+    },
+    "pending": {
+      "type": "integer",
+      "title": "Pending"
+    },
+    "acceptance_rate": {
+      "type": "number",
+      "title": "Acceptance Rate"
+    }
+  },
+  "type": "object",
+  "required": [
+    "category",
+    "total_flags",
+    "accepted",
+    "rejected",
+    "pending",
+    "acceptance_rate"
+  ],
+  "title": "ExemptionAccuracyReport"
+}
+
+
ExemptionDashboard
+{
+  "properties": {
+    "total_flags": {
+      "type": "integer",
+      "title": "Total Flags"
+    },
+    "by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "By Status"
+    },
+    "by_category": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "By Category"
+    },
+    "acceptance_rate": {
+      "type": "number",
+      "title": "Acceptance Rate"
+    },
+    "total_rules": {
+      "type": "integer",
+      "title": "Total Rules"
+    },
+    "active_rules": {
+      "type": "integer",
+      "title": "Active Rules"
+    }
+  },
+  "type": "object",
+  "required": [
+    "total_flags",
+    "by_status",
+    "by_category",
+    "acceptance_rate",
+    "total_rules",
+    "active_rules"
+  ],
+  "title": "ExemptionDashboard"
+}
+
+
ExemptionDecisionCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-exemption-decision",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ExemptionDecisionPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "ExemptionDecisionCommand"
+}
+
+
ExemptionDecisionPayload
+{
+  "properties": {
+    "exemptionSource": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionsource"
+    },
+    "exemptionKind": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionkind"
+    },
+    "exemptionFinding": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionfinding"
+    },
+    "exemptionDecision": {
+      "type": "string",
+      "enum": [
+        "release",
+        "redact",
+        "exempt"
+      ],
+      "title": "Exemptiondecision"
+    },
+    "exemptionBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionbasis"
+    },
+    "exemptionReviewer": {
+      "type": "string",
+      "title": "Exemptionreviewer",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "exemptionSource",
+    "exemptionKind",
+    "exemptionFinding",
+    "exemptionDecision",
+    "exemptionBasis"
+  ],
+  "title": "ExemptionDecisionPayload"
+}
+
+
ExemptionDecisionView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "source": {
+      "type": "string",
+      "title": "Source"
+    },
+    "kind": {
+      "type": "string",
+      "title": "Kind"
+    },
+    "finding": {
+      "type": "string",
+      "title": "Finding"
+    },
+    "decision": {
+      "type": "string",
+      "enum": [
+        "release",
+        "redact",
+        "exempt"
+      ],
+      "title": "Decision"
+    },
+    "basis": {
+      "type": "string",
+      "title": "Basis"
+    },
+    "reviewer": {
+      "type": "string",
+      "title": "Reviewer"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "source",
+    "kind",
+    "finding",
+    "decision",
+    "basis",
+    "reviewer",
+    "created_at_unix_seconds"
+  ],
+  "title": "ExemptionDecisionView"
+}
+
+
ExemptionFlagRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "chunk_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Chunk Id"
+    },
+    "rule_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Rule Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "matched_text": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Matched Text"
+    },
+    "confidence": {
+      "type": "number",
+      "title": "Confidence"
+    },
+    "status": {
+      "$ref": "#/components/schemas/FlagStatus"
+    },
+    "reviewed_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reviewed By"
+    },
+    "reviewed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reviewed At"
+    },
+    "review_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Reason"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "chunk_id",
+    "rule_id",
+    "request_id",
+    "category",
+    "matched_text",
+    "confidence",
+    "status",
+    "reviewed_by",
+    "reviewed_at",
+    "review_reason",
+    "created_at"
+  ],
+  "title": "ExemptionFlagRead"
+}
+
+
ExemptionFlagReview
+{
+  "properties": {
+    "status": {
+      "$ref": "#/components/schemas/FlagStatus"
+    },
+    "review_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Reason"
+    }
+  },
+  "type": "object",
+  "required": [
+    "status"
+  ],
+  "title": "ExemptionFlagReview"
+}
+
+
ExemptionNoteCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-exemption-review",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ExemptionNotePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "ExemptionNoteCommand"
+}
+
+
ExemptionNotePayload
+{
+  "properties": {
+    "exemptionNote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionnote"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "exemptionNote"
+  ],
+  "title": "ExemptionNotePayload"
+}
+
+
ExemptionRuleCreate
+{
+  "properties": {
+    "state_code": {
+      "type": "string",
+      "title": "State Code"
+    },
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "rule_type": {
+      "$ref": "#/components/schemas/RuleType"
+    },
+    "rule_definition": {
+      "type": "string",
+      "title": "Rule Definition"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "enabled": {
+      "type": "boolean",
+      "title": "Enabled",
+      "default": true
+    }
+  },
+  "type": "object",
+  "required": [
+    "state_code",
+    "category",
+    "rule_type",
+    "rule_definition"
+  ],
+  "title": "ExemptionRuleCreate"
+}
+
+
ExemptionRuleRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "state_code": {
+      "type": "string",
+      "title": "State Code"
+    },
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "rule_type": {
+      "$ref": "#/components/schemas/RuleType"
+    },
+    "rule_definition": {
+      "type": "string",
+      "title": "Rule Definition"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "enabled": {
+      "type": "boolean",
+      "title": "Enabled"
+    },
+    "version": {
+      "type": "integer",
+      "title": "Version",
+      "default": 1
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "state_code",
+    "category",
+    "rule_type",
+    "rule_definition",
+    "description",
+    "enabled",
+    "created_by",
+    "created_at"
+  ],
+  "title": "ExemptionRuleRead"
+}
+
+
ExemptionRuleUpdate
+{
+  "properties": {
+    "rule_definition": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Rule Definition"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "enabled": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Enabled"
+    }
+  },
+  "type": "object",
+  "title": "ExemptionRuleUpdate"
+}
+
+
ExportReceipt
+{
+  "properties": {
+    "export_path": {
+      "type": "string",
+      "maxLength": 32768,
+      "minLength": 1,
+      "title": "Export Path"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "export_path"
+  ],
+  "title": "ExportReceipt"
+}
+
+
FeeEstimateCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "estimate-records-fee",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/FeeEstimatePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "FeeEstimateCommand"
+}
+
+
FeeEstimatePayload
+{
+  "properties": {
+    "feeEstimate": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feeestimate"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "feeEstimate"
+  ],
+  "title": "FeeEstimatePayload"
+}
+
+
FeeEstimateRequest
+{
+  "properties": {
+    "page_count": {
+      "type": "integer",
+      "title": "Page Count"
+    },
+    "fee_schedule_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Fee Schedule Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "page_count",
+    "fee_schedule_id"
+  ],
+  "title": "FeeEstimateRequest"
+}
+
+
FeeEstimateResponse
+{
+  "properties": {
+    "page_count": {
+      "type": "integer",
+      "title": "Page Count"
+    },
+    "unit_price": {
+      "type": "number",
+      "title": "Unit Price"
+    },
+    "total": {
+      "type": "number",
+      "title": "Total"
+    },
+    "fee_type": {
+      "type": "string",
+      "title": "Fee Type"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    }
+  },
+  "type": "object",
+  "required": [
+    "page_count",
+    "unit_price",
+    "total",
+    "fee_type",
+    "description"
+  ],
+  "title": "FeeEstimateResponse"
+}
+
+
FeeLineCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-fee-line",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/FeeLinePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "FeeLineCommand"
+}
+
+
FeeLineItemCreate
+{
+  "properties": {
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "quantity": {
+      "type": "integer",
+      "title": "Quantity",
+      "default": 1
+    },
+    "unit_price": {
+      "type": "number",
+      "title": "Unit Price"
+    },
+    "fee_schedule_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Schedule Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "description",
+    "unit_price"
+  ],
+  "title": "FeeLineItemCreate"
+}
+
+
FeeLineItemRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "fee_schedule_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Schedule Id"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "quantity": {
+      "type": "integer",
+      "title": "Quantity"
+    },
+    "unit_price": {
+      "type": "number",
+      "title": "Unit Price"
+    },
+    "total": {
+      "type": "number",
+      "title": "Total"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "fee_schedule_id",
+    "description",
+    "quantity",
+    "unit_price",
+    "total",
+    "status",
+    "created_at"
+  ],
+  "title": "FeeLineItemRead"
+}
+
+
FeeLinePayload
+{
+  "properties": {
+    "feeLineDescription": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feelinedescription"
+    },
+    "feeScheduleBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feeschedulebasis"
+    },
+    "feeLineAmount": {
+      "type": "string",
+      "title": "Feelineamount"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "feeLineDescription",
+    "feeScheduleBasis",
+    "feeLineAmount"
+  ],
+  "title": "FeeLinePayload"
+}
+
+
FeeLineView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "schedule_basis": {
+      "type": "string",
+      "title": "Schedule Basis"
+    },
+    "amount_cents": {
+      "type": "integer",
+      "title": "Amount Cents"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "description",
+    "schedule_basis",
+    "amount_cents",
+    "created_at_unix_seconds"
+  ],
+  "title": "FeeLineView"
+}
+
+
FeeScheduleCreate
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "title": "Jurisdiction"
+    },
+    "fee_type": {
+      "type": "string",
+      "title": "Fee Type"
+    },
+    "amount": {
+      "type": "number",
+      "title": "Amount"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "effective_date": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective Date"
+    }
+  },
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "fee_type",
+    "amount"
+  ],
+  "title": "FeeScheduleCreate"
+}
+
+
FeeScheduleRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "jurisdiction": {
+      "type": "string",
+      "title": "Jurisdiction"
+    },
+    "fee_type": {
+      "type": "string",
+      "title": "Fee Type"
+    },
+    "amount": {
+      "type": "number",
+      "title": "Amount"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "effective_date": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective Date"
+    },
+    "created_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "jurisdiction",
+    "fee_type",
+    "amount",
+    "description",
+    "effective_date",
+    "created_by",
+    "created_at"
+  ],
+  "title": "FeeScheduleRead"
+}
+
+
FeeScheduleUpdate
+{
+  "properties": {
+    "fee_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Type"
+    },
+    "amount": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Amount"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "effective_date": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective Date"
+    }
+  },
+  "type": "object",
+  "title": "FeeScheduleUpdate"
+}
+
+
FeeWaiverCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "waive-records-fee",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/FeeWaiverPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "FeeWaiverCommand"
+}
+
+
FeeWaiverCreateRequest
+{
+  "properties": {
+    "waiver_type": {
+      "type": "string",
+      "title": "Waiver Type"
+    },
+    "reason": {
+      "type": "string",
+      "title": "Reason"
+    }
+  },
+  "type": "object",
+  "required": [
+    "waiver_type",
+    "reason"
+  ],
+  "title": "FeeWaiverCreateRequest"
+}
+
+
FeeWaiverPayload
+{
+  "properties": {
+    "feeWaiverReason": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feewaiverreason"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "feeWaiverReason"
+  ],
+  "title": "FeeWaiverPayload"
+}
+
+
FeeWaiverReadResponse
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "waiver_type": {
+      "type": "string",
+      "title": "Waiver Type"
+    },
+    "reason": {
+      "type": "string",
+      "title": "Reason"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    },
+    "created_at": {
+      "type": "string",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "waiver_type",
+    "reason",
+    "status",
+    "created_at"
+  ],
+  "title": "FeeWaiverReadResponse"
+}
+
+
FeeWaiverReviewRequest
+{
+  "properties": {
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    }
+  },
+  "type": "object",
+  "required": [
+    "status"
+  ],
+  "title": "FeeWaiverReviewRequest"
+}
+
+
FinishCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "fulfill-records-request",
+        "close-records-request"
+      ],
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/NativePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "FinishCommand"
+}
+
+
FlagStatus
+{
+  "type": "string",
+  "enum": [
+    "flagged",
+    "reviewed",
+    "accepted",
+    "rejected"
+  ],
+  "title": "FlagStatus"
+}
+
+
FormPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "form-plan",
+      "title": "Action"
+    },
+    "formName": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Formname",
+      "default": ""
+    },
+    "fields": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 50,
+      "title": "Fields"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "FormPlan"
+}
+
+
GeneratedDraft
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "model": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Model"
+    },
+    "previous_response_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Previous Response Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text",
+    "model",
+    "previous_response_sha256"
+  ],
+  "title": "GeneratedDraft"
+}
+
+
HTTPValidationError
+{
+  "properties": {
+    "detail": {
+      "items": {
+        "$ref": "#/components/schemas/ValidationError"
+      },
+      "type": "array",
+      "title": "Detail"
+    }
+  },
+  "type": "object",
+  "title": "HTTPValidationError"
+}
+
+
Handoff
+{
+  "properties": {
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "request_id"
+  ],
+  "title": "Handoff"
+}
+
+
ImportBundleCreate
+{
+  "properties": {
+    "job_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Job Id"
+    },
+    "connector_type": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Connector Type"
+    },
+    "source": {
+      "$ref": "#/components/schemas/SourceCreate"
+    },
+    "sources": {
+      "items": {
+        "$ref": "#/components/schemas/SourceCreate"
+      },
+      "type": "array",
+      "title": "Sources"
+    },
+    "titles": {
+      "items": {
+        "$ref": "#/components/schemas/TitleCreate"
+      },
+      "type": "array",
+      "title": "Titles"
+    },
+    "chapters": {
+      "items": {
+        "$ref": "#/components/schemas/ChapterCreate"
+      },
+      "type": "array",
+      "title": "Chapters"
+    },
+    "sections": {
+      "items": {
+        "$ref": "#/components/schemas/SectionCreate"
+      },
+      "type": "array",
+      "title": "Sections"
+    },
+    "versions": {
+      "items": {
+        "$ref": "#/components/schemas/SectionVersionCreate"
+      },
+      "type": "array",
+      "title": "Versions"
+    },
+    "provenance": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Provenance"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "connector_type",
+    "source"
+  ],
+  "title": "ImportBundleCreate",
+  "description": "Request body for local fixture/file-drop import jobs."
+}
+
+
InclusionStatus
+{
+  "type": "string",
+  "enum": [
+    "included",
+    "excluded",
+    "pending"
+  ],
+  "title": "InclusionStatus"
+}
+
+
IngestionStats
+{
+  "properties": {
+    "total_sources": {
+      "type": "integer",
+      "title": "Total Sources"
+    },
+    "active_sources": {
+      "type": "integer",
+      "title": "Active Sources"
+    },
+    "total_documents": {
+      "type": "integer",
+      "title": "Total Documents"
+    },
+    "documents_by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "Documents By Status"
+    },
+    "total_chunks": {
+      "type": "integer",
+      "title": "Total Chunks"
+    }
+  },
+  "type": "object",
+  "required": [
+    "total_sources",
+    "active_sources",
+    "total_documents",
+    "documents_by_status",
+    "total_chunks"
+  ],
+  "title": "IngestionStats"
+}
+
+
IngestionStatus
+{
+  "type": "string",
+  "enum": [
+    "pending",
+    "processing",
+    "completed",
+    "failed"
+  ],
+  "title": "IngestionStatus"
+}
+
+
InitiativeInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "policy": {
+      "$ref": "#/components/schemas/PolicySelection"
+    },
+    "responsible_staff": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Responsible Staff"
+    },
+    "target": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "string"
+        }
+      ],
+      "title": "Target"
+    },
+    "unit": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Unit"
+    },
+    "due_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Due On"
+    },
+    "status": {
+      "type": "string",
+      "enum": [
+        "planned",
+        "active",
+        "completed",
+        "cancelled"
+      ],
+      "title": "Status",
+      "default": "planned"
+    },
+    "milestones": {
+      "items": {
+        "$ref": "#/components/schemas/Milestone"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "title": "Milestones"
+    },
+    "measurements": {
+      "items": {
+        "$ref": "#/components/schemas/Measurement"
+      },
+      "type": "array",
+      "maxItems": 1000,
+      "title": "Measurements"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "policy",
+    "responsible_staff",
+    "target",
+    "unit",
+    "due_on",
+    "note"
+  ],
+  "title": "InitiativeInput"
+}
+
+
InspectionInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "property_reference": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Property Reference"
+    },
+    "inspection_reference": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Inspection Reference"
+    },
+    "dataset_kind": {
+      "type": "string",
+      "enum": [
+        "municipal",
+        "fictional"
+      ],
+      "title": "Dataset Kind"
+    },
+    "inspector_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "minLength": 1,
+      "title": "Inspector Notes"
+    },
+    "photo_observations": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Photo Observations"
+    },
+    "voice_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Voice Notes",
+      "default": ""
+    },
+    "evidence": {
+      "items": {
+        "$ref": "#/components/schemas/Evidence"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "title": "Evidence"
+    },
+    "linked_sources": {
+      "items": {
+        "$ref": "#/components/schemas/townlight_inspections__workflow_models__SourceLink"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Linked Sources"
+    },
+    "assigned_to": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Assigned To",
+      "default": ""
+    },
+    "staff_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Staff Notes",
+      "default": ""
+    },
+    "notice_draft": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Notice Draft",
+      "default": ""
+    },
+    "review_state": {
+      "type": "string",
+      "enum": [
+        "draft",
+        "follow_up",
+        "reviewed"
+      ],
+      "title": "Review State",
+      "default": "draft"
+    },
+    "review_notes": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Review Notes",
+      "default": ""
+    },
+    "public_summary": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Public Summary",
+      "default": ""
+    },
+    "analysis": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/AnalysisRecord"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "property_reference",
+    "inspection_reference",
+    "dataset_kind",
+    "inspector_notes"
+  ],
+  "title": "InspectionInput"
+}
+
+
IntakeInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "project_name": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Project Name"
+    },
+    "project_description": {
+      "type": "string",
+      "maxLength": 10000,
+      "minLength": 1,
+      "title": "Project Description"
+    },
+    "location": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Location"
+    },
+    "applicant_contact": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Applicant Contact",
+      "default": ""
+    },
+    "requirement_revision": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Requirement Revision"
+    },
+    "materials": {
+      "items": {
+        "$ref": "#/components/schemas/MaterialReview"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "minItems": 1,
+      "title": "Materials"
+    },
+    "linked_sources": {
+      "items": {
+        "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Linked Sources"
+    },
+    "staff_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Staff Notes",
+      "default": ""
+    },
+    "assigned_to": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Assigned To",
+      "default": ""
+    },
+    "review_state": {
+      "type": "string",
+      "enum": [
+        "draft",
+        "follow_up",
+        "reviewed"
+      ],
+      "title": "Review State",
+      "default": "draft"
+    },
+    "review_notes": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Review Notes",
+      "default": ""
+    },
+    "public_summary": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Public Summary",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "project_name",
+    "project_description",
+    "location",
+    "requirement_revision",
+    "materials"
+  ],
+  "title": "IntakeInput"
+}
+
+
InterpretationNoteCreate
+{
+  "properties": {
+    "note_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Note Id"
+    },
+    "note_text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Note Text"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "note_text"
+  ],
+  "title": "InterpretationNoteCreate",
+  "description": "Request body for staff-only interpretation notes."
+}
+
+
InterviewRequest
+{
+  "properties": {
+    "last_answer": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Answer"
+    },
+    "last_field": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Field"
+    },
+    "skipped_fields": {
+      "anyOf": [
+        {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Skipped Fields"
+    }
+  },
+  "type": "object",
+  "title": "InterviewRequest"
+}
+
+
InterviewResponse
+{
+  "properties": {
+    "question": {
+      "type": "string",
+      "title": "Question"
+    },
+    "target_field": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Target Field"
+    },
+    "all_complete": {
+      "type": "boolean",
+      "title": "All Complete"
+    },
+    "completed_fields": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Completed Fields"
+    },
+    "onboarding_status": {
+      "type": "string",
+      "title": "Onboarding Status"
+    },
+    "skipped_fields": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Skipped Fields"
+    }
+  },
+  "type": "object",
+  "required": [
+    "question",
+    "target_field",
+    "all_complete",
+    "completed_fields",
+    "onboarding_status",
+    "skipped_fields"
+  ],
+  "title": "InterviewResponse"
+}
+
+
ManagedFileReceipt
+{
+  "properties": {
+    "original_path": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Original Path"
+    },
+    "stored_path": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Stored Path"
+    },
+    "file_name": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "File Name"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Sha256"
+    },
+    "size_bytes": {
+      "type": "integer",
+      "maximum": 2147483647.0,
+      "minimum": 0.0,
+      "title": "Size Bytes"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "original_path",
+    "stored_path",
+    "file_name",
+    "sha256",
+    "size_bytes"
+  ],
+  "title": "ManagedFileReceipt"
+}
+
+
ManagedSource
+{
+  "properties": {
+    "original_path": {
+      "type": "string",
+      "title": "Original Path"
+    },
+    "stored_path": {
+      "type": "string",
+      "title": "Stored Path"
+    },
+    "file_name": {
+      "type": "string",
+      "title": "File Name"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Sha256"
+    },
+    "size_bytes": {
+      "type": "integer",
+      "minimum": 0.0,
+      "title": "Size Bytes"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "original_path",
+    "stored_path",
+    "file_name",
+    "sha256",
+    "size_bytes"
+  ],
+  "title": "ManagedSource"
+}
+
+
Material
+{
+  "properties": {
+    "material_id": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9_-]{1,80}$",
+      "title": "Material Id"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Description"
+    },
+    "citation": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Citation"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "material_id",
+    "description",
+    "citation"
+  ],
+  "title": "Material"
+}
+
+
MaterialReview
+{
+  "properties": {
+    "material_id": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Material Id"
+    },
+    "status": {
+      "type": "string",
+      "enum": [
+        "not_reviewed",
+        "provided",
+        "missing",
+        "unclear"
+      ],
+      "title": "Status",
+      "default": "not_reviewed"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Note",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "material_id"
+  ],
+  "title": "MaterialReview"
+}
+
+
Measurement
+{
+  "properties": {
+    "recorded_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Recorded On"
+    },
+    "value": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "string"
+        }
+      ],
+      "title": "Value"
+    },
+    "evidence": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Evidence"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "recorded_on",
+    "value",
+    "evidence"
+  ],
+  "title": "Measurement"
+}
+
+
MediaAnalysis
+{
+  "properties": {
+    "items": {
+      "items": {
+        "$ref": "#/components/schemas/EvidenceItem"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "minItems": 1,
+      "title": "Items"
+    },
+    "code_links": {
+      "items": {
+        "$ref": "#/components/schemas/CodeLink"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Code Links"
+    },
+    "inspector_supplied_text": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Inspector Supplied Text",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "items"
+  ],
+  "title": "MediaAnalysis"
+}
+
+
MeetingInput
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "scheduled_start": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Scheduled Start"
+    },
+    "location": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Location"
+    },
+    "meeting_type": {
+      "type": "string",
+      "enum": [
+        "regular",
+        "special",
+        "emergency",
+        "closed_session",
+        "executive"
+      ],
+      "title": "Meeting Type",
+      "default": "regular"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "scheduled_start",
+    "location"
+  ],
+  "title": "MeetingInput"
+}
+
+
MeetingLink
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 200,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    },
+    "relation": {
+      "type": "string",
+      "enum": [
+        "hearing",
+        "context",
+        "precedent"
+      ],
+      "title": "Relation"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256",
+    "relation"
+  ],
+  "title": "MeetingLink"
+}
+
+
MeetingSearch
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "MeetingSearch"
+}
+
+
MeetingStageInput
+{
+  "properties": {
+    "to_status": {
+      "type": "string",
+      "enum": [
+        "SCHEDULED",
+        "NOTICED",
+        "PACKET_POSTED",
+        "IN_PROGRESS",
+        "RECESSED",
+        "ADJOURNED",
+        "TRANSCRIPT_READY",
+        "MINUTES_DRAFTED",
+        "MINUTES_POSTED",
+        "MINUTES_ADOPTED",
+        "MINUTES_SIGNED",
+        "ARCHIVED",
+        "CANCELLED"
+      ],
+      "title": "To Status"
+    },
+    "statutory_basis": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Basis"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "to_status"
+  ],
+  "title": "MeetingStageInput"
+}
+
+
MeetingsSearch
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "MeetingsSearch"
+}
+
+
MeetingsSourceSelection
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 200,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "MeetingsSourceSelection"
+}
+
+
MessageCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-message",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/MessagePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "MessageCommand"
+}
+
+
MessageCreate
+{
+  "properties": {
+    "message_text": {
+      "type": "string",
+      "title": "Message Text"
+    },
+    "is_internal": {
+      "type": "boolean",
+      "title": "Is Internal",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "message_text"
+  ],
+  "title": "MessageCreate"
+}
+
+
MessagePayload
+{
+  "properties": {
+    "requestMessageBody": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestmessagebody"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requestMessageBody"
+  ],
+  "title": "MessagePayload"
+}
+
+
MessageRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "sender_type": {
+      "type": "string",
+      "title": "Sender Type"
+    },
+    "sender_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sender Id"
+    },
+    "message_text": {
+      "type": "string",
+      "title": "Message Text"
+    },
+    "is_internal": {
+      "type": "boolean",
+      "title": "Is Internal"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "sender_type",
+    "sender_id",
+    "message_text",
+    "is_internal",
+    "created_at"
+  ],
+  "title": "MessageRead"
+}
+
+
MessageView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "author": {
+      "type": "string",
+      "title": "Author"
+    },
+    "author_role": {
+      "type": "string",
+      "title": "Author Role"
+    },
+    "body": {
+      "type": "string",
+      "title": "Body"
+    },
+    "visibility": {
+      "type": "string",
+      "title": "Visibility"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "author",
+    "author_role",
+    "body",
+    "visibility",
+    "created_at_unix_seconds"
+  ],
+  "title": "MessageView"
+}
+
+
Milestone
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "due_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Due On"
+    },
+    "completed_on": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Completed On"
+    },
+    "evidence": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Evidence",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "due_on"
+  ],
+  "title": "Milestone"
+}
+
+
MinutesDecision
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "post",
+        "adopt",
+        "sign"
+      ],
+      "title": "Action"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "MinutesDecision"
+}
+
+
ModelRegistryCreate
+{
+  "properties": {
+    "model_name": {
+      "type": "string",
+      "title": "Model Name"
+    },
+    "model_version": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Version"
+    },
+    "parameter_count": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parameter Count"
+    },
+    "license": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "License"
+    },
+    "model_card_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Card Url"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active",
+      "default": false
+    },
+    "context_window_size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Context Window Size"
+    },
+    "supports_ner": {
+      "type": "boolean",
+      "title": "Supports Ner",
+      "default": false
+    },
+    "supports_vision": {
+      "type": "boolean",
+      "title": "Supports Vision",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "model_name"
+  ],
+  "title": "ModelRegistryCreate",
+  "description": "Schema for creating a new model_registry record (POST body)."
+}
+
+
ModelRegistryRead
+{
+  "properties": {
+    "id": {
+      "type": "integer",
+      "title": "Id"
+    },
+    "model_name": {
+      "type": "string",
+      "title": "Model Name"
+    },
+    "model_version": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Version"
+    },
+    "parameter_count": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parameter Count"
+    },
+    "license": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "License"
+    },
+    "model_card_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Card Url"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "added_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Added At"
+    },
+    "context_window_size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Context Window Size"
+    },
+    "supports_ner": {
+      "type": "boolean",
+      "title": "Supports Ner"
+    },
+    "supports_vision": {
+      "type": "boolean",
+      "title": "Supports Vision"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "model_name",
+    "is_active",
+    "supports_ner",
+    "supports_vision"
+  ],
+  "title": "ModelRegistryRead",
+  "description": "Schema for returning a model_registry record (GET response).\n\n``from_attributes=True`` allows construction directly from an ORM instance."
+}
+
+
ModelRegistryUpdate
+{
+  "properties": {
+    "model_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Name"
+    },
+    "model_version": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Version"
+    },
+    "parameter_count": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parameter Count"
+    },
+    "license": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "License"
+    },
+    "model_card_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Card Url"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    },
+    "context_window_size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Context Window Size"
+    },
+    "supports_ner": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supports Ner"
+    },
+    "supports_vision": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supports Vision"
+    }
+  },
+  "type": "object",
+  "title": "ModelRegistryUpdate",
+  "description": "Schema for partially updating a model_registry record (PATCH body).\n\nEvery field is optional so callers can send only the fields they want to\nchange."
+}
+
+
MotionCorrection
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "reason": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Reason"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text",
+    "reason"
+  ],
+  "title": "MotionCorrection"
+}
+
+
MotionInput
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "seconded_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "minLength": 1
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Seconded By"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text"
+  ],
+  "title": "MotionInput"
+}
+
+
NativePayload
+{
+  "properties": {},
+  "additionalProperties": false,
+  "type": "object",
+  "title": "NativePayload"
+}
+
+
NativeRequestRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "requester_name": {
+      "type": "string",
+      "title": "Requester Name"
+    },
+    "requester_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Email"
+    },
+    "requester_phone": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Phone"
+    },
+    "requester_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Type"
+    },
+    "date_received": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Date Received"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "status": {
+      "$ref": "#/components/schemas/RequestStatus"
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "created_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "response_draft": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Response Draft"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    },
+    "estimated_fee": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Estimated Fee"
+    },
+    "fee_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Status"
+    },
+    "fee_waiver_requested": {
+      "type": "boolean",
+      "title": "Fee Waiver Requested",
+      "default": false
+    },
+    "priority": {
+      "type": "string",
+      "title": "Priority",
+      "default": "normal"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    },
+    "closed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closed At"
+    },
+    "closure_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closure Reason"
+    },
+    "desktop_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Desktop Id"
+    },
+    "public_tracking_number": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Public Tracking Number"
+    },
+    "submitted_via": {
+      "type": "string",
+      "title": "Submitted Via"
+    },
+    "deadline_label": {
+      "type": "string",
+      "title": "Deadline Label"
+    },
+    "deadline_basis": {
+      "type": "string",
+      "title": "Deadline Basis"
+    },
+    "deadline_reviewed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Deadline Reviewed At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "requester_name",
+    "requester_email",
+    "date_received",
+    "statutory_deadline",
+    "description",
+    "status",
+    "assigned_to",
+    "created_by",
+    "created_at",
+    "response_draft",
+    "review_notes",
+    "desktop_id",
+    "public_tracking_number",
+    "submitted_via",
+    "deadline_label",
+    "deadline_basis",
+    "deadline_reviewed_at"
+  ],
+  "title": "NativeRequestRead"
+}
+
+
NoticeDocumentInput
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text"
+  ],
+  "title": "NoticeDocumentInput"
+}
+
+
NoticeDraft
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 100000,
+      "minLength": 1,
+      "title": "Body"
+    },
+    "notice_type": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Notice Type"
+    },
+    "statutory_basis": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Statutory Basis"
+    },
+    "event_date": {
+      "type": "string",
+      "format": "date",
+      "title": "Event Date"
+    },
+    "lead_days": {
+      "type": "integer",
+      "maximum": 365.0,
+      "minimum": 0.0,
+      "title": "Lead Days"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "body",
+    "notice_type",
+    "statutory_basis",
+    "event_date",
+    "lead_days"
+  ],
+  "title": "NoticeDraft"
+}
+
+
NoticeInput
+{
+  "properties": {
+    "notice_type": {
+      "type": "string",
+      "enum": [
+        "regular",
+        "special",
+        "emergency",
+        "closed_session",
+        "executive"
+      ],
+      "title": "Notice Type"
+    },
+    "posted_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Posted At"
+    },
+    "minimum_notice_hours": {
+      "type": "integer",
+      "minimum": 0.0,
+      "title": "Minimum Notice Hours"
+    },
+    "statutory_basis": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Basis"
+    },
+    "approved_by": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Approved By"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "notice_type",
+    "posted_at",
+    "minimum_notice_hours"
+  ],
+  "title": "NoticeInput"
+}
+
+
NoticeProofInput
+{
+  "properties": {
+    "location": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Location"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note",
+      "default": ""
+    },
+    "document_delivery_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Document Delivery Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "location"
+  ],
+  "title": "NoticeProofInput"
+}
+
+
NotificationLogRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "template_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Template Id"
+    },
+    "recipient_email": {
+      "type": "string",
+      "title": "Recipient Email"
+    },
+    "request_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Request Id"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "sent_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sent At"
+    },
+    "error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Message"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "template_id",
+    "recipient_email",
+    "request_id",
+    "channel",
+    "status",
+    "sent_at",
+    "error_message",
+    "created_at"
+  ],
+  "title": "NotificationLogRead"
+}
+
+
NotificationTemplateCreate
+{
+  "properties": {
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel",
+      "default": "email"
+    },
+    "subject_template": {
+      "type": "string",
+      "title": "Subject Template"
+    },
+    "body_template": {
+      "type": "string",
+      "title": "Body Template"
+    }
+  },
+  "type": "object",
+  "required": [
+    "event_type",
+    "subject_template",
+    "body_template"
+  ],
+  "title": "NotificationTemplateCreate"
+}
+
+
NotificationTemplateRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel"
+    },
+    "subject_template": {
+      "type": "string",
+      "title": "Subject Template"
+    },
+    "body_template": {
+      "type": "string",
+      "title": "Body Template"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "event_type",
+    "channel",
+    "subject_template",
+    "body_template",
+    "is_active",
+    "created_at"
+  ],
+  "title": "NotificationTemplateRead"
+}
+
+
NotificationTemplateUpdate
+{
+  "properties": {
+    "subject_template": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Subject Template"
+    },
+    "body_template": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Body Template"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "NotificationTemplateUpdate"
+}
+
+
NotificationView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "notification_id": {
+      "type": "string",
+      "title": "Notification Id"
+    },
+    "module_id": {
+      "type": "string",
+      "title": "Module Id"
+    },
+    "record_id": {
+      "type": "string",
+      "title": "Record Id"
+    },
+    "audience": {
+      "type": "string",
+      "title": "Audience"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel"
+    },
+    "subject": {
+      "type": "string",
+      "title": "Subject"
+    },
+    "body": {
+      "type": "string",
+      "title": "Body"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    },
+    "sent_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sent At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "notification_id",
+    "module_id",
+    "record_id",
+    "audience",
+    "channel",
+    "subject",
+    "body",
+    "status",
+    "created_at_unix_seconds",
+    "sent_at_unix_seconds"
+  ],
+  "title": "NotificationView"
+}
+
+
OllamaModelInfo
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Size"
+    },
+    "details": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Details"
+    }
+  },
+  "type": "object",
+  "required": [
+    "name"
+  ],
+  "title": "OllamaModelInfo"
+}
+
+
OllamaStatus
+{
+  "properties": {
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "models": {
+      "items": {
+        "$ref": "#/components/schemas/OllamaModelInfo"
+      },
+      "type": "array",
+      "title": "Models"
+    }
+  },
+  "type": "object",
+  "required": [
+    "status",
+    "models"
+  ],
+  "title": "OllamaStatus"
+}
+
+
OperationalMetrics
+{
+  "properties": {
+    "average_response_time_days": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Average Response Time Days"
+    },
+    "median_response_time_days": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Median Response Time Days"
+    },
+    "requests_by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "Requests By Status"
+    },
+    "requests_by_department": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "Requests By Department"
+    },
+    "deadline_compliance_rate": {
+      "type": "number",
+      "title": "Deadline Compliance Rate"
+    },
+    "total_open": {
+      "type": "integer",
+      "title": "Total Open"
+    },
+    "total_closed": {
+      "type": "integer",
+      "title": "Total Closed"
+    },
+    "total_overdue": {
+      "type": "integer",
+      "title": "Total Overdue"
+    },
+    "clarification_frequency": {
+      "type": "number",
+      "title": "Clarification Frequency"
+    },
+    "top_request_topics": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Top Request Topics"
+    }
+  },
+  "type": "object",
+  "required": [
+    "average_response_time_days",
+    "median_response_time_days",
+    "requests_by_status",
+    "requests_by_department",
+    "deadline_compliance_rate",
+    "total_open",
+    "total_closed",
+    "total_overdue",
+    "clarification_frequency",
+    "top_request_topics"
+  ],
+  "title": "OperationalMetrics"
+}
+
+
Outline
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "question_ids": {
+      "items": {
+        "type": "string",
+        "format": "uuid"
+      },
+      "type": "array",
+      "maxItems": 50,
+      "minItems": 1,
+      "title": "Question Ids"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "question_ids"
+  ],
+  "title": "Outline"
+}
+
+
Packet
+{
+  "properties": {
+    "expected_revision": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Expected Revision"
+    },
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "staff_only",
+        "records_copy"
+      ],
+      "title": "Visibility"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "expected_revision",
+    "visibility"
+  ],
+  "title": "Packet"
+}
+
+
PacketInput
+{
+  "properties": {
+    "agenda_item_ids": {
+      "items": {
+        "type": "string",
+        "format": "uuid"
+      },
+      "type": "array",
+      "title": "Agenda Item Ids"
+    },
+    "source_files": {
+      "items": {
+        "$ref": "#/components/schemas/ManagedSource"
+      },
+      "type": "array",
+      "title": "Source Files"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "agenda_item_ids"
+  ],
+  "title": "PacketInput"
+}
+
+
Pathway
+{
+  "properties": {
+    "project_type": {
+      "type": "string",
+      "maxLength": 120,
+      "minLength": 1,
+      "title": "Project Type"
+    },
+    "proposal": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Proposal",
+      "default": ""
+    },
+    "location_context": {
+      "type": "string",
+      "maxLength": 1000,
+      "title": "Location Context",
+      "default": ""
+    },
+    "requirement_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requirement Revision"
+    },
+    "fee_link": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "project_type"
+  ],
+  "title": "Pathway"
+}
+
+
PathwayStep
+{
+  "properties": {
+    "step": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Step"
+    },
+    "citation": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Citation"
+    },
+    "typical_time": {
+      "type": "string",
+      "maxLength": 1000,
+      "title": "Typical Time",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "step",
+    "citation"
+  ],
+  "title": "PathwayStep"
+}
+
+
PlainLanguageSummaryCreate
+{
+  "properties": {
+    "summary_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Summary Id"
+    },
+    "section_version_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Version Id"
+    },
+    "summary_text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Summary Text"
+    },
+    "language_code": {
+      "type": "string",
+      "title": "Language Code",
+      "default": "en"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "section_version_id",
+    "summary_text"
+  ],
+  "title": "PlainLanguageSummaryCreate",
+  "description": "Request body for staff-drafted plain-language summaries."
+}
+
+
PolicySelection
+{
+  "properties": {
+    "plan_id": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Plan Id"
+    },
+    "revision_id": {
+      "type": "string",
+      "maxLength": 36,
+      "minLength": 36,
+      "title": "Revision Id"
+    },
+    "policy_id": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Policy Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "plan_id",
+    "revision_id",
+    "policy_id"
+  ],
+  "title": "PolicySelection"
+}
+
+
PortalModeResponse
+{
+  "properties": {
+    "mode": {
+      "type": "string",
+      "enum": [
+        "public",
+        "private"
+      ],
+      "title": "Mode",
+      "description": "Active portal posture for this deployment. ``public`` = minimal resident surface (landing + authenticated records-request submission + resident registration) reachable without staff auth. ``private`` = staff-only; no public routes, no resident self-registration."
+    }
+  },
+  "type": "object",
+  "required": [
+    "mode"
+  ],
+  "title": "PortalModeResponse",
+  "description": "T5D — schema for ``GET /config/portal-mode``.\n\nExposed to the frontend on boot so it can branch routing without a\nuser-identity lookup. The payload is intentionally the single field\nbelow — no staff config, no user state, no schema version."
+}
+
+
PrepareArtifact
+{
+  "properties": {
+    "kind": {
+      "type": "string",
+      "enum": [
+        "response",
+        "release-package"
+      ],
+      "title": "Kind"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "kind"
+  ],
+  "title": "PrepareArtifact"
+}
+
+
Proof
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    },
+    "filename": {
+      "type": "string",
+      "maxLength": 150,
+      "minLength": 1,
+      "title": "Filename"
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 7000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "location": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Location"
+    },
+    "published_at": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Published At"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence",
+    "filename",
+    "content_base64",
+    "location",
+    "published_at"
+  ],
+  "title": "Proof"
+}
+
+
Proposal
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "pattern": "^[A-Za-z0-9_-]{1,64}$",
+      "title": "Id"
+    },
+    "version_id": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Version Id"
+    },
+    "meeting_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Meeting Id"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "ordinance_number": {
+      "type": "string",
+      "maxLength": 120,
+      "minLength": 1,
+      "title": "Ordinance Number"
+    },
+    "proposed_text": {
+      "type": "string",
+      "maxLength": 1000000,
+      "minLength": 1,
+      "title": "Proposed Text"
+    },
+    "supersedes_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^[A-Za-z0-9_-]{1,64}$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supersedes Id"
+    },
+    "reconciliation_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reconciliation Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "version_id",
+    "meeting_id",
+    "title",
+    "ordinance_number",
+    "proposed_text"
+  ],
+  "title": "Proposal"
+}
+
+
PublicExplore
+{
+  "properties": {
+    "goal": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Goal",
+      "default": ""
+    },
+    "topic": {
+      "type": "string",
+      "maxLength": 160,
+      "title": "Topic",
+      "default": ""
+    },
+    "neighborhood": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Neighborhood",
+      "default": ""
+    },
+    "plan_type": {
+      "type": "string",
+      "maxLength": 120,
+      "title": "Plan Type",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "PublicExplore"
+}
+
+
PublicIntake
+{
+  "properties": {
+    "requester": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requester"
+    },
+    "requesterContact": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestercontact"
+    },
+    "summary": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Summary"
+    },
+    "deadline": {
+      "type": "string",
+      "title": "Deadline",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requester",
+    "requesterContact",
+    "summary"
+  ],
+  "title": "PublicIntake"
+}
+
+
PublicLookup
+{
+  "properties": {
+    "trackingNumber": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Trackingnumber"
+    },
+    "requesterContact": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestercontact"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "trackingNumber",
+    "requesterContact"
+  ],
+  "title": "PublicLookup"
+}
+
+
PublicMessage
+{
+  "properties": {
+    "trackingNumber": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Trackingnumber"
+    },
+    "requesterContact": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestercontact"
+    },
+    "publicRequestMessage": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Publicrequestmessage"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "trackingNumber",
+    "requesterContact",
+    "publicRequestMessage"
+  ],
+  "title": "PublicMessage"
+}
+
+
PublicStatusView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "label": {
+      "type": "string",
+      "title": "Label"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "label",
+    "summary",
+    "status",
+    "created_at_unix_seconds"
+  ],
+  "title": "PublicStatusView"
+}
+
+
PublicationView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "source_module": {
+      "type": "string",
+      "title": "Source Module"
+    },
+    "source_record_id": {
+      "type": "string",
+      "title": "Source Record Id"
+    },
+    "record_type": {
+      "type": "string",
+      "title": "Record Type"
+    },
+    "public_payload": {
+      "type": "string",
+      "title": "Public Payload"
+    },
+    "payload_hash": {
+      "type": "string",
+      "title": "Payload Hash"
+    },
+    "published_at_unix_seconds": {
+      "type": "integer",
+      "title": "Published At Unix Seconds"
+    },
+    "retracted_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Retracted At Unix Seconds"
+    },
+    "retracted_by": {
+      "type": "string",
+      "title": "Retracted By",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "source_module",
+    "source_record_id",
+    "record_type",
+    "public_payload",
+    "payload_hash",
+    "published_at_unix_seconds"
+  ],
+  "title": "PublicationView"
+}
+
+
PublishingPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "publishing-workflow",
+      "title": "Action"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "hasReview": {
+      "type": "boolean",
+      "title": "Hasreview",
+      "default": false
+    },
+    "hasPlainLanguage": {
+      "type": "boolean",
+      "title": "Hasplainlanguage",
+      "default": false
+    },
+    "hasTranslationReview": {
+      "type": "boolean",
+      "title": "Hastranslationreview",
+      "default": false
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "PublishingPlan"
+}
+
+
Question
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    },
+    "question": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Question"
+    },
+    "kind": {
+      "type": "string",
+      "enum": [
+        "use",
+        "dimension"
+      ],
+      "title": "Kind"
+    },
+    "key": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Key"
+    },
+    "audience": {
+      "type": "string",
+      "enum": [
+        "resident",
+        "staff"
+      ],
+      "title": "Audience",
+      "default": "resident"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "query",
+    "question",
+    "kind",
+    "key"
+  ],
+  "title": "Question"
+}
+
+
QuestionAnswerRequest
+{
+  "properties": {
+    "question": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Question"
+    },
+    "section_number": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Section Number"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "question"
+  ],
+  "title": "QuestionAnswerRequest",
+  "description": "Request body for citation-grounded code Q&A."
+}
+
+
RecordsDocumentView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "attachment_id": {
+      "type": "string",
+      "title": "Attachment Id"
+    },
+    "title": {
+      "type": "string",
+      "title": "Title"
+    },
+    "original_path": {
+      "type": "string",
+      "title": "Original Path"
+    },
+    "stored_path": {
+      "type": "string",
+      "title": "Stored Path"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation"
+    },
+    "sha256": {
+      "type": "string",
+      "title": "Sha256"
+    },
+    "size_bytes": {
+      "type": "integer",
+      "title": "Size Bytes"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "added_by": {
+      "type": "string",
+      "title": "Added By"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    },
+    "release_original_path": {
+      "type": "string",
+      "title": "Release Original Path",
+      "default": ""
+    },
+    "release_stored_path": {
+      "type": "string",
+      "title": "Release Stored Path",
+      "default": ""
+    },
+    "release_file_name": {
+      "type": "string",
+      "title": "Release File Name",
+      "default": ""
+    },
+    "release_sha256": {
+      "type": "string",
+      "title": "Release Sha256",
+      "default": ""
+    },
+    "release_size_bytes": {
+      "type": "integer",
+      "title": "Release Size Bytes",
+      "default": 0
+    },
+    "release_status": {
+      "type": "string",
+      "title": "Release Status",
+      "default": ""
+    },
+    "release_note": {
+      "type": "string",
+      "title": "Release Note",
+      "default": ""
+    },
+    "release_added_by": {
+      "type": "string",
+      "title": "Release Added By",
+      "default": ""
+    },
+    "release_added_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Release Added At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "attachment_id",
+    "title",
+    "original_path",
+    "stored_path",
+    "citation",
+    "sha256",
+    "size_bytes",
+    "status",
+    "added_by",
+    "created_at_unix_seconds"
+  ],
+  "title": "RecordsDocumentView"
+}
+
+
RecordsOperationRead
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "message": {
+      "type": "string",
+      "title": "Message"
+    },
+    "request": {
+      "$ref": "#/components/schemas/RecordsView"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "message",
+    "request"
+  ],
+  "title": "RecordsOperationRead"
+}
+
+
RecordsStateRead
+{
+  "properties": {
+    "demo_fixture": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Demo Fixture"
+    },
+    "records_requests": {
+      "items": {
+        "$ref": "#/components/schemas/RecordsView"
+      },
+      "type": "array",
+      "title": "Records Requests"
+    },
+    "notification_events": {
+      "items": {
+        "$ref": "#/components/schemas/NotificationView"
+      },
+      "type": "array",
+      "title": "Notification Events"
+    },
+    "publication_events": {
+      "items": {
+        "$ref": "#/components/schemas/PublicationView"
+      },
+      "type": "array",
+      "title": "Publication Events"
+    },
+    "audit_entries": {
+      "items": {
+        "$ref": "#/components/schemas/AuditView"
+      },
+      "type": "array",
+      "title": "Audit Entries"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "records_requests"
+  ],
+  "title": "RecordsStateRead"
+}
+
+
RecordsView
+{
+  "properties": {
+    "request_id": {
+      "type": "string",
+      "title": "Request Id"
+    },
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "public_tracking_number": {
+      "type": "string",
+      "title": "Public Tracking Number"
+    },
+    "requester": {
+      "type": "string",
+      "title": "Requester"
+    },
+    "requester_contact": {
+      "type": "string",
+      "title": "Requester Contact"
+    },
+    "submitted_via": {
+      "type": "string",
+      "title": "Submitted Via"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "deadline": {
+      "type": "string",
+      "title": "Deadline"
+    },
+    "deadline_basis": {
+      "type": "string",
+      "title": "Deadline Basis"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "assigned_to": {
+      "type": "string",
+      "title": "Assigned To"
+    },
+    "clarification_notes": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Clarification Notes"
+    },
+    "search_notes": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Search Notes"
+    },
+    "search_sessions": {
+      "items": {
+        "$ref": "#/components/schemas/SearchReceiptView"
+      },
+      "type": "array",
+      "title": "Search Sessions"
+    },
+    "exemption_reviews": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Exemption Reviews"
+    },
+    "exemption_decisions": {
+      "items": {
+        "$ref": "#/components/schemas/ExemptionDecisionView"
+      },
+      "type": "array",
+      "title": "Exemption Decisions"
+    },
+    "fee_estimate": {
+      "type": "string",
+      "title": "Fee Estimate"
+    },
+    "fee_line_items": {
+      "items": {
+        "$ref": "#/components/schemas/FeeLineView"
+      },
+      "type": "array",
+      "title": "Fee Line Items"
+    },
+    "fee_waiver_reason": {
+      "type": "string",
+      "title": "Fee Waiver Reason"
+    },
+    "citations": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Citations"
+    },
+    "response_draft": {
+      "type": "string",
+      "title": "Response Draft"
+    },
+    "approval_notes": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Approval Notes"
+    },
+    "exports": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Exports"
+    },
+    "documents": {
+      "items": {
+        "$ref": "#/components/schemas/RecordsDocumentView"
+      },
+      "type": "array",
+      "title": "Documents"
+    },
+    "release_packages": {
+      "items": {
+        "$ref": "#/components/schemas/ReleasePackageView"
+      },
+      "type": "array",
+      "title": "Release Packages"
+    },
+    "timeline": {
+      "items": {
+        "$ref": "#/components/schemas/TimelineView"
+      },
+      "type": "array",
+      "title": "Timeline"
+    },
+    "public_status_events": {
+      "items": {
+        "$ref": "#/components/schemas/PublicStatusView"
+      },
+      "type": "array",
+      "title": "Public Status Events"
+    },
+    "messages": {
+      "items": {
+        "$ref": "#/components/schemas/MessageView"
+      },
+      "type": "array",
+      "title": "Messages"
+    },
+    "deadline_reviewed_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Deadline Reviewed At Unix Seconds"
+    },
+    "approved_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Approved At Unix Seconds"
+    },
+    "fulfilled_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fulfilled At Unix Seconds"
+    },
+    "closed_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closed At Unix Seconds"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "request_id",
+    "id",
+    "public_tracking_number",
+    "requester",
+    "requester_contact",
+    "submitted_via",
+    "summary",
+    "deadline",
+    "deadline_basis",
+    "status",
+    "assigned_to",
+    "clarification_notes",
+    "search_notes",
+    "search_sessions",
+    "exemption_reviews",
+    "exemption_decisions",
+    "fee_estimate",
+    "fee_line_items",
+    "fee_waiver_reason",
+    "citations",
+    "response_draft",
+    "approval_notes",
+    "exports",
+    "timeline",
+    "public_status_events",
+    "messages",
+    "deadline_reviewed_at_unix_seconds",
+    "approved_at_unix_seconds",
+    "fulfilled_at_unix_seconds",
+    "closed_at_unix_seconds",
+    "created_at_unix_seconds"
+  ],
+  "title": "RecordsView"
+}
+
+
ReleasePackageView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "export_path": {
+      "type": "string",
+      "title": "Export Path"
+    },
+    "package_hash": {
+      "type": "string",
+      "title": "Package Hash"
+    },
+    "document_count": {
+      "type": "integer",
+      "title": "Document Count"
+    },
+    "release_artifact_count": {
+      "type": "integer",
+      "title": "Release Artifact Count"
+    },
+    "search_session_count": {
+      "type": "integer",
+      "title": "Search Session Count"
+    },
+    "release_count": {
+      "type": "integer",
+      "title": "Release Count"
+    },
+    "redacted_count": {
+      "type": "integer",
+      "title": "Redacted Count"
+    },
+    "exempt_count": {
+      "type": "integer",
+      "title": "Exempt Count"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "export_path",
+    "package_hash",
+    "document_count",
+    "release_artifact_count",
+    "search_session_count",
+    "release_count",
+    "redacted_count",
+    "exempt_count",
+    "created_at_unix_seconds"
+  ],
+  "title": "ReleasePackageView"
+}
+
+
RepeatLookup
+{
+  "properties": {
+    "property_reference": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Property Reference"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "property_reference"
+  ],
+  "title": "RepeatLookup"
+}
+
+
RequestCreate
+{
+  "properties": {
+    "requester_name": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Requester Name"
+    },
+    "requester_email": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 255
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Email"
+    },
+    "requester_phone": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 50
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Phone"
+    },
+    "requester_type": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 100
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Type"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Description"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "priority": {
+      "type": "string",
+      "title": "Priority",
+      "default": "normal"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^(narrow|moderate|broad)$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "requester_name",
+    "description"
+  ],
+  "title": "RequestCreate"
+}
+
+
RequestDocumentAdd
+{
+  "properties": {
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "relevance_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Relevance Note"
+    }
+  },
+  "type": "object",
+  "required": [
+    "document_id"
+  ],
+  "title": "RequestDocumentAdd"
+}
+
+
RequestDocumentRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "relevance_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Relevance Note"
+    },
+    "exemption_flags": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Exemption Flags"
+    },
+    "inclusion_status": {
+      "$ref": "#/components/schemas/InclusionStatus"
+    },
+    "attached_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Attached At"
+    },
+    "attached_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Attached By"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "document_id",
+    "relevance_note",
+    "exemption_flags",
+    "inclusion_status",
+    "attached_at",
+    "attached_by"
+  ],
+  "title": "RequestDocumentRead"
+}
+
+
RequestRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "requester_name": {
+      "type": "string",
+      "title": "Requester Name"
+    },
+    "requester_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Email"
+    },
+    "requester_phone": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Phone"
+    },
+    "requester_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Type"
+    },
+    "date_received": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Date Received"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "status": {
+      "$ref": "#/components/schemas/RequestStatus"
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "created_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "response_draft": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Response Draft"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    },
+    "estimated_fee": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Estimated Fee"
+    },
+    "fee_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Status"
+    },
+    "fee_waiver_requested": {
+      "type": "boolean",
+      "title": "Fee Waiver Requested",
+      "default": false
+    },
+    "priority": {
+      "type": "string",
+      "title": "Priority",
+      "default": "normal"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    },
+    "closed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closed At"
+    },
+    "closure_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closure Reason"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "requester_name",
+    "requester_email",
+    "date_received",
+    "statutory_deadline",
+    "description",
+    "status",
+    "assigned_to",
+    "created_by",
+    "created_at",
+    "response_draft",
+    "review_notes"
+  ],
+  "title": "RequestRead"
+}
+
+
RequestStats
+{
+  "properties": {
+    "total_requests": {
+      "type": "integer",
+      "title": "Total Requests"
+    },
+    "by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "By Status"
+    },
+    "approaching_deadline": {
+      "type": "integer",
+      "title": "Approaching Deadline"
+    },
+    "overdue": {
+      "type": "integer",
+      "title": "Overdue"
+    }
+  },
+  "type": "object",
+  "required": [
+    "total_requests",
+    "by_status",
+    "approaching_deadline",
+    "overdue"
+  ],
+  "title": "RequestStats"
+}
+
+
RequestStatus
+{
+  "type": "string",
+  "enum": [
+    "received",
+    "clarification_needed",
+    "assigned",
+    "searching",
+    "in_review",
+    "ready_for_release",
+    "drafted",
+    "approved",
+    "fulfilled",
+    "closed"
+  ],
+  "title": "RequestStatus"
+}
+
+
RequestUpdate
+{
+  "properties": {
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/RequestStatus"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "response_draft": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Response Draft"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    }
+  },
+  "type": "object",
+  "title": "RequestUpdate"
+}
+
+
RequirementBundle
+{
+  "properties": {
+    "requirement_id": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9_-]{1,100}$",
+      "title": "Requirement Id"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "project_type": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Project Type"
+    },
+    "source_reference": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Source Reference"
+    },
+    "source_date": {
+      "type": "string",
+      "format": "date",
+      "title": "Source Date"
+    },
+    "effective_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Effective On"
+    },
+    "dataset_kind": {
+      "type": "string",
+      "enum": [
+        "municipal",
+        "fictional"
+      ],
+      "title": "Dataset Kind"
+    },
+    "filename": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$",
+      "title": "Filename"
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 14000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Sha256"
+    },
+    "materials": {
+      "items": {
+        "$ref": "#/components/schemas/Material"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "minItems": 1,
+      "title": "Materials"
+    },
+    "pathway": {
+      "items": {
+        "$ref": "#/components/schemas/PathwayStep"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "title": "Pathway"
+    },
+    "fee_link": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    },
+    "staff_note": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Staff Note",
+      "default": ""
+    },
+    "change_note": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Change Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requirement_id",
+    "title",
+    "jurisdiction",
+    "project_type",
+    "source_reference",
+    "source_date",
+    "effective_on",
+    "dataset_kind",
+    "filename",
+    "content_base64",
+    "sha256",
+    "materials",
+    "change_note"
+  ],
+  "title": "RequirementBundle"
+}
+
+
ResponseLetterCreate
+{
+  "properties": {
+    "template_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Template Id"
+    }
+  },
+  "type": "object",
+  "title": "ResponseLetterCreate"
+}
+
+
ResponseLetterRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "template_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Template Id"
+    },
+    "generated_content": {
+      "type": "string",
+      "title": "Generated Content"
+    },
+    "edited_content": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Edited Content"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "generated_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Generated By"
+    },
+    "approved_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Approved By"
+    },
+    "sent_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sent At"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "template_id",
+    "generated_content",
+    "edited_content",
+    "status",
+    "generated_by",
+    "approved_by",
+    "sent_at",
+    "created_at"
+  ],
+  "title": "ResponseLetterRead"
+}
+
+
ResponseLetterUpdate
+{
+  "properties": {
+    "edited_content": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Edited Content"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Status"
+    }
+  },
+  "type": "object",
+  "title": "ResponseLetterUpdate"
+}
+
+
ReviewInput
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 5000,
+      "title": "Body",
+      "default": ""
+    },
+    "hasAltText": {
+      "type": "boolean",
+      "title": "Hasalttext",
+      "default": false
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": "en"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "ReviewInput"
+}
+
+
Revision
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    },
+    "document": {
+      "$ref": "#/components/schemas/NoticeDraft"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence",
+    "document"
+  ],
+  "title": "Revision"
+}
+
+
RewriteInput
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "plain-language",
+        "language-variant"
+      ],
+      "title": "Action"
+    },
+    "text": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Text"
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "text"
+  ],
+  "title": "RewriteInput"
+}
+
+
RewriteResult
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "plain-language",
+        "language-variant"
+      ],
+      "title": "Action"
+    },
+    "text": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Text"
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": ""
+    },
+    "outcome": {
+      "type": "string",
+      "enum": [
+        "generated",
+        "unavailable"
+      ],
+      "title": "Outcome"
+    },
+    "generated": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 100000
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Generated"
+    },
+    "model": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 200
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "text",
+    "outcome"
+  ],
+  "title": "RewriteResult"
+}
+
+
Rule
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "zone_code": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Zone Code"
+    },
+    "key": {
+      "type": "string",
+      "maxLength": 120,
+      "minLength": 1,
+      "title": "Key"
+    },
+    "section_number": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Section Number"
+    },
+    "kind": {
+      "type": "string",
+      "enum": [
+        "use",
+        "dimension"
+      ],
+      "title": "Kind"
+    },
+    "value": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Value"
+    },
+    "overlay_code": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 255
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Overlay Code"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "zone_code",
+    "key",
+    "section_number",
+    "kind",
+    "value"
+  ],
+  "title": "Rule"
+}
+
+
RuleTestMatch
+{
+  "properties": {
+    "matched_text": {
+      "type": "string",
+      "title": "Matched Text"
+    },
+    "start": {
+      "type": "integer",
+      "title": "Start"
+    },
+    "end": {
+      "type": "integer",
+      "title": "End"
+    }
+  },
+  "type": "object",
+  "required": [
+    "matched_text",
+    "start",
+    "end"
+  ],
+  "title": "RuleTestMatch"
+}
+
+
RuleTestRequest
+{
+  "properties": {
+    "sample_text": {
+      "type": "string",
+      "title": "Sample Text"
+    }
+  },
+  "type": "object",
+  "required": [
+    "sample_text"
+  ],
+  "title": "RuleTestRequest"
+}
+
+
RuleTestResponse
+{
+  "properties": {
+    "rule_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Rule Id"
+    },
+    "rule_type": {
+      "type": "string",
+      "title": "Rule Type"
+    },
+    "matched": {
+      "type": "boolean",
+      "title": "Matched"
+    },
+    "matches": {
+      "items": {
+        "$ref": "#/components/schemas/RuleTestMatch"
+      },
+      "type": "array",
+      "title": "Matches"
+    }
+  },
+  "type": "object",
+  "required": [
+    "rule_id",
+    "rule_type",
+    "matched",
+    "matches"
+  ],
+  "title": "RuleTestResponse"
+}
+
+
RuleType
+{
+  "type": "string",
+  "enum": [
+    "regex",
+    "keyword",
+    "llm_prompt"
+  ],
+  "title": "RuleType"
+}
+
+
SaveReview
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 5000,
+      "title": "Body",
+      "default": ""
+    },
+    "hasAltText": {
+      "type": "boolean",
+      "title": "Hasalttext",
+      "default": false
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": "en"
+    },
+    "ai_analysis": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 100000
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ai Analysis"
+    },
+    "ai_analysis_model": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 200
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ai Analysis Model"
+    },
+    "ai_outcome": {
+      "type": "string",
+      "enum": [
+        "generated",
+        "unavailable",
+        "failed"
+      ],
+      "title": "Ai Outcome"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "ai_outcome"
+  ],
+  "title": "SaveReview"
+}
+
+
SearchFilterOptions
+{
+  "properties": {
+    "file_types": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "File Types"
+    },
+    "source_names": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Source Names"
+    },
+    "departments": {
+      "items": {
+        "additionalProperties": true,
+        "type": "object"
+      },
+      "type": "array",
+      "title": "Departments",
+      "default": []
+    },
+    "date_range": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Date Range"
+    }
+  },
+  "type": "object",
+  "required": [
+    "file_types",
+    "source_names"
+  ],
+  "title": "SearchFilterOptions"
+}
+
+
SearchInput
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "SearchInput"
+}
+
+
SearchNoteCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "record-records-search",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/SearchNotePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "SearchNoteCommand"
+}
+
+
SearchNotePayload
+{
+  "properties": {
+    "sourceNote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Sourcenote"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sourceNote"
+  ],
+  "title": "SearchNotePayload"
+}
+
+
SearchReceiptCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "record-records-search-session",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/SearchReceiptPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "SearchReceiptCommand"
+}
+
+
SearchReceiptPayload
+{
+  "properties": {
+    "searchQuery": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchquery"
+    },
+    "searchLocations": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchlocations"
+    },
+    "searchResultTitle": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchresulttitle"
+    },
+    "searchResultCitation": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchresultcitation"
+    },
+    "searchResultSummary": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchresultsummary"
+    },
+    "searchResultStatus": {
+      "type": "string",
+      "title": "Searchresultstatus",
+      "default": ""
+    },
+    "searchReviewer": {
+      "type": "string",
+      "title": "Searchreviewer",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "searchQuery",
+    "searchLocations",
+    "searchResultTitle",
+    "searchResultCitation",
+    "searchResultSummary"
+  ],
+  "title": "SearchReceiptPayload"
+}
+
+
SearchReceiptView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "query": {
+      "type": "string",
+      "title": "Query"
+    },
+    "locations": {
+      "type": "string",
+      "title": "Locations"
+    },
+    "reviewer": {
+      "type": "string",
+      "title": "Reviewer"
+    },
+    "results": {
+      "items": {
+        "$ref": "#/components/schemas/SearchResultView"
+      },
+      "type": "array",
+      "title": "Results"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "query",
+    "locations",
+    "reviewer",
+    "results",
+    "created_at_unix_seconds"
+  ],
+  "title": "SearchReceiptView"
+}
+
+
SearchRequest
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "title": "Query"
+    },
+    "session_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Session Id"
+    },
+    "filters": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Filters"
+    },
+    "limit": {
+      "type": "integer",
+      "maximum": 50.0,
+      "title": "Limit",
+      "default": 10
+    },
+    "synthesize": {
+      "type": "boolean",
+      "title": "Synthesize",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "SearchRequest"
+}
+
+
SearchResponse
+{
+  "properties": {
+    "query_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Query Id"
+    },
+    "session_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Session Id"
+    },
+    "query_text": {
+      "type": "string",
+      "title": "Query Text"
+    },
+    "results": {
+      "items": {
+        "$ref": "#/components/schemas/SearchResultItem"
+      },
+      "type": "array",
+      "title": "Results"
+    },
+    "results_count": {
+      "type": "integer",
+      "title": "Results Count"
+    },
+    "synthesized_answer": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Synthesized Answer"
+    },
+    "ai_generated": {
+      "type": "boolean",
+      "title": "Ai Generated",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "query_id",
+    "session_id",
+    "query_text",
+    "results",
+    "results_count"
+  ],
+  "title": "SearchResponse"
+}
+
+
SearchResultItem
+{
+  "properties": {
+    "chunk_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Chunk Id"
+    },
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "filename": {
+      "type": "string",
+      "title": "Filename"
+    },
+    "file_type": {
+      "type": "string",
+      "title": "File Type"
+    },
+    "source_path": {
+      "type": "string",
+      "title": "Source Path"
+    },
+    "page_number": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Page Number"
+    },
+    "content_text": {
+      "type": "string",
+      "title": "Content Text"
+    },
+    "similarity_score": {
+      "type": "number",
+      "title": "Similarity Score"
+    },
+    "rank": {
+      "type": "integer",
+      "title": "Rank"
+    }
+  },
+  "type": "object",
+  "required": [
+    "chunk_id",
+    "document_id",
+    "filename",
+    "file_type",
+    "source_path",
+    "page_number",
+    "content_text",
+    "similarity_score",
+    "rank"
+  ],
+  "title": "SearchResultItem"
+}
+
+
SearchResultView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "title": {
+      "type": "string",
+      "title": "Title"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "title",
+    "citation",
+    "summary",
+    "status"
+  ],
+  "title": "SearchResultView"
+}
+
+
SearchSessionRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "user_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "User Id"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "queries": {
+      "items": {
+        "additionalProperties": true,
+        "type": "object"
+      },
+      "type": "array",
+      "title": "Queries",
+      "default": []
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "user_id",
+    "created_at"
+  ],
+  "title": "SearchSessionRead"
+}
+
+
SectionCreate
+{
+  "properties": {
+    "section_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Section Id"
+    },
+    "chapter_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Chapter Id"
+    },
+    "section_number": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Number"
+    },
+    "section_heading": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Heading"
+    },
+    "parent_section_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parent Section Id"
+    },
+    "sort_order": {
+      "type": "integer",
+      "title": "Sort Order",
+      "default": 0
+    },
+    "administrative_regulation_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Administrative Regulation Refs"
+    },
+    "resolution_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Resolution Refs"
+    },
+    "policy_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Policy Refs"
+    },
+    "approved_summary_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Approved Summary Refs"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "chapter_id",
+    "section_number",
+    "section_heading"
+  ],
+  "title": "SectionCreate",
+  "description": "Request body for creating a code section or subsection."
+}
+
+
SectionVersionCreate
+{
+  "properties": {
+    "version_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Version Id"
+    },
+    "section_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Id"
+    },
+    "source_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "version_label": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Version Label"
+    },
+    "body": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Body"
+    },
+    "effective_start": {
+      "type": "string",
+      "format": "date",
+      "title": "Effective Start"
+    },
+    "effective_end": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective End"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    },
+    "is_current": {
+      "type": "boolean",
+      "title": "Is Current",
+      "default": false
+    },
+    "adoption_event_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Adoption Event Id"
+    },
+    "amendment_event_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Amendment Event Id"
+    },
+    "amendment_summary": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Amendment Summary"
+    },
+    "prior_version_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Prior Version Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "section_id",
+    "source_id",
+    "version_label",
+    "body",
+    "effective_start"
+  ],
+  "title": "SectionVersionCreate",
+  "description": "Request body for adding an immutable section version."
+}
+
+
Selection
+{
+  "properties": {
+    "recording_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Recording Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "recording_id",
+    "expected_sha256"
+  ],
+  "title": "Selection"
+}
+
+
SentenceInput
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "citations": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Citations"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text"
+  ],
+  "title": "SentenceInput"
+}
+
+
ServiceAccountCreate
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole",
+      "default": "read_only"
+    }
+  },
+  "type": "object",
+  "required": [
+    "name"
+  ],
+  "title": "ServiceAccountCreate"
+}
+
+
ServiceAccountCreated
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "api_key": {
+      "type": "string",
+      "title": "Api Key"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "role",
+    "created_by",
+    "created_at",
+    "is_active",
+    "api_key"
+  ],
+  "title": "ServiceAccountCreated",
+  "description": "Returned only on creation — includes the plaintext API key (shown once)."
+}
+
+
ServiceAccountRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "role",
+    "created_by",
+    "created_at",
+    "is_active"
+  ],
+  "title": "ServiceAccountRead"
+}
+
+
ServiceAccountUpdate
+{
+  "properties": {
+    "role": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/UserRole"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "ServiceAccountUpdate"
+}
+
+
Snapshot
+{
+  "properties": {
+    "expected_revision": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Expected Revision"
+    },
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "staff_only",
+        "public"
+      ],
+      "title": "Visibility"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "expected_revision",
+    "visibility"
+  ],
+  "title": "Snapshot"
+}
+
+
SourceCreate
+{
+  "properties": {
+    "source_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Id"
+    },
+    "name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Name"
+    },
+    "publisher": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Publisher"
+    },
+    "source_type": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Type"
+    },
+    "source_category": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Category"
+    },
+    "source_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Url"
+    },
+    "file_reference": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "File Reference"
+    },
+    "retrieved_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Retrieved At"
+    },
+    "retrieval_method": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Retrieval Method"
+    },
+    "checksum": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Checksum"
+    },
+    "source_owner": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Owner"
+    },
+    "is_official": {
+      "type": "boolean",
+      "title": "Is Official",
+      "default": true
+    },
+    "official_status_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Official Status Note"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    },
+    "staff_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Staff Notes"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "name",
+    "publisher",
+    "source_type",
+    "source_category"
+  ],
+  "title": "SourceCreate",
+  "description": "Request body for registering an official or explicitly labeled source."
+}
+
+
SourceInput
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "label": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Label"
+    },
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "label",
+    "text"
+  ],
+  "title": "SourceInput"
+}
+
+
SourceSnapshot
+{
+  "properties": {
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "public",
+        "staff_only"
+      ],
+      "title": "Visibility"
+    },
+    "meeting_event_ids": {
+      "items": {
+        "type": "string",
+        "format": "uuid"
+      },
+      "type": "array",
+      "maxItems": 50,
+      "title": "Meeting Event Ids"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "visibility"
+  ],
+  "title": "SourceSnapshot"
+}
+
+
SourceType
+{
+  "type": "string",
+  "enum": [
+    "manual_drop",
+    "file_system",
+    "rest_api",
+    "odbc"
+  ],
+  "title": "SourceType"
+}
+
+
StaffRecordsIntake
+{
+  "properties": {
+    "requester": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requester"
+    },
+    "summary": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Summary"
+    },
+    "deadline": {
+      "type": "string",
+      "title": "Deadline"
+    },
+    "deadlineBasis": {
+      "type": "string",
+      "title": "Deadlinebasis",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requester",
+    "summary",
+    "deadline"
+  ],
+  "title": "StaffRecordsIntake",
+  "description": "Existing native create-records-request input; no caller-supplied actor."
+}
+
+
StandardsExplanation
+{
+  "properties": {
+    "question": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Question"
+    },
+    "process_section": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Process Section",
+      "default": ""
+    },
+    "zone_code": {
+      "type": "string",
+      "maxLength": 40,
+      "title": "Zone Code",
+      "default": ""
+    },
+    "rule_types": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "title": "Rule Types"
+    },
+    "observed": {
+      "additionalProperties": {
+        "type": "string"
+      },
+      "type": "object",
+      "title": "Observed"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "question"
+  ],
+  "title": "StandardsExplanation"
+}
+
+
SyncFailureRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "source_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Source Id"
+    },
+    "source_path": {
+      "type": "string",
+      "title": "Source Path"
+    },
+    "error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Message"
+    },
+    "error_class": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Class"
+    },
+    "http_status_code": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Http Status Code"
+    },
+    "retry_count": {
+      "type": "integer",
+      "title": "Retry Count"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "first_failed_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "First Failed At"
+    },
+    "last_retried_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Retried At"
+    },
+    "dismissed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Dismissed At"
+    },
+    "dismissed_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Dismissed By"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "source_id",
+    "source_path",
+    "error_message",
+    "error_class",
+    "http_status_code",
+    "retry_count",
+    "status",
+    "first_failed_at",
+    "last_retried_at",
+    "dismissed_at",
+    "dismissed_by"
+  ],
+  "title": "SyncFailureRead"
+}
+
+
SyncRunLogRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "source_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Source Id"
+    },
+    "started_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Started At"
+    },
+    "finished_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Finished At"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Status"
+    },
+    "records_attempted": {
+      "type": "integer",
+      "title": "Records Attempted"
+    },
+    "records_succeeded": {
+      "type": "integer",
+      "title": "Records Succeeded"
+    },
+    "records_failed": {
+      "type": "integer",
+      "title": "Records Failed"
+    },
+    "error_summary": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Summary"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "source_id",
+    "started_at",
+    "finished_at",
+    "status",
+    "records_attempted",
+    "records_succeeded",
+    "records_failed",
+    "error_summary"
+  ],
+  "title": "SyncRunLogRead"
+}
+
+
SystemStatus
+{
+  "properties": {
+    "version": {
+      "type": "string",
+      "title": "Version"
+    },
+    "database": {
+      "type": "string",
+      "title": "Database"
+    },
+    "ollama": {
+      "type": "string",
+      "title": "Ollama"
+    },
+    "redis": {
+      "type": "string",
+      "title": "Redis"
+    },
+    "user_count": {
+      "type": "integer",
+      "title": "User Count"
+    },
+    "audit_log_count": {
+      "type": "integer",
+      "title": "Audit Log Count"
+    },
+    "suite_session": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Suite Session"
+    }
+  },
+  "type": "object",
+  "required": [
+    "version",
+    "database",
+    "ollama",
+    "redis",
+    "user_count",
+    "audit_log_count"
+  ],
+  "title": "SystemStatus"
+}
+
+
TaggedPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "tagged-pdf",
+      "title": "Action"
+    },
+    "headingLevels": {
+      "items": {
+        "type": "integer",
+        "maximum": 4294967295.0,
+        "minimum": 0.0
+      },
+      "type": "array",
+      "maxItems": 50,
+      "title": "Headinglevels"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "TaggedPlan"
+}
+
+
TestConnectionRequest
+{
+  "properties": {
+    "source_type": {
+      "type": "string",
+      "title": "Source Type"
+    },
+    "host": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Host"
+    },
+    "port": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Port"
+    },
+    "path": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Path"
+    },
+    "username": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Username"
+    },
+    "password": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Password"
+    },
+    "rest_api_config": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Rest Api Config"
+    },
+    "odbc_config": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Odbc Config"
+    }
+  },
+  "type": "object",
+  "required": [
+    "source_type"
+  ],
+  "title": "TestConnectionRequest",
+  "description": "Dedicated schema for test-connection. NOT the create schema.\n\nSecurity: credentials in this request body are never persisted, never\nwritten to audit logs, and never returned in the response."
+}
+
+
TestConnectionResponse
+{
+  "properties": {
+    "success": {
+      "type": "boolean",
+      "title": "Success"
+    },
+    "message": {
+      "type": "string",
+      "title": "Message"
+    },
+    "latency_ms": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Latency Ms"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Status"
+    },
+    "warning": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Warning"
+    },
+    "differing_keys": {
+      "anyOf": [
+        {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Differing Keys"
+    }
+  },
+  "type": "object",
+  "required": [
+    "success",
+    "message"
+  ],
+  "title": "TestConnectionResponse"
+}
+
+
TimelineEventCreate
+{
+  "properties": {
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "internal_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Internal Note"
+    }
+  },
+  "type": "object",
+  "required": [
+    "event_type",
+    "description"
+  ],
+  "title": "TimelineEventCreate"
+}
+
+
TimelineEventRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "actor_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Actor Id"
+    },
+    "actor_role": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Actor Role"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "internal_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Internal Note"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "event_type",
+    "actor_id",
+    "actor_role",
+    "description",
+    "internal_note",
+    "created_at"
+  ],
+  "title": "TimelineEventRead"
+}
+
+
TimelineView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "actor": {
+      "type": "string",
+      "title": "Actor"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "action",
+    "actor",
+    "note",
+    "created_at_unix_seconds"
+  ],
+  "title": "TimelineView"
+}
+
+
TitleCreate
+{
+  "properties": {
+    "title_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Title Id"
+    },
+    "title_number": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title Number"
+    },
+    "title_name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title Name"
+    },
+    "sort_order": {
+      "type": "integer",
+      "title": "Sort Order",
+      "default": 0
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title_number",
+    "title_name"
+  ],
+  "title": "TitleCreate",
+  "description": "Request body for creating a code title."
+}
+
+
TranscriptInput
+{
+  "properties": {
+    "source_label": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Label"
+    },
+    "transcript_text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Transcript Text"
+    },
+    "correction_of_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Correction Of Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_label",
+    "transcript_text"
+  ],
+  "title": "TranscriptInput"
+}
+
+
UserRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "email": {
+      "type": "string",
+      "format": "email",
+      "title": "Email"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active",
+      "default": true
+    },
+    "is_superuser": {
+      "type": "boolean",
+      "title": "Is Superuser",
+      "default": false
+    },
+    "is_verified": {
+      "type": "boolean",
+      "title": "Is Verified",
+      "default": false
+    },
+    "full_name": {
+      "type": "string",
+      "title": "Full Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "last_login": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Login"
+    },
+    "must_change_password": {
+      "type": "boolean",
+      "title": "Must Change Password",
+      "default": false
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "email",
+    "full_name",
+    "role",
+    "created_at",
+    "last_login"
+  ],
+  "title": "UserRead"
+}
+
+
UserRole
+{
+  "type": "string",
+  "enum": [
+    "admin",
+    "staff",
+    "reviewer",
+    "read_only",
+    "liaison",
+    "public"
+  ],
+  "title": "UserRole"
+}
+
+
UserSelfUpdate
+{
+  "properties": {
+    "password": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Password"
+    },
+    "email": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "email"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    },
+    "is_superuser": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Superuser"
+    },
+    "is_verified": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Verified"
+    },
+    "full_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Full Name"
+    }
+  },
+  "type": "object",
+  "title": "UserSelfUpdate",
+  "description": "Schema for user self-update via PATCH /users/me.\n\nExcludes role and department_id. Any payload containing those fields is\nrejected at parse time (HTTP 422). Role and department changes require\nadmin privileges via /admin/users/{id}."
+}
+
+
UserUpdateRequest
+{
+  "properties": {
+    "full_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Full Name"
+    },
+    "role": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Role"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "UserUpdateRequest"
+}
+
+
ValidationError
+{
+  "properties": {
+    "loc": {
+      "items": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "integer"
+          }
+        ]
+      },
+      "type": "array",
+      "title": "Location"
+    },
+    "msg": {
+      "type": "string",
+      "title": "Message"
+    },
+    "type": {
+      "type": "string",
+      "title": "Error Type"
+    },
+    "input": {
+      "title": "Input"
+    },
+    "ctx": {
+      "type": "object",
+      "title": "Context"
+    }
+  },
+  "type": "object",
+  "required": [
+    "loc",
+    "msg",
+    "type"
+  ],
+  "title": "ValidationError"
+}
+
+
Version
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence"
+  ],
+  "title": "Version"
+}
+
+
VoteCorrection
+{
+  "properties": {
+    "vote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Vote"
+    },
+    "reason": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Reason"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "vote",
+    "reason"
+  ],
+  "title": "VoteCorrection"
+}
+
+
VoteInput
+{
+  "properties": {
+    "voter_name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Voter Name"
+    },
+    "vote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Vote"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "voter_name",
+    "vote"
+  ],
+  "title": "VoteInput"
+}
+
+
_ParcelLookupIn
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "query"
+  ],
+  "title": "_ParcelLookupIn"
+}
+
+
townlight_inspections__workflow_models__SourceLink
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "const": "code",
+      "title": "Provider",
+      "default": "code"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "SourceLink"
+}
+
+
townlight_permitting__workflow_models__SourceLink
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "enum": [
+        "code",
+        "zoning"
+      ],
+      "title": "Provider"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "SourceLink"
+}
+
+
townlight_runtime__inspections_bridge__Search
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "const": "code",
+      "title": "Provider"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "query"
+  ],
+  "title": "Search"
+}
+
+
townlight_runtime__notice_bridge__Review
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence",
+    "note"
+  ],
+  "title": "Review"
+}
+
+
townlight_runtime__permitting_bridge__Import
+{
+  "properties": {
+    "bundle": {
+      "$ref": "#/components/schemas/RequirementBundle"
+    },
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "bundle"
+  ],
+  "title": "Import"
+}
+
+
townlight_runtime__permitting_bridge__Search
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "enum": [
+        "code",
+        "zoning"
+      ],
+      "title": "Provider"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "query"
+  ],
+  "title": "Search"
+}
+
+
townlight_runtime__planning_bridge__Import
+{
+  "properties": {
+    "bundle": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Bundle"
+    },
+    "expected_previous_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Previous Revision"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "bundle"
+  ],
+  "title": "Import"
+}
+
+
townlight_runtime__planning_bridge__Search
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Query"
+    },
+    "plan_type": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 40
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Plan Type"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "Search"
+}
+
+
townlight_runtime__zoning_bridge__Review
+{
+  "properties": {
+    "answer": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Answer",
+      "default": ""
+    },
+    "notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Notes",
+      "default": ""
+    },
+    "queue_status": {
+      "type": "string",
+      "enum": [
+        "open",
+        "in_review",
+        "resolved",
+        "closed"
+      ],
+      "title": "Queue Status",
+      "default": "resolved"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "Review"
+}
+
Townlight · AGPL-3.0-only · Source schema evidence only
\ No newline at end of file diff --git a/docs/beta-1/api/inspections-openapi.json b/docs/beta-1/api/inspections-openapi.json new file mode 100644 index 0000000..41a40ef --- /dev/null +++ b/docs/beta-1/api/inspections-openapi.json @@ -0,0 +1,11811 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "Townlight Records", + "description": "Prepared source schema for the actual native composition; installed acceptance remains pending. Exported without lifespan, migrations or database/network access.", + "version": "1.8.0.dev2" + }, + "paths": { + "/desktop/v1/inspections-sources/search": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Search Inspections Sources", + "operationId": "search_inspections_sources_desktop_v1_inspections_sources_search_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MeetingsSearch" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/inspections/repeat-cases": { + "post": { + "tags": [ + "native-inspections" + ], + "summary": "Repeat Cases", + "operationId": "repeat_cases_desktop_v1_inspections_repeat_cases_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RepeatLookup" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/inspections/notice-draft": { + "post": { + "tags": [ + "native-inspections" + ], + "summary": "Notice", + "operationId": "notice_desktop_v1_inspections_notice_draft_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InspectionInput" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/inspections/cases": { + "get": { + "tags": [ + "native-inspections" + ], + "summary": "Cases", + "operationId": "cases_desktop_v1_inspections_cases_get", + "parameters": [ + { + "name": "offset", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 100000, + "minimum": 0, + "default": 0, + "title": "Offset" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "tags": [ + "native-inspections" + ], + "summary": "Create Case", + "operationId": "create_case_desktop_v1_inspections_cases_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InspectionInput" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/inspections/cases/{case_id}": { + "get": { + "tags": [ + "native-inspections" + ], + "summary": "Case", + "operationId": "case_desktop_v1_inspections_cases__case_id__get", + "parameters": [ + { + "name": "case_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Case Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/inspections/cases/{case_id}/revisions": { + "post": { + "tags": [ + "native-inspections" + ], + "summary": "Revise", + "operationId": "revise_desktop_v1_inspections_cases__case_id__revisions_post", + "parameters": [ + { + "name": "case_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Case Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InspectionInput" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/inspections/cases/{case_id}/history": { + "get": { + "tags": [ + "native-inspections" + ], + "summary": "History", + "operationId": "history_desktop_v1_inspections_cases__case_id__history_get", + "parameters": [ + { + "name": "case_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Case Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/inspections/cases/{case_id}/packets": { + "post": { + "tags": [ + "native-inspections" + ], + "summary": "Packet", + "operationId": "packet_desktop_v1_inspections_cases__case_id__packets_post", + "parameters": [ + { + "name": "case_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Case Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Packet" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/inspections/packets/{packet_id}": { + "get": { + "tags": [ + "native-inspections" + ], + "summary": "Document", + "operationId": "document_desktop_v1_inspections_packets__packet_id__get", + "parameters": [ + { + "name": "packet_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Packet Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/inspections/evidence/supported-types": { + "get": { + "tags": [ + "native-inspections" + ], + "summary": "Supported Types", + "description": "The media types this deployment's product model actually accepts.", + "operationId": "supported_types_desktop_v1_inspections_evidence_supported_types_get", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/inspections/evidence/retain": { + "post": { + "tags": [ + "native-inspections" + ], + "summary": "Retain", + "operationId": "retain_desktop_v1_inspections_evidence_retain_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvidenceItems" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/inspections/media/analyse": { + "post": { + "tags": [ + "native-inspections" + ], + "summary": "Media Analyse", + "description": "Run the configured adapters over retained originals; draft only.\n\nThe result carries the same observations/citations the product route returns\nplus ``analysis_record``: the exact ``AnalysisRecord`` the caller puts on its\ncase payload, so the reviewed draft is the analysed one.", + "operationId": "media_analyse_desktop_v1_inspections_media_analyse_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MediaAnalysis" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/inspections/connections/search": { + "post": { + "tags": [ + "native-inspections" + ], + "summary": "Connections", + "operationId": "connections_desktop_v1_inspections_connections_search_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/townlight_runtime__inspections_bridge__Search" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "ActionItemInput": { + "properties": { + "description": { + "type": "string", + "minLength": 1, + "title": "Description" + }, + "assigned_to": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "source_motion_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Source Motion Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "description" + ], + "title": "ActionItemInput" + }, + "AdaPlan": { + "properties": { + "action": { + "type": "string", + "const": "ada-title-ii", + "title": "Action" + }, + "serviceArea": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Servicearea" + }, + "hasCoordinatorReview": { + "type": "boolean", + "title": "Hascoordinatorreview", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "serviceArea" + ], + "title": "AdaPlan" + }, + "AdminUserCreateRequest": { + "properties": { + "email": { + "type": "string", + "title": "Email" + }, + "password": { + "type": "string", + "title": "Password" + }, + "full_name": { + "type": "string", + "title": "Full Name", + "default": "" + }, + "role": { + "type": "string", + "title": "Role", + "default": "staff" + } + }, + "type": "object", + "required": [ + "email", + "password" + ], + "title": "AdminUserCreateRequest" + }, + "AdminUserCreateResponse": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "email": { + "type": "string", + "title": "Email" + }, + "full_name": { + "type": "string", + "title": "Full Name" + }, + "role": { + "type": "string", + "title": "Role" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + } + }, + "type": "object", + "required": [ + "id", + "email", + "full_name", + "role", + "is_active" + ], + "title": "AdminUserCreateResponse" + }, + "AgendaAssignment": { + "properties": { + "meeting_id": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "meeting_id" + ], + "title": "AgendaAssignment" + }, + "AgendaInput": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "department_name": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Department Name" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "department_name" + ], + "title": "AgendaInput" + }, + "AgendaReviewInput": { + "properties": { + "to_status": { + "type": "string", + "enum": [ + "DRAFTED", + "SUBMITTED", + "DEPT_APPROVED", + "LEGAL_REVIEWED", + "CLERK_ACCEPTED", + "ON_AGENDA", + "IN_PACKET", + "POSTED", + "HEARD", + "DISPOSED", + "ARCHIVED" + ], + "title": "To Status" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "to_status" + ], + "title": "AgendaReviewInput" + }, + "AmendmentInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "policy": { + "$ref": "#/components/schemas/PolicySelection" + }, + "proposal": { + "type": "string", + "maxLength": 20000, + "minLength": 1, + "title": "Proposal" + }, + "responsible_staff": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Responsible Staff" + }, + "status": { + "type": "string", + "enum": [ + "draft", + "review", + "adopted", + "withdrawn" + ], + "title": "Status", + "default": "draft" + }, + "review_note": { + "type": "string", + "maxLength": 5000, + "title": "Review Note", + "default": "" + }, + "adoption_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Adoption Revision" + }, + "note": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "policy", + "proposal", + "responsible_staff", + "note" + ], + "title": "AmendmentInput" + }, + "AnalysisObservation": { + "properties": { + "source": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "title": "Source" + }, + "filename": { + "type": "string", + "maxLength": 160, + "title": "Filename", + "default": "" + }, + "media_type": { + "type": "string", + "maxLength": 80, + "title": "Media Type", + "default": "" + }, + "text": { + "type": "string", + "maxLength": 4000, + "minLength": 1, + "title": "Text" + }, + "adapter": { + "type": "string", + "maxLength": 120, + "title": "Adapter", + "default": "" + }, + "citation_source_ids": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 30, + "title": "Citation Source Ids" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source", + "text" + ], + "title": "AnalysisObservation", + "description": "One draft observation, named with the adapter that actually produced it." + }, + "AnalysisRecord": { + "properties": { + "observations": { + "items": { + "$ref": "#/components/schemas/AnalysisObservation" + }, + "type": "array", + "maxItems": 30, + "title": "Observations" + }, + "cited_sections": { + "items": { + "$ref": "#/components/schemas/CitedSection" + }, + "type": "array", + "maxItems": 30, + "title": "Cited Sections" + }, + "unavailable": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 30, + "title": "Unavailable" + }, + "runtime": { + "additionalProperties": true, + "type": "object", + "title": "Runtime" + }, + "review_required": { + "type": "boolean", + "title": "Review Required", + "default": true + } + }, + "additionalProperties": false, + "type": "object", + "title": "AnalysisRecord", + "description": "The adapter output that accompanies a saved inspection draft." + }, + "ApprovalCommand": { + "properties": { + "action": { + "type": "string", + "const": "approve-records-response", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ApprovalPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "ApprovalCommand" + }, + "ApprovalPayload": { + "properties": { + "approvalNote": { + "type": "string", + "title": "Approvalnote", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "title": "ApprovalPayload" + }, + "ArchiveInput": { + "properties": { + "visibility": { + "type": "string", + "enum": [ + "public", + "closed_session" + ], + "title": "Visibility" + }, + "packet_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Packet Id" + }, + "minutes_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Minutes Id" + }, + "plain_language_summary": { + "type": "string", + "title": "Plain Language Summary", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "visibility" + ], + "title": "ArchiveInput" + }, + "ArtifactPlan": { + "properties": { + "artifact_id": { + "type": "string", + "title": "Artifact Id" + }, + "file_name": { + "type": "string", + "title": "File Name" + }, + "content": { + "type": "string", + "title": "Content" + }, + "sha256": { + "type": "string", + "title": "Sha256" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "artifact_id", + "file_name", + "content", + "sha256", + "created_at_unix_seconds" + ], + "title": "ArtifactPlan" + }, + "AssignCommand": { + "properties": { + "action": { + "type": "string", + "const": "assign-records-request", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/AssignmentPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "AssignCommand" + }, + "AssignmentPayload": { + "properties": { + "assignedTo": { + "type": "string", + "minLength": 1, + "title": "Assignedto" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "assignedTo" + ], + "title": "AssignmentPayload" + }, + "AttachDocument": { + "properties": { + "title": { + "type": "string", + "minLength": 1, + "title": "Title" + }, + "citation": { + "type": "string", + "title": "Citation", + "default": "" + }, + "file": { + "$ref": "#/components/schemas/ManagedFileReceipt" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "file" + ], + "title": "AttachDocument" + }, + "AttachReleaseCopy": { + "properties": { + "status": { + "type": "string", + "enum": [ + "release-ready copy", + "redacted copy" + ], + "title": "Status" + }, + "note": { + "type": "string", + "title": "Note", + "default": "" + }, + "added_by": { + "type": "string", + "title": "Added By", + "default": "" + }, + "file": { + "$ref": "#/components/schemas/ManagedFileReceipt" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "status", + "file" + ], + "title": "AttachReleaseCopy" + }, + "AuditChainVerification": { + "properties": { + "is_valid": { + "type": "boolean", + "title": "Is Valid" + }, + "entries_checked": { + "type": "integer", + "title": "Entries Checked" + }, + "error_message": { + "type": "string", + "title": "Error Message" + } + }, + "type": "object", + "required": [ + "is_valid", + "entries_checked", + "error_message" + ], + "title": "AuditChainVerification" + }, + "AuditLogRead": { + "properties": { + "id": { + "type": "integer", + "title": "Id" + }, + "prev_hash": { + "type": "string", + "title": "Prev Hash" + }, + "entry_hash": { + "type": "string", + "title": "Entry Hash" + }, + "timestamp": { + "type": "string", + "format": "date-time", + "title": "Timestamp" + }, + "user_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "User Id" + }, + "action": { + "type": "string", + "title": "Action" + }, + "resource_type": { + "type": "string", + "title": "Resource Type" + }, + "resource_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Resource Id" + }, + "details": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Details" + }, + "ai_generated": { + "type": "boolean", + "title": "Ai Generated" + } + }, + "type": "object", + "required": [ + "id", + "prev_hash", + "entry_hash", + "timestamp", + "user_id", + "action", + "resource_type", + "resource_id", + "details", + "ai_generated" + ], + "title": "AuditLogRead" + }, + "AuditView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "module_id": { + "type": "string", + "title": "Module Id" + }, + "action": { + "type": "string", + "title": "Action" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + }, + "previous_hash": { + "type": "string", + "title": "Previous Hash" + }, + "entry_hash": { + "type": "string", + "title": "Entry Hash" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "module_id", + "action", + "summary", + "created_at_unix_seconds", + "previous_hash", + "entry_hash" + ], + "title": "AuditView" + }, + "BearerResponse": { + "properties": { + "access_token": { + "type": "string", + "title": "Access Token" + }, + "token_type": { + "type": "string", + "title": "Token Type" + } + }, + "type": "object", + "required": [ + "access_token", + "token_type" + ], + "title": "BearerResponse" + }, + "Body_auth_jwt_login_auth_jwt_login_post": { + "properties": { + "grant_type": { + "anyOf": [ + { + "type": "string", + "pattern": "^password$" + }, + { + "type": "null" + } + ], + "title": "Grant Type" + }, + "username": { + "type": "string", + "title": "Username" + }, + "password": { + "type": "string", + "format": "password", + "title": "Password" + }, + "scope": { + "type": "string", + "title": "Scope", + "default": "" + }, + "client_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Client Id" + }, + "client_secret": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "format": "password", + "title": "Client Secret" + } + }, + "type": "object", + "required": [ + "username", + "password" + ], + "title": "Body_auth_jwt_login_auth_jwt_login_post" + }, + "Body_upload_file_datasources_upload_post": { + "properties": { + "file": { + "type": "string", + "contentMediaType": "application/octet-stream", + "title": "File" + } + }, + "type": "object", + "required": [ + "file" + ], + "title": "Body_upload_file_datasources_upload_post" + }, + "CalculateDeadlineCommand": { + "properties": { + "action": { + "type": "string", + "const": "calculate-records-deadline", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/CalculateDeadlinePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "CalculateDeadlineCommand" + }, + "CalculateDeadlinePayload": { + "properties": { + "deadlineReceivedDate": { + "type": "string", + "title": "Deadlinereceiveddate" + }, + "deadlineRuleName": { + "type": "string", + "minLength": 1, + "title": "Deadlinerulename" + }, + "deadlineDayCount": { + "type": "string", + "title": "Deadlinedaycount" + }, + "deadlineDayType": { + "type": "string", + "title": "Deadlinedaytype" + }, + "deadlineBasis": { + "type": "string", + "minLength": 1, + "title": "Deadlinebasis" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "deadlineReceivedDate", + "deadlineRuleName", + "deadlineDayCount", + "deadlineDayType", + "deadlineBasis" + ], + "title": "CalculateDeadlinePayload" + }, + "ChapterCreate": { + "properties": { + "chapter_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Chapter Id" + }, + "title_id": { + "type": "string", + "minLength": 1, + "title": "Title Id" + }, + "chapter_number": { + "type": "string", + "minLength": 1, + "title": "Chapter Number" + }, + "chapter_name": { + "type": "string", + "minLength": 1, + "title": "Chapter Name" + }, + "sort_order": { + "type": "integer", + "title": "Sort Order", + "default": 0 + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title_id", + "chapter_number", + "chapter_name" + ], + "title": "ChapterCreate", + "description": "Request body for creating a code chapter." + }, + "CitedSection": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "citation": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Citation" + }, + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "version": { + "type": "string", + "maxLength": 80, + "title": "Version", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "citation" + ], + "title": "CitedSection", + "description": "One resolved public Code section; never a caller-supplied quotation." + }, + "CityProfileCreate": { + "properties": { + "city_name": { + "type": "string", + "title": "City Name" + }, + "state": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State" + }, + "county": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "County" + }, + "population_band": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Population Band" + }, + "email_platform": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Email Platform" + }, + "has_dedicated_it": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Has Dedicated It" + }, + "monthly_request_volume": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Monthly Request Volume" + }, + "profile_data": { + "additionalProperties": true, + "type": "object", + "title": "Profile Data", + "default": {} + }, + "gap_map": { + "additionalProperties": true, + "type": "object", + "title": "Gap Map", + "default": {} + } + }, + "type": "object", + "required": [ + "city_name" + ], + "title": "CityProfileCreate" + }, + "CityProfileRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "city_name": { + "type": "string", + "title": "City Name" + }, + "state": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State" + }, + "county": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "County" + }, + "population_band": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Population Band" + }, + "email_platform": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Email Platform" + }, + "has_dedicated_it": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Has Dedicated It" + }, + "monthly_request_volume": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Monthly Request Volume" + }, + "onboarding_status": { + "type": "string", + "title": "Onboarding Status" + }, + "profile_data": { + "additionalProperties": true, + "type": "object", + "title": "Profile Data" + }, + "gap_map": { + "additionalProperties": true, + "type": "object", + "title": "Gap Map" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "city_name", + "state", + "county", + "population_band", + "email_platform", + "has_dedicated_it", + "monthly_request_volume", + "onboarding_status", + "profile_data", + "gap_map", + "created_at", + "updated_at" + ], + "title": "CityProfileRead" + }, + "CityProfileUpdate": { + "properties": { + "city_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "City Name" + }, + "state": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State" + }, + "county": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "County" + }, + "population_band": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Population Band" + }, + "email_platform": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Email Platform" + }, + "has_dedicated_it": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Has Dedicated It" + }, + "monthly_request_volume": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Monthly Request Volume" + }, + "onboarding_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Onboarding Status" + }, + "profile_data": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Profile Data" + }, + "gap_map": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Gap Map" + } + }, + "type": "object", + "title": "CityProfileUpdate" + }, + "ClarificationCommand": { + "properties": { + "action": { + "type": "string", + "const": "request-records-clarification", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ClarificationPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "ClarificationCommand" + }, + "ClarificationPayload": { + "properties": { + "clarificationNote": { + "type": "string", + "minLength": 1, + "title": "Clarificationnote" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "clarificationNote" + ], + "title": "ClarificationPayload" + }, + "Closeout": { + "properties": { + "decision_id": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Decision Id" + }, + "version_id": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Version Id" + }, + "source_id": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Source Id" + }, + "version_label": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Version Label" + }, + "body": { + "type": "string", + "maxLength": 1000000, + "minLength": 1, + "title": "Body" + }, + "effective_start": { + "type": "string", + "format": "date", + "title": "Effective Start" + }, + "effective_end": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective End" + }, + "is_current": { + "type": "boolean", + "title": "Is Current" + }, + "reconciliation_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reconciliation Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "decision_id", + "version_id", + "source_id", + "version_label", + "body", + "effective_start", + "is_current" + ], + "title": "Closeout" + }, + "CodeContext": { + "properties": { + "section_number": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Section Number" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "section_number" + ], + "title": "CodeContext" + }, + "CodeLink": { + "properties": { + "provider": { + "type": "string", + "const": "code", + "title": "Provider", + "default": "code" + }, + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "CodeLink" + }, + "CodeSearch": { + "properties": { + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "CodeSearch" + }, + "CodeSourceSelection": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "CodeSourceSelection" + }, + "CompleteArtifact": { + "properties": { + "export_path": { + "type": "string", + "minLength": 1, + "title": "Export Path" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "export_path" + ], + "title": "CompleteArtifact" + }, + "ConnectionSearch": { + "properties": { + "provider": { + "type": "string", + "enum": [ + "meetings", + "zoning" + ], + "title": "Provider" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "query" + ], + "title": "ConnectionSearch" + }, + "CoverageGapResponse": { + "properties": { + "jurisdictions_without_rules": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Jurisdictions Without Rules" + }, + "departments_without_staff": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array", + "title": "Departments Without Staff" + }, + "uncovered_categories": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Uncovered Categories" + }, + "total_gaps": { + "type": "integer", + "title": "Total Gaps" + } + }, + "type": "object", + "required": [ + "jurisdictions_without_rules", + "departments_without_staff", + "uncovered_categories", + "total_gaps" + ], + "title": "CoverageGapResponse" + }, + "DataSourceAdminRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "source_type": { + "$ref": "#/components/schemas/SourceType" + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "type": "boolean", + "title": "Schedule Enabled", + "default": true + }, + "next_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Next Sync At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "last_ingestion_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Ingestion At" + }, + "last_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Sync At" + }, + "last_sync_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Sync Status" + }, + "last_error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Error Message" + }, + "consecutive_failure_count": { + "type": "integer", + "title": "Consecutive Failure Count", + "default": 0 + }, + "sync_paused": { + "type": "boolean", + "title": "Sync Paused", + "default": false + }, + "health_status": { + "type": "string", + "title": "Health Status", + "default": "healthy" + }, + "active_failure_count": { + "type": "integer", + "title": "Active Failure Count", + "default": 0 + }, + "connector_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Connector Type" + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At" + }, + "connection_config": { + "additionalProperties": true, + "type": "object", + "title": "Connection Config" + } + }, + "type": "object", + "required": [ + "id", + "name", + "source_type", + "is_active", + "created_by", + "created_at", + "last_ingestion_at", + "connection_config" + ], + "title": "DataSourceAdminRead", + "description": "Full datasource shape including connection_config. Returned only by admin-gated endpoints." + }, + "DataSourceCreate": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "source_type": { + "$ref": "#/components/schemas/SourceType" + }, + "connection_config": { + "additionalProperties": true, + "type": "object", + "title": "Connection Config", + "default": {} + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "type": "boolean", + "title": "Schedule Enabled", + "default": true + } + }, + "type": "object", + "required": [ + "name", + "source_type" + ], + "title": "DataSourceCreate" + }, + "DataSourceRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "source_type": { + "$ref": "#/components/schemas/SourceType" + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "type": "boolean", + "title": "Schedule Enabled", + "default": true + }, + "next_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Next Sync At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "last_ingestion_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Ingestion At" + }, + "last_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Sync At" + }, + "last_sync_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Sync Status" + }, + "last_error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Error Message" + }, + "consecutive_failure_count": { + "type": "integer", + "title": "Consecutive Failure Count", + "default": 0 + }, + "sync_paused": { + "type": "boolean", + "title": "Sync Paused", + "default": false + }, + "health_status": { + "type": "string", + "title": "Health Status", + "default": "healthy" + }, + "active_failure_count": { + "type": "integer", + "title": "Active Failure Count", + "default": 0 + }, + "connector_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Connector Type" + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "name", + "source_type", + "is_active", + "created_by", + "created_at", + "last_ingestion_at" + ], + "title": "DataSourceRead", + "description": "Redacted datasource shape — safe for non-admin roles. connection_config omitted." + }, + "DataSourceUpdate": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "connection_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Connection Config" + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Schedule Enabled" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "DataSourceUpdate" + }, + "DeadlineCommand": { + "properties": { + "action": { + "type": "string", + "const": "set-records-deadline", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/DeadlinePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "DeadlineCommand" + }, + "DeadlinePayload": { + "properties": { + "deadline": { + "type": "string", + "title": "Deadline" + }, + "deadlineBasis": { + "type": "string", + "minLength": 1, + "title": "Deadlinebasis" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "deadline", + "deadlineBasis" + ], + "title": "DeadlinePayload" + }, + "Decision": { + "properties": { + "id": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Id" + }, + "outcome": { + "type": "string", + "enum": [ + "adopted", + "not_adopted", + "deferred", + "withdrawn" + ], + "title": "Outcome" + }, + "decided_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Decided At" + }, + "decision_text": { + "type": "string", + "maxLength": 1000000, + "minLength": 1, + "title": "Decision Text" + }, + "supporting_references": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Supporting References" + }, + "supersedes_decision_id": { + "anyOf": [ + { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$" + }, + { + "type": "null" + } + ], + "title": "Supersedes Decision Id" + }, + "reconciliation_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reconciliation Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "outcome", + "decision_text" + ], + "title": "Decision" + }, + "DepartmentCreate": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "code": { + "type": "string", + "title": "Code" + }, + "contact_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Contact Email" + } + }, + "type": "object", + "required": [ + "name", + "code" + ], + "title": "DepartmentCreate" + }, + "DepartmentRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "code": { + "type": "string", + "title": "Code" + }, + "contact_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Contact Email" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "name", + "code", + "contact_email", + "created_at" + ], + "title": "DepartmentRead" + }, + "DepartmentUpdate": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Code" + }, + "contact_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Contact Email" + } + }, + "type": "object", + "title": "DepartmentUpdate" + }, + "DisclosureTemplateCreate": { + "properties": { + "template_type": { + "type": "string", + "title": "Template Type" + }, + "state_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State Code" + }, + "content": { + "type": "string", + "title": "Content" + } + }, + "type": "object", + "required": [ + "template_type", + "content" + ], + "title": "DisclosureTemplateCreate" + }, + "DisclosureTemplateRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "template_type": { + "type": "string", + "title": "Template Type" + }, + "state_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State Code" + }, + "content": { + "type": "string", + "title": "Content" + }, + "version": { + "type": "integer", + "title": "Version" + }, + "updated_by": { + "type": "string", + "format": "uuid", + "title": "Updated By" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "template_type", + "state_code", + "content", + "version", + "updated_by", + "updated_at" + ], + "title": "DisclosureTemplateRead" + }, + "DisclosureTemplateRendered": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "template_type": { + "type": "string", + "title": "Template Type" + }, + "rendered_content": { + "type": "string", + "title": "Rendered Content" + }, + "has_unresolved_variables": { + "type": "boolean", + "title": "Has Unresolved Variables" + } + }, + "type": "object", + "required": [ + "id", + "template_type", + "rendered_content", + "has_unresolved_variables" + ], + "title": "DisclosureTemplateRendered" + }, + "DisclosureTemplateUpdate": { + "properties": { + "content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Content" + }, + "state_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State Code" + } + }, + "type": "object", + "title": "DisclosureTemplateUpdate" + }, + "DocumentChunkRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "chunk_index": { + "type": "integer", + "title": "Chunk Index" + }, + "content_text": { + "type": "string", + "title": "Content Text" + }, + "token_count": { + "type": "integer", + "title": "Token Count" + }, + "page_number": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Page Number" + } + }, + "type": "object", + "required": [ + "id", + "document_id", + "chunk_index", + "content_text", + "token_count", + "page_number" + ], + "title": "DocumentChunkRead" + }, + "DocumentRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "source_id": { + "type": "string", + "format": "uuid", + "title": "Source Id" + }, + "source_path": { + "type": "string", + "title": "Source Path" + }, + "filename": { + "type": "string", + "title": "Filename" + }, + "file_type": { + "type": "string", + "title": "File Type" + }, + "file_hash": { + "type": "string", + "title": "File Hash" + }, + "file_size": { + "type": "integer", + "title": "File Size" + }, + "ingestion_status": { + "$ref": "#/components/schemas/IngestionStatus" + }, + "ingestion_error": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Ingestion Error" + }, + "chunk_count": { + "type": "integer", + "title": "Chunk Count" + }, + "ingested_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Ingested At" + }, + "connector_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Connector Type" + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "source_id", + "source_path", + "filename", + "file_type", + "file_hash", + "file_size", + "ingestion_status", + "ingestion_error", + "chunk_count", + "ingested_at" + ], + "title": "DocumentRead" + }, + "DraftCommand": { + "properties": { + "action": { + "type": "string", + "const": "draft-records-response", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/DraftPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "DraftCommand" + }, + "DraftInput": { + "properties": { + "source_materials": { + "items": { + "$ref": "#/components/schemas/SourceInput" + }, + "type": "array", + "title": "Source Materials" + }, + "sentences": { + "items": { + "$ref": "#/components/schemas/SentenceInput" + }, + "type": "array", + "minItems": 1, + "title": "Sentences" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sentences" + ], + "title": "DraftInput" + }, + "DraftPayload": { + "properties": { + "responseDraft": { + "type": "string", + "minLength": 1, + "title": "Responsedraft" + }, + "citation": { + "type": "string", + "title": "Citation", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "responseDraft" + ], + "title": "DraftPayload" + }, + "ErrorModel": { + "properties": { + "detail": { + "anyOf": [ + { + "type": "string" + }, + { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + ], + "title": "Detail" + } + }, + "type": "object", + "required": [ + "detail" + ], + "title": "ErrorModel" + }, + "Evidence": { + "properties": { + "filename": { + "type": "string", + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$", + "title": "Filename" + }, + "description": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Description" + }, + "media_type": { + "type": "string", + "enum": [ + "text/plain", + "image/jpeg", + "image/png", + "image/webp", + "application/pdf", + "audio/webm", + "audio/ogg", + "audio/wav", + "audio/mpeg", + "audio/mp4" + ], + "title": "Media Type" + }, + "content_base64": { + "type": "string", + "maxLength": 14000000, + "minLength": 1, + "title": "Content Base64" + }, + "sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "filename", + "description", + "media_type", + "content_base64", + "sha256" + ], + "title": "Evidence" + }, + "EvidenceItem": { + "properties": { + "filename": { + "type": "string", + "maxLength": 151, + "minLength": 1, + "title": "Filename" + }, + "media_type": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Media Type" + }, + "description": { + "type": "string", + "maxLength": 2000, + "title": "Description", + "default": "" + }, + "content_base64": { + "type": "string", + "maxLength": 14000000, + "minLength": 1, + "title": "Content Base64" + }, + "sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "filename", + "media_type", + "content_base64", + "sha256" + ], + "title": "EvidenceItem" + }, + "EvidenceItems": { + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/EvidenceItem" + }, + "type": "array", + "maxItems": 10, + "minItems": 1, + "title": "Items" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "items" + ], + "title": "EvidenceItems" + }, + "ExemptionAccuracyReport": { + "properties": { + "category": { + "type": "string", + "title": "Category" + }, + "total_flags": { + "type": "integer", + "title": "Total Flags" + }, + "accepted": { + "type": "integer", + "title": "Accepted" + }, + "rejected": { + "type": "integer", + "title": "Rejected" + }, + "pending": { + "type": "integer", + "title": "Pending" + }, + "acceptance_rate": { + "type": "number", + "title": "Acceptance Rate" + } + }, + "type": "object", + "required": [ + "category", + "total_flags", + "accepted", + "rejected", + "pending", + "acceptance_rate" + ], + "title": "ExemptionAccuracyReport" + }, + "ExemptionDashboard": { + "properties": { + "total_flags": { + "type": "integer", + "title": "Total Flags" + }, + "by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "By Status" + }, + "by_category": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "By Category" + }, + "acceptance_rate": { + "type": "number", + "title": "Acceptance Rate" + }, + "total_rules": { + "type": "integer", + "title": "Total Rules" + }, + "active_rules": { + "type": "integer", + "title": "Active Rules" + } + }, + "type": "object", + "required": [ + "total_flags", + "by_status", + "by_category", + "acceptance_rate", + "total_rules", + "active_rules" + ], + "title": "ExemptionDashboard" + }, + "ExemptionDecisionCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-exemption-decision", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ExemptionDecisionPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "ExemptionDecisionCommand" + }, + "ExemptionDecisionPayload": { + "properties": { + "exemptionSource": { + "type": "string", + "minLength": 1, + "title": "Exemptionsource" + }, + "exemptionKind": { + "type": "string", + "minLength": 1, + "title": "Exemptionkind" + }, + "exemptionFinding": { + "type": "string", + "minLength": 1, + "title": "Exemptionfinding" + }, + "exemptionDecision": { + "type": "string", + "enum": [ + "release", + "redact", + "exempt" + ], + "title": "Exemptiondecision" + }, + "exemptionBasis": { + "type": "string", + "minLength": 1, + "title": "Exemptionbasis" + }, + "exemptionReviewer": { + "type": "string", + "title": "Exemptionreviewer", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "exemptionSource", + "exemptionKind", + "exemptionFinding", + "exemptionDecision", + "exemptionBasis" + ], + "title": "ExemptionDecisionPayload" + }, + "ExemptionDecisionView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "source": { + "type": "string", + "title": "Source" + }, + "kind": { + "type": "string", + "title": "Kind" + }, + "finding": { + "type": "string", + "title": "Finding" + }, + "decision": { + "type": "string", + "enum": [ + "release", + "redact", + "exempt" + ], + "title": "Decision" + }, + "basis": { + "type": "string", + "title": "Basis" + }, + "reviewer": { + "type": "string", + "title": "Reviewer" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "source", + "kind", + "finding", + "decision", + "basis", + "reviewer", + "created_at_unix_seconds" + ], + "title": "ExemptionDecisionView" + }, + "ExemptionFlagRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "chunk_id": { + "type": "string", + "format": "uuid", + "title": "Chunk Id" + }, + "rule_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Rule Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "category": { + "type": "string", + "title": "Category" + }, + "matched_text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Matched Text" + }, + "confidence": { + "type": "number", + "title": "Confidence" + }, + "status": { + "$ref": "#/components/schemas/FlagStatus" + }, + "reviewed_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Reviewed By" + }, + "reviewed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Reviewed At" + }, + "review_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Reason" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "chunk_id", + "rule_id", + "request_id", + "category", + "matched_text", + "confidence", + "status", + "reviewed_by", + "reviewed_at", + "review_reason", + "created_at" + ], + "title": "ExemptionFlagRead" + }, + "ExemptionFlagReview": { + "properties": { + "status": { + "$ref": "#/components/schemas/FlagStatus" + }, + "review_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Reason" + } + }, + "type": "object", + "required": [ + "status" + ], + "title": "ExemptionFlagReview" + }, + "ExemptionNoteCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-exemption-review", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ExemptionNotePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "ExemptionNoteCommand" + }, + "ExemptionNotePayload": { + "properties": { + "exemptionNote": { + "type": "string", + "minLength": 1, + "title": "Exemptionnote" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "exemptionNote" + ], + "title": "ExemptionNotePayload" + }, + "ExemptionRuleCreate": { + "properties": { + "state_code": { + "type": "string", + "title": "State Code" + }, + "category": { + "type": "string", + "title": "Category" + }, + "rule_type": { + "$ref": "#/components/schemas/RuleType" + }, + "rule_definition": { + "type": "string", + "title": "Rule Definition" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "enabled": { + "type": "boolean", + "title": "Enabled", + "default": true + } + }, + "type": "object", + "required": [ + "state_code", + "category", + "rule_type", + "rule_definition" + ], + "title": "ExemptionRuleCreate" + }, + "ExemptionRuleRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "state_code": { + "type": "string", + "title": "State Code" + }, + "category": { + "type": "string", + "title": "Category" + }, + "rule_type": { + "$ref": "#/components/schemas/RuleType" + }, + "rule_definition": { + "type": "string", + "title": "Rule Definition" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "enabled": { + "type": "boolean", + "title": "Enabled" + }, + "version": { + "type": "integer", + "title": "Version", + "default": 1 + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "state_code", + "category", + "rule_type", + "rule_definition", + "description", + "enabled", + "created_by", + "created_at" + ], + "title": "ExemptionRuleRead" + }, + "ExemptionRuleUpdate": { + "properties": { + "rule_definition": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Rule Definition" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "enabled": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Enabled" + } + }, + "type": "object", + "title": "ExemptionRuleUpdate" + }, + "ExportReceipt": { + "properties": { + "export_path": { + "type": "string", + "maxLength": 32768, + "minLength": 1, + "title": "Export Path" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "export_path" + ], + "title": "ExportReceipt" + }, + "FeeEstimateCommand": { + "properties": { + "action": { + "type": "string", + "const": "estimate-records-fee", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/FeeEstimatePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "FeeEstimateCommand" + }, + "FeeEstimatePayload": { + "properties": { + "feeEstimate": { + "type": "string", + "minLength": 1, + "title": "Feeestimate" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "feeEstimate" + ], + "title": "FeeEstimatePayload" + }, + "FeeEstimateRequest": { + "properties": { + "page_count": { + "type": "integer", + "title": "Page Count" + }, + "fee_schedule_id": { + "type": "string", + "format": "uuid", + "title": "Fee Schedule Id" + } + }, + "type": "object", + "required": [ + "page_count", + "fee_schedule_id" + ], + "title": "FeeEstimateRequest" + }, + "FeeEstimateResponse": { + "properties": { + "page_count": { + "type": "integer", + "title": "Page Count" + }, + "unit_price": { + "type": "number", + "title": "Unit Price" + }, + "total": { + "type": "number", + "title": "Total" + }, + "fee_type": { + "type": "string", + "title": "Fee Type" + }, + "description": { + "type": "string", + "title": "Description" + } + }, + "type": "object", + "required": [ + "page_count", + "unit_price", + "total", + "fee_type", + "description" + ], + "title": "FeeEstimateResponse" + }, + "FeeLineCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-fee-line", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/FeeLinePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "FeeLineCommand" + }, + "FeeLineItemCreate": { + "properties": { + "description": { + "type": "string", + "title": "Description" + }, + "quantity": { + "type": "integer", + "title": "Quantity", + "default": 1 + }, + "unit_price": { + "type": "number", + "title": "Unit Price" + }, + "fee_schedule_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Fee Schedule Id" + } + }, + "type": "object", + "required": [ + "description", + "unit_price" + ], + "title": "FeeLineItemCreate" + }, + "FeeLineItemRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "fee_schedule_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Fee Schedule Id" + }, + "description": { + "type": "string", + "title": "Description" + }, + "quantity": { + "type": "integer", + "title": "Quantity" + }, + "unit_price": { + "type": "number", + "title": "Unit Price" + }, + "total": { + "type": "number", + "title": "Total" + }, + "status": { + "type": "string", + "title": "Status" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "fee_schedule_id", + "description", + "quantity", + "unit_price", + "total", + "status", + "created_at" + ], + "title": "FeeLineItemRead" + }, + "FeeLinePayload": { + "properties": { + "feeLineDescription": { + "type": "string", + "minLength": 1, + "title": "Feelinedescription" + }, + "feeScheduleBasis": { + "type": "string", + "minLength": 1, + "title": "Feeschedulebasis" + }, + "feeLineAmount": { + "type": "string", + "title": "Feelineamount" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "feeLineDescription", + "feeScheduleBasis", + "feeLineAmount" + ], + "title": "FeeLinePayload" + }, + "FeeLineView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "description": { + "type": "string", + "title": "Description" + }, + "schedule_basis": { + "type": "string", + "title": "Schedule Basis" + }, + "amount_cents": { + "type": "integer", + "title": "Amount Cents" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "description", + "schedule_basis", + "amount_cents", + "created_at_unix_seconds" + ], + "title": "FeeLineView" + }, + "FeeScheduleCreate": { + "properties": { + "jurisdiction": { + "type": "string", + "title": "Jurisdiction" + }, + "fee_type": { + "type": "string", + "title": "Fee Type" + }, + "amount": { + "type": "number", + "title": "Amount" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "effective_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective Date" + } + }, + "type": "object", + "required": [ + "jurisdiction", + "fee_type", + "amount" + ], + "title": "FeeScheduleCreate" + }, + "FeeScheduleRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "jurisdiction": { + "type": "string", + "title": "Jurisdiction" + }, + "fee_type": { + "type": "string", + "title": "Fee Type" + }, + "amount": { + "type": "number", + "title": "Amount" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "effective_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective Date" + }, + "created_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "jurisdiction", + "fee_type", + "amount", + "description", + "effective_date", + "created_by", + "created_at" + ], + "title": "FeeScheduleRead" + }, + "FeeScheduleUpdate": { + "properties": { + "fee_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Fee Type" + }, + "amount": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Amount" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "effective_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective Date" + } + }, + "type": "object", + "title": "FeeScheduleUpdate" + }, + "FeeWaiverCommand": { + "properties": { + "action": { + "type": "string", + "const": "waive-records-fee", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/FeeWaiverPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "FeeWaiverCommand" + }, + "FeeWaiverCreateRequest": { + "properties": { + "waiver_type": { + "type": "string", + "title": "Waiver Type" + }, + "reason": { + "type": "string", + "title": "Reason" + } + }, + "type": "object", + "required": [ + "waiver_type", + "reason" + ], + "title": "FeeWaiverCreateRequest" + }, + "FeeWaiverPayload": { + "properties": { + "feeWaiverReason": { + "type": "string", + "minLength": 1, + "title": "Feewaiverreason" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "feeWaiverReason" + ], + "title": "FeeWaiverPayload" + }, + "FeeWaiverReadResponse": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "waiver_type": { + "type": "string", + "title": "Waiver Type" + }, + "reason": { + "type": "string", + "title": "Reason" + }, + "status": { + "type": "string", + "title": "Status" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + }, + "created_at": { + "type": "string", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "waiver_type", + "reason", + "status", + "created_at" + ], + "title": "FeeWaiverReadResponse" + }, + "FeeWaiverReviewRequest": { + "properties": { + "status": { + "type": "string", + "title": "Status" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + } + }, + "type": "object", + "required": [ + "status" + ], + "title": "FeeWaiverReviewRequest" + }, + "FinishCommand": { + "properties": { + "action": { + "type": "string", + "enum": [ + "fulfill-records-request", + "close-records-request" + ], + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/NativePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "FinishCommand" + }, + "FlagStatus": { + "type": "string", + "enum": [ + "flagged", + "reviewed", + "accepted", + "rejected" + ], + "title": "FlagStatus" + }, + "FormPlan": { + "properties": { + "action": { + "type": "string", + "const": "form-plan", + "title": "Action" + }, + "formName": { + "type": "string", + "maxLength": 500, + "title": "Formname", + "default": "" + }, + "fields": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 50, + "title": "Fields" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "FormPlan" + }, + "GeneratedDraft": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "model": { + "type": "string", + "minLength": 1, + "title": "Model" + }, + "previous_response_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Previous Response Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text", + "model", + "previous_response_sha256" + ], + "title": "GeneratedDraft" + }, + "HTTPValidationError": { + "properties": { + "detail": { + "items": { + "$ref": "#/components/schemas/ValidationError" + }, + "type": "array", + "title": "Detail" + } + }, + "type": "object", + "title": "HTTPValidationError" + }, + "Handoff": { + "properties": { + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "request_id" + ], + "title": "Handoff" + }, + "ImportBundleCreate": { + "properties": { + "job_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Job Id" + }, + "connector_type": { + "type": "string", + "minLength": 1, + "title": "Connector Type" + }, + "source": { + "$ref": "#/components/schemas/SourceCreate" + }, + "sources": { + "items": { + "$ref": "#/components/schemas/SourceCreate" + }, + "type": "array", + "title": "Sources" + }, + "titles": { + "items": { + "$ref": "#/components/schemas/TitleCreate" + }, + "type": "array", + "title": "Titles" + }, + "chapters": { + "items": { + "$ref": "#/components/schemas/ChapterCreate" + }, + "type": "array", + "title": "Chapters" + }, + "sections": { + "items": { + "$ref": "#/components/schemas/SectionCreate" + }, + "type": "array", + "title": "Sections" + }, + "versions": { + "items": { + "$ref": "#/components/schemas/SectionVersionCreate" + }, + "type": "array", + "title": "Versions" + }, + "provenance": { + "additionalProperties": true, + "type": "object", + "title": "Provenance" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "connector_type", + "source" + ], + "title": "ImportBundleCreate", + "description": "Request body for local fixture/file-drop import jobs." + }, + "InclusionStatus": { + "type": "string", + "enum": [ + "included", + "excluded", + "pending" + ], + "title": "InclusionStatus" + }, + "IngestionStats": { + "properties": { + "total_sources": { + "type": "integer", + "title": "Total Sources" + }, + "active_sources": { + "type": "integer", + "title": "Active Sources" + }, + "total_documents": { + "type": "integer", + "title": "Total Documents" + }, + "documents_by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Documents By Status" + }, + "total_chunks": { + "type": "integer", + "title": "Total Chunks" + } + }, + "type": "object", + "required": [ + "total_sources", + "active_sources", + "total_documents", + "documents_by_status", + "total_chunks" + ], + "title": "IngestionStats" + }, + "IngestionStatus": { + "type": "string", + "enum": [ + "pending", + "processing", + "completed", + "failed" + ], + "title": "IngestionStatus" + }, + "InitiativeInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "policy": { + "$ref": "#/components/schemas/PolicySelection" + }, + "responsible_staff": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Responsible Staff" + }, + "target": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "title": "Target" + }, + "unit": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Unit" + }, + "due_on": { + "type": "string", + "format": "date", + "title": "Due On" + }, + "status": { + "type": "string", + "enum": [ + "planned", + "active", + "completed", + "cancelled" + ], + "title": "Status", + "default": "planned" + }, + "milestones": { + "items": { + "$ref": "#/components/schemas/Milestone" + }, + "type": "array", + "maxItems": 100, + "title": "Milestones" + }, + "measurements": { + "items": { + "$ref": "#/components/schemas/Measurement" + }, + "type": "array", + "maxItems": 1000, + "title": "Measurements" + }, + "note": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "policy", + "responsible_staff", + "target", + "unit", + "due_on", + "note" + ], + "title": "InitiativeInput" + }, + "InspectionInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "property_reference": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Property Reference" + }, + "inspection_reference": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Inspection Reference" + }, + "dataset_kind": { + "type": "string", + "enum": [ + "municipal", + "fictional" + ], + "title": "Dataset Kind" + }, + "inspector_notes": { + "type": "string", + "maxLength": 10000, + "minLength": 1, + "title": "Inspector Notes" + }, + "photo_observations": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 30, + "title": "Photo Observations" + }, + "voice_notes": { + "type": "string", + "maxLength": 10000, + "title": "Voice Notes", + "default": "" + }, + "evidence": { + "items": { + "$ref": "#/components/schemas/Evidence" + }, + "type": "array", + "maxItems": 10, + "title": "Evidence" + }, + "linked_sources": { + "items": { + "$ref": "#/components/schemas/townlight_inspections__workflow_models__SourceLink" + }, + "type": "array", + "maxItems": 30, + "title": "Linked Sources" + }, + "assigned_to": { + "type": "string", + "maxLength": 255, + "title": "Assigned To", + "default": "" + }, + "staff_notes": { + "type": "string", + "maxLength": 10000, + "title": "Staff Notes", + "default": "" + }, + "notice_draft": { + "type": "string", + "maxLength": 10000, + "title": "Notice Draft", + "default": "" + }, + "review_state": { + "type": "string", + "enum": [ + "draft", + "follow_up", + "reviewed" + ], + "title": "Review State", + "default": "draft" + }, + "review_notes": { + "type": "string", + "maxLength": 4000, + "title": "Review Notes", + "default": "" + }, + "public_summary": { + "type": "string", + "maxLength": 10000, + "title": "Public Summary", + "default": "" + }, + "analysis": { + "anyOf": [ + { + "$ref": "#/components/schemas/AnalysisRecord" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "property_reference", + "inspection_reference", + "dataset_kind", + "inspector_notes" + ], + "title": "InspectionInput" + }, + "IntakeInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "project_name": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Project Name" + }, + "project_description": { + "type": "string", + "maxLength": 10000, + "minLength": 1, + "title": "Project Description" + }, + "location": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Location" + }, + "applicant_contact": { + "type": "string", + "maxLength": 2000, + "title": "Applicant Contact", + "default": "" + }, + "requirement_revision": { + "type": "string", + "format": "uuid", + "title": "Requirement Revision" + }, + "materials": { + "items": { + "$ref": "#/components/schemas/MaterialReview" + }, + "type": "array", + "maxItems": 100, + "minItems": 1, + "title": "Materials" + }, + "linked_sources": { + "items": { + "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink" + }, + "type": "array", + "maxItems": 30, + "title": "Linked Sources" + }, + "staff_notes": { + "type": "string", + "maxLength": 10000, + "title": "Staff Notes", + "default": "" + }, + "assigned_to": { + "type": "string", + "maxLength": 255, + "title": "Assigned To", + "default": "" + }, + "review_state": { + "type": "string", + "enum": [ + "draft", + "follow_up", + "reviewed" + ], + "title": "Review State", + "default": "draft" + }, + "review_notes": { + "type": "string", + "maxLength": 4000, + "title": "Review Notes", + "default": "" + }, + "public_summary": { + "type": "string", + "maxLength": 10000, + "title": "Public Summary", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "project_name", + "project_description", + "location", + "requirement_revision", + "materials" + ], + "title": "IntakeInput" + }, + "InterpretationNoteCreate": { + "properties": { + "note_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Note Id" + }, + "note_text": { + "type": "string", + "minLength": 1, + "title": "Note Text" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "note_text" + ], + "title": "InterpretationNoteCreate", + "description": "Request body for staff-only interpretation notes." + }, + "InterviewRequest": { + "properties": { + "last_answer": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Answer" + }, + "last_field": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Field" + }, + "skipped_fields": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Skipped Fields" + } + }, + "type": "object", + "title": "InterviewRequest" + }, + "InterviewResponse": { + "properties": { + "question": { + "type": "string", + "title": "Question" + }, + "target_field": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Target Field" + }, + "all_complete": { + "type": "boolean", + "title": "All Complete" + }, + "completed_fields": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Completed Fields" + }, + "onboarding_status": { + "type": "string", + "title": "Onboarding Status" + }, + "skipped_fields": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Skipped Fields" + } + }, + "type": "object", + "required": [ + "question", + "target_field", + "all_complete", + "completed_fields", + "onboarding_status", + "skipped_fields" + ], + "title": "InterviewResponse" + }, + "ManagedFileReceipt": { + "properties": { + "original_path": { + "type": "string", + "minLength": 1, + "title": "Original Path" + }, + "stored_path": { + "type": "string", + "minLength": 1, + "title": "Stored Path" + }, + "file_name": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "File Name" + }, + "sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Sha256" + }, + "size_bytes": { + "type": "integer", + "maximum": 2147483647.0, + "minimum": 0.0, + "title": "Size Bytes" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "original_path", + "stored_path", + "file_name", + "sha256", + "size_bytes" + ], + "title": "ManagedFileReceipt" + }, + "ManagedSource": { + "properties": { + "original_path": { + "type": "string", + "title": "Original Path" + }, + "stored_path": { + "type": "string", + "title": "Stored Path" + }, + "file_name": { + "type": "string", + "title": "File Name" + }, + "sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Sha256" + }, + "size_bytes": { + "type": "integer", + "minimum": 0.0, + "title": "Size Bytes" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "original_path", + "stored_path", + "file_name", + "sha256", + "size_bytes" + ], + "title": "ManagedSource" + }, + "Material": { + "properties": { + "material_id": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]{1,80}$", + "title": "Material Id" + }, + "description": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Description" + }, + "citation": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Citation" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "material_id", + "description", + "citation" + ], + "title": "Material" + }, + "MaterialReview": { + "properties": { + "material_id": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Material Id" + }, + "status": { + "type": "string", + "enum": [ + "not_reviewed", + "provided", + "missing", + "unclear" + ], + "title": "Status", + "default": "not_reviewed" + }, + "note": { + "type": "string", + "maxLength": 2000, + "title": "Note", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "material_id" + ], + "title": "MaterialReview" + }, + "Measurement": { + "properties": { + "recorded_on": { + "type": "string", + "format": "date", + "title": "Recorded On" + }, + "value": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "title": "Value" + }, + "evidence": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Evidence" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "recorded_on", + "value", + "evidence" + ], + "title": "Measurement" + }, + "MediaAnalysis": { + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/EvidenceItem" + }, + "type": "array", + "maxItems": 10, + "minItems": 1, + "title": "Items" + }, + "code_links": { + "items": { + "$ref": "#/components/schemas/CodeLink" + }, + "type": "array", + "maxItems": 30, + "title": "Code Links" + }, + "inspector_supplied_text": { + "type": "string", + "maxLength": 10000, + "title": "Inspector Supplied Text", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "items" + ], + "title": "MediaAnalysis" + }, + "MeetingInput": { + "properties": { + "title": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Title" + }, + "scheduled_start": { + "type": "string", + "format": "date-time", + "title": "Scheduled Start" + }, + "location": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Location" + }, + "meeting_type": { + "type": "string", + "enum": [ + "regular", + "special", + "emergency", + "closed_session", + "executive" + ], + "title": "Meeting Type", + "default": "regular" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "scheduled_start", + "location" + ], + "title": "MeetingInput" + }, + "MeetingLink": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + }, + "relation": { + "type": "string", + "enum": [ + "hearing", + "context", + "precedent" + ], + "title": "Relation" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256", + "relation" + ], + "title": "MeetingLink" + }, + "MeetingSearch": { + "properties": { + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "MeetingSearch" + }, + "MeetingStageInput": { + "properties": { + "to_status": { + "type": "string", + "enum": [ + "SCHEDULED", + "NOTICED", + "PACKET_POSTED", + "IN_PROGRESS", + "RECESSED", + "ADJOURNED", + "TRANSCRIPT_READY", + "MINUTES_DRAFTED", + "MINUTES_POSTED", + "MINUTES_ADOPTED", + "MINUTES_SIGNED", + "ARCHIVED", + "CANCELLED" + ], + "title": "To Status" + }, + "statutory_basis": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Statutory Basis" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "to_status" + ], + "title": "MeetingStageInput" + }, + "MeetingsSearch": { + "properties": { + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "MeetingsSearch" + }, + "MeetingsSourceSelection": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "MeetingsSourceSelection" + }, + "MessageCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-message", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/MessagePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "MessageCommand" + }, + "MessageCreate": { + "properties": { + "message_text": { + "type": "string", + "title": "Message Text" + }, + "is_internal": { + "type": "boolean", + "title": "Is Internal", + "default": false + } + }, + "type": "object", + "required": [ + "message_text" + ], + "title": "MessageCreate" + }, + "MessagePayload": { + "properties": { + "requestMessageBody": { + "type": "string", + "minLength": 1, + "title": "Requestmessagebody" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requestMessageBody" + ], + "title": "MessagePayload" + }, + "MessageRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "sender_type": { + "type": "string", + "title": "Sender Type" + }, + "sender_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Sender Id" + }, + "message_text": { + "type": "string", + "title": "Message Text" + }, + "is_internal": { + "type": "boolean", + "title": "Is Internal" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "sender_type", + "sender_id", + "message_text", + "is_internal", + "created_at" + ], + "title": "MessageRead" + }, + "MessageView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "author": { + "type": "string", + "title": "Author" + }, + "author_role": { + "type": "string", + "title": "Author Role" + }, + "body": { + "type": "string", + "title": "Body" + }, + "visibility": { + "type": "string", + "title": "Visibility" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "author", + "author_role", + "body", + "visibility", + "created_at_unix_seconds" + ], + "title": "MessageView" + }, + "Milestone": { + "properties": { + "title": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Title" + }, + "due_on": { + "type": "string", + "format": "date", + "title": "Due On" + }, + "completed_on": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Completed On" + }, + "evidence": { + "type": "string", + "maxLength": 2000, + "title": "Evidence", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "due_on" + ], + "title": "Milestone" + }, + "MinutesDecision": { + "properties": { + "action": { + "type": "string", + "enum": [ + "post", + "adopt", + "sign" + ], + "title": "Action" + }, + "note": { + "type": "string", + "title": "Note", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "MinutesDecision" + }, + "ModelRegistryCreate": { + "properties": { + "model_name": { + "type": "string", + "title": "Model Name" + }, + "model_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Version" + }, + "parameter_count": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parameter Count" + }, + "license": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License" + }, + "model_card_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Card Url" + }, + "is_active": { + "type": "boolean", + "title": "Is Active", + "default": false + }, + "context_window_size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Context Window Size" + }, + "supports_ner": { + "type": "boolean", + "title": "Supports Ner", + "default": false + }, + "supports_vision": { + "type": "boolean", + "title": "Supports Vision", + "default": false + } + }, + "type": "object", + "required": [ + "model_name" + ], + "title": "ModelRegistryCreate", + "description": "Schema for creating a new model_registry record (POST body)." + }, + "ModelRegistryRead": { + "properties": { + "id": { + "type": "integer", + "title": "Id" + }, + "model_name": { + "type": "string", + "title": "Model Name" + }, + "model_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Version" + }, + "parameter_count": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parameter Count" + }, + "license": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License" + }, + "model_card_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Card Url" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "added_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Added At" + }, + "context_window_size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Context Window Size" + }, + "supports_ner": { + "type": "boolean", + "title": "Supports Ner" + }, + "supports_vision": { + "type": "boolean", + "title": "Supports Vision" + } + }, + "type": "object", + "required": [ + "id", + "model_name", + "is_active", + "supports_ner", + "supports_vision" + ], + "title": "ModelRegistryRead", + "description": "Schema for returning a model_registry record (GET response).\n\n``from_attributes=True`` allows construction directly from an ORM instance." + }, + "ModelRegistryUpdate": { + "properties": { + "model_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Name" + }, + "model_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Version" + }, + "parameter_count": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parameter Count" + }, + "license": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License" + }, + "model_card_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Card Url" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + }, + "context_window_size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Context Window Size" + }, + "supports_ner": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Supports Ner" + }, + "supports_vision": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Supports Vision" + } + }, + "type": "object", + "title": "ModelRegistryUpdate", + "description": "Schema for partially updating a model_registry record (PATCH body).\n\nEvery field is optional so callers can send only the fields they want to\nchange." + }, + "MotionCorrection": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "reason": { + "type": "string", + "minLength": 1, + "title": "Reason" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text", + "reason" + ], + "title": "MotionCorrection" + }, + "MotionInput": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "seconded_by": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Seconded By" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text" + ], + "title": "MotionInput" + }, + "NativePayload": { + "properties": {}, + "additionalProperties": false, + "type": "object", + "title": "NativePayload" + }, + "NativeRequestRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "requester_name": { + "type": "string", + "title": "Requester Name" + }, + "requester_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Email" + }, + "requester_phone": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Phone" + }, + "requester_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Type" + }, + "date_received": { + "type": "string", + "format": "date-time", + "title": "Date Received" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "description": { + "type": "string", + "title": "Description" + }, + "status": { + "$ref": "#/components/schemas/RequestStatus" + }, + "assigned_to": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "created_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "response_draft": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Response Draft" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + }, + "estimated_fee": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Estimated Fee" + }, + "fee_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Fee Status" + }, + "fee_waiver_requested": { + "type": "boolean", + "title": "Fee Waiver Requested", + "default": false + }, + "priority": { + "type": "string", + "title": "Priority", + "default": "normal" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + }, + "closed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Closed At" + }, + "closure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Closure Reason" + }, + "desktop_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Desktop Id" + }, + "public_tracking_number": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Public Tracking Number" + }, + "submitted_via": { + "type": "string", + "title": "Submitted Via" + }, + "deadline_label": { + "type": "string", + "title": "Deadline Label" + }, + "deadline_basis": { + "type": "string", + "title": "Deadline Basis" + }, + "deadline_reviewed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Deadline Reviewed At" + } + }, + "type": "object", + "required": [ + "id", + "requester_name", + "requester_email", + "date_received", + "statutory_deadline", + "description", + "status", + "assigned_to", + "created_by", + "created_at", + "response_draft", + "review_notes", + "desktop_id", + "public_tracking_number", + "submitted_via", + "deadline_label", + "deadline_basis", + "deadline_reviewed_at" + ], + "title": "NativeRequestRead" + }, + "NoticeDocumentInput": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text" + ], + "title": "NoticeDocumentInput" + }, + "NoticeDraft": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "body": { + "type": "string", + "maxLength": 100000, + "minLength": 1, + "title": "Body" + }, + "notice_type": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Notice Type" + }, + "statutory_basis": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Statutory Basis" + }, + "event_date": { + "type": "string", + "format": "date", + "title": "Event Date" + }, + "lead_days": { + "type": "integer", + "maximum": 365.0, + "minimum": 0.0, + "title": "Lead Days" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "body", + "notice_type", + "statutory_basis", + "event_date", + "lead_days" + ], + "title": "NoticeDraft" + }, + "NoticeInput": { + "properties": { + "notice_type": { + "type": "string", + "enum": [ + "regular", + "special", + "emergency", + "closed_session", + "executive" + ], + "title": "Notice Type" + }, + "posted_at": { + "type": "string", + "format": "date-time", + "title": "Posted At" + }, + "minimum_notice_hours": { + "type": "integer", + "minimum": 0.0, + "title": "Minimum Notice Hours" + }, + "statutory_basis": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Statutory Basis" + }, + "approved_by": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Approved By" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "notice_type", + "posted_at", + "minimum_notice_hours" + ], + "title": "NoticeInput" + }, + "NoticeProofInput": { + "properties": { + "location": { + "type": "string", + "minLength": 1, + "title": "Location" + }, + "note": { + "type": "string", + "title": "Note", + "default": "" + }, + "document_delivery_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Document Delivery Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "location" + ], + "title": "NoticeProofInput" + }, + "NotificationLogRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "template_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Template Id" + }, + "recipient_email": { + "type": "string", + "title": "Recipient Email" + }, + "request_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Request Id" + }, + "channel": { + "type": "string", + "title": "Channel" + }, + "status": { + "type": "string", + "title": "Status" + }, + "sent_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Sent At" + }, + "error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Message" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "template_id", + "recipient_email", + "request_id", + "channel", + "status", + "sent_at", + "error_message", + "created_at" + ], + "title": "NotificationLogRead" + }, + "NotificationTemplateCreate": { + "properties": { + "event_type": { + "type": "string", + "title": "Event Type" + }, + "channel": { + "type": "string", + "title": "Channel", + "default": "email" + }, + "subject_template": { + "type": "string", + "title": "Subject Template" + }, + "body_template": { + "type": "string", + "title": "Body Template" + } + }, + "type": "object", + "required": [ + "event_type", + "subject_template", + "body_template" + ], + "title": "NotificationTemplateCreate" + }, + "NotificationTemplateRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "event_type": { + "type": "string", + "title": "Event Type" + }, + "channel": { + "type": "string", + "title": "Channel" + }, + "subject_template": { + "type": "string", + "title": "Subject Template" + }, + "body_template": { + "type": "string", + "title": "Body Template" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "event_type", + "channel", + "subject_template", + "body_template", + "is_active", + "created_at" + ], + "title": "NotificationTemplateRead" + }, + "NotificationTemplateUpdate": { + "properties": { + "subject_template": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Subject Template" + }, + "body_template": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Body Template" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "NotificationTemplateUpdate" + }, + "NotificationView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "notification_id": { + "type": "string", + "title": "Notification Id" + }, + "module_id": { + "type": "string", + "title": "Module Id" + }, + "record_id": { + "type": "string", + "title": "Record Id" + }, + "audience": { + "type": "string", + "title": "Audience" + }, + "channel": { + "type": "string", + "title": "Channel" + }, + "subject": { + "type": "string", + "title": "Subject" + }, + "body": { + "type": "string", + "title": "Body" + }, + "status": { + "type": "string", + "title": "Status" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + }, + "sent_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Sent At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "notification_id", + "module_id", + "record_id", + "audience", + "channel", + "subject", + "body", + "status", + "created_at_unix_seconds", + "sent_at_unix_seconds" + ], + "title": "NotificationView" + }, + "OllamaModelInfo": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Size" + }, + "details": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Details" + } + }, + "type": "object", + "required": [ + "name" + ], + "title": "OllamaModelInfo" + }, + "OllamaStatus": { + "properties": { + "status": { + "type": "string", + "title": "Status" + }, + "models": { + "items": { + "$ref": "#/components/schemas/OllamaModelInfo" + }, + "type": "array", + "title": "Models" + } + }, + "type": "object", + "required": [ + "status", + "models" + ], + "title": "OllamaStatus" + }, + "OperationalMetrics": { + "properties": { + "average_response_time_days": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Average Response Time Days" + }, + "median_response_time_days": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Median Response Time Days" + }, + "requests_by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Requests By Status" + }, + "requests_by_department": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Requests By Department" + }, + "deadline_compliance_rate": { + "type": "number", + "title": "Deadline Compliance Rate" + }, + "total_open": { + "type": "integer", + "title": "Total Open" + }, + "total_closed": { + "type": "integer", + "title": "Total Closed" + }, + "total_overdue": { + "type": "integer", + "title": "Total Overdue" + }, + "clarification_frequency": { + "type": "number", + "title": "Clarification Frequency" + }, + "top_request_topics": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Top Request Topics" + } + }, + "type": "object", + "required": [ + "average_response_time_days", + "median_response_time_days", + "requests_by_status", + "requests_by_department", + "deadline_compliance_rate", + "total_open", + "total_closed", + "total_overdue", + "clarification_frequency", + "top_request_topics" + ], + "title": "OperationalMetrics" + }, + "Outline": { + "properties": { + "title": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Title" + }, + "question_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "maxItems": 50, + "minItems": 1, + "title": "Question Ids" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "question_ids" + ], + "title": "Outline" + }, + "Packet": { + "properties": { + "expected_revision": { + "type": "string", + "format": "uuid", + "title": "Expected Revision" + }, + "visibility": { + "type": "string", + "enum": [ + "staff_only", + "records_copy" + ], + "title": "Visibility" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "expected_revision", + "visibility" + ], + "title": "Packet" + }, + "PacketInput": { + "properties": { + "agenda_item_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "title": "Agenda Item Ids" + }, + "source_files": { + "items": { + "$ref": "#/components/schemas/ManagedSource" + }, + "type": "array", + "title": "Source Files" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "agenda_item_ids" + ], + "title": "PacketInput" + }, + "Pathway": { + "properties": { + "project_type": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Project Type" + }, + "proposal": { + "type": "string", + "maxLength": 4000, + "title": "Proposal", + "default": "" + }, + "location_context": { + "type": "string", + "maxLength": 1000, + "title": "Location Context", + "default": "" + }, + "requirement_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Requirement Revision" + }, + "fee_link": { + "anyOf": [ + { + "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "project_type" + ], + "title": "Pathway" + }, + "PathwayStep": { + "properties": { + "step": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Step" + }, + "citation": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Citation" + }, + "typical_time": { + "type": "string", + "maxLength": 1000, + "title": "Typical Time", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "step", + "citation" + ], + "title": "PathwayStep" + }, + "PlainLanguageSummaryCreate": { + "properties": { + "summary_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Summary Id" + }, + "section_version_id": { + "type": "string", + "minLength": 1, + "title": "Section Version Id" + }, + "summary_text": { + "type": "string", + "minLength": 1, + "title": "Summary Text" + }, + "language_code": { + "type": "string", + "title": "Language Code", + "default": "en" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "section_version_id", + "summary_text" + ], + "title": "PlainLanguageSummaryCreate", + "description": "Request body for staff-drafted plain-language summaries." + }, + "PolicySelection": { + "properties": { + "plan_id": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Plan Id" + }, + "revision_id": { + "type": "string", + "maxLength": 36, + "minLength": 36, + "title": "Revision Id" + }, + "policy_id": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Policy Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "plan_id", + "revision_id", + "policy_id" + ], + "title": "PolicySelection" + }, + "PortalModeResponse": { + "properties": { + "mode": { + "type": "string", + "enum": [ + "public", + "private" + ], + "title": "Mode", + "description": "Active portal posture for this deployment. ``public`` = minimal resident surface (landing + authenticated records-request submission + resident registration) reachable without staff auth. ``private`` = staff-only; no public routes, no resident self-registration." + } + }, + "type": "object", + "required": [ + "mode" + ], + "title": "PortalModeResponse", + "description": "T5D — schema for ``GET /config/portal-mode``.\n\nExposed to the frontend on boot so it can branch routing without a\nuser-identity lookup. The payload is intentionally the single field\nbelow — no staff config, no user state, no schema version." + }, + "PrepareArtifact": { + "properties": { + "kind": { + "type": "string", + "enum": [ + "response", + "release-package" + ], + "title": "Kind" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "kind" + ], + "title": "PrepareArtifact" + }, + "Proof": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + }, + "filename": { + "type": "string", + "maxLength": 150, + "minLength": 1, + "title": "Filename" + }, + "content_base64": { + "type": "string", + "maxLength": 7000000, + "minLength": 1, + "title": "Content Base64" + }, + "location": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Location" + }, + "published_at": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Published At" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence", + "filename", + "content_base64", + "location", + "published_at" + ], + "title": "Proof" + }, + "Proposal": { + "properties": { + "id": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Id" + }, + "version_id": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Version Id" + }, + "meeting_id": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "ordinance_number": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Ordinance Number" + }, + "proposed_text": { + "type": "string", + "maxLength": 1000000, + "minLength": 1, + "title": "Proposed Text" + }, + "supersedes_id": { + "anyOf": [ + { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$" + }, + { + "type": "null" + } + ], + "title": "Supersedes Id" + }, + "reconciliation_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reconciliation Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "version_id", + "meeting_id", + "title", + "ordinance_number", + "proposed_text" + ], + "title": "Proposal" + }, + "PublicExplore": { + "properties": { + "goal": { + "type": "string", + "maxLength": 500, + "title": "Goal", + "default": "" + }, + "topic": { + "type": "string", + "maxLength": 160, + "title": "Topic", + "default": "" + }, + "neighborhood": { + "type": "string", + "maxLength": 255, + "title": "Neighborhood", + "default": "" + }, + "plan_type": { + "type": "string", + "maxLength": 120, + "title": "Plan Type", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "title": "PublicExplore" + }, + "PublicIntake": { + "properties": { + "requester": { + "type": "string", + "minLength": 1, + "title": "Requester" + }, + "requesterContact": { + "type": "string", + "minLength": 1, + "title": "Requestercontact" + }, + "summary": { + "type": "string", + "minLength": 1, + "title": "Summary" + }, + "deadline": { + "type": "string", + "title": "Deadline", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requester", + "requesterContact", + "summary" + ], + "title": "PublicIntake" + }, + "PublicLookup": { + "properties": { + "trackingNumber": { + "type": "string", + "minLength": 1, + "title": "Trackingnumber" + }, + "requesterContact": { + "type": "string", + "minLength": 1, + "title": "Requestercontact" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "trackingNumber", + "requesterContact" + ], + "title": "PublicLookup" + }, + "PublicMessage": { + "properties": { + "trackingNumber": { + "type": "string", + "minLength": 1, + "title": "Trackingnumber" + }, + "requesterContact": { + "type": "string", + "minLength": 1, + "title": "Requestercontact" + }, + "publicRequestMessage": { + "type": "string", + "minLength": 1, + "title": "Publicrequestmessage" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "trackingNumber", + "requesterContact", + "publicRequestMessage" + ], + "title": "PublicMessage" + }, + "PublicStatusView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "label": { + "type": "string", + "title": "Label" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "status": { + "type": "string", + "title": "Status" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "label", + "summary", + "status", + "created_at_unix_seconds" + ], + "title": "PublicStatusView" + }, + "PublicationView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "source_module": { + "type": "string", + "title": "Source Module" + }, + "source_record_id": { + "type": "string", + "title": "Source Record Id" + }, + "record_type": { + "type": "string", + "title": "Record Type" + }, + "public_payload": { + "type": "string", + "title": "Public Payload" + }, + "payload_hash": { + "type": "string", + "title": "Payload Hash" + }, + "published_at_unix_seconds": { + "type": "integer", + "title": "Published At Unix Seconds" + }, + "retracted_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Retracted At Unix Seconds" + }, + "retracted_by": { + "type": "string", + "title": "Retracted By", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "source_module", + "source_record_id", + "record_type", + "public_payload", + "payload_hash", + "published_at_unix_seconds" + ], + "title": "PublicationView" + }, + "PublishingPlan": { + "properties": { + "action": { + "type": "string", + "const": "publishing-workflow", + "title": "Action" + }, + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "hasReview": { + "type": "boolean", + "title": "Hasreview", + "default": false + }, + "hasPlainLanguage": { + "type": "boolean", + "title": "Hasplainlanguage", + "default": false + }, + "hasTranslationReview": { + "type": "boolean", + "title": "Hastranslationreview", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "PublishingPlan" + }, + "Question": { + "properties": { + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + }, + "question": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Question" + }, + "kind": { + "type": "string", + "enum": [ + "use", + "dimension" + ], + "title": "Kind" + }, + "key": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Key" + }, + "audience": { + "type": "string", + "enum": [ + "resident", + "staff" + ], + "title": "Audience", + "default": "resident" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "jurisdiction", + "query", + "question", + "kind", + "key" + ], + "title": "Question" + }, + "QuestionAnswerRequest": { + "properties": { + "question": { + "type": "string", + "minLength": 1, + "title": "Question" + }, + "section_number": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Section Number" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "question" + ], + "title": "QuestionAnswerRequest", + "description": "Request body for citation-grounded code Q&A." + }, + "RecordsDocumentView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "attachment_id": { + "type": "string", + "title": "Attachment Id" + }, + "title": { + "type": "string", + "title": "Title" + }, + "original_path": { + "type": "string", + "title": "Original Path" + }, + "stored_path": { + "type": "string", + "title": "Stored Path" + }, + "citation": { + "type": "string", + "title": "Citation" + }, + "sha256": { + "type": "string", + "title": "Sha256" + }, + "size_bytes": { + "type": "integer", + "title": "Size Bytes" + }, + "status": { + "type": "string", + "title": "Status" + }, + "added_by": { + "type": "string", + "title": "Added By" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + }, + "release_original_path": { + "type": "string", + "title": "Release Original Path", + "default": "" + }, + "release_stored_path": { + "type": "string", + "title": "Release Stored Path", + "default": "" + }, + "release_file_name": { + "type": "string", + "title": "Release File Name", + "default": "" + }, + "release_sha256": { + "type": "string", + "title": "Release Sha256", + "default": "" + }, + "release_size_bytes": { + "type": "integer", + "title": "Release Size Bytes", + "default": 0 + }, + "release_status": { + "type": "string", + "title": "Release Status", + "default": "" + }, + "release_note": { + "type": "string", + "title": "Release Note", + "default": "" + }, + "release_added_by": { + "type": "string", + "title": "Release Added By", + "default": "" + }, + "release_added_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Release Added At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "attachment_id", + "title", + "original_path", + "stored_path", + "citation", + "sha256", + "size_bytes", + "status", + "added_by", + "created_at_unix_seconds" + ], + "title": "RecordsDocumentView" + }, + "RecordsOperationRead": { + "properties": { + "action": { + "type": "string", + "title": "Action" + }, + "message": { + "type": "string", + "title": "Message" + }, + "request": { + "$ref": "#/components/schemas/RecordsView" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "message", + "request" + ], + "title": "RecordsOperationRead" + }, + "RecordsStateRead": { + "properties": { + "demo_fixture": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Demo Fixture" + }, + "records_requests": { + "items": { + "$ref": "#/components/schemas/RecordsView" + }, + "type": "array", + "title": "Records Requests" + }, + "notification_events": { + "items": { + "$ref": "#/components/schemas/NotificationView" + }, + "type": "array", + "title": "Notification Events" + }, + "publication_events": { + "items": { + "$ref": "#/components/schemas/PublicationView" + }, + "type": "array", + "title": "Publication Events" + }, + "audit_entries": { + "items": { + "$ref": "#/components/schemas/AuditView" + }, + "type": "array", + "title": "Audit Entries" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "records_requests" + ], + "title": "RecordsStateRead" + }, + "RecordsView": { + "properties": { + "request_id": { + "type": "string", + "title": "Request Id" + }, + "id": { + "type": "string", + "title": "Id" + }, + "public_tracking_number": { + "type": "string", + "title": "Public Tracking Number" + }, + "requester": { + "type": "string", + "title": "Requester" + }, + "requester_contact": { + "type": "string", + "title": "Requester Contact" + }, + "submitted_via": { + "type": "string", + "title": "Submitted Via" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "deadline": { + "type": "string", + "title": "Deadline" + }, + "deadline_basis": { + "type": "string", + "title": "Deadline Basis" + }, + "status": { + "type": "string", + "title": "Status" + }, + "assigned_to": { + "type": "string", + "title": "Assigned To" + }, + "clarification_notes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Clarification Notes" + }, + "search_notes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Search Notes" + }, + "search_sessions": { + "items": { + "$ref": "#/components/schemas/SearchReceiptView" + }, + "type": "array", + "title": "Search Sessions" + }, + "exemption_reviews": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Exemption Reviews" + }, + "exemption_decisions": { + "items": { + "$ref": "#/components/schemas/ExemptionDecisionView" + }, + "type": "array", + "title": "Exemption Decisions" + }, + "fee_estimate": { + "type": "string", + "title": "Fee Estimate" + }, + "fee_line_items": { + "items": { + "$ref": "#/components/schemas/FeeLineView" + }, + "type": "array", + "title": "Fee Line Items" + }, + "fee_waiver_reason": { + "type": "string", + "title": "Fee Waiver Reason" + }, + "citations": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Citations" + }, + "response_draft": { + "type": "string", + "title": "Response Draft" + }, + "approval_notes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Approval Notes" + }, + "exports": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Exports" + }, + "documents": { + "items": { + "$ref": "#/components/schemas/RecordsDocumentView" + }, + "type": "array", + "title": "Documents" + }, + "release_packages": { + "items": { + "$ref": "#/components/schemas/ReleasePackageView" + }, + "type": "array", + "title": "Release Packages" + }, + "timeline": { + "items": { + "$ref": "#/components/schemas/TimelineView" + }, + "type": "array", + "title": "Timeline" + }, + "public_status_events": { + "items": { + "$ref": "#/components/schemas/PublicStatusView" + }, + "type": "array", + "title": "Public Status Events" + }, + "messages": { + "items": { + "$ref": "#/components/schemas/MessageView" + }, + "type": "array", + "title": "Messages" + }, + "deadline_reviewed_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Deadline Reviewed At Unix Seconds" + }, + "approved_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Approved At Unix Seconds" + }, + "fulfilled_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Fulfilled At Unix Seconds" + }, + "closed_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Closed At Unix Seconds" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "request_id", + "id", + "public_tracking_number", + "requester", + "requester_contact", + "submitted_via", + "summary", + "deadline", + "deadline_basis", + "status", + "assigned_to", + "clarification_notes", + "search_notes", + "search_sessions", + "exemption_reviews", + "exemption_decisions", + "fee_estimate", + "fee_line_items", + "fee_waiver_reason", + "citations", + "response_draft", + "approval_notes", + "exports", + "timeline", + "public_status_events", + "messages", + "deadline_reviewed_at_unix_seconds", + "approved_at_unix_seconds", + "fulfilled_at_unix_seconds", + "closed_at_unix_seconds", + "created_at_unix_seconds" + ], + "title": "RecordsView" + }, + "ReleasePackageView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "export_path": { + "type": "string", + "title": "Export Path" + }, + "package_hash": { + "type": "string", + "title": "Package Hash" + }, + "document_count": { + "type": "integer", + "title": "Document Count" + }, + "release_artifact_count": { + "type": "integer", + "title": "Release Artifact Count" + }, + "search_session_count": { + "type": "integer", + "title": "Search Session Count" + }, + "release_count": { + "type": "integer", + "title": "Release Count" + }, + "redacted_count": { + "type": "integer", + "title": "Redacted Count" + }, + "exempt_count": { + "type": "integer", + "title": "Exempt Count" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "export_path", + "package_hash", + "document_count", + "release_artifact_count", + "search_session_count", + "release_count", + "redacted_count", + "exempt_count", + "created_at_unix_seconds" + ], + "title": "ReleasePackageView" + }, + "RepeatLookup": { + "properties": { + "property_reference": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Property Reference" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "property_reference" + ], + "title": "RepeatLookup" + }, + "RequestCreate": { + "properties": { + "requester_name": { + "type": "string", + "maxLength": 255, + "title": "Requester Name" + }, + "requester_email": { + "anyOf": [ + { + "type": "string", + "maxLength": 255 + }, + { + "type": "null" + } + ], + "title": "Requester Email" + }, + "requester_phone": { + "anyOf": [ + { + "type": "string", + "maxLength": 50 + }, + { + "type": "null" + } + ], + "title": "Requester Phone" + }, + "requester_type": { + "anyOf": [ + { + "type": "string", + "maxLength": 100 + }, + { + "type": "null" + } + ], + "title": "Requester Type" + }, + "description": { + "type": "string", + "maxLength": 10000, + "title": "Description" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "priority": { + "type": "string", + "title": "Priority", + "default": "normal" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string", + "pattern": "^(narrow|moderate|broad)$" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + } + }, + "type": "object", + "required": [ + "requester_name", + "description" + ], + "title": "RequestCreate" + }, + "RequestDocumentAdd": { + "properties": { + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "relevance_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Relevance Note" + } + }, + "type": "object", + "required": [ + "document_id" + ], + "title": "RequestDocumentAdd" + }, + "RequestDocumentRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "relevance_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Relevance Note" + }, + "exemption_flags": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Exemption Flags" + }, + "inclusion_status": { + "$ref": "#/components/schemas/InclusionStatus" + }, + "attached_at": { + "type": "string", + "format": "date-time", + "title": "Attached At" + }, + "attached_by": { + "type": "string", + "format": "uuid", + "title": "Attached By" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "document_id", + "relevance_note", + "exemption_flags", + "inclusion_status", + "attached_at", + "attached_by" + ], + "title": "RequestDocumentRead" + }, + "RequestRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "requester_name": { + "type": "string", + "title": "Requester Name" + }, + "requester_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Email" + }, + "requester_phone": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Phone" + }, + "requester_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Type" + }, + "date_received": { + "type": "string", + "format": "date-time", + "title": "Date Received" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "description": { + "type": "string", + "title": "Description" + }, + "status": { + "$ref": "#/components/schemas/RequestStatus" + }, + "assigned_to": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "created_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "response_draft": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Response Draft" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + }, + "estimated_fee": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Estimated Fee" + }, + "fee_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Fee Status" + }, + "fee_waiver_requested": { + "type": "boolean", + "title": "Fee Waiver Requested", + "default": false + }, + "priority": { + "type": "string", + "title": "Priority", + "default": "normal" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + }, + "closed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Closed At" + }, + "closure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Closure Reason" + } + }, + "type": "object", + "required": [ + "id", + "requester_name", + "requester_email", + "date_received", + "statutory_deadline", + "description", + "status", + "assigned_to", + "created_by", + "created_at", + "response_draft", + "review_notes" + ], + "title": "RequestRead" + }, + "RequestStats": { + "properties": { + "total_requests": { + "type": "integer", + "title": "Total Requests" + }, + "by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "By Status" + }, + "approaching_deadline": { + "type": "integer", + "title": "Approaching Deadline" + }, + "overdue": { + "type": "integer", + "title": "Overdue" + } + }, + "type": "object", + "required": [ + "total_requests", + "by_status", + "approaching_deadline", + "overdue" + ], + "title": "RequestStats" + }, + "RequestStatus": { + "type": "string", + "enum": [ + "received", + "clarification_needed", + "assigned", + "searching", + "in_review", + "ready_for_release", + "drafted", + "approved", + "fulfilled", + "closed" + ], + "title": "RequestStatus" + }, + "RequestUpdate": { + "properties": { + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "status": { + "anyOf": [ + { + "$ref": "#/components/schemas/RequestStatus" + }, + { + "type": "null" + } + ] + }, + "assigned_to": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "response_draft": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Response Draft" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + } + }, + "type": "object", + "title": "RequestUpdate" + }, + "RequirementBundle": { + "properties": { + "requirement_id": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]{1,100}$", + "title": "Requirement Id" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "project_type": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Project Type" + }, + "source_reference": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Source Reference" + }, + "source_date": { + "type": "string", + "format": "date", + "title": "Source Date" + }, + "effective_on": { + "type": "string", + "format": "date", + "title": "Effective On" + }, + "dataset_kind": { + "type": "string", + "enum": [ + "municipal", + "fictional" + ], + "title": "Dataset Kind" + }, + "filename": { + "type": "string", + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$", + "title": "Filename" + }, + "content_base64": { + "type": "string", + "maxLength": 14000000, + "minLength": 1, + "title": "Content Base64" + }, + "sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Sha256" + }, + "materials": { + "items": { + "$ref": "#/components/schemas/Material" + }, + "type": "array", + "maxItems": 100, + "minItems": 1, + "title": "Materials" + }, + "pathway": { + "items": { + "$ref": "#/components/schemas/PathwayStep" + }, + "type": "array", + "maxItems": 100, + "title": "Pathway" + }, + "fee_link": { + "anyOf": [ + { + "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink" + }, + { + "type": "null" + } + ] + }, + "staff_note": { + "type": "string", + "maxLength": 4000, + "title": "Staff Note", + "default": "" + }, + "change_note": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Change Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requirement_id", + "title", + "jurisdiction", + "project_type", + "source_reference", + "source_date", + "effective_on", + "dataset_kind", + "filename", + "content_base64", + "sha256", + "materials", + "change_note" + ], + "title": "RequirementBundle" + }, + "ResponseLetterCreate": { + "properties": { + "template_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Template Id" + } + }, + "type": "object", + "title": "ResponseLetterCreate" + }, + "ResponseLetterRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "template_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Template Id" + }, + "generated_content": { + "type": "string", + "title": "Generated Content" + }, + "edited_content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Edited Content" + }, + "status": { + "type": "string", + "title": "Status" + }, + "generated_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Generated By" + }, + "approved_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Approved By" + }, + "sent_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Sent At" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "template_id", + "generated_content", + "edited_content", + "status", + "generated_by", + "approved_by", + "sent_at", + "created_at" + ], + "title": "ResponseLetterRead" + }, + "ResponseLetterUpdate": { + "properties": { + "edited_content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Edited Content" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + } + }, + "type": "object", + "title": "ResponseLetterUpdate" + }, + "ReviewInput": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "body": { + "type": "string", + "maxLength": 5000, + "title": "Body", + "default": "" + }, + "hasAltText": { + "type": "boolean", + "title": "Hasalttext", + "default": false + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "en" + } + }, + "additionalProperties": false, + "type": "object", + "title": "ReviewInput" + }, + "Revision": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + }, + "document": { + "$ref": "#/components/schemas/NoticeDraft" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence", + "document" + ], + "title": "Revision" + }, + "RewriteInput": { + "properties": { + "action": { + "type": "string", + "enum": [ + "plain-language", + "language-variant" + ], + "title": "Action" + }, + "text": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Text" + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "text" + ], + "title": "RewriteInput" + }, + "RewriteResult": { + "properties": { + "action": { + "type": "string", + "enum": [ + "plain-language", + "language-variant" + ], + "title": "Action" + }, + "text": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Text" + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "" + }, + "outcome": { + "type": "string", + "enum": [ + "generated", + "unavailable" + ], + "title": "Outcome" + }, + "generated": { + "anyOf": [ + { + "type": "string", + "maxLength": 100000 + }, + { + "type": "null" + } + ], + "title": "Generated" + }, + "model": { + "anyOf": [ + { + "type": "string", + "maxLength": 200 + }, + { + "type": "null" + } + ], + "title": "Model" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "text", + "outcome" + ], + "title": "RewriteResult" + }, + "Rule": { + "properties": { + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "zone_code": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Zone Code" + }, + "key": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Key" + }, + "section_number": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Section Number" + }, + "kind": { + "type": "string", + "enum": [ + "use", + "dimension" + ], + "title": "Kind" + }, + "value": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Value" + }, + "overlay_code": { + "anyOf": [ + { + "type": "string", + "maxLength": 255 + }, + { + "type": "null" + } + ], + "title": "Overlay Code" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "jurisdiction", + "zone_code", + "key", + "section_number", + "kind", + "value" + ], + "title": "Rule" + }, + "RuleTestMatch": { + "properties": { + "matched_text": { + "type": "string", + "title": "Matched Text" + }, + "start": { + "type": "integer", + "title": "Start" + }, + "end": { + "type": "integer", + "title": "End" + } + }, + "type": "object", + "required": [ + "matched_text", + "start", + "end" + ], + "title": "RuleTestMatch" + }, + "RuleTestRequest": { + "properties": { + "sample_text": { + "type": "string", + "title": "Sample Text" + } + }, + "type": "object", + "required": [ + "sample_text" + ], + "title": "RuleTestRequest" + }, + "RuleTestResponse": { + "properties": { + "rule_id": { + "type": "string", + "format": "uuid", + "title": "Rule Id" + }, + "rule_type": { + "type": "string", + "title": "Rule Type" + }, + "matched": { + "type": "boolean", + "title": "Matched" + }, + "matches": { + "items": { + "$ref": "#/components/schemas/RuleTestMatch" + }, + "type": "array", + "title": "Matches" + } + }, + "type": "object", + "required": [ + "rule_id", + "rule_type", + "matched", + "matches" + ], + "title": "RuleTestResponse" + }, + "RuleType": { + "type": "string", + "enum": [ + "regex", + "keyword", + "llm_prompt" + ], + "title": "RuleType" + }, + "SaveReview": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "body": { + "type": "string", + "maxLength": 5000, + "title": "Body", + "default": "" + }, + "hasAltText": { + "type": "boolean", + "title": "Hasalttext", + "default": false + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "en" + }, + "ai_analysis": { + "anyOf": [ + { + "type": "string", + "maxLength": 100000 + }, + { + "type": "null" + } + ], + "title": "Ai Analysis" + }, + "ai_analysis_model": { + "anyOf": [ + { + "type": "string", + "maxLength": 200 + }, + { + "type": "null" + } + ], + "title": "Ai Analysis Model" + }, + "ai_outcome": { + "type": "string", + "enum": [ + "generated", + "unavailable", + "failed" + ], + "title": "Ai Outcome" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "ai_outcome" + ], + "title": "SaveReview" + }, + "SearchFilterOptions": { + "properties": { + "file_types": { + "items": { + "type": "string" + }, + "type": "array", + "title": "File Types" + }, + "source_names": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Source Names" + }, + "departments": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array", + "title": "Departments", + "default": [] + }, + "date_range": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Date Range" + } + }, + "type": "object", + "required": [ + "file_types", + "source_names" + ], + "title": "SearchFilterOptions" + }, + "SearchInput": { + "properties": { + "query": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "SearchInput" + }, + "SearchNoteCommand": { + "properties": { + "action": { + "type": "string", + "const": "record-records-search", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/SearchNotePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "SearchNoteCommand" + }, + "SearchNotePayload": { + "properties": { + "sourceNote": { + "type": "string", + "minLength": 1, + "title": "Sourcenote" + }, + "citation": { + "type": "string", + "title": "Citation", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sourceNote" + ], + "title": "SearchNotePayload" + }, + "SearchReceiptCommand": { + "properties": { + "action": { + "type": "string", + "const": "record-records-search-session", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/SearchReceiptPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "SearchReceiptCommand" + }, + "SearchReceiptPayload": { + "properties": { + "searchQuery": { + "type": "string", + "minLength": 1, + "title": "Searchquery" + }, + "searchLocations": { + "type": "string", + "minLength": 1, + "title": "Searchlocations" + }, + "searchResultTitle": { + "type": "string", + "minLength": 1, + "title": "Searchresulttitle" + }, + "searchResultCitation": { + "type": "string", + "minLength": 1, + "title": "Searchresultcitation" + }, + "searchResultSummary": { + "type": "string", + "minLength": 1, + "title": "Searchresultsummary" + }, + "searchResultStatus": { + "type": "string", + "title": "Searchresultstatus", + "default": "" + }, + "searchReviewer": { + "type": "string", + "title": "Searchreviewer", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "searchQuery", + "searchLocations", + "searchResultTitle", + "searchResultCitation", + "searchResultSummary" + ], + "title": "SearchReceiptPayload" + }, + "SearchReceiptView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "query": { + "type": "string", + "title": "Query" + }, + "locations": { + "type": "string", + "title": "Locations" + }, + "reviewer": { + "type": "string", + "title": "Reviewer" + }, + "results": { + "items": { + "$ref": "#/components/schemas/SearchResultView" + }, + "type": "array", + "title": "Results" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "query", + "locations", + "reviewer", + "results", + "created_at_unix_seconds" + ], + "title": "SearchReceiptView" + }, + "SearchRequest": { + "properties": { + "query": { + "type": "string", + "title": "Query" + }, + "session_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Session Id" + }, + "filters": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Filters" + }, + "limit": { + "type": "integer", + "maximum": 50.0, + "title": "Limit", + "default": 10 + }, + "synthesize": { + "type": "boolean", + "title": "Synthesize", + "default": false + } + }, + "type": "object", + "required": [ + "query" + ], + "title": "SearchRequest" + }, + "SearchResponse": { + "properties": { + "query_id": { + "type": "string", + "format": "uuid", + "title": "Query Id" + }, + "session_id": { + "type": "string", + "format": "uuid", + "title": "Session Id" + }, + "query_text": { + "type": "string", + "title": "Query Text" + }, + "results": { + "items": { + "$ref": "#/components/schemas/SearchResultItem" + }, + "type": "array", + "title": "Results" + }, + "results_count": { + "type": "integer", + "title": "Results Count" + }, + "synthesized_answer": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Synthesized Answer" + }, + "ai_generated": { + "type": "boolean", + "title": "Ai Generated", + "default": false + } + }, + "type": "object", + "required": [ + "query_id", + "session_id", + "query_text", + "results", + "results_count" + ], + "title": "SearchResponse" + }, + "SearchResultItem": { + "properties": { + "chunk_id": { + "type": "string", + "format": "uuid", + "title": "Chunk Id" + }, + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "filename": { + "type": "string", + "title": "Filename" + }, + "file_type": { + "type": "string", + "title": "File Type" + }, + "source_path": { + "type": "string", + "title": "Source Path" + }, + "page_number": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Page Number" + }, + "content_text": { + "type": "string", + "title": "Content Text" + }, + "similarity_score": { + "type": "number", + "title": "Similarity Score" + }, + "rank": { + "type": "integer", + "title": "Rank" + } + }, + "type": "object", + "required": [ + "chunk_id", + "document_id", + "filename", + "file_type", + "source_path", + "page_number", + "content_text", + "similarity_score", + "rank" + ], + "title": "SearchResultItem" + }, + "SearchResultView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "title": { + "type": "string", + "title": "Title" + }, + "citation": { + "type": "string", + "title": "Citation" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "status": { + "type": "string", + "title": "Status" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "title", + "citation", + "summary", + "status" + ], + "title": "SearchResultView" + }, + "SearchSessionRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "user_id": { + "type": "string", + "format": "uuid", + "title": "User Id" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "queries": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array", + "title": "Queries", + "default": [] + } + }, + "type": "object", + "required": [ + "id", + "user_id", + "created_at" + ], + "title": "SearchSessionRead" + }, + "SectionCreate": { + "properties": { + "section_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Section Id" + }, + "chapter_id": { + "type": "string", + "minLength": 1, + "title": "Chapter Id" + }, + "section_number": { + "type": "string", + "minLength": 1, + "title": "Section Number" + }, + "section_heading": { + "type": "string", + "minLength": 1, + "title": "Section Heading" + }, + "parent_section_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parent Section Id" + }, + "sort_order": { + "type": "integer", + "title": "Sort Order", + "default": 0 + }, + "administrative_regulation_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Administrative Regulation Refs" + }, + "resolution_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Resolution Refs" + }, + "policy_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Policy Refs" + }, + "approved_summary_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Approved Summary Refs" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "chapter_id", + "section_number", + "section_heading" + ], + "title": "SectionCreate", + "description": "Request body for creating a code section or subsection." + }, + "SectionVersionCreate": { + "properties": { + "version_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Version Id" + }, + "section_id": { + "type": "string", + "minLength": 1, + "title": "Section Id" + }, + "source_id": { + "type": "string", + "minLength": 1, + "title": "Source Id" + }, + "version_label": { + "type": "string", + "minLength": 1, + "title": "Version Label" + }, + "body": { + "type": "string", + "minLength": 1, + "title": "Body" + }, + "effective_start": { + "type": "string", + "format": "date", + "title": "Effective Start" + }, + "effective_end": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective End" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + }, + "is_current": { + "type": "boolean", + "title": "Is Current", + "default": false + }, + "adoption_event_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Adoption Event Id" + }, + "amendment_event_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Amendment Event Id" + }, + "amendment_summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Amendment Summary" + }, + "prior_version_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Prior Version Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "section_id", + "source_id", + "version_label", + "body", + "effective_start" + ], + "title": "SectionVersionCreate", + "description": "Request body for adding an immutable section version." + }, + "Selection": { + "properties": { + "recording_id": { + "type": "string", + "format": "uuid", + "title": "Recording Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "recording_id", + "expected_sha256" + ], + "title": "Selection" + }, + "SentenceInput": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "citations": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Citations" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text" + ], + "title": "SentenceInput" + }, + "ServiceAccountCreate": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole", + "default": "read_only" + } + }, + "type": "object", + "required": [ + "name" + ], + "title": "ServiceAccountCreate" + }, + "ServiceAccountCreated": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "api_key": { + "type": "string", + "title": "Api Key" + } + }, + "type": "object", + "required": [ + "id", + "name", + "role", + "created_by", + "created_at", + "is_active", + "api_key" + ], + "title": "ServiceAccountCreated", + "description": "Returned only on creation — includes the plaintext API key (shown once)." + }, + "ServiceAccountRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + } + }, + "type": "object", + "required": [ + "id", + "name", + "role", + "created_by", + "created_at", + "is_active" + ], + "title": "ServiceAccountRead" + }, + "ServiceAccountUpdate": { + "properties": { + "role": { + "anyOf": [ + { + "$ref": "#/components/schemas/UserRole" + }, + { + "type": "null" + } + ] + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "ServiceAccountUpdate" + }, + "Snapshot": { + "properties": { + "expected_revision": { + "type": "string", + "format": "uuid", + "title": "Expected Revision" + }, + "visibility": { + "type": "string", + "enum": [ + "staff_only", + "public" + ], + "title": "Visibility" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "expected_revision", + "visibility" + ], + "title": "Snapshot" + }, + "SourceCreate": { + "properties": { + "source_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Id" + }, + "name": { + "type": "string", + "minLength": 1, + "title": "Name" + }, + "publisher": { + "type": "string", + "minLength": 1, + "title": "Publisher" + }, + "source_type": { + "type": "string", + "minLength": 1, + "title": "Source Type" + }, + "source_category": { + "type": "string", + "minLength": 1, + "title": "Source Category" + }, + "source_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Url" + }, + "file_reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "File Reference" + }, + "retrieved_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Retrieved At" + }, + "retrieval_method": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Retrieval Method" + }, + "checksum": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Checksum" + }, + "source_owner": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Owner" + }, + "is_official": { + "type": "boolean", + "title": "Is Official", + "default": true + }, + "official_status_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Official Status Note" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + }, + "staff_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Staff Notes" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "name", + "publisher", + "source_type", + "source_category" + ], + "title": "SourceCreate", + "description": "Request body for registering an official or explicitly labeled source." + }, + "SourceInput": { + "properties": { + "source_id": { + "type": "string", + "minLength": 1, + "title": "Source Id" + }, + "label": { + "type": "string", + "minLength": 1, + "title": "Label" + }, + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "label", + "text" + ], + "title": "SourceInput" + }, + "SourceSnapshot": { + "properties": { + "visibility": { + "type": "string", + "enum": [ + "public", + "staff_only" + ], + "title": "Visibility" + }, + "meeting_event_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "maxItems": 50, + "title": "Meeting Event Ids" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "visibility" + ], + "title": "SourceSnapshot" + }, + "SourceType": { + "type": "string", + "enum": [ + "manual_drop", + "file_system", + "rest_api", + "odbc" + ], + "title": "SourceType" + }, + "StaffRecordsIntake": { + "properties": { + "requester": { + "type": "string", + "minLength": 1, + "title": "Requester" + }, + "summary": { + "type": "string", + "minLength": 1, + "title": "Summary" + }, + "deadline": { + "type": "string", + "title": "Deadline" + }, + "deadlineBasis": { + "type": "string", + "title": "Deadlinebasis", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requester", + "summary", + "deadline" + ], + "title": "StaffRecordsIntake", + "description": "Existing native create-records-request input; no caller-supplied actor." + }, + "StandardsExplanation": { + "properties": { + "question": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Question" + }, + "process_section": { + "type": "string", + "maxLength": 255, + "title": "Process Section", + "default": "" + }, + "zone_code": { + "type": "string", + "maxLength": 40, + "title": "Zone Code", + "default": "" + }, + "rule_types": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 10, + "title": "Rule Types" + }, + "observed": { + "additionalProperties": { + "type": "string" + }, + "type": "object", + "title": "Observed" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "question" + ], + "title": "StandardsExplanation" + }, + "SyncFailureRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "source_id": { + "type": "string", + "format": "uuid", + "title": "Source Id" + }, + "source_path": { + "type": "string", + "title": "Source Path" + }, + "error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Message" + }, + "error_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Class" + }, + "http_status_code": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Http Status Code" + }, + "retry_count": { + "type": "integer", + "title": "Retry Count" + }, + "status": { + "type": "string", + "title": "Status" + }, + "first_failed_at": { + "type": "string", + "format": "date-time", + "title": "First Failed At" + }, + "last_retried_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Retried At" + }, + "dismissed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Dismissed At" + }, + "dismissed_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Dismissed By" + } + }, + "type": "object", + "required": [ + "id", + "source_id", + "source_path", + "error_message", + "error_class", + "http_status_code", + "retry_count", + "status", + "first_failed_at", + "last_retried_at", + "dismissed_at", + "dismissed_by" + ], + "title": "SyncFailureRead" + }, + "SyncRunLogRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "source_id": { + "type": "string", + "format": "uuid", + "title": "Source Id" + }, + "started_at": { + "type": "string", + "format": "date-time", + "title": "Started At" + }, + "finished_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Finished At" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + }, + "records_attempted": { + "type": "integer", + "title": "Records Attempted" + }, + "records_succeeded": { + "type": "integer", + "title": "Records Succeeded" + }, + "records_failed": { + "type": "integer", + "title": "Records Failed" + }, + "error_summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Summary" + } + }, + "type": "object", + "required": [ + "id", + "source_id", + "started_at", + "finished_at", + "status", + "records_attempted", + "records_succeeded", + "records_failed", + "error_summary" + ], + "title": "SyncRunLogRead" + }, + "SystemStatus": { + "properties": { + "version": { + "type": "string", + "title": "Version" + }, + "database": { + "type": "string", + "title": "Database" + }, + "ollama": { + "type": "string", + "title": "Ollama" + }, + "redis": { + "type": "string", + "title": "Redis" + }, + "user_count": { + "type": "integer", + "title": "User Count" + }, + "audit_log_count": { + "type": "integer", + "title": "Audit Log Count" + }, + "suite_session": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Suite Session" + } + }, + "type": "object", + "required": [ + "version", + "database", + "ollama", + "redis", + "user_count", + "audit_log_count" + ], + "title": "SystemStatus" + }, + "TaggedPlan": { + "properties": { + "action": { + "type": "string", + "const": "tagged-pdf", + "title": "Action" + }, + "headingLevels": { + "items": { + "type": "integer", + "maximum": 4294967295.0, + "minimum": 0.0 + }, + "type": "array", + "maxItems": 50, + "title": "Headinglevels" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "TaggedPlan" + }, + "TestConnectionRequest": { + "properties": { + "source_type": { + "type": "string", + "title": "Source Type" + }, + "host": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Host" + }, + "port": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Port" + }, + "path": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Path" + }, + "username": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Username" + }, + "password": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Password" + }, + "rest_api_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Rest Api Config" + }, + "odbc_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Odbc Config" + } + }, + "type": "object", + "required": [ + "source_type" + ], + "title": "TestConnectionRequest", + "description": "Dedicated schema for test-connection. NOT the create schema.\n\nSecurity: credentials in this request body are never persisted, never\nwritten to audit logs, and never returned in the response." + }, + "TestConnectionResponse": { + "properties": { + "success": { + "type": "boolean", + "title": "Success" + }, + "message": { + "type": "string", + "title": "Message" + }, + "latency_ms": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Latency Ms" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + }, + "warning": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Warning" + }, + "differing_keys": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Differing Keys" + } + }, + "type": "object", + "required": [ + "success", + "message" + ], + "title": "TestConnectionResponse" + }, + "TimelineEventCreate": { + "properties": { + "event_type": { + "type": "string", + "title": "Event Type" + }, + "description": { + "type": "string", + "title": "Description" + }, + "internal_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Internal Note" + } + }, + "type": "object", + "required": [ + "event_type", + "description" + ], + "title": "TimelineEventCreate" + }, + "TimelineEventRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "event_type": { + "type": "string", + "title": "Event Type" + }, + "actor_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Actor Id" + }, + "actor_role": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Actor Role" + }, + "description": { + "type": "string", + "title": "Description" + }, + "internal_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Internal Note" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "event_type", + "actor_id", + "actor_role", + "description", + "internal_note", + "created_at" + ], + "title": "TimelineEventRead" + }, + "TimelineView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "action": { + "type": "string", + "title": "Action" + }, + "actor": { + "type": "string", + "title": "Actor" + }, + "note": { + "type": "string", + "title": "Note" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "action", + "actor", + "note", + "created_at_unix_seconds" + ], + "title": "TimelineView" + }, + "TitleCreate": { + "properties": { + "title_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Title Id" + }, + "title_number": { + "type": "string", + "minLength": 1, + "title": "Title Number" + }, + "title_name": { + "type": "string", + "minLength": 1, + "title": "Title Name" + }, + "sort_order": { + "type": "integer", + "title": "Sort Order", + "default": 0 + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title_number", + "title_name" + ], + "title": "TitleCreate", + "description": "Request body for creating a code title." + }, + "TranscriptInput": { + "properties": { + "source_label": { + "type": "string", + "minLength": 1, + "title": "Source Label" + }, + "transcript_text": { + "type": "string", + "minLength": 1, + "title": "Transcript Text" + }, + "correction_of_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Correction Of Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_label", + "transcript_text" + ], + "title": "TranscriptInput" + }, + "UserRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "email": { + "type": "string", + "format": "email", + "title": "Email" + }, + "is_active": { + "type": "boolean", + "title": "Is Active", + "default": true + }, + "is_superuser": { + "type": "boolean", + "title": "Is Superuser", + "default": false + }, + "is_verified": { + "type": "boolean", + "title": "Is Verified", + "default": false + }, + "full_name": { + "type": "string", + "title": "Full Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "last_login": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Login" + }, + "must_change_password": { + "type": "boolean", + "title": "Must Change Password", + "default": false + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + } + }, + "type": "object", + "required": [ + "id", + "email", + "full_name", + "role", + "created_at", + "last_login" + ], + "title": "UserRead" + }, + "UserRole": { + "type": "string", + "enum": [ + "admin", + "staff", + "reviewer", + "read_only", + "liaison", + "public" + ], + "title": "UserRole" + }, + "UserSelfUpdate": { + "properties": { + "password": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Password" + }, + "email": { + "anyOf": [ + { + "type": "string", + "format": "email" + }, + { + "type": "null" + } + ], + "title": "Email" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + }, + "is_superuser": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Superuser" + }, + "is_verified": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Verified" + }, + "full_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Full Name" + } + }, + "type": "object", + "title": "UserSelfUpdate", + "description": "Schema for user self-update via PATCH /users/me.\n\nExcludes role and department_id. Any payload containing those fields is\nrejected at parse time (HTTP 422). Role and department changes require\nadmin privileges via /admin/users/{id}." + }, + "UserUpdateRequest": { + "properties": { + "full_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Full Name" + }, + "role": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Role" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "UserUpdateRequest" + }, + "ValidationError": { + "properties": { + "loc": { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "integer" + } + ] + }, + "type": "array", + "title": "Location" + }, + "msg": { + "type": "string", + "title": "Message" + }, + "type": { + "type": "string", + "title": "Error Type" + }, + "input": { + "title": "Input" + }, + "ctx": { + "type": "object", + "title": "Context" + } + }, + "type": "object", + "required": [ + "loc", + "msg", + "type" + ], + "title": "ValidationError" + }, + "Version": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence" + ], + "title": "Version" + }, + "VoteCorrection": { + "properties": { + "vote": { + "type": "string", + "minLength": 1, + "title": "Vote" + }, + "reason": { + "type": "string", + "minLength": 1, + "title": "Reason" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "vote", + "reason" + ], + "title": "VoteCorrection" + }, + "VoteInput": { + "properties": { + "voter_name": { + "type": "string", + "minLength": 1, + "title": "Voter Name" + }, + "vote": { + "type": "string", + "minLength": 1, + "title": "Vote" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "voter_name", + "vote" + ], + "title": "VoteInput" + }, + "_ParcelLookupIn": { + "properties": { + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "jurisdiction", + "query" + ], + "title": "_ParcelLookupIn" + }, + "townlight_inspections__workflow_models__SourceLink": { + "properties": { + "provider": { + "type": "string", + "const": "code", + "title": "Provider", + "default": "code" + }, + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "SourceLink" + }, + "townlight_permitting__workflow_models__SourceLink": { + "properties": { + "provider": { + "type": "string", + "enum": [ + "code", + "zoning" + ], + "title": "Provider" + }, + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "source_id", + "expected_sha256" + ], + "title": "SourceLink" + }, + "townlight_runtime__inspections_bridge__Search": { + "properties": { + "provider": { + "type": "string", + "const": "code", + "title": "Provider" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "query" + ], + "title": "Search" + }, + "townlight_runtime__notice_bridge__Review": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + }, + "note": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence", + "note" + ], + "title": "Review" + }, + "townlight_runtime__permitting_bridge__Import": { + "properties": { + "bundle": { + "$ref": "#/components/schemas/RequirementBundle" + }, + "expected_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "bundle" + ], + "title": "Import" + }, + "townlight_runtime__permitting_bridge__Search": { + "properties": { + "provider": { + "type": "string", + "enum": [ + "code", + "zoning" + ], + "title": "Provider" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "query" + ], + "title": "Search" + }, + "townlight_runtime__planning_bridge__Import": { + "properties": { + "bundle": { + "additionalProperties": true, + "type": "object", + "title": "Bundle" + }, + "expected_previous_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Expected Previous Revision" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "bundle" + ], + "title": "Import" + }, + "townlight_runtime__planning_bridge__Search": { + "properties": { + "query": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Query" + }, + "plan_type": { + "anyOf": [ + { + "type": "string", + "maxLength": 40 + }, + { + "type": "null" + } + ], + "title": "Plan Type" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "Search" + }, + "townlight_runtime__zoning_bridge__Review": { + "properties": { + "answer": { + "type": "string", + "maxLength": 10000, + "title": "Answer", + "default": "" + }, + "notes": { + "type": "string", + "maxLength": 10000, + "title": "Notes", + "default": "" + }, + "queue_status": { + "type": "string", + "enum": [ + "open", + "in_review", + "resolved", + "closed" + ], + "title": "Queue Status", + "default": "resolved" + } + }, + "additionalProperties": false, + "type": "object", + "title": "Review" + } + }, + "securitySchemes": { + "OAuth2PasswordBearer": { + "type": "oauth2", + "flows": { + "password": { + "scopes": {}, + "tokenUrl": "auth/jwt/login" + } + } + } + } + }, + "x-townlight-component": { + "view": "inspections", + "identity": "Townlight Inspections 0.3.0+dev.2", + "evidence": "source-schema-only" + } +} diff --git a/docs/beta-1/api/inspections.html b/docs/beta-1/api/inspections.html new file mode 100644 index 0000000..91ede31 --- /dev/null +++ b/docs/beta-1/api/inspections.html @@ -0,0 +1,12288 @@ +Townlight Inspections API reference
Townlight

Townlight Inspections API reference

+

Prepared source candidate, November 2, 2026. New signed Windows installed acceptance and publication remain pending.

+

Townlight Inspections 0.3.0+dev.2. The HTTP host is Townlight Records 1.8.0.dev2. Component package versions and the host API version are separate identities.

+

Generated from the actual native inspections-preview composition without application lifespan, migrations or database/network access. It describes route and validation contracts; it does not establish endpoint behavior, individual authorization or installed acceptance. Standalone product applications have separate deployment boundaries.

+

Machine-readable OpenAPI schema · Operating manual and limits

+

HTTP operations

+
POST /desktop/v1/inspections-sources/search +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Search Inspections Sources",
+  "operationId": "search_inspections_sources_desktop_v1_inspections_sources_search_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MeetingsSearch"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/inspections/cases +
{
+  "tags": [
+    "native-inspections"
+  ],
+  "summary": "Cases",
+  "operationId": "cases_desktop_v1_inspections_cases_get",
+  "parameters": [
+    {
+      "name": "offset",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 100000,
+        "minimum": 0,
+        "default": 0,
+        "title": "Offset"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/inspections/cases +
{
+  "tags": [
+    "native-inspections"
+  ],
+  "summary": "Create Case",
+  "operationId": "create_case_desktop_v1_inspections_cases_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/InspectionInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/inspections/cases/{case_id} +
{
+  "tags": [
+    "native-inspections"
+  ],
+  "summary": "Case",
+  "operationId": "case_desktop_v1_inspections_cases__case_id__get",
+  "parameters": [
+    {
+      "name": "case_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Case Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/inspections/cases/{case_id}/history +
{
+  "tags": [
+    "native-inspections"
+  ],
+  "summary": "History",
+  "operationId": "history_desktop_v1_inspections_cases__case_id__history_get",
+  "parameters": [
+    {
+      "name": "case_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Case Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/inspections/cases/{case_id}/packets +
{
+  "tags": [
+    "native-inspections"
+  ],
+  "summary": "Packet",
+  "operationId": "packet_desktop_v1_inspections_cases__case_id__packets_post",
+  "parameters": [
+    {
+      "name": "case_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Case Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/Packet"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/inspections/cases/{case_id}/revisions +
{
+  "tags": [
+    "native-inspections"
+  ],
+  "summary": "Revise",
+  "operationId": "revise_desktop_v1_inspections_cases__case_id__revisions_post",
+  "parameters": [
+    {
+      "name": "case_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Case Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/InspectionInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/inspections/connections/search +
{
+  "tags": [
+    "native-inspections"
+  ],
+  "summary": "Connections",
+  "operationId": "connections_desktop_v1_inspections_connections_search_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/townlight_runtime__inspections_bridge__Search"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/inspections/evidence/retain +
{
+  "tags": [
+    "native-inspections"
+  ],
+  "summary": "Retain",
+  "operationId": "retain_desktop_v1_inspections_evidence_retain_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/EvidenceItems"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/inspections/evidence/supported-types +
{
+  "tags": [
+    "native-inspections"
+  ],
+  "summary": "Supported Types",
+  "description": "The media types this deployment's product model actually accepts.",
+  "operationId": "supported_types_desktop_v1_inspections_evidence_supported_types_get",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/inspections/media/analyse +
{
+  "tags": [
+    "native-inspections"
+  ],
+  "summary": "Media Analyse",
+  "description": "Run the configured adapters over retained originals; draft only.\n\nThe result carries the same observations/citations the product route returns\nplus ``analysis_record``: the exact ``AnalysisRecord`` the caller puts on its\ncase payload, so the reviewed draft is the analysed one.",
+  "operationId": "media_analyse_desktop_v1_inspections_media_analyse_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MediaAnalysis"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/inspections/notice-draft +
{
+  "tags": [
+    "native-inspections"
+  ],
+  "summary": "Notice",
+  "operationId": "notice_desktop_v1_inspections_notice_draft_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/InspectionInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/inspections/packets/{packet_id} +
{
+  "tags": [
+    "native-inspections"
+  ],
+  "summary": "Document",
+  "operationId": "document_desktop_v1_inspections_packets__packet_id__get",
+  "parameters": [
+    {
+      "name": "packet_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Packet Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/inspections/repeat-cases +
{
+  "tags": [
+    "native-inspections"
+  ],
+  "summary": "Repeat Cases",
+  "operationId": "repeat_cases_desktop_v1_inspections_repeat_cases_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/RepeatLookup"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+

Request and response data dictionary

+

Each schema includes the actual required fields, types, constraints and descriptions. References resolve against the machine-readable document.

+
ActionItemInput
+{
+  "properties": {
+    "description": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Description"
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "source_motion_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Motion Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "description"
+  ],
+  "title": "ActionItemInput"
+}
+
+
AdaPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "ada-title-ii",
+      "title": "Action"
+    },
+    "serviceArea": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Servicearea"
+    },
+    "hasCoordinatorReview": {
+      "type": "boolean",
+      "title": "Hascoordinatorreview",
+      "default": false
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "serviceArea"
+  ],
+  "title": "AdaPlan"
+}
+
+
AdminUserCreateRequest
+{
+  "properties": {
+    "email": {
+      "type": "string",
+      "title": "Email"
+    },
+    "password": {
+      "type": "string",
+      "title": "Password"
+    },
+    "full_name": {
+      "type": "string",
+      "title": "Full Name",
+      "default": ""
+    },
+    "role": {
+      "type": "string",
+      "title": "Role",
+      "default": "staff"
+    }
+  },
+  "type": "object",
+  "required": [
+    "email",
+    "password"
+  ],
+  "title": "AdminUserCreateRequest"
+}
+
+
AdminUserCreateResponse
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "email": {
+      "type": "string",
+      "title": "Email"
+    },
+    "full_name": {
+      "type": "string",
+      "title": "Full Name"
+    },
+    "role": {
+      "type": "string",
+      "title": "Role"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "email",
+    "full_name",
+    "role",
+    "is_active"
+  ],
+  "title": "AdminUserCreateResponse"
+}
+
+
AgendaAssignment
+{
+  "properties": {
+    "meeting_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Meeting Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "meeting_id"
+  ],
+  "title": "AgendaAssignment"
+}
+
+
AgendaInput
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "department_name": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Department Name"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "department_name"
+  ],
+  "title": "AgendaInput"
+}
+
+
AgendaReviewInput
+{
+  "properties": {
+    "to_status": {
+      "type": "string",
+      "enum": [
+        "DRAFTED",
+        "SUBMITTED",
+        "DEPT_APPROVED",
+        "LEGAL_REVIEWED",
+        "CLERK_ACCEPTED",
+        "ON_AGENDA",
+        "IN_PACKET",
+        "POSTED",
+        "HEARD",
+        "DISPOSED",
+        "ARCHIVED"
+      ],
+      "title": "To Status"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "to_status"
+  ],
+  "title": "AgendaReviewInput"
+}
+
+
AmendmentInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "policy": {
+      "$ref": "#/components/schemas/PolicySelection"
+    },
+    "proposal": {
+      "type": "string",
+      "maxLength": 20000,
+      "minLength": 1,
+      "title": "Proposal"
+    },
+    "responsible_staff": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Responsible Staff"
+    },
+    "status": {
+      "type": "string",
+      "enum": [
+        "draft",
+        "review",
+        "adopted",
+        "withdrawn"
+      ],
+      "title": "Status",
+      "default": "draft"
+    },
+    "review_note": {
+      "type": "string",
+      "maxLength": 5000,
+      "title": "Review Note",
+      "default": ""
+    },
+    "adoption_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Adoption Revision"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "policy",
+    "proposal",
+    "responsible_staff",
+    "note"
+  ],
+  "title": "AmendmentInput"
+}
+
+
AnalysisObservation
+{
+  "properties": {
+    "source": {
+      "type": "string",
+      "maxLength": 64,
+      "minLength": 1,
+      "title": "Source"
+    },
+    "filename": {
+      "type": "string",
+      "maxLength": 160,
+      "title": "Filename",
+      "default": ""
+    },
+    "media_type": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Media Type",
+      "default": ""
+    },
+    "text": {
+      "type": "string",
+      "maxLength": 4000,
+      "minLength": 1,
+      "title": "Text"
+    },
+    "adapter": {
+      "type": "string",
+      "maxLength": 120,
+      "title": "Adapter",
+      "default": ""
+    },
+    "citation_source_ids": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Citation Source Ids"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source",
+    "text"
+  ],
+  "title": "AnalysisObservation",
+  "description": "One draft observation, named with the adapter that actually produced it."
+}
+
+
AnalysisRecord
+{
+  "properties": {
+    "observations": {
+      "items": {
+        "$ref": "#/components/schemas/AnalysisObservation"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Observations"
+    },
+    "cited_sections": {
+      "items": {
+        "$ref": "#/components/schemas/CitedSection"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Cited Sections"
+    },
+    "unavailable": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Unavailable"
+    },
+    "runtime": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Runtime"
+    },
+    "review_required": {
+      "type": "boolean",
+      "title": "Review Required",
+      "default": true
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "AnalysisRecord",
+  "description": "The adapter output that accompanies a saved inspection draft."
+}
+
+
ApprovalCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "approve-records-response",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ApprovalPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "ApprovalCommand"
+}
+
+
ApprovalPayload
+{
+  "properties": {
+    "approvalNote": {
+      "type": "string",
+      "title": "Approvalnote",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "ApprovalPayload"
+}
+
+
ArchiveInput
+{
+  "properties": {
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "public",
+        "closed_session"
+      ],
+      "title": "Visibility"
+    },
+    "packet_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Packet Id"
+    },
+    "minutes_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Minutes Id"
+    },
+    "plain_language_summary": {
+      "type": "string",
+      "title": "Plain Language Summary",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "visibility"
+  ],
+  "title": "ArchiveInput"
+}
+
+
ArtifactPlan
+{
+  "properties": {
+    "artifact_id": {
+      "type": "string",
+      "title": "Artifact Id"
+    },
+    "file_name": {
+      "type": "string",
+      "title": "File Name"
+    },
+    "content": {
+      "type": "string",
+      "title": "Content"
+    },
+    "sha256": {
+      "type": "string",
+      "title": "Sha256"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "artifact_id",
+    "file_name",
+    "content",
+    "sha256",
+    "created_at_unix_seconds"
+  ],
+  "title": "ArtifactPlan"
+}
+
+
AssignCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "assign-records-request",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/AssignmentPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "AssignCommand"
+}
+
+
AssignmentPayload
+{
+  "properties": {
+    "assignedTo": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Assignedto"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "assignedTo"
+  ],
+  "title": "AssignmentPayload"
+}
+
+
AttachDocument
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation",
+      "default": ""
+    },
+    "file": {
+      "$ref": "#/components/schemas/ManagedFileReceipt"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "file"
+  ],
+  "title": "AttachDocument"
+}
+
+
AttachReleaseCopy
+{
+  "properties": {
+    "status": {
+      "type": "string",
+      "enum": [
+        "release-ready copy",
+        "redacted copy"
+      ],
+      "title": "Status"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note",
+      "default": ""
+    },
+    "added_by": {
+      "type": "string",
+      "title": "Added By",
+      "default": ""
+    },
+    "file": {
+      "$ref": "#/components/schemas/ManagedFileReceipt"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "status",
+    "file"
+  ],
+  "title": "AttachReleaseCopy"
+}
+
+
AuditChainVerification
+{
+  "properties": {
+    "is_valid": {
+      "type": "boolean",
+      "title": "Is Valid"
+    },
+    "entries_checked": {
+      "type": "integer",
+      "title": "Entries Checked"
+    },
+    "error_message": {
+      "type": "string",
+      "title": "Error Message"
+    }
+  },
+  "type": "object",
+  "required": [
+    "is_valid",
+    "entries_checked",
+    "error_message"
+  ],
+  "title": "AuditChainVerification"
+}
+
+
AuditLogRead
+{
+  "properties": {
+    "id": {
+      "type": "integer",
+      "title": "Id"
+    },
+    "prev_hash": {
+      "type": "string",
+      "title": "Prev Hash"
+    },
+    "entry_hash": {
+      "type": "string",
+      "title": "Entry Hash"
+    },
+    "timestamp": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Timestamp"
+    },
+    "user_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "User Id"
+    },
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "resource_type": {
+      "type": "string",
+      "title": "Resource Type"
+    },
+    "resource_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Resource Id"
+    },
+    "details": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Details"
+    },
+    "ai_generated": {
+      "type": "boolean",
+      "title": "Ai Generated"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "prev_hash",
+    "entry_hash",
+    "timestamp",
+    "user_id",
+    "action",
+    "resource_type",
+    "resource_id",
+    "details",
+    "ai_generated"
+  ],
+  "title": "AuditLogRead"
+}
+
+
AuditView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "module_id": {
+      "type": "string",
+      "title": "Module Id"
+    },
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    },
+    "previous_hash": {
+      "type": "string",
+      "title": "Previous Hash"
+    },
+    "entry_hash": {
+      "type": "string",
+      "title": "Entry Hash"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "module_id",
+    "action",
+    "summary",
+    "created_at_unix_seconds",
+    "previous_hash",
+    "entry_hash"
+  ],
+  "title": "AuditView"
+}
+
+
BearerResponse
+{
+  "properties": {
+    "access_token": {
+      "type": "string",
+      "title": "Access Token"
+    },
+    "token_type": {
+      "type": "string",
+      "title": "Token Type"
+    }
+  },
+  "type": "object",
+  "required": [
+    "access_token",
+    "token_type"
+  ],
+  "title": "BearerResponse"
+}
+
+
Body_auth_jwt_login_auth_jwt_login_post
+{
+  "properties": {
+    "grant_type": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^password$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Grant Type"
+    },
+    "username": {
+      "type": "string",
+      "title": "Username"
+    },
+    "password": {
+      "type": "string",
+      "format": "password",
+      "title": "Password"
+    },
+    "scope": {
+      "type": "string",
+      "title": "Scope",
+      "default": ""
+    },
+    "client_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Client Id"
+    },
+    "client_secret": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "format": "password",
+      "title": "Client Secret"
+    }
+  },
+  "type": "object",
+  "required": [
+    "username",
+    "password"
+  ],
+  "title": "Body_auth_jwt_login_auth_jwt_login_post"
+}
+
+
Body_upload_file_datasources_upload_post
+{
+  "properties": {
+    "file": {
+      "type": "string",
+      "contentMediaType": "application/octet-stream",
+      "title": "File"
+    }
+  },
+  "type": "object",
+  "required": [
+    "file"
+  ],
+  "title": "Body_upload_file_datasources_upload_post"
+}
+
+
CalculateDeadlineCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "calculate-records-deadline",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/CalculateDeadlinePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "CalculateDeadlineCommand"
+}
+
+
CalculateDeadlinePayload
+{
+  "properties": {
+    "deadlineReceivedDate": {
+      "type": "string",
+      "title": "Deadlinereceiveddate"
+    },
+    "deadlineRuleName": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Deadlinerulename"
+    },
+    "deadlineDayCount": {
+      "type": "string",
+      "title": "Deadlinedaycount"
+    },
+    "deadlineDayType": {
+      "type": "string",
+      "title": "Deadlinedaytype"
+    },
+    "deadlineBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Deadlinebasis"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "deadlineReceivedDate",
+    "deadlineRuleName",
+    "deadlineDayCount",
+    "deadlineDayType",
+    "deadlineBasis"
+  ],
+  "title": "CalculateDeadlinePayload"
+}
+
+
ChapterCreate
+{
+  "properties": {
+    "chapter_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Chapter Id"
+    },
+    "title_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title Id"
+    },
+    "chapter_number": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Chapter Number"
+    },
+    "chapter_name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Chapter Name"
+    },
+    "sort_order": {
+      "type": "integer",
+      "title": "Sort Order",
+      "default": 0
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title_id",
+    "chapter_number",
+    "chapter_name"
+  ],
+  "title": "ChapterCreate",
+  "description": "Request body for creating a code chapter."
+}
+
+
CitedSection
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "citation": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Citation"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "version": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Version",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "citation"
+  ],
+  "title": "CitedSection",
+  "description": "One resolved public Code section; never a caller-supplied quotation."
+}
+
+
CityProfileCreate
+{
+  "properties": {
+    "city_name": {
+      "type": "string",
+      "title": "City Name"
+    },
+    "state": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State"
+    },
+    "county": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "County"
+    },
+    "population_band": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Population Band"
+    },
+    "email_platform": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email Platform"
+    },
+    "has_dedicated_it": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Has Dedicated It"
+    },
+    "monthly_request_volume": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Monthly Request Volume"
+    },
+    "profile_data": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Profile Data",
+      "default": {}
+    },
+    "gap_map": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Gap Map",
+      "default": {}
+    }
+  },
+  "type": "object",
+  "required": [
+    "city_name"
+  ],
+  "title": "CityProfileCreate"
+}
+
+
CityProfileRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "city_name": {
+      "type": "string",
+      "title": "City Name"
+    },
+    "state": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State"
+    },
+    "county": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "County"
+    },
+    "population_band": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Population Band"
+    },
+    "email_platform": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email Platform"
+    },
+    "has_dedicated_it": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Has Dedicated It"
+    },
+    "monthly_request_volume": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Monthly Request Volume"
+    },
+    "onboarding_status": {
+      "type": "string",
+      "title": "Onboarding Status"
+    },
+    "profile_data": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Profile Data"
+    },
+    "gap_map": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Gap Map"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "updated_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "city_name",
+    "state",
+    "county",
+    "population_band",
+    "email_platform",
+    "has_dedicated_it",
+    "monthly_request_volume",
+    "onboarding_status",
+    "profile_data",
+    "gap_map",
+    "created_at",
+    "updated_at"
+  ],
+  "title": "CityProfileRead"
+}
+
+
CityProfileUpdate
+{
+  "properties": {
+    "city_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "City Name"
+    },
+    "state": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State"
+    },
+    "county": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "County"
+    },
+    "population_band": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Population Band"
+    },
+    "email_platform": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email Platform"
+    },
+    "has_dedicated_it": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Has Dedicated It"
+    },
+    "monthly_request_volume": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Monthly Request Volume"
+    },
+    "onboarding_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Onboarding Status"
+    },
+    "profile_data": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Profile Data"
+    },
+    "gap_map": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Gap Map"
+    }
+  },
+  "type": "object",
+  "title": "CityProfileUpdate"
+}
+
+
ClarificationCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "request-records-clarification",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ClarificationPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "ClarificationCommand"
+}
+
+
ClarificationPayload
+{
+  "properties": {
+    "clarificationNote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Clarificationnote"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "clarificationNote"
+  ],
+  "title": "ClarificationPayload"
+}
+
+
Closeout
+{
+  "properties": {
+    "decision_id": {
+      "type": "string",
+      "pattern": "^[A-Za-z0-9_-]{1,64}$",
+      "title": "Decision Id"
+    },
+    "version_id": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Version Id"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "version_label": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Version Label"
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 1000000,
+      "minLength": 1,
+      "title": "Body"
+    },
+    "effective_start": {
+      "type": "string",
+      "format": "date",
+      "title": "Effective Start"
+    },
+    "effective_end": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective End"
+    },
+    "is_current": {
+      "type": "boolean",
+      "title": "Is Current"
+    },
+    "reconciliation_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reconciliation Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "decision_id",
+    "version_id",
+    "source_id",
+    "version_label",
+    "body",
+    "effective_start",
+    "is_current"
+  ],
+  "title": "Closeout"
+}
+
+
CodeContext
+{
+  "properties": {
+    "section_number": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Section Number"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "section_number"
+  ],
+  "title": "CodeContext"
+}
+
+
CodeLink
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "const": "code",
+      "title": "Provider",
+      "default": "code"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "CodeLink"
+}
+
+
CodeSearch
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "CodeSearch"
+}
+
+
CodeSourceSelection
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 200,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "CodeSourceSelection"
+}
+
+
CompleteArtifact
+{
+  "properties": {
+    "export_path": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Export Path"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "export_path"
+  ],
+  "title": "CompleteArtifact"
+}
+
+
ConnectionSearch
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "enum": [
+        "meetings",
+        "zoning"
+      ],
+      "title": "Provider"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "query"
+  ],
+  "title": "ConnectionSearch"
+}
+
+
CoverageGapResponse
+{
+  "properties": {
+    "jurisdictions_without_rules": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Jurisdictions Without Rules"
+    },
+    "departments_without_staff": {
+      "items": {
+        "additionalProperties": true,
+        "type": "object"
+      },
+      "type": "array",
+      "title": "Departments Without Staff"
+    },
+    "uncovered_categories": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Uncovered Categories"
+    },
+    "total_gaps": {
+      "type": "integer",
+      "title": "Total Gaps"
+    }
+  },
+  "type": "object",
+  "required": [
+    "jurisdictions_without_rules",
+    "departments_without_staff",
+    "uncovered_categories",
+    "total_gaps"
+  ],
+  "title": "CoverageGapResponse"
+}
+
+
DataSourceAdminRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "source_type": {
+      "$ref": "#/components/schemas/SourceType"
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "type": "boolean",
+      "title": "Schedule Enabled",
+      "default": true
+    },
+    "next_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Next Sync At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "last_ingestion_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Ingestion At"
+    },
+    "last_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync At"
+    },
+    "last_sync_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync Status"
+    },
+    "last_error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Error Message"
+    },
+    "consecutive_failure_count": {
+      "type": "integer",
+      "title": "Consecutive Failure Count",
+      "default": 0
+    },
+    "sync_paused": {
+      "type": "boolean",
+      "title": "Sync Paused",
+      "default": false
+    },
+    "health_status": {
+      "type": "string",
+      "title": "Health Status",
+      "default": "healthy"
+    },
+    "active_failure_count": {
+      "type": "integer",
+      "title": "Active Failure Count",
+      "default": 0
+    },
+    "connector_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connector Type"
+    },
+    "updated_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Updated At"
+    },
+    "connection_config": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Connection Config"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "source_type",
+    "is_active",
+    "created_by",
+    "created_at",
+    "last_ingestion_at",
+    "connection_config"
+  ],
+  "title": "DataSourceAdminRead",
+  "description": "Full datasource shape including connection_config. Returned only by admin-gated endpoints."
+}
+
+
DataSourceCreate
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "source_type": {
+      "$ref": "#/components/schemas/SourceType"
+    },
+    "connection_config": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Connection Config",
+      "default": {}
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "type": "boolean",
+      "title": "Schedule Enabled",
+      "default": true
+    }
+  },
+  "type": "object",
+  "required": [
+    "name",
+    "source_type"
+  ],
+  "title": "DataSourceCreate"
+}
+
+
DataSourceRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "source_type": {
+      "$ref": "#/components/schemas/SourceType"
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "type": "boolean",
+      "title": "Schedule Enabled",
+      "default": true
+    },
+    "next_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Next Sync At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "last_ingestion_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Ingestion At"
+    },
+    "last_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync At"
+    },
+    "last_sync_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync Status"
+    },
+    "last_error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Error Message"
+    },
+    "consecutive_failure_count": {
+      "type": "integer",
+      "title": "Consecutive Failure Count",
+      "default": 0
+    },
+    "sync_paused": {
+      "type": "boolean",
+      "title": "Sync Paused",
+      "default": false
+    },
+    "health_status": {
+      "type": "string",
+      "title": "Health Status",
+      "default": "healthy"
+    },
+    "active_failure_count": {
+      "type": "integer",
+      "title": "Active Failure Count",
+      "default": 0
+    },
+    "connector_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connector Type"
+    },
+    "updated_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "source_type",
+    "is_active",
+    "created_by",
+    "created_at",
+    "last_ingestion_at"
+  ],
+  "title": "DataSourceRead",
+  "description": "Redacted datasource shape — safe for non-admin roles. connection_config omitted."
+}
+
+
DataSourceUpdate
+{
+  "properties": {
+    "name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Name"
+    },
+    "connection_config": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connection Config"
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Schedule Enabled"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "DataSourceUpdate"
+}
+
+
DeadlineCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "set-records-deadline",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/DeadlinePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "DeadlineCommand"
+}
+
+
DeadlinePayload
+{
+  "properties": {
+    "deadline": {
+      "type": "string",
+      "title": "Deadline"
+    },
+    "deadlineBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Deadlinebasis"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "deadline",
+    "deadlineBasis"
+  ],
+  "title": "DeadlinePayload"
+}
+
+
Decision
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "pattern": "^[A-Za-z0-9_-]{1,64}$",
+      "title": "Id"
+    },
+    "outcome": {
+      "type": "string",
+      "enum": [
+        "adopted",
+        "not_adopted",
+        "deferred",
+        "withdrawn"
+      ],
+      "title": "Outcome"
+    },
+    "decided_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Decided At"
+    },
+    "decision_text": {
+      "type": "string",
+      "maxLength": 1000000,
+      "minLength": 1,
+      "title": "Decision Text"
+    },
+    "supporting_references": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Supporting References"
+    },
+    "supersedes_decision_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^[A-Za-z0-9_-]{1,64}$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supersedes Decision Id"
+    },
+    "reconciliation_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reconciliation Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "outcome",
+    "decision_text"
+  ],
+  "title": "Decision"
+}
+
+
DepartmentCreate
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "code": {
+      "type": "string",
+      "title": "Code"
+    },
+    "contact_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Contact Email"
+    }
+  },
+  "type": "object",
+  "required": [
+    "name",
+    "code"
+  ],
+  "title": "DepartmentCreate"
+}
+
+
DepartmentRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "code": {
+      "type": "string",
+      "title": "Code"
+    },
+    "contact_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Contact Email"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "code",
+    "contact_email",
+    "created_at"
+  ],
+  "title": "DepartmentRead"
+}
+
+
DepartmentUpdate
+{
+  "properties": {
+    "name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Name"
+    },
+    "code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Code"
+    },
+    "contact_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Contact Email"
+    }
+  },
+  "type": "object",
+  "title": "DepartmentUpdate"
+}
+
+
DisclosureTemplateCreate
+{
+  "properties": {
+    "template_type": {
+      "type": "string",
+      "title": "Template Type"
+    },
+    "state_code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State Code"
+    },
+    "content": {
+      "type": "string",
+      "title": "Content"
+    }
+  },
+  "type": "object",
+  "required": [
+    "template_type",
+    "content"
+  ],
+  "title": "DisclosureTemplateCreate"
+}
+
+
DisclosureTemplateRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "template_type": {
+      "type": "string",
+      "title": "Template Type"
+    },
+    "state_code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State Code"
+    },
+    "content": {
+      "type": "string",
+      "title": "Content"
+    },
+    "version": {
+      "type": "integer",
+      "title": "Version"
+    },
+    "updated_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Updated By"
+    },
+    "updated_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "template_type",
+    "state_code",
+    "content",
+    "version",
+    "updated_by",
+    "updated_at"
+  ],
+  "title": "DisclosureTemplateRead"
+}
+
+
DisclosureTemplateRendered
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "template_type": {
+      "type": "string",
+      "title": "Template Type"
+    },
+    "rendered_content": {
+      "type": "string",
+      "title": "Rendered Content"
+    },
+    "has_unresolved_variables": {
+      "type": "boolean",
+      "title": "Has Unresolved Variables"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "template_type",
+    "rendered_content",
+    "has_unresolved_variables"
+  ],
+  "title": "DisclosureTemplateRendered"
+}
+
+
DisclosureTemplateUpdate
+{
+  "properties": {
+    "content": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Content"
+    },
+    "state_code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State Code"
+    }
+  },
+  "type": "object",
+  "title": "DisclosureTemplateUpdate"
+}
+
+
DocumentChunkRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "chunk_index": {
+      "type": "integer",
+      "title": "Chunk Index"
+    },
+    "content_text": {
+      "type": "string",
+      "title": "Content Text"
+    },
+    "token_count": {
+      "type": "integer",
+      "title": "Token Count"
+    },
+    "page_number": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Page Number"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "document_id",
+    "chunk_index",
+    "content_text",
+    "token_count",
+    "page_number"
+  ],
+  "title": "DocumentChunkRead"
+}
+
+
DocumentRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "source_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Source Id"
+    },
+    "source_path": {
+      "type": "string",
+      "title": "Source Path"
+    },
+    "filename": {
+      "type": "string",
+      "title": "Filename"
+    },
+    "file_type": {
+      "type": "string",
+      "title": "File Type"
+    },
+    "file_hash": {
+      "type": "string",
+      "title": "File Hash"
+    },
+    "file_size": {
+      "type": "integer",
+      "title": "File Size"
+    },
+    "ingestion_status": {
+      "$ref": "#/components/schemas/IngestionStatus"
+    },
+    "ingestion_error": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ingestion Error"
+    },
+    "chunk_count": {
+      "type": "integer",
+      "title": "Chunk Count"
+    },
+    "ingested_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ingested At"
+    },
+    "connector_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connector Type"
+    },
+    "updated_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "source_id",
+    "source_path",
+    "filename",
+    "file_type",
+    "file_hash",
+    "file_size",
+    "ingestion_status",
+    "ingestion_error",
+    "chunk_count",
+    "ingested_at"
+  ],
+  "title": "DocumentRead"
+}
+
+
DraftCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "draft-records-response",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/DraftPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "DraftCommand"
+}
+
+
DraftInput
+{
+  "properties": {
+    "source_materials": {
+      "items": {
+        "$ref": "#/components/schemas/SourceInput"
+      },
+      "type": "array",
+      "title": "Source Materials"
+    },
+    "sentences": {
+      "items": {
+        "$ref": "#/components/schemas/SentenceInput"
+      },
+      "type": "array",
+      "minItems": 1,
+      "title": "Sentences"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sentences"
+  ],
+  "title": "DraftInput"
+}
+
+
DraftPayload
+{
+  "properties": {
+    "responseDraft": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Responsedraft"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "responseDraft"
+  ],
+  "title": "DraftPayload"
+}
+
+
ErrorModel
+{
+  "properties": {
+    "detail": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "additionalProperties": {
+            "type": "string"
+          },
+          "type": "object"
+        }
+      ],
+      "title": "Detail"
+    }
+  },
+  "type": "object",
+  "required": [
+    "detail"
+  ],
+  "title": "ErrorModel"
+}
+
+
Evidence
+{
+  "properties": {
+    "filename": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$",
+      "title": "Filename"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Description"
+    },
+    "media_type": {
+      "type": "string",
+      "enum": [
+        "text/plain",
+        "image/jpeg",
+        "image/png",
+        "image/webp",
+        "application/pdf",
+        "audio/webm",
+        "audio/ogg",
+        "audio/wav",
+        "audio/mpeg",
+        "audio/mp4"
+      ],
+      "title": "Media Type"
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 14000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "filename",
+    "description",
+    "media_type",
+    "content_base64",
+    "sha256"
+  ],
+  "title": "Evidence"
+}
+
+
EvidenceItem
+{
+  "properties": {
+    "filename": {
+      "type": "string",
+      "maxLength": 151,
+      "minLength": 1,
+      "title": "Filename"
+    },
+    "media_type": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Media Type"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Description",
+      "default": ""
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 14000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "filename",
+    "media_type",
+    "content_base64",
+    "sha256"
+  ],
+  "title": "EvidenceItem"
+}
+
+
EvidenceItems
+{
+  "properties": {
+    "items": {
+      "items": {
+        "$ref": "#/components/schemas/EvidenceItem"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "minItems": 1,
+      "title": "Items"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "items"
+  ],
+  "title": "EvidenceItems"
+}
+
+
ExemptionAccuracyReport
+{
+  "properties": {
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "total_flags": {
+      "type": "integer",
+      "title": "Total Flags"
+    },
+    "accepted": {
+      "type": "integer",
+      "title": "Accepted"
+    },
+    "rejected": {
+      "type": "integer",
+      "title": "Rejected"
+    },
+    "pending": {
+      "type": "integer",
+      "title": "Pending"
+    },
+    "acceptance_rate": {
+      "type": "number",
+      "title": "Acceptance Rate"
+    }
+  },
+  "type": "object",
+  "required": [
+    "category",
+    "total_flags",
+    "accepted",
+    "rejected",
+    "pending",
+    "acceptance_rate"
+  ],
+  "title": "ExemptionAccuracyReport"
+}
+
+
ExemptionDashboard
+{
+  "properties": {
+    "total_flags": {
+      "type": "integer",
+      "title": "Total Flags"
+    },
+    "by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "By Status"
+    },
+    "by_category": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "By Category"
+    },
+    "acceptance_rate": {
+      "type": "number",
+      "title": "Acceptance Rate"
+    },
+    "total_rules": {
+      "type": "integer",
+      "title": "Total Rules"
+    },
+    "active_rules": {
+      "type": "integer",
+      "title": "Active Rules"
+    }
+  },
+  "type": "object",
+  "required": [
+    "total_flags",
+    "by_status",
+    "by_category",
+    "acceptance_rate",
+    "total_rules",
+    "active_rules"
+  ],
+  "title": "ExemptionDashboard"
+}
+
+
ExemptionDecisionCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-exemption-decision",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ExemptionDecisionPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "ExemptionDecisionCommand"
+}
+
+
ExemptionDecisionPayload
+{
+  "properties": {
+    "exemptionSource": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionsource"
+    },
+    "exemptionKind": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionkind"
+    },
+    "exemptionFinding": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionfinding"
+    },
+    "exemptionDecision": {
+      "type": "string",
+      "enum": [
+        "release",
+        "redact",
+        "exempt"
+      ],
+      "title": "Exemptiondecision"
+    },
+    "exemptionBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionbasis"
+    },
+    "exemptionReviewer": {
+      "type": "string",
+      "title": "Exemptionreviewer",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "exemptionSource",
+    "exemptionKind",
+    "exemptionFinding",
+    "exemptionDecision",
+    "exemptionBasis"
+  ],
+  "title": "ExemptionDecisionPayload"
+}
+
+
ExemptionDecisionView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "source": {
+      "type": "string",
+      "title": "Source"
+    },
+    "kind": {
+      "type": "string",
+      "title": "Kind"
+    },
+    "finding": {
+      "type": "string",
+      "title": "Finding"
+    },
+    "decision": {
+      "type": "string",
+      "enum": [
+        "release",
+        "redact",
+        "exempt"
+      ],
+      "title": "Decision"
+    },
+    "basis": {
+      "type": "string",
+      "title": "Basis"
+    },
+    "reviewer": {
+      "type": "string",
+      "title": "Reviewer"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "source",
+    "kind",
+    "finding",
+    "decision",
+    "basis",
+    "reviewer",
+    "created_at_unix_seconds"
+  ],
+  "title": "ExemptionDecisionView"
+}
+
+
ExemptionFlagRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "chunk_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Chunk Id"
+    },
+    "rule_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Rule Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "matched_text": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Matched Text"
+    },
+    "confidence": {
+      "type": "number",
+      "title": "Confidence"
+    },
+    "status": {
+      "$ref": "#/components/schemas/FlagStatus"
+    },
+    "reviewed_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reviewed By"
+    },
+    "reviewed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reviewed At"
+    },
+    "review_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Reason"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "chunk_id",
+    "rule_id",
+    "request_id",
+    "category",
+    "matched_text",
+    "confidence",
+    "status",
+    "reviewed_by",
+    "reviewed_at",
+    "review_reason",
+    "created_at"
+  ],
+  "title": "ExemptionFlagRead"
+}
+
+
ExemptionFlagReview
+{
+  "properties": {
+    "status": {
+      "$ref": "#/components/schemas/FlagStatus"
+    },
+    "review_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Reason"
+    }
+  },
+  "type": "object",
+  "required": [
+    "status"
+  ],
+  "title": "ExemptionFlagReview"
+}
+
+
ExemptionNoteCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-exemption-review",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ExemptionNotePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "ExemptionNoteCommand"
+}
+
+
ExemptionNotePayload
+{
+  "properties": {
+    "exemptionNote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionnote"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "exemptionNote"
+  ],
+  "title": "ExemptionNotePayload"
+}
+
+
ExemptionRuleCreate
+{
+  "properties": {
+    "state_code": {
+      "type": "string",
+      "title": "State Code"
+    },
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "rule_type": {
+      "$ref": "#/components/schemas/RuleType"
+    },
+    "rule_definition": {
+      "type": "string",
+      "title": "Rule Definition"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "enabled": {
+      "type": "boolean",
+      "title": "Enabled",
+      "default": true
+    }
+  },
+  "type": "object",
+  "required": [
+    "state_code",
+    "category",
+    "rule_type",
+    "rule_definition"
+  ],
+  "title": "ExemptionRuleCreate"
+}
+
+
ExemptionRuleRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "state_code": {
+      "type": "string",
+      "title": "State Code"
+    },
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "rule_type": {
+      "$ref": "#/components/schemas/RuleType"
+    },
+    "rule_definition": {
+      "type": "string",
+      "title": "Rule Definition"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "enabled": {
+      "type": "boolean",
+      "title": "Enabled"
+    },
+    "version": {
+      "type": "integer",
+      "title": "Version",
+      "default": 1
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "state_code",
+    "category",
+    "rule_type",
+    "rule_definition",
+    "description",
+    "enabled",
+    "created_by",
+    "created_at"
+  ],
+  "title": "ExemptionRuleRead"
+}
+
+
ExemptionRuleUpdate
+{
+  "properties": {
+    "rule_definition": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Rule Definition"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "enabled": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Enabled"
+    }
+  },
+  "type": "object",
+  "title": "ExemptionRuleUpdate"
+}
+
+
ExportReceipt
+{
+  "properties": {
+    "export_path": {
+      "type": "string",
+      "maxLength": 32768,
+      "minLength": 1,
+      "title": "Export Path"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "export_path"
+  ],
+  "title": "ExportReceipt"
+}
+
+
FeeEstimateCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "estimate-records-fee",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/FeeEstimatePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "FeeEstimateCommand"
+}
+
+
FeeEstimatePayload
+{
+  "properties": {
+    "feeEstimate": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feeestimate"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "feeEstimate"
+  ],
+  "title": "FeeEstimatePayload"
+}
+
+
FeeEstimateRequest
+{
+  "properties": {
+    "page_count": {
+      "type": "integer",
+      "title": "Page Count"
+    },
+    "fee_schedule_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Fee Schedule Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "page_count",
+    "fee_schedule_id"
+  ],
+  "title": "FeeEstimateRequest"
+}
+
+
FeeEstimateResponse
+{
+  "properties": {
+    "page_count": {
+      "type": "integer",
+      "title": "Page Count"
+    },
+    "unit_price": {
+      "type": "number",
+      "title": "Unit Price"
+    },
+    "total": {
+      "type": "number",
+      "title": "Total"
+    },
+    "fee_type": {
+      "type": "string",
+      "title": "Fee Type"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    }
+  },
+  "type": "object",
+  "required": [
+    "page_count",
+    "unit_price",
+    "total",
+    "fee_type",
+    "description"
+  ],
+  "title": "FeeEstimateResponse"
+}
+
+
FeeLineCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-fee-line",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/FeeLinePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "FeeLineCommand"
+}
+
+
FeeLineItemCreate
+{
+  "properties": {
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "quantity": {
+      "type": "integer",
+      "title": "Quantity",
+      "default": 1
+    },
+    "unit_price": {
+      "type": "number",
+      "title": "Unit Price"
+    },
+    "fee_schedule_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Schedule Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "description",
+    "unit_price"
+  ],
+  "title": "FeeLineItemCreate"
+}
+
+
FeeLineItemRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "fee_schedule_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Schedule Id"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "quantity": {
+      "type": "integer",
+      "title": "Quantity"
+    },
+    "unit_price": {
+      "type": "number",
+      "title": "Unit Price"
+    },
+    "total": {
+      "type": "number",
+      "title": "Total"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "fee_schedule_id",
+    "description",
+    "quantity",
+    "unit_price",
+    "total",
+    "status",
+    "created_at"
+  ],
+  "title": "FeeLineItemRead"
+}
+
+
FeeLinePayload
+{
+  "properties": {
+    "feeLineDescription": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feelinedescription"
+    },
+    "feeScheduleBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feeschedulebasis"
+    },
+    "feeLineAmount": {
+      "type": "string",
+      "title": "Feelineamount"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "feeLineDescription",
+    "feeScheduleBasis",
+    "feeLineAmount"
+  ],
+  "title": "FeeLinePayload"
+}
+
+
FeeLineView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "schedule_basis": {
+      "type": "string",
+      "title": "Schedule Basis"
+    },
+    "amount_cents": {
+      "type": "integer",
+      "title": "Amount Cents"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "description",
+    "schedule_basis",
+    "amount_cents",
+    "created_at_unix_seconds"
+  ],
+  "title": "FeeLineView"
+}
+
+
FeeScheduleCreate
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "title": "Jurisdiction"
+    },
+    "fee_type": {
+      "type": "string",
+      "title": "Fee Type"
+    },
+    "amount": {
+      "type": "number",
+      "title": "Amount"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "effective_date": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective Date"
+    }
+  },
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "fee_type",
+    "amount"
+  ],
+  "title": "FeeScheduleCreate"
+}
+
+
FeeScheduleRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "jurisdiction": {
+      "type": "string",
+      "title": "Jurisdiction"
+    },
+    "fee_type": {
+      "type": "string",
+      "title": "Fee Type"
+    },
+    "amount": {
+      "type": "number",
+      "title": "Amount"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "effective_date": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective Date"
+    },
+    "created_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "jurisdiction",
+    "fee_type",
+    "amount",
+    "description",
+    "effective_date",
+    "created_by",
+    "created_at"
+  ],
+  "title": "FeeScheduleRead"
+}
+
+
FeeScheduleUpdate
+{
+  "properties": {
+    "fee_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Type"
+    },
+    "amount": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Amount"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "effective_date": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective Date"
+    }
+  },
+  "type": "object",
+  "title": "FeeScheduleUpdate"
+}
+
+
FeeWaiverCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "waive-records-fee",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/FeeWaiverPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "FeeWaiverCommand"
+}
+
+
FeeWaiverCreateRequest
+{
+  "properties": {
+    "waiver_type": {
+      "type": "string",
+      "title": "Waiver Type"
+    },
+    "reason": {
+      "type": "string",
+      "title": "Reason"
+    }
+  },
+  "type": "object",
+  "required": [
+    "waiver_type",
+    "reason"
+  ],
+  "title": "FeeWaiverCreateRequest"
+}
+
+
FeeWaiverPayload
+{
+  "properties": {
+    "feeWaiverReason": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feewaiverreason"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "feeWaiverReason"
+  ],
+  "title": "FeeWaiverPayload"
+}
+
+
FeeWaiverReadResponse
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "waiver_type": {
+      "type": "string",
+      "title": "Waiver Type"
+    },
+    "reason": {
+      "type": "string",
+      "title": "Reason"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    },
+    "created_at": {
+      "type": "string",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "waiver_type",
+    "reason",
+    "status",
+    "created_at"
+  ],
+  "title": "FeeWaiverReadResponse"
+}
+
+
FeeWaiverReviewRequest
+{
+  "properties": {
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    }
+  },
+  "type": "object",
+  "required": [
+    "status"
+  ],
+  "title": "FeeWaiverReviewRequest"
+}
+
+
FinishCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "fulfill-records-request",
+        "close-records-request"
+      ],
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/NativePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "FinishCommand"
+}
+
+
FlagStatus
+{
+  "type": "string",
+  "enum": [
+    "flagged",
+    "reviewed",
+    "accepted",
+    "rejected"
+  ],
+  "title": "FlagStatus"
+}
+
+
FormPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "form-plan",
+      "title": "Action"
+    },
+    "formName": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Formname",
+      "default": ""
+    },
+    "fields": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 50,
+      "title": "Fields"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "FormPlan"
+}
+
+
GeneratedDraft
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "model": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Model"
+    },
+    "previous_response_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Previous Response Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text",
+    "model",
+    "previous_response_sha256"
+  ],
+  "title": "GeneratedDraft"
+}
+
+
HTTPValidationError
+{
+  "properties": {
+    "detail": {
+      "items": {
+        "$ref": "#/components/schemas/ValidationError"
+      },
+      "type": "array",
+      "title": "Detail"
+    }
+  },
+  "type": "object",
+  "title": "HTTPValidationError"
+}
+
+
Handoff
+{
+  "properties": {
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "request_id"
+  ],
+  "title": "Handoff"
+}
+
+
ImportBundleCreate
+{
+  "properties": {
+    "job_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Job Id"
+    },
+    "connector_type": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Connector Type"
+    },
+    "source": {
+      "$ref": "#/components/schemas/SourceCreate"
+    },
+    "sources": {
+      "items": {
+        "$ref": "#/components/schemas/SourceCreate"
+      },
+      "type": "array",
+      "title": "Sources"
+    },
+    "titles": {
+      "items": {
+        "$ref": "#/components/schemas/TitleCreate"
+      },
+      "type": "array",
+      "title": "Titles"
+    },
+    "chapters": {
+      "items": {
+        "$ref": "#/components/schemas/ChapterCreate"
+      },
+      "type": "array",
+      "title": "Chapters"
+    },
+    "sections": {
+      "items": {
+        "$ref": "#/components/schemas/SectionCreate"
+      },
+      "type": "array",
+      "title": "Sections"
+    },
+    "versions": {
+      "items": {
+        "$ref": "#/components/schemas/SectionVersionCreate"
+      },
+      "type": "array",
+      "title": "Versions"
+    },
+    "provenance": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Provenance"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "connector_type",
+    "source"
+  ],
+  "title": "ImportBundleCreate",
+  "description": "Request body for local fixture/file-drop import jobs."
+}
+
+
InclusionStatus
+{
+  "type": "string",
+  "enum": [
+    "included",
+    "excluded",
+    "pending"
+  ],
+  "title": "InclusionStatus"
+}
+
+
IngestionStats
+{
+  "properties": {
+    "total_sources": {
+      "type": "integer",
+      "title": "Total Sources"
+    },
+    "active_sources": {
+      "type": "integer",
+      "title": "Active Sources"
+    },
+    "total_documents": {
+      "type": "integer",
+      "title": "Total Documents"
+    },
+    "documents_by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "Documents By Status"
+    },
+    "total_chunks": {
+      "type": "integer",
+      "title": "Total Chunks"
+    }
+  },
+  "type": "object",
+  "required": [
+    "total_sources",
+    "active_sources",
+    "total_documents",
+    "documents_by_status",
+    "total_chunks"
+  ],
+  "title": "IngestionStats"
+}
+
+
IngestionStatus
+{
+  "type": "string",
+  "enum": [
+    "pending",
+    "processing",
+    "completed",
+    "failed"
+  ],
+  "title": "IngestionStatus"
+}
+
+
InitiativeInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "policy": {
+      "$ref": "#/components/schemas/PolicySelection"
+    },
+    "responsible_staff": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Responsible Staff"
+    },
+    "target": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "string"
+        }
+      ],
+      "title": "Target"
+    },
+    "unit": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Unit"
+    },
+    "due_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Due On"
+    },
+    "status": {
+      "type": "string",
+      "enum": [
+        "planned",
+        "active",
+        "completed",
+        "cancelled"
+      ],
+      "title": "Status",
+      "default": "planned"
+    },
+    "milestones": {
+      "items": {
+        "$ref": "#/components/schemas/Milestone"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "title": "Milestones"
+    },
+    "measurements": {
+      "items": {
+        "$ref": "#/components/schemas/Measurement"
+      },
+      "type": "array",
+      "maxItems": 1000,
+      "title": "Measurements"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "policy",
+    "responsible_staff",
+    "target",
+    "unit",
+    "due_on",
+    "note"
+  ],
+  "title": "InitiativeInput"
+}
+
+
InspectionInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "property_reference": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Property Reference"
+    },
+    "inspection_reference": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Inspection Reference"
+    },
+    "dataset_kind": {
+      "type": "string",
+      "enum": [
+        "municipal",
+        "fictional"
+      ],
+      "title": "Dataset Kind"
+    },
+    "inspector_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "minLength": 1,
+      "title": "Inspector Notes"
+    },
+    "photo_observations": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Photo Observations"
+    },
+    "voice_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Voice Notes",
+      "default": ""
+    },
+    "evidence": {
+      "items": {
+        "$ref": "#/components/schemas/Evidence"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "title": "Evidence"
+    },
+    "linked_sources": {
+      "items": {
+        "$ref": "#/components/schemas/townlight_inspections__workflow_models__SourceLink"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Linked Sources"
+    },
+    "assigned_to": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Assigned To",
+      "default": ""
+    },
+    "staff_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Staff Notes",
+      "default": ""
+    },
+    "notice_draft": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Notice Draft",
+      "default": ""
+    },
+    "review_state": {
+      "type": "string",
+      "enum": [
+        "draft",
+        "follow_up",
+        "reviewed"
+      ],
+      "title": "Review State",
+      "default": "draft"
+    },
+    "review_notes": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Review Notes",
+      "default": ""
+    },
+    "public_summary": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Public Summary",
+      "default": ""
+    },
+    "analysis": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/AnalysisRecord"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "property_reference",
+    "inspection_reference",
+    "dataset_kind",
+    "inspector_notes"
+  ],
+  "title": "InspectionInput"
+}
+
+
IntakeInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "project_name": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Project Name"
+    },
+    "project_description": {
+      "type": "string",
+      "maxLength": 10000,
+      "minLength": 1,
+      "title": "Project Description"
+    },
+    "location": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Location"
+    },
+    "applicant_contact": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Applicant Contact",
+      "default": ""
+    },
+    "requirement_revision": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Requirement Revision"
+    },
+    "materials": {
+      "items": {
+        "$ref": "#/components/schemas/MaterialReview"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "minItems": 1,
+      "title": "Materials"
+    },
+    "linked_sources": {
+      "items": {
+        "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Linked Sources"
+    },
+    "staff_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Staff Notes",
+      "default": ""
+    },
+    "assigned_to": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Assigned To",
+      "default": ""
+    },
+    "review_state": {
+      "type": "string",
+      "enum": [
+        "draft",
+        "follow_up",
+        "reviewed"
+      ],
+      "title": "Review State",
+      "default": "draft"
+    },
+    "review_notes": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Review Notes",
+      "default": ""
+    },
+    "public_summary": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Public Summary",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "project_name",
+    "project_description",
+    "location",
+    "requirement_revision",
+    "materials"
+  ],
+  "title": "IntakeInput"
+}
+
+
InterpretationNoteCreate
+{
+  "properties": {
+    "note_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Note Id"
+    },
+    "note_text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Note Text"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "note_text"
+  ],
+  "title": "InterpretationNoteCreate",
+  "description": "Request body for staff-only interpretation notes."
+}
+
+
InterviewRequest
+{
+  "properties": {
+    "last_answer": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Answer"
+    },
+    "last_field": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Field"
+    },
+    "skipped_fields": {
+      "anyOf": [
+        {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Skipped Fields"
+    }
+  },
+  "type": "object",
+  "title": "InterviewRequest"
+}
+
+
InterviewResponse
+{
+  "properties": {
+    "question": {
+      "type": "string",
+      "title": "Question"
+    },
+    "target_field": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Target Field"
+    },
+    "all_complete": {
+      "type": "boolean",
+      "title": "All Complete"
+    },
+    "completed_fields": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Completed Fields"
+    },
+    "onboarding_status": {
+      "type": "string",
+      "title": "Onboarding Status"
+    },
+    "skipped_fields": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Skipped Fields"
+    }
+  },
+  "type": "object",
+  "required": [
+    "question",
+    "target_field",
+    "all_complete",
+    "completed_fields",
+    "onboarding_status",
+    "skipped_fields"
+  ],
+  "title": "InterviewResponse"
+}
+
+
ManagedFileReceipt
+{
+  "properties": {
+    "original_path": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Original Path"
+    },
+    "stored_path": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Stored Path"
+    },
+    "file_name": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "File Name"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Sha256"
+    },
+    "size_bytes": {
+      "type": "integer",
+      "maximum": 2147483647.0,
+      "minimum": 0.0,
+      "title": "Size Bytes"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "original_path",
+    "stored_path",
+    "file_name",
+    "sha256",
+    "size_bytes"
+  ],
+  "title": "ManagedFileReceipt"
+}
+
+
ManagedSource
+{
+  "properties": {
+    "original_path": {
+      "type": "string",
+      "title": "Original Path"
+    },
+    "stored_path": {
+      "type": "string",
+      "title": "Stored Path"
+    },
+    "file_name": {
+      "type": "string",
+      "title": "File Name"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Sha256"
+    },
+    "size_bytes": {
+      "type": "integer",
+      "minimum": 0.0,
+      "title": "Size Bytes"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "original_path",
+    "stored_path",
+    "file_name",
+    "sha256",
+    "size_bytes"
+  ],
+  "title": "ManagedSource"
+}
+
+
Material
+{
+  "properties": {
+    "material_id": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9_-]{1,80}$",
+      "title": "Material Id"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Description"
+    },
+    "citation": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Citation"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "material_id",
+    "description",
+    "citation"
+  ],
+  "title": "Material"
+}
+
+
MaterialReview
+{
+  "properties": {
+    "material_id": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Material Id"
+    },
+    "status": {
+      "type": "string",
+      "enum": [
+        "not_reviewed",
+        "provided",
+        "missing",
+        "unclear"
+      ],
+      "title": "Status",
+      "default": "not_reviewed"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Note",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "material_id"
+  ],
+  "title": "MaterialReview"
+}
+
+
Measurement
+{
+  "properties": {
+    "recorded_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Recorded On"
+    },
+    "value": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "string"
+        }
+      ],
+      "title": "Value"
+    },
+    "evidence": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Evidence"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "recorded_on",
+    "value",
+    "evidence"
+  ],
+  "title": "Measurement"
+}
+
+
MediaAnalysis
+{
+  "properties": {
+    "items": {
+      "items": {
+        "$ref": "#/components/schemas/EvidenceItem"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "minItems": 1,
+      "title": "Items"
+    },
+    "code_links": {
+      "items": {
+        "$ref": "#/components/schemas/CodeLink"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Code Links"
+    },
+    "inspector_supplied_text": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Inspector Supplied Text",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "items"
+  ],
+  "title": "MediaAnalysis"
+}
+
+
MeetingInput
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "scheduled_start": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Scheduled Start"
+    },
+    "location": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Location"
+    },
+    "meeting_type": {
+      "type": "string",
+      "enum": [
+        "regular",
+        "special",
+        "emergency",
+        "closed_session",
+        "executive"
+      ],
+      "title": "Meeting Type",
+      "default": "regular"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "scheduled_start",
+    "location"
+  ],
+  "title": "MeetingInput"
+}
+
+
MeetingLink
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 200,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    },
+    "relation": {
+      "type": "string",
+      "enum": [
+        "hearing",
+        "context",
+        "precedent"
+      ],
+      "title": "Relation"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256",
+    "relation"
+  ],
+  "title": "MeetingLink"
+}
+
+
MeetingSearch
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "MeetingSearch"
+}
+
+
MeetingStageInput
+{
+  "properties": {
+    "to_status": {
+      "type": "string",
+      "enum": [
+        "SCHEDULED",
+        "NOTICED",
+        "PACKET_POSTED",
+        "IN_PROGRESS",
+        "RECESSED",
+        "ADJOURNED",
+        "TRANSCRIPT_READY",
+        "MINUTES_DRAFTED",
+        "MINUTES_POSTED",
+        "MINUTES_ADOPTED",
+        "MINUTES_SIGNED",
+        "ARCHIVED",
+        "CANCELLED"
+      ],
+      "title": "To Status"
+    },
+    "statutory_basis": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Basis"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "to_status"
+  ],
+  "title": "MeetingStageInput"
+}
+
+
MeetingsSearch
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "MeetingsSearch"
+}
+
+
MeetingsSourceSelection
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 200,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "MeetingsSourceSelection"
+}
+
+
MessageCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-message",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/MessagePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "MessageCommand"
+}
+
+
MessageCreate
+{
+  "properties": {
+    "message_text": {
+      "type": "string",
+      "title": "Message Text"
+    },
+    "is_internal": {
+      "type": "boolean",
+      "title": "Is Internal",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "message_text"
+  ],
+  "title": "MessageCreate"
+}
+
+
MessagePayload
+{
+  "properties": {
+    "requestMessageBody": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestmessagebody"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requestMessageBody"
+  ],
+  "title": "MessagePayload"
+}
+
+
MessageRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "sender_type": {
+      "type": "string",
+      "title": "Sender Type"
+    },
+    "sender_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sender Id"
+    },
+    "message_text": {
+      "type": "string",
+      "title": "Message Text"
+    },
+    "is_internal": {
+      "type": "boolean",
+      "title": "Is Internal"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "sender_type",
+    "sender_id",
+    "message_text",
+    "is_internal",
+    "created_at"
+  ],
+  "title": "MessageRead"
+}
+
+
MessageView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "author": {
+      "type": "string",
+      "title": "Author"
+    },
+    "author_role": {
+      "type": "string",
+      "title": "Author Role"
+    },
+    "body": {
+      "type": "string",
+      "title": "Body"
+    },
+    "visibility": {
+      "type": "string",
+      "title": "Visibility"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "author",
+    "author_role",
+    "body",
+    "visibility",
+    "created_at_unix_seconds"
+  ],
+  "title": "MessageView"
+}
+
+
Milestone
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "due_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Due On"
+    },
+    "completed_on": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Completed On"
+    },
+    "evidence": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Evidence",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "due_on"
+  ],
+  "title": "Milestone"
+}
+
+
MinutesDecision
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "post",
+        "adopt",
+        "sign"
+      ],
+      "title": "Action"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "MinutesDecision"
+}
+
+
ModelRegistryCreate
+{
+  "properties": {
+    "model_name": {
+      "type": "string",
+      "title": "Model Name"
+    },
+    "model_version": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Version"
+    },
+    "parameter_count": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parameter Count"
+    },
+    "license": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "License"
+    },
+    "model_card_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Card Url"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active",
+      "default": false
+    },
+    "context_window_size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Context Window Size"
+    },
+    "supports_ner": {
+      "type": "boolean",
+      "title": "Supports Ner",
+      "default": false
+    },
+    "supports_vision": {
+      "type": "boolean",
+      "title": "Supports Vision",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "model_name"
+  ],
+  "title": "ModelRegistryCreate",
+  "description": "Schema for creating a new model_registry record (POST body)."
+}
+
+
ModelRegistryRead
+{
+  "properties": {
+    "id": {
+      "type": "integer",
+      "title": "Id"
+    },
+    "model_name": {
+      "type": "string",
+      "title": "Model Name"
+    },
+    "model_version": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Version"
+    },
+    "parameter_count": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parameter Count"
+    },
+    "license": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "License"
+    },
+    "model_card_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Card Url"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "added_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Added At"
+    },
+    "context_window_size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Context Window Size"
+    },
+    "supports_ner": {
+      "type": "boolean",
+      "title": "Supports Ner"
+    },
+    "supports_vision": {
+      "type": "boolean",
+      "title": "Supports Vision"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "model_name",
+    "is_active",
+    "supports_ner",
+    "supports_vision"
+  ],
+  "title": "ModelRegistryRead",
+  "description": "Schema for returning a model_registry record (GET response).\n\n``from_attributes=True`` allows construction directly from an ORM instance."
+}
+
+
ModelRegistryUpdate
+{
+  "properties": {
+    "model_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Name"
+    },
+    "model_version": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Version"
+    },
+    "parameter_count": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parameter Count"
+    },
+    "license": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "License"
+    },
+    "model_card_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Card Url"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    },
+    "context_window_size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Context Window Size"
+    },
+    "supports_ner": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supports Ner"
+    },
+    "supports_vision": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supports Vision"
+    }
+  },
+  "type": "object",
+  "title": "ModelRegistryUpdate",
+  "description": "Schema for partially updating a model_registry record (PATCH body).\n\nEvery field is optional so callers can send only the fields they want to\nchange."
+}
+
+
MotionCorrection
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "reason": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Reason"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text",
+    "reason"
+  ],
+  "title": "MotionCorrection"
+}
+
+
MotionInput
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "seconded_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "minLength": 1
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Seconded By"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text"
+  ],
+  "title": "MotionInput"
+}
+
+
NativePayload
+{
+  "properties": {},
+  "additionalProperties": false,
+  "type": "object",
+  "title": "NativePayload"
+}
+
+
NativeRequestRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "requester_name": {
+      "type": "string",
+      "title": "Requester Name"
+    },
+    "requester_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Email"
+    },
+    "requester_phone": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Phone"
+    },
+    "requester_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Type"
+    },
+    "date_received": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Date Received"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "status": {
+      "$ref": "#/components/schemas/RequestStatus"
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "created_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "response_draft": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Response Draft"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    },
+    "estimated_fee": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Estimated Fee"
+    },
+    "fee_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Status"
+    },
+    "fee_waiver_requested": {
+      "type": "boolean",
+      "title": "Fee Waiver Requested",
+      "default": false
+    },
+    "priority": {
+      "type": "string",
+      "title": "Priority",
+      "default": "normal"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    },
+    "closed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closed At"
+    },
+    "closure_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closure Reason"
+    },
+    "desktop_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Desktop Id"
+    },
+    "public_tracking_number": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Public Tracking Number"
+    },
+    "submitted_via": {
+      "type": "string",
+      "title": "Submitted Via"
+    },
+    "deadline_label": {
+      "type": "string",
+      "title": "Deadline Label"
+    },
+    "deadline_basis": {
+      "type": "string",
+      "title": "Deadline Basis"
+    },
+    "deadline_reviewed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Deadline Reviewed At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "requester_name",
+    "requester_email",
+    "date_received",
+    "statutory_deadline",
+    "description",
+    "status",
+    "assigned_to",
+    "created_by",
+    "created_at",
+    "response_draft",
+    "review_notes",
+    "desktop_id",
+    "public_tracking_number",
+    "submitted_via",
+    "deadline_label",
+    "deadline_basis",
+    "deadline_reviewed_at"
+  ],
+  "title": "NativeRequestRead"
+}
+
+
NoticeDocumentInput
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text"
+  ],
+  "title": "NoticeDocumentInput"
+}
+
+
NoticeDraft
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 100000,
+      "minLength": 1,
+      "title": "Body"
+    },
+    "notice_type": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Notice Type"
+    },
+    "statutory_basis": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Statutory Basis"
+    },
+    "event_date": {
+      "type": "string",
+      "format": "date",
+      "title": "Event Date"
+    },
+    "lead_days": {
+      "type": "integer",
+      "maximum": 365.0,
+      "minimum": 0.0,
+      "title": "Lead Days"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "body",
+    "notice_type",
+    "statutory_basis",
+    "event_date",
+    "lead_days"
+  ],
+  "title": "NoticeDraft"
+}
+
+
NoticeInput
+{
+  "properties": {
+    "notice_type": {
+      "type": "string",
+      "enum": [
+        "regular",
+        "special",
+        "emergency",
+        "closed_session",
+        "executive"
+      ],
+      "title": "Notice Type"
+    },
+    "posted_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Posted At"
+    },
+    "minimum_notice_hours": {
+      "type": "integer",
+      "minimum": 0.0,
+      "title": "Minimum Notice Hours"
+    },
+    "statutory_basis": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Basis"
+    },
+    "approved_by": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Approved By"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "notice_type",
+    "posted_at",
+    "minimum_notice_hours"
+  ],
+  "title": "NoticeInput"
+}
+
+
NoticeProofInput
+{
+  "properties": {
+    "location": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Location"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note",
+      "default": ""
+    },
+    "document_delivery_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Document Delivery Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "location"
+  ],
+  "title": "NoticeProofInput"
+}
+
+
NotificationLogRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "template_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Template Id"
+    },
+    "recipient_email": {
+      "type": "string",
+      "title": "Recipient Email"
+    },
+    "request_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Request Id"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "sent_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sent At"
+    },
+    "error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Message"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "template_id",
+    "recipient_email",
+    "request_id",
+    "channel",
+    "status",
+    "sent_at",
+    "error_message",
+    "created_at"
+  ],
+  "title": "NotificationLogRead"
+}
+
+
NotificationTemplateCreate
+{
+  "properties": {
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel",
+      "default": "email"
+    },
+    "subject_template": {
+      "type": "string",
+      "title": "Subject Template"
+    },
+    "body_template": {
+      "type": "string",
+      "title": "Body Template"
+    }
+  },
+  "type": "object",
+  "required": [
+    "event_type",
+    "subject_template",
+    "body_template"
+  ],
+  "title": "NotificationTemplateCreate"
+}
+
+
NotificationTemplateRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel"
+    },
+    "subject_template": {
+      "type": "string",
+      "title": "Subject Template"
+    },
+    "body_template": {
+      "type": "string",
+      "title": "Body Template"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "event_type",
+    "channel",
+    "subject_template",
+    "body_template",
+    "is_active",
+    "created_at"
+  ],
+  "title": "NotificationTemplateRead"
+}
+
+
NotificationTemplateUpdate
+{
+  "properties": {
+    "subject_template": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Subject Template"
+    },
+    "body_template": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Body Template"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "NotificationTemplateUpdate"
+}
+
+
NotificationView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "notification_id": {
+      "type": "string",
+      "title": "Notification Id"
+    },
+    "module_id": {
+      "type": "string",
+      "title": "Module Id"
+    },
+    "record_id": {
+      "type": "string",
+      "title": "Record Id"
+    },
+    "audience": {
+      "type": "string",
+      "title": "Audience"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel"
+    },
+    "subject": {
+      "type": "string",
+      "title": "Subject"
+    },
+    "body": {
+      "type": "string",
+      "title": "Body"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    },
+    "sent_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sent At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "notification_id",
+    "module_id",
+    "record_id",
+    "audience",
+    "channel",
+    "subject",
+    "body",
+    "status",
+    "created_at_unix_seconds",
+    "sent_at_unix_seconds"
+  ],
+  "title": "NotificationView"
+}
+
+
OllamaModelInfo
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Size"
+    },
+    "details": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Details"
+    }
+  },
+  "type": "object",
+  "required": [
+    "name"
+  ],
+  "title": "OllamaModelInfo"
+}
+
+
OllamaStatus
+{
+  "properties": {
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "models": {
+      "items": {
+        "$ref": "#/components/schemas/OllamaModelInfo"
+      },
+      "type": "array",
+      "title": "Models"
+    }
+  },
+  "type": "object",
+  "required": [
+    "status",
+    "models"
+  ],
+  "title": "OllamaStatus"
+}
+
+
OperationalMetrics
+{
+  "properties": {
+    "average_response_time_days": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Average Response Time Days"
+    },
+    "median_response_time_days": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Median Response Time Days"
+    },
+    "requests_by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "Requests By Status"
+    },
+    "requests_by_department": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "Requests By Department"
+    },
+    "deadline_compliance_rate": {
+      "type": "number",
+      "title": "Deadline Compliance Rate"
+    },
+    "total_open": {
+      "type": "integer",
+      "title": "Total Open"
+    },
+    "total_closed": {
+      "type": "integer",
+      "title": "Total Closed"
+    },
+    "total_overdue": {
+      "type": "integer",
+      "title": "Total Overdue"
+    },
+    "clarification_frequency": {
+      "type": "number",
+      "title": "Clarification Frequency"
+    },
+    "top_request_topics": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Top Request Topics"
+    }
+  },
+  "type": "object",
+  "required": [
+    "average_response_time_days",
+    "median_response_time_days",
+    "requests_by_status",
+    "requests_by_department",
+    "deadline_compliance_rate",
+    "total_open",
+    "total_closed",
+    "total_overdue",
+    "clarification_frequency",
+    "top_request_topics"
+  ],
+  "title": "OperationalMetrics"
+}
+
+
Outline
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "question_ids": {
+      "items": {
+        "type": "string",
+        "format": "uuid"
+      },
+      "type": "array",
+      "maxItems": 50,
+      "minItems": 1,
+      "title": "Question Ids"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "question_ids"
+  ],
+  "title": "Outline"
+}
+
+
Packet
+{
+  "properties": {
+    "expected_revision": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Expected Revision"
+    },
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "staff_only",
+        "records_copy"
+      ],
+      "title": "Visibility"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "expected_revision",
+    "visibility"
+  ],
+  "title": "Packet"
+}
+
+
PacketInput
+{
+  "properties": {
+    "agenda_item_ids": {
+      "items": {
+        "type": "string",
+        "format": "uuid"
+      },
+      "type": "array",
+      "title": "Agenda Item Ids"
+    },
+    "source_files": {
+      "items": {
+        "$ref": "#/components/schemas/ManagedSource"
+      },
+      "type": "array",
+      "title": "Source Files"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "agenda_item_ids"
+  ],
+  "title": "PacketInput"
+}
+
+
Pathway
+{
+  "properties": {
+    "project_type": {
+      "type": "string",
+      "maxLength": 120,
+      "minLength": 1,
+      "title": "Project Type"
+    },
+    "proposal": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Proposal",
+      "default": ""
+    },
+    "location_context": {
+      "type": "string",
+      "maxLength": 1000,
+      "title": "Location Context",
+      "default": ""
+    },
+    "requirement_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requirement Revision"
+    },
+    "fee_link": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "project_type"
+  ],
+  "title": "Pathway"
+}
+
+
PathwayStep
+{
+  "properties": {
+    "step": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Step"
+    },
+    "citation": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Citation"
+    },
+    "typical_time": {
+      "type": "string",
+      "maxLength": 1000,
+      "title": "Typical Time",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "step",
+    "citation"
+  ],
+  "title": "PathwayStep"
+}
+
+
PlainLanguageSummaryCreate
+{
+  "properties": {
+    "summary_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Summary Id"
+    },
+    "section_version_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Version Id"
+    },
+    "summary_text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Summary Text"
+    },
+    "language_code": {
+      "type": "string",
+      "title": "Language Code",
+      "default": "en"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "section_version_id",
+    "summary_text"
+  ],
+  "title": "PlainLanguageSummaryCreate",
+  "description": "Request body for staff-drafted plain-language summaries."
+}
+
+
PolicySelection
+{
+  "properties": {
+    "plan_id": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Plan Id"
+    },
+    "revision_id": {
+      "type": "string",
+      "maxLength": 36,
+      "minLength": 36,
+      "title": "Revision Id"
+    },
+    "policy_id": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Policy Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "plan_id",
+    "revision_id",
+    "policy_id"
+  ],
+  "title": "PolicySelection"
+}
+
+
PortalModeResponse
+{
+  "properties": {
+    "mode": {
+      "type": "string",
+      "enum": [
+        "public",
+        "private"
+      ],
+      "title": "Mode",
+      "description": "Active portal posture for this deployment. ``public`` = minimal resident surface (landing + authenticated records-request submission + resident registration) reachable without staff auth. ``private`` = staff-only; no public routes, no resident self-registration."
+    }
+  },
+  "type": "object",
+  "required": [
+    "mode"
+  ],
+  "title": "PortalModeResponse",
+  "description": "T5D — schema for ``GET /config/portal-mode``.\n\nExposed to the frontend on boot so it can branch routing without a\nuser-identity lookup. The payload is intentionally the single field\nbelow — no staff config, no user state, no schema version."
+}
+
+
PrepareArtifact
+{
+  "properties": {
+    "kind": {
+      "type": "string",
+      "enum": [
+        "response",
+        "release-package"
+      ],
+      "title": "Kind"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "kind"
+  ],
+  "title": "PrepareArtifact"
+}
+
+
Proof
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    },
+    "filename": {
+      "type": "string",
+      "maxLength": 150,
+      "minLength": 1,
+      "title": "Filename"
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 7000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "location": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Location"
+    },
+    "published_at": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Published At"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence",
+    "filename",
+    "content_base64",
+    "location",
+    "published_at"
+  ],
+  "title": "Proof"
+}
+
+
Proposal
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "pattern": "^[A-Za-z0-9_-]{1,64}$",
+      "title": "Id"
+    },
+    "version_id": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Version Id"
+    },
+    "meeting_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Meeting Id"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "ordinance_number": {
+      "type": "string",
+      "maxLength": 120,
+      "minLength": 1,
+      "title": "Ordinance Number"
+    },
+    "proposed_text": {
+      "type": "string",
+      "maxLength": 1000000,
+      "minLength": 1,
+      "title": "Proposed Text"
+    },
+    "supersedes_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^[A-Za-z0-9_-]{1,64}$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supersedes Id"
+    },
+    "reconciliation_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reconciliation Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "version_id",
+    "meeting_id",
+    "title",
+    "ordinance_number",
+    "proposed_text"
+  ],
+  "title": "Proposal"
+}
+
+
PublicExplore
+{
+  "properties": {
+    "goal": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Goal",
+      "default": ""
+    },
+    "topic": {
+      "type": "string",
+      "maxLength": 160,
+      "title": "Topic",
+      "default": ""
+    },
+    "neighborhood": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Neighborhood",
+      "default": ""
+    },
+    "plan_type": {
+      "type": "string",
+      "maxLength": 120,
+      "title": "Plan Type",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "PublicExplore"
+}
+
+
PublicIntake
+{
+  "properties": {
+    "requester": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requester"
+    },
+    "requesterContact": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestercontact"
+    },
+    "summary": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Summary"
+    },
+    "deadline": {
+      "type": "string",
+      "title": "Deadline",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requester",
+    "requesterContact",
+    "summary"
+  ],
+  "title": "PublicIntake"
+}
+
+
PublicLookup
+{
+  "properties": {
+    "trackingNumber": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Trackingnumber"
+    },
+    "requesterContact": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestercontact"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "trackingNumber",
+    "requesterContact"
+  ],
+  "title": "PublicLookup"
+}
+
+
PublicMessage
+{
+  "properties": {
+    "trackingNumber": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Trackingnumber"
+    },
+    "requesterContact": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestercontact"
+    },
+    "publicRequestMessage": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Publicrequestmessage"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "trackingNumber",
+    "requesterContact",
+    "publicRequestMessage"
+  ],
+  "title": "PublicMessage"
+}
+
+
PublicStatusView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "label": {
+      "type": "string",
+      "title": "Label"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "label",
+    "summary",
+    "status",
+    "created_at_unix_seconds"
+  ],
+  "title": "PublicStatusView"
+}
+
+
PublicationView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "source_module": {
+      "type": "string",
+      "title": "Source Module"
+    },
+    "source_record_id": {
+      "type": "string",
+      "title": "Source Record Id"
+    },
+    "record_type": {
+      "type": "string",
+      "title": "Record Type"
+    },
+    "public_payload": {
+      "type": "string",
+      "title": "Public Payload"
+    },
+    "payload_hash": {
+      "type": "string",
+      "title": "Payload Hash"
+    },
+    "published_at_unix_seconds": {
+      "type": "integer",
+      "title": "Published At Unix Seconds"
+    },
+    "retracted_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Retracted At Unix Seconds"
+    },
+    "retracted_by": {
+      "type": "string",
+      "title": "Retracted By",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "source_module",
+    "source_record_id",
+    "record_type",
+    "public_payload",
+    "payload_hash",
+    "published_at_unix_seconds"
+  ],
+  "title": "PublicationView"
+}
+
+
PublishingPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "publishing-workflow",
+      "title": "Action"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "hasReview": {
+      "type": "boolean",
+      "title": "Hasreview",
+      "default": false
+    },
+    "hasPlainLanguage": {
+      "type": "boolean",
+      "title": "Hasplainlanguage",
+      "default": false
+    },
+    "hasTranslationReview": {
+      "type": "boolean",
+      "title": "Hastranslationreview",
+      "default": false
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "PublishingPlan"
+}
+
+
Question
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    },
+    "question": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Question"
+    },
+    "kind": {
+      "type": "string",
+      "enum": [
+        "use",
+        "dimension"
+      ],
+      "title": "Kind"
+    },
+    "key": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Key"
+    },
+    "audience": {
+      "type": "string",
+      "enum": [
+        "resident",
+        "staff"
+      ],
+      "title": "Audience",
+      "default": "resident"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "query",
+    "question",
+    "kind",
+    "key"
+  ],
+  "title": "Question"
+}
+
+
QuestionAnswerRequest
+{
+  "properties": {
+    "question": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Question"
+    },
+    "section_number": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Section Number"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "question"
+  ],
+  "title": "QuestionAnswerRequest",
+  "description": "Request body for citation-grounded code Q&A."
+}
+
+
RecordsDocumentView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "attachment_id": {
+      "type": "string",
+      "title": "Attachment Id"
+    },
+    "title": {
+      "type": "string",
+      "title": "Title"
+    },
+    "original_path": {
+      "type": "string",
+      "title": "Original Path"
+    },
+    "stored_path": {
+      "type": "string",
+      "title": "Stored Path"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation"
+    },
+    "sha256": {
+      "type": "string",
+      "title": "Sha256"
+    },
+    "size_bytes": {
+      "type": "integer",
+      "title": "Size Bytes"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "added_by": {
+      "type": "string",
+      "title": "Added By"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    },
+    "release_original_path": {
+      "type": "string",
+      "title": "Release Original Path",
+      "default": ""
+    },
+    "release_stored_path": {
+      "type": "string",
+      "title": "Release Stored Path",
+      "default": ""
+    },
+    "release_file_name": {
+      "type": "string",
+      "title": "Release File Name",
+      "default": ""
+    },
+    "release_sha256": {
+      "type": "string",
+      "title": "Release Sha256",
+      "default": ""
+    },
+    "release_size_bytes": {
+      "type": "integer",
+      "title": "Release Size Bytes",
+      "default": 0
+    },
+    "release_status": {
+      "type": "string",
+      "title": "Release Status",
+      "default": ""
+    },
+    "release_note": {
+      "type": "string",
+      "title": "Release Note",
+      "default": ""
+    },
+    "release_added_by": {
+      "type": "string",
+      "title": "Release Added By",
+      "default": ""
+    },
+    "release_added_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Release Added At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "attachment_id",
+    "title",
+    "original_path",
+    "stored_path",
+    "citation",
+    "sha256",
+    "size_bytes",
+    "status",
+    "added_by",
+    "created_at_unix_seconds"
+  ],
+  "title": "RecordsDocumentView"
+}
+
+
RecordsOperationRead
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "message": {
+      "type": "string",
+      "title": "Message"
+    },
+    "request": {
+      "$ref": "#/components/schemas/RecordsView"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "message",
+    "request"
+  ],
+  "title": "RecordsOperationRead"
+}
+
+
RecordsStateRead
+{
+  "properties": {
+    "demo_fixture": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Demo Fixture"
+    },
+    "records_requests": {
+      "items": {
+        "$ref": "#/components/schemas/RecordsView"
+      },
+      "type": "array",
+      "title": "Records Requests"
+    },
+    "notification_events": {
+      "items": {
+        "$ref": "#/components/schemas/NotificationView"
+      },
+      "type": "array",
+      "title": "Notification Events"
+    },
+    "publication_events": {
+      "items": {
+        "$ref": "#/components/schemas/PublicationView"
+      },
+      "type": "array",
+      "title": "Publication Events"
+    },
+    "audit_entries": {
+      "items": {
+        "$ref": "#/components/schemas/AuditView"
+      },
+      "type": "array",
+      "title": "Audit Entries"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "records_requests"
+  ],
+  "title": "RecordsStateRead"
+}
+
+
RecordsView
+{
+  "properties": {
+    "request_id": {
+      "type": "string",
+      "title": "Request Id"
+    },
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "public_tracking_number": {
+      "type": "string",
+      "title": "Public Tracking Number"
+    },
+    "requester": {
+      "type": "string",
+      "title": "Requester"
+    },
+    "requester_contact": {
+      "type": "string",
+      "title": "Requester Contact"
+    },
+    "submitted_via": {
+      "type": "string",
+      "title": "Submitted Via"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "deadline": {
+      "type": "string",
+      "title": "Deadline"
+    },
+    "deadline_basis": {
+      "type": "string",
+      "title": "Deadline Basis"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "assigned_to": {
+      "type": "string",
+      "title": "Assigned To"
+    },
+    "clarification_notes": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Clarification Notes"
+    },
+    "search_notes": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Search Notes"
+    },
+    "search_sessions": {
+      "items": {
+        "$ref": "#/components/schemas/SearchReceiptView"
+      },
+      "type": "array",
+      "title": "Search Sessions"
+    },
+    "exemption_reviews": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Exemption Reviews"
+    },
+    "exemption_decisions": {
+      "items": {
+        "$ref": "#/components/schemas/ExemptionDecisionView"
+      },
+      "type": "array",
+      "title": "Exemption Decisions"
+    },
+    "fee_estimate": {
+      "type": "string",
+      "title": "Fee Estimate"
+    },
+    "fee_line_items": {
+      "items": {
+        "$ref": "#/components/schemas/FeeLineView"
+      },
+      "type": "array",
+      "title": "Fee Line Items"
+    },
+    "fee_waiver_reason": {
+      "type": "string",
+      "title": "Fee Waiver Reason"
+    },
+    "citations": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Citations"
+    },
+    "response_draft": {
+      "type": "string",
+      "title": "Response Draft"
+    },
+    "approval_notes": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Approval Notes"
+    },
+    "exports": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Exports"
+    },
+    "documents": {
+      "items": {
+        "$ref": "#/components/schemas/RecordsDocumentView"
+      },
+      "type": "array",
+      "title": "Documents"
+    },
+    "release_packages": {
+      "items": {
+        "$ref": "#/components/schemas/ReleasePackageView"
+      },
+      "type": "array",
+      "title": "Release Packages"
+    },
+    "timeline": {
+      "items": {
+        "$ref": "#/components/schemas/TimelineView"
+      },
+      "type": "array",
+      "title": "Timeline"
+    },
+    "public_status_events": {
+      "items": {
+        "$ref": "#/components/schemas/PublicStatusView"
+      },
+      "type": "array",
+      "title": "Public Status Events"
+    },
+    "messages": {
+      "items": {
+        "$ref": "#/components/schemas/MessageView"
+      },
+      "type": "array",
+      "title": "Messages"
+    },
+    "deadline_reviewed_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Deadline Reviewed At Unix Seconds"
+    },
+    "approved_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Approved At Unix Seconds"
+    },
+    "fulfilled_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fulfilled At Unix Seconds"
+    },
+    "closed_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closed At Unix Seconds"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "request_id",
+    "id",
+    "public_tracking_number",
+    "requester",
+    "requester_contact",
+    "submitted_via",
+    "summary",
+    "deadline",
+    "deadline_basis",
+    "status",
+    "assigned_to",
+    "clarification_notes",
+    "search_notes",
+    "search_sessions",
+    "exemption_reviews",
+    "exemption_decisions",
+    "fee_estimate",
+    "fee_line_items",
+    "fee_waiver_reason",
+    "citations",
+    "response_draft",
+    "approval_notes",
+    "exports",
+    "timeline",
+    "public_status_events",
+    "messages",
+    "deadline_reviewed_at_unix_seconds",
+    "approved_at_unix_seconds",
+    "fulfilled_at_unix_seconds",
+    "closed_at_unix_seconds",
+    "created_at_unix_seconds"
+  ],
+  "title": "RecordsView"
+}
+
+
ReleasePackageView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "export_path": {
+      "type": "string",
+      "title": "Export Path"
+    },
+    "package_hash": {
+      "type": "string",
+      "title": "Package Hash"
+    },
+    "document_count": {
+      "type": "integer",
+      "title": "Document Count"
+    },
+    "release_artifact_count": {
+      "type": "integer",
+      "title": "Release Artifact Count"
+    },
+    "search_session_count": {
+      "type": "integer",
+      "title": "Search Session Count"
+    },
+    "release_count": {
+      "type": "integer",
+      "title": "Release Count"
+    },
+    "redacted_count": {
+      "type": "integer",
+      "title": "Redacted Count"
+    },
+    "exempt_count": {
+      "type": "integer",
+      "title": "Exempt Count"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "export_path",
+    "package_hash",
+    "document_count",
+    "release_artifact_count",
+    "search_session_count",
+    "release_count",
+    "redacted_count",
+    "exempt_count",
+    "created_at_unix_seconds"
+  ],
+  "title": "ReleasePackageView"
+}
+
+
RepeatLookup
+{
+  "properties": {
+    "property_reference": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Property Reference"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "property_reference"
+  ],
+  "title": "RepeatLookup"
+}
+
+
RequestCreate
+{
+  "properties": {
+    "requester_name": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Requester Name"
+    },
+    "requester_email": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 255
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Email"
+    },
+    "requester_phone": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 50
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Phone"
+    },
+    "requester_type": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 100
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Type"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Description"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "priority": {
+      "type": "string",
+      "title": "Priority",
+      "default": "normal"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^(narrow|moderate|broad)$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "requester_name",
+    "description"
+  ],
+  "title": "RequestCreate"
+}
+
+
RequestDocumentAdd
+{
+  "properties": {
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "relevance_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Relevance Note"
+    }
+  },
+  "type": "object",
+  "required": [
+    "document_id"
+  ],
+  "title": "RequestDocumentAdd"
+}
+
+
RequestDocumentRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "relevance_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Relevance Note"
+    },
+    "exemption_flags": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Exemption Flags"
+    },
+    "inclusion_status": {
+      "$ref": "#/components/schemas/InclusionStatus"
+    },
+    "attached_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Attached At"
+    },
+    "attached_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Attached By"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "document_id",
+    "relevance_note",
+    "exemption_flags",
+    "inclusion_status",
+    "attached_at",
+    "attached_by"
+  ],
+  "title": "RequestDocumentRead"
+}
+
+
RequestRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "requester_name": {
+      "type": "string",
+      "title": "Requester Name"
+    },
+    "requester_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Email"
+    },
+    "requester_phone": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Phone"
+    },
+    "requester_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Type"
+    },
+    "date_received": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Date Received"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "status": {
+      "$ref": "#/components/schemas/RequestStatus"
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "created_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "response_draft": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Response Draft"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    },
+    "estimated_fee": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Estimated Fee"
+    },
+    "fee_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Status"
+    },
+    "fee_waiver_requested": {
+      "type": "boolean",
+      "title": "Fee Waiver Requested",
+      "default": false
+    },
+    "priority": {
+      "type": "string",
+      "title": "Priority",
+      "default": "normal"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    },
+    "closed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closed At"
+    },
+    "closure_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closure Reason"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "requester_name",
+    "requester_email",
+    "date_received",
+    "statutory_deadline",
+    "description",
+    "status",
+    "assigned_to",
+    "created_by",
+    "created_at",
+    "response_draft",
+    "review_notes"
+  ],
+  "title": "RequestRead"
+}
+
+
RequestStats
+{
+  "properties": {
+    "total_requests": {
+      "type": "integer",
+      "title": "Total Requests"
+    },
+    "by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "By Status"
+    },
+    "approaching_deadline": {
+      "type": "integer",
+      "title": "Approaching Deadline"
+    },
+    "overdue": {
+      "type": "integer",
+      "title": "Overdue"
+    }
+  },
+  "type": "object",
+  "required": [
+    "total_requests",
+    "by_status",
+    "approaching_deadline",
+    "overdue"
+  ],
+  "title": "RequestStats"
+}
+
+
RequestStatus
+{
+  "type": "string",
+  "enum": [
+    "received",
+    "clarification_needed",
+    "assigned",
+    "searching",
+    "in_review",
+    "ready_for_release",
+    "drafted",
+    "approved",
+    "fulfilled",
+    "closed"
+  ],
+  "title": "RequestStatus"
+}
+
+
RequestUpdate
+{
+  "properties": {
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/RequestStatus"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "response_draft": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Response Draft"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    }
+  },
+  "type": "object",
+  "title": "RequestUpdate"
+}
+
+
RequirementBundle
+{
+  "properties": {
+    "requirement_id": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9_-]{1,100}$",
+      "title": "Requirement Id"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "project_type": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Project Type"
+    },
+    "source_reference": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Source Reference"
+    },
+    "source_date": {
+      "type": "string",
+      "format": "date",
+      "title": "Source Date"
+    },
+    "effective_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Effective On"
+    },
+    "dataset_kind": {
+      "type": "string",
+      "enum": [
+        "municipal",
+        "fictional"
+      ],
+      "title": "Dataset Kind"
+    },
+    "filename": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$",
+      "title": "Filename"
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 14000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Sha256"
+    },
+    "materials": {
+      "items": {
+        "$ref": "#/components/schemas/Material"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "minItems": 1,
+      "title": "Materials"
+    },
+    "pathway": {
+      "items": {
+        "$ref": "#/components/schemas/PathwayStep"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "title": "Pathway"
+    },
+    "fee_link": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    },
+    "staff_note": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Staff Note",
+      "default": ""
+    },
+    "change_note": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Change Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requirement_id",
+    "title",
+    "jurisdiction",
+    "project_type",
+    "source_reference",
+    "source_date",
+    "effective_on",
+    "dataset_kind",
+    "filename",
+    "content_base64",
+    "sha256",
+    "materials",
+    "change_note"
+  ],
+  "title": "RequirementBundle"
+}
+
+
ResponseLetterCreate
+{
+  "properties": {
+    "template_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Template Id"
+    }
+  },
+  "type": "object",
+  "title": "ResponseLetterCreate"
+}
+
+
ResponseLetterRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "template_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Template Id"
+    },
+    "generated_content": {
+      "type": "string",
+      "title": "Generated Content"
+    },
+    "edited_content": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Edited Content"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "generated_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Generated By"
+    },
+    "approved_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Approved By"
+    },
+    "sent_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sent At"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "template_id",
+    "generated_content",
+    "edited_content",
+    "status",
+    "generated_by",
+    "approved_by",
+    "sent_at",
+    "created_at"
+  ],
+  "title": "ResponseLetterRead"
+}
+
+
ResponseLetterUpdate
+{
+  "properties": {
+    "edited_content": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Edited Content"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Status"
+    }
+  },
+  "type": "object",
+  "title": "ResponseLetterUpdate"
+}
+
+
ReviewInput
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 5000,
+      "title": "Body",
+      "default": ""
+    },
+    "hasAltText": {
+      "type": "boolean",
+      "title": "Hasalttext",
+      "default": false
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": "en"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "ReviewInput"
+}
+
+
Revision
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    },
+    "document": {
+      "$ref": "#/components/schemas/NoticeDraft"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence",
+    "document"
+  ],
+  "title": "Revision"
+}
+
+
RewriteInput
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "plain-language",
+        "language-variant"
+      ],
+      "title": "Action"
+    },
+    "text": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Text"
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "text"
+  ],
+  "title": "RewriteInput"
+}
+
+
RewriteResult
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "plain-language",
+        "language-variant"
+      ],
+      "title": "Action"
+    },
+    "text": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Text"
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": ""
+    },
+    "outcome": {
+      "type": "string",
+      "enum": [
+        "generated",
+        "unavailable"
+      ],
+      "title": "Outcome"
+    },
+    "generated": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 100000
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Generated"
+    },
+    "model": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 200
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "text",
+    "outcome"
+  ],
+  "title": "RewriteResult"
+}
+
+
Rule
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "zone_code": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Zone Code"
+    },
+    "key": {
+      "type": "string",
+      "maxLength": 120,
+      "minLength": 1,
+      "title": "Key"
+    },
+    "section_number": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Section Number"
+    },
+    "kind": {
+      "type": "string",
+      "enum": [
+        "use",
+        "dimension"
+      ],
+      "title": "Kind"
+    },
+    "value": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Value"
+    },
+    "overlay_code": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 255
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Overlay Code"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "zone_code",
+    "key",
+    "section_number",
+    "kind",
+    "value"
+  ],
+  "title": "Rule"
+}
+
+
RuleTestMatch
+{
+  "properties": {
+    "matched_text": {
+      "type": "string",
+      "title": "Matched Text"
+    },
+    "start": {
+      "type": "integer",
+      "title": "Start"
+    },
+    "end": {
+      "type": "integer",
+      "title": "End"
+    }
+  },
+  "type": "object",
+  "required": [
+    "matched_text",
+    "start",
+    "end"
+  ],
+  "title": "RuleTestMatch"
+}
+
+
RuleTestRequest
+{
+  "properties": {
+    "sample_text": {
+      "type": "string",
+      "title": "Sample Text"
+    }
+  },
+  "type": "object",
+  "required": [
+    "sample_text"
+  ],
+  "title": "RuleTestRequest"
+}
+
+
RuleTestResponse
+{
+  "properties": {
+    "rule_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Rule Id"
+    },
+    "rule_type": {
+      "type": "string",
+      "title": "Rule Type"
+    },
+    "matched": {
+      "type": "boolean",
+      "title": "Matched"
+    },
+    "matches": {
+      "items": {
+        "$ref": "#/components/schemas/RuleTestMatch"
+      },
+      "type": "array",
+      "title": "Matches"
+    }
+  },
+  "type": "object",
+  "required": [
+    "rule_id",
+    "rule_type",
+    "matched",
+    "matches"
+  ],
+  "title": "RuleTestResponse"
+}
+
+
RuleType
+{
+  "type": "string",
+  "enum": [
+    "regex",
+    "keyword",
+    "llm_prompt"
+  ],
+  "title": "RuleType"
+}
+
+
SaveReview
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 5000,
+      "title": "Body",
+      "default": ""
+    },
+    "hasAltText": {
+      "type": "boolean",
+      "title": "Hasalttext",
+      "default": false
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": "en"
+    },
+    "ai_analysis": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 100000
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ai Analysis"
+    },
+    "ai_analysis_model": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 200
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ai Analysis Model"
+    },
+    "ai_outcome": {
+      "type": "string",
+      "enum": [
+        "generated",
+        "unavailable",
+        "failed"
+      ],
+      "title": "Ai Outcome"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "ai_outcome"
+  ],
+  "title": "SaveReview"
+}
+
+
SearchFilterOptions
+{
+  "properties": {
+    "file_types": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "File Types"
+    },
+    "source_names": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Source Names"
+    },
+    "departments": {
+      "items": {
+        "additionalProperties": true,
+        "type": "object"
+      },
+      "type": "array",
+      "title": "Departments",
+      "default": []
+    },
+    "date_range": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Date Range"
+    }
+  },
+  "type": "object",
+  "required": [
+    "file_types",
+    "source_names"
+  ],
+  "title": "SearchFilterOptions"
+}
+
+
SearchInput
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "SearchInput"
+}
+
+
SearchNoteCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "record-records-search",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/SearchNotePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "SearchNoteCommand"
+}
+
+
SearchNotePayload
+{
+  "properties": {
+    "sourceNote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Sourcenote"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sourceNote"
+  ],
+  "title": "SearchNotePayload"
+}
+
+
SearchReceiptCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "record-records-search-session",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/SearchReceiptPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "SearchReceiptCommand"
+}
+
+
SearchReceiptPayload
+{
+  "properties": {
+    "searchQuery": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchquery"
+    },
+    "searchLocations": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchlocations"
+    },
+    "searchResultTitle": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchresulttitle"
+    },
+    "searchResultCitation": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchresultcitation"
+    },
+    "searchResultSummary": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchresultsummary"
+    },
+    "searchResultStatus": {
+      "type": "string",
+      "title": "Searchresultstatus",
+      "default": ""
+    },
+    "searchReviewer": {
+      "type": "string",
+      "title": "Searchreviewer",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "searchQuery",
+    "searchLocations",
+    "searchResultTitle",
+    "searchResultCitation",
+    "searchResultSummary"
+  ],
+  "title": "SearchReceiptPayload"
+}
+
+
SearchReceiptView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "query": {
+      "type": "string",
+      "title": "Query"
+    },
+    "locations": {
+      "type": "string",
+      "title": "Locations"
+    },
+    "reviewer": {
+      "type": "string",
+      "title": "Reviewer"
+    },
+    "results": {
+      "items": {
+        "$ref": "#/components/schemas/SearchResultView"
+      },
+      "type": "array",
+      "title": "Results"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "query",
+    "locations",
+    "reviewer",
+    "results",
+    "created_at_unix_seconds"
+  ],
+  "title": "SearchReceiptView"
+}
+
+
SearchRequest
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "title": "Query"
+    },
+    "session_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Session Id"
+    },
+    "filters": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Filters"
+    },
+    "limit": {
+      "type": "integer",
+      "maximum": 50.0,
+      "title": "Limit",
+      "default": 10
+    },
+    "synthesize": {
+      "type": "boolean",
+      "title": "Synthesize",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "SearchRequest"
+}
+
+
SearchResponse
+{
+  "properties": {
+    "query_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Query Id"
+    },
+    "session_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Session Id"
+    },
+    "query_text": {
+      "type": "string",
+      "title": "Query Text"
+    },
+    "results": {
+      "items": {
+        "$ref": "#/components/schemas/SearchResultItem"
+      },
+      "type": "array",
+      "title": "Results"
+    },
+    "results_count": {
+      "type": "integer",
+      "title": "Results Count"
+    },
+    "synthesized_answer": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Synthesized Answer"
+    },
+    "ai_generated": {
+      "type": "boolean",
+      "title": "Ai Generated",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "query_id",
+    "session_id",
+    "query_text",
+    "results",
+    "results_count"
+  ],
+  "title": "SearchResponse"
+}
+
+
SearchResultItem
+{
+  "properties": {
+    "chunk_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Chunk Id"
+    },
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "filename": {
+      "type": "string",
+      "title": "Filename"
+    },
+    "file_type": {
+      "type": "string",
+      "title": "File Type"
+    },
+    "source_path": {
+      "type": "string",
+      "title": "Source Path"
+    },
+    "page_number": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Page Number"
+    },
+    "content_text": {
+      "type": "string",
+      "title": "Content Text"
+    },
+    "similarity_score": {
+      "type": "number",
+      "title": "Similarity Score"
+    },
+    "rank": {
+      "type": "integer",
+      "title": "Rank"
+    }
+  },
+  "type": "object",
+  "required": [
+    "chunk_id",
+    "document_id",
+    "filename",
+    "file_type",
+    "source_path",
+    "page_number",
+    "content_text",
+    "similarity_score",
+    "rank"
+  ],
+  "title": "SearchResultItem"
+}
+
+
SearchResultView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "title": {
+      "type": "string",
+      "title": "Title"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "title",
+    "citation",
+    "summary",
+    "status"
+  ],
+  "title": "SearchResultView"
+}
+
+
SearchSessionRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "user_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "User Id"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "queries": {
+      "items": {
+        "additionalProperties": true,
+        "type": "object"
+      },
+      "type": "array",
+      "title": "Queries",
+      "default": []
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "user_id",
+    "created_at"
+  ],
+  "title": "SearchSessionRead"
+}
+
+
SectionCreate
+{
+  "properties": {
+    "section_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Section Id"
+    },
+    "chapter_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Chapter Id"
+    },
+    "section_number": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Number"
+    },
+    "section_heading": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Heading"
+    },
+    "parent_section_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parent Section Id"
+    },
+    "sort_order": {
+      "type": "integer",
+      "title": "Sort Order",
+      "default": 0
+    },
+    "administrative_regulation_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Administrative Regulation Refs"
+    },
+    "resolution_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Resolution Refs"
+    },
+    "policy_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Policy Refs"
+    },
+    "approved_summary_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Approved Summary Refs"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "chapter_id",
+    "section_number",
+    "section_heading"
+  ],
+  "title": "SectionCreate",
+  "description": "Request body for creating a code section or subsection."
+}
+
+
SectionVersionCreate
+{
+  "properties": {
+    "version_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Version Id"
+    },
+    "section_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Id"
+    },
+    "source_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "version_label": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Version Label"
+    },
+    "body": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Body"
+    },
+    "effective_start": {
+      "type": "string",
+      "format": "date",
+      "title": "Effective Start"
+    },
+    "effective_end": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective End"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    },
+    "is_current": {
+      "type": "boolean",
+      "title": "Is Current",
+      "default": false
+    },
+    "adoption_event_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Adoption Event Id"
+    },
+    "amendment_event_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Amendment Event Id"
+    },
+    "amendment_summary": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Amendment Summary"
+    },
+    "prior_version_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Prior Version Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "section_id",
+    "source_id",
+    "version_label",
+    "body",
+    "effective_start"
+  ],
+  "title": "SectionVersionCreate",
+  "description": "Request body for adding an immutable section version."
+}
+
+
Selection
+{
+  "properties": {
+    "recording_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Recording Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "recording_id",
+    "expected_sha256"
+  ],
+  "title": "Selection"
+}
+
+
SentenceInput
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "citations": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Citations"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text"
+  ],
+  "title": "SentenceInput"
+}
+
+
ServiceAccountCreate
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole",
+      "default": "read_only"
+    }
+  },
+  "type": "object",
+  "required": [
+    "name"
+  ],
+  "title": "ServiceAccountCreate"
+}
+
+
ServiceAccountCreated
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "api_key": {
+      "type": "string",
+      "title": "Api Key"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "role",
+    "created_by",
+    "created_at",
+    "is_active",
+    "api_key"
+  ],
+  "title": "ServiceAccountCreated",
+  "description": "Returned only on creation — includes the plaintext API key (shown once)."
+}
+
+
ServiceAccountRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "role",
+    "created_by",
+    "created_at",
+    "is_active"
+  ],
+  "title": "ServiceAccountRead"
+}
+
+
ServiceAccountUpdate
+{
+  "properties": {
+    "role": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/UserRole"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "ServiceAccountUpdate"
+}
+
+
Snapshot
+{
+  "properties": {
+    "expected_revision": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Expected Revision"
+    },
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "staff_only",
+        "public"
+      ],
+      "title": "Visibility"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "expected_revision",
+    "visibility"
+  ],
+  "title": "Snapshot"
+}
+
+
SourceCreate
+{
+  "properties": {
+    "source_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Id"
+    },
+    "name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Name"
+    },
+    "publisher": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Publisher"
+    },
+    "source_type": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Type"
+    },
+    "source_category": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Category"
+    },
+    "source_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Url"
+    },
+    "file_reference": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "File Reference"
+    },
+    "retrieved_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Retrieved At"
+    },
+    "retrieval_method": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Retrieval Method"
+    },
+    "checksum": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Checksum"
+    },
+    "source_owner": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Owner"
+    },
+    "is_official": {
+      "type": "boolean",
+      "title": "Is Official",
+      "default": true
+    },
+    "official_status_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Official Status Note"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    },
+    "staff_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Staff Notes"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "name",
+    "publisher",
+    "source_type",
+    "source_category"
+  ],
+  "title": "SourceCreate",
+  "description": "Request body for registering an official or explicitly labeled source."
+}
+
+
SourceInput
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "label": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Label"
+    },
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "label",
+    "text"
+  ],
+  "title": "SourceInput"
+}
+
+
SourceSnapshot
+{
+  "properties": {
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "public",
+        "staff_only"
+      ],
+      "title": "Visibility"
+    },
+    "meeting_event_ids": {
+      "items": {
+        "type": "string",
+        "format": "uuid"
+      },
+      "type": "array",
+      "maxItems": 50,
+      "title": "Meeting Event Ids"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "visibility"
+  ],
+  "title": "SourceSnapshot"
+}
+
+
SourceType
+{
+  "type": "string",
+  "enum": [
+    "manual_drop",
+    "file_system",
+    "rest_api",
+    "odbc"
+  ],
+  "title": "SourceType"
+}
+
+
StaffRecordsIntake
+{
+  "properties": {
+    "requester": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requester"
+    },
+    "summary": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Summary"
+    },
+    "deadline": {
+      "type": "string",
+      "title": "Deadline"
+    },
+    "deadlineBasis": {
+      "type": "string",
+      "title": "Deadlinebasis",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requester",
+    "summary",
+    "deadline"
+  ],
+  "title": "StaffRecordsIntake",
+  "description": "Existing native create-records-request input; no caller-supplied actor."
+}
+
+
StandardsExplanation
+{
+  "properties": {
+    "question": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Question"
+    },
+    "process_section": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Process Section",
+      "default": ""
+    },
+    "zone_code": {
+      "type": "string",
+      "maxLength": 40,
+      "title": "Zone Code",
+      "default": ""
+    },
+    "rule_types": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "title": "Rule Types"
+    },
+    "observed": {
+      "additionalProperties": {
+        "type": "string"
+      },
+      "type": "object",
+      "title": "Observed"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "question"
+  ],
+  "title": "StandardsExplanation"
+}
+
+
SyncFailureRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "source_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Source Id"
+    },
+    "source_path": {
+      "type": "string",
+      "title": "Source Path"
+    },
+    "error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Message"
+    },
+    "error_class": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Class"
+    },
+    "http_status_code": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Http Status Code"
+    },
+    "retry_count": {
+      "type": "integer",
+      "title": "Retry Count"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "first_failed_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "First Failed At"
+    },
+    "last_retried_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Retried At"
+    },
+    "dismissed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Dismissed At"
+    },
+    "dismissed_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Dismissed By"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "source_id",
+    "source_path",
+    "error_message",
+    "error_class",
+    "http_status_code",
+    "retry_count",
+    "status",
+    "first_failed_at",
+    "last_retried_at",
+    "dismissed_at",
+    "dismissed_by"
+  ],
+  "title": "SyncFailureRead"
+}
+
+
SyncRunLogRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "source_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Source Id"
+    },
+    "started_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Started At"
+    },
+    "finished_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Finished At"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Status"
+    },
+    "records_attempted": {
+      "type": "integer",
+      "title": "Records Attempted"
+    },
+    "records_succeeded": {
+      "type": "integer",
+      "title": "Records Succeeded"
+    },
+    "records_failed": {
+      "type": "integer",
+      "title": "Records Failed"
+    },
+    "error_summary": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Summary"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "source_id",
+    "started_at",
+    "finished_at",
+    "status",
+    "records_attempted",
+    "records_succeeded",
+    "records_failed",
+    "error_summary"
+  ],
+  "title": "SyncRunLogRead"
+}
+
+
SystemStatus
+{
+  "properties": {
+    "version": {
+      "type": "string",
+      "title": "Version"
+    },
+    "database": {
+      "type": "string",
+      "title": "Database"
+    },
+    "ollama": {
+      "type": "string",
+      "title": "Ollama"
+    },
+    "redis": {
+      "type": "string",
+      "title": "Redis"
+    },
+    "user_count": {
+      "type": "integer",
+      "title": "User Count"
+    },
+    "audit_log_count": {
+      "type": "integer",
+      "title": "Audit Log Count"
+    },
+    "suite_session": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Suite Session"
+    }
+  },
+  "type": "object",
+  "required": [
+    "version",
+    "database",
+    "ollama",
+    "redis",
+    "user_count",
+    "audit_log_count"
+  ],
+  "title": "SystemStatus"
+}
+
+
TaggedPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "tagged-pdf",
+      "title": "Action"
+    },
+    "headingLevels": {
+      "items": {
+        "type": "integer",
+        "maximum": 4294967295.0,
+        "minimum": 0.0
+      },
+      "type": "array",
+      "maxItems": 50,
+      "title": "Headinglevels"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "TaggedPlan"
+}
+
+
TestConnectionRequest
+{
+  "properties": {
+    "source_type": {
+      "type": "string",
+      "title": "Source Type"
+    },
+    "host": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Host"
+    },
+    "port": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Port"
+    },
+    "path": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Path"
+    },
+    "username": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Username"
+    },
+    "password": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Password"
+    },
+    "rest_api_config": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Rest Api Config"
+    },
+    "odbc_config": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Odbc Config"
+    }
+  },
+  "type": "object",
+  "required": [
+    "source_type"
+  ],
+  "title": "TestConnectionRequest",
+  "description": "Dedicated schema for test-connection. NOT the create schema.\n\nSecurity: credentials in this request body are never persisted, never\nwritten to audit logs, and never returned in the response."
+}
+
+
TestConnectionResponse
+{
+  "properties": {
+    "success": {
+      "type": "boolean",
+      "title": "Success"
+    },
+    "message": {
+      "type": "string",
+      "title": "Message"
+    },
+    "latency_ms": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Latency Ms"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Status"
+    },
+    "warning": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Warning"
+    },
+    "differing_keys": {
+      "anyOf": [
+        {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Differing Keys"
+    }
+  },
+  "type": "object",
+  "required": [
+    "success",
+    "message"
+  ],
+  "title": "TestConnectionResponse"
+}
+
+
TimelineEventCreate
+{
+  "properties": {
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "internal_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Internal Note"
+    }
+  },
+  "type": "object",
+  "required": [
+    "event_type",
+    "description"
+  ],
+  "title": "TimelineEventCreate"
+}
+
+
TimelineEventRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "actor_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Actor Id"
+    },
+    "actor_role": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Actor Role"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "internal_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Internal Note"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "event_type",
+    "actor_id",
+    "actor_role",
+    "description",
+    "internal_note",
+    "created_at"
+  ],
+  "title": "TimelineEventRead"
+}
+
+
TimelineView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "actor": {
+      "type": "string",
+      "title": "Actor"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "action",
+    "actor",
+    "note",
+    "created_at_unix_seconds"
+  ],
+  "title": "TimelineView"
+}
+
+
TitleCreate
+{
+  "properties": {
+    "title_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Title Id"
+    },
+    "title_number": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title Number"
+    },
+    "title_name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title Name"
+    },
+    "sort_order": {
+      "type": "integer",
+      "title": "Sort Order",
+      "default": 0
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title_number",
+    "title_name"
+  ],
+  "title": "TitleCreate",
+  "description": "Request body for creating a code title."
+}
+
+
TranscriptInput
+{
+  "properties": {
+    "source_label": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Label"
+    },
+    "transcript_text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Transcript Text"
+    },
+    "correction_of_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Correction Of Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_label",
+    "transcript_text"
+  ],
+  "title": "TranscriptInput"
+}
+
+
UserRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "email": {
+      "type": "string",
+      "format": "email",
+      "title": "Email"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active",
+      "default": true
+    },
+    "is_superuser": {
+      "type": "boolean",
+      "title": "Is Superuser",
+      "default": false
+    },
+    "is_verified": {
+      "type": "boolean",
+      "title": "Is Verified",
+      "default": false
+    },
+    "full_name": {
+      "type": "string",
+      "title": "Full Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "last_login": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Login"
+    },
+    "must_change_password": {
+      "type": "boolean",
+      "title": "Must Change Password",
+      "default": false
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "email",
+    "full_name",
+    "role",
+    "created_at",
+    "last_login"
+  ],
+  "title": "UserRead"
+}
+
+
UserRole
+{
+  "type": "string",
+  "enum": [
+    "admin",
+    "staff",
+    "reviewer",
+    "read_only",
+    "liaison",
+    "public"
+  ],
+  "title": "UserRole"
+}
+
+
UserSelfUpdate
+{
+  "properties": {
+    "password": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Password"
+    },
+    "email": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "email"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    },
+    "is_superuser": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Superuser"
+    },
+    "is_verified": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Verified"
+    },
+    "full_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Full Name"
+    }
+  },
+  "type": "object",
+  "title": "UserSelfUpdate",
+  "description": "Schema for user self-update via PATCH /users/me.\n\nExcludes role and department_id. Any payload containing those fields is\nrejected at parse time (HTTP 422). Role and department changes require\nadmin privileges via /admin/users/{id}."
+}
+
+
UserUpdateRequest
+{
+  "properties": {
+    "full_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Full Name"
+    },
+    "role": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Role"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "UserUpdateRequest"
+}
+
+
ValidationError
+{
+  "properties": {
+    "loc": {
+      "items": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "integer"
+          }
+        ]
+      },
+      "type": "array",
+      "title": "Location"
+    },
+    "msg": {
+      "type": "string",
+      "title": "Message"
+    },
+    "type": {
+      "type": "string",
+      "title": "Error Type"
+    },
+    "input": {
+      "title": "Input"
+    },
+    "ctx": {
+      "type": "object",
+      "title": "Context"
+    }
+  },
+  "type": "object",
+  "required": [
+    "loc",
+    "msg",
+    "type"
+  ],
+  "title": "ValidationError"
+}
+
+
Version
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence"
+  ],
+  "title": "Version"
+}
+
+
VoteCorrection
+{
+  "properties": {
+    "vote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Vote"
+    },
+    "reason": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Reason"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "vote",
+    "reason"
+  ],
+  "title": "VoteCorrection"
+}
+
+
VoteInput
+{
+  "properties": {
+    "voter_name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Voter Name"
+    },
+    "vote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Vote"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "voter_name",
+    "vote"
+  ],
+  "title": "VoteInput"
+}
+
+
_ParcelLookupIn
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "query"
+  ],
+  "title": "_ParcelLookupIn"
+}
+
+
townlight_inspections__workflow_models__SourceLink
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "const": "code",
+      "title": "Provider",
+      "default": "code"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "SourceLink"
+}
+
+
townlight_permitting__workflow_models__SourceLink
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "enum": [
+        "code",
+        "zoning"
+      ],
+      "title": "Provider"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "SourceLink"
+}
+
+
townlight_runtime__inspections_bridge__Search
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "const": "code",
+      "title": "Provider"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "query"
+  ],
+  "title": "Search"
+}
+
+
townlight_runtime__notice_bridge__Review
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence",
+    "note"
+  ],
+  "title": "Review"
+}
+
+
townlight_runtime__permitting_bridge__Import
+{
+  "properties": {
+    "bundle": {
+      "$ref": "#/components/schemas/RequirementBundle"
+    },
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "bundle"
+  ],
+  "title": "Import"
+}
+
+
townlight_runtime__permitting_bridge__Search
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "enum": [
+        "code",
+        "zoning"
+      ],
+      "title": "Provider"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "query"
+  ],
+  "title": "Search"
+}
+
+
townlight_runtime__planning_bridge__Import
+{
+  "properties": {
+    "bundle": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Bundle"
+    },
+    "expected_previous_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Previous Revision"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "bundle"
+  ],
+  "title": "Import"
+}
+
+
townlight_runtime__planning_bridge__Search
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Query"
+    },
+    "plan_type": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 40
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Plan Type"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "Search"
+}
+
+
townlight_runtime__zoning_bridge__Review
+{
+  "properties": {
+    "answer": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Answer",
+      "default": ""
+    },
+    "notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Notes",
+      "default": ""
+    },
+    "queue_status": {
+      "type": "string",
+      "enum": [
+        "open",
+        "in_review",
+        "resolved",
+        "closed"
+      ],
+      "title": "Queue Status",
+      "default": "resolved"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "Review"
+}
+
Townlight · AGPL-3.0-only · Source schema evidence only
\ No newline at end of file diff --git a/docs/beta-1/api/meetings-openapi.json b/docs/beta-1/api/meetings-openapi.json new file mode 100644 index 0000000..c9ab41a --- /dev/null +++ b/docs/beta-1/api/meetings-openapi.json @@ -0,0 +1,12880 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "Townlight Records", + "description": "Prepared source schema for the actual native composition; installed acceptance remains pending. Exported without lifespan, migrations or database/network access.", + "version": "1.8.0.dev2" + }, + "paths": { + "/desktop/v1/meetings-sources/search": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Search Meetings Sources", + "operationId": "search_meetings_sources_desktop_v1_meetings_sources_search_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MeetingsSearch" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/meetings/{meeting_id}/stages": { + "post": { + "tags": [ + "native-meetings" + ], + "summary": "Record Meeting Stage", + "operationId": "record_meeting_stage_desktop_v1_meetings_meetings__meeting_id__stages_post", + "parameters": [ + { + "name": "meeting_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MeetingStageInput" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/meetings": { + "post": { + "tags": [ + "native-meetings" + ], + "summary": "Create Meeting", + "operationId": "create_meeting_desktop_v1_meetings_meetings_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MeetingInput" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/meetings/{meeting_id}": { + "get": { + "tags": [ + "native-meetings" + ], + "summary": "Get Meeting", + "operationId": "get_meeting_desktop_v1_meetings_meetings__meeting_id__get", + "parameters": [ + { + "name": "meeting_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/agenda-items": { + "post": { + "tags": [ + "native-meetings" + ], + "summary": "Create Agenda Item", + "operationId": "create_agenda_item_desktop_v1_meetings_agenda_items_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgendaInput" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/agenda-items/{item_id}": { + "get": { + "tags": [ + "native-meetings" + ], + "summary": "Get Agenda Item", + "operationId": "get_agenda_item_desktop_v1_meetings_agenda_items__item_id__get", + "parameters": [ + { + "name": "item_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Item Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/agenda-items/{item_id}/reviews": { + "post": { + "tags": [ + "native-meetings" + ], + "summary": "Record Agenda Review", + "operationId": "record_agenda_review_desktop_v1_meetings_agenda_items__item_id__reviews_post", + "parameters": [ + { + "name": "item_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Item Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgendaReviewInput" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/agenda-items/{item_id}/meeting": { + "post": { + "tags": [ + "native-meetings" + ], + "summary": "Assign Agenda", + "operationId": "assign_agenda_desktop_v1_meetings_agenda_items__item_id__meeting_post", + "parameters": [ + { + "name": "item_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Item Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgendaAssignment" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/notices/{notice_id}/template": { + "get": { + "tags": [ + "native-meetings" + ], + "summary": "Notice Template", + "operationId": "notice_template_desktop_v1_meetings_notices__notice_id__template_get", + "parameters": [ + { + "name": "notice_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Notice Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/notices/{notice_id}/document": { + "post": { + "tags": [ + "native-meetings" + ], + "summary": "Notice Document", + "operationId": "notice_document_desktop_v1_meetings_notices__notice_id__document_post", + "parameters": [ + { + "name": "notice_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Notice Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NoticeDocumentInput" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/meetings/{meeting_id}/notice-checks": { + "post": { + "tags": [ + "native-meetings" + ], + "summary": "Check Notice", + "operationId": "check_notice_desktop_v1_meetings_meetings__meeting_id__notice_checks_post", + "parameters": [ + { + "name": "meeting_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NoticeInput" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/notices/{notice_id}/proof": { + "post": { + "tags": [ + "native-meetings" + ], + "summary": "Record Notice Proof", + "operationId": "record_notice_proof_desktop_v1_meetings_notices__notice_id__proof_post", + "parameters": [ + { + "name": "notice_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Notice Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NoticeProofInput" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/meetings/{meeting_id}/transcripts": { + "post": { + "tags": [ + "native-meetings" + ], + "summary": "Capture Transcript", + "operationId": "capture_transcript_desktop_v1_meetings_meetings__meeting_id__transcripts_post", + "parameters": [ + { + "name": "meeting_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TranscriptInput" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/meetings/{meeting_id}/action-items": { + "post": { + "tags": [ + "native-meetings" + ], + "summary": "Capture Action Item", + "operationId": "capture_action_item_desktop_v1_meetings_meetings__meeting_id__action_items_post", + "parameters": [ + { + "name": "meeting_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ActionItemInput" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/meetings/{meeting_id}/archive": { + "post": { + "tags": [ + "native-meetings" + ], + "summary": "Archive Meeting", + "operationId": "archive_meeting_desktop_v1_meetings_meetings__meeting_id__archive_post", + "parameters": [ + { + "name": "meeting_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ArchiveInput" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/meetings/{meeting_id}/packet-snapshots": { + "post": { + "tags": [ + "native-meetings" + ], + "summary": "Capture Packet", + "operationId": "capture_packet_desktop_v1_meetings_meetings__meeting_id__packet_snapshots_post", + "parameters": [ + { + "name": "meeting_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PacketInput" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/packets/{packet_id}/deliver": { + "post": { + "tags": [ + "native-meetings" + ], + "summary": "Export Packet", + "operationId": "export_packet_desktop_v1_meetings_packets__packet_id__deliver_post", + "parameters": [ + { + "name": "packet_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Packet Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/minutes/{draft_id}/decisions": { + "post": { + "tags": [ + "native-meetings" + ], + "summary": "Decide Minutes", + "operationId": "decide_minutes_desktop_v1_meetings_minutes__draft_id__decisions_post", + "parameters": [ + { + "name": "draft_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Draft Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MinutesDecision" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/meetings/{meeting_id}/motions": { + "post": { + "tags": [ + "native-meetings" + ], + "summary": "Capture Motion", + "operationId": "capture_motion_desktop_v1_meetings_meetings__meeting_id__motions_post", + "parameters": [ + { + "name": "meeting_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MotionInput" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/motions/{motion_id}/corrections": { + "post": { + "tags": [ + "native-meetings" + ], + "summary": "Correct Motion", + "operationId": "correct_motion_desktop_v1_meetings_motions__motion_id__corrections_post", + "parameters": [ + { + "name": "motion_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Motion Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MotionCorrection" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/motions/{motion_id}/votes": { + "post": { + "tags": [ + "native-meetings" + ], + "summary": "Capture Vote", + "operationId": "capture_vote_desktop_v1_meetings_motions__motion_id__votes_post", + "parameters": [ + { + "name": "motion_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Motion Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VoteInput" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/votes/{vote_id}/corrections": { + "post": { + "tags": [ + "native-meetings" + ], + "summary": "Correct Vote", + "operationId": "correct_vote_desktop_v1_meetings_votes__vote_id__corrections_post", + "parameters": [ + { + "name": "vote_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Vote Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VoteCorrection" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/meetings/{meeting_id}/minutes/drafts": { + "post": { + "tags": [ + "native-meetings" + ], + "summary": "Create Minutes", + "operationId": "create_minutes_desktop_v1_meetings_meetings__meeting_id__minutes_drafts_post", + "parameters": [ + { + "name": "meeting_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DraftInput" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/meetings/{meeting_id}/proceedings": { + "get": { + "tags": [ + "native-meetings" + ], + "summary": "Proceedings", + "operationId": "proceedings_desktop_v1_meetings_meetings__meeting_id__proceedings_get", + "parameters": [ + { + "name": "meeting_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/station/catalog": { + "get": { + "tags": [ + "native-meetings" + ], + "summary": "Station Catalog", + "description": "Authorized name-based operator selection from canonical Meetings data.", + "operationId": "station_catalog_desktop_v1_meetings_station_catalog_get", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/public/meetings": { + "get": { + "tags": [ + "public-meetings" + ], + "summary": "Public Archive Index", + "operationId": "public_archive_index_public_meetings_get", + "parameters": [ + { + "name": "q", + "in": "query", + "required": false, + "schema": { + "type": "string", + "default": "", + "title": "Q" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "text/html": { + "schema": { + "type": "string" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/public/meetings/{record_id}": { + "get": { + "tags": [ + "public-meetings" + ], + "summary": "Public Archive Detail", + "operationId": "public_archive_detail_public_meetings__record_id__get", + "parameters": [ + { + "name": "record_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Record Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "text/html": { + "schema": { + "type": "string" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/public/meetings/{record_id}/{kind}.txt": { + "get": { + "tags": [ + "public-meetings" + ], + "summary": "Public Archive Download", + "operationId": "public_archive_download_public_meetings__record_id___kind__txt_get", + "parameters": [ + { + "name": "record_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Record Id" + } + }, + { + "name": "kind", + "in": "path", + "required": true, + "schema": { + "enum": [ + "agenda", + "packet", + "minutes" + ], + "type": "string", + "title": "Kind" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/code-connections": { + "get": { + "summary": "List Code Connections", + "operationId": "list_code_connections_desktop_v1_meetings_code_connections_get", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/code-connections/{connection_id}": { + "get": { + "summary": "Get Code Connection", + "operationId": "get_code_connection_desktop_v1_meetings_code_connections__connection_id__get", + "parameters": [ + { + "name": "connection_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Connection Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/code-connections/{connection_id}/decisions": { + "post": { + "summary": "Record Decision", + "operationId": "record_decision_desktop_v1_meetings_code_connections__connection_id__decisions_post", + "parameters": [ + { + "name": "connection_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Connection Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Decision" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "ActionItemInput": { + "properties": { + "description": { + "type": "string", + "minLength": 1, + "title": "Description" + }, + "assigned_to": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "source_motion_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Source Motion Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "description" + ], + "title": "ActionItemInput" + }, + "AdaPlan": { + "properties": { + "action": { + "type": "string", + "const": "ada-title-ii", + "title": "Action" + }, + "serviceArea": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Servicearea" + }, + "hasCoordinatorReview": { + "type": "boolean", + "title": "Hascoordinatorreview", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "serviceArea" + ], + "title": "AdaPlan" + }, + "AdminUserCreateRequest": { + "properties": { + "email": { + "type": "string", + "title": "Email" + }, + "password": { + "type": "string", + "title": "Password" + }, + "full_name": { + "type": "string", + "title": "Full Name", + "default": "" + }, + "role": { + "type": "string", + "title": "Role", + "default": "staff" + } + }, + "type": "object", + "required": [ + "email", + "password" + ], + "title": "AdminUserCreateRequest" + }, + "AdminUserCreateResponse": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "email": { + "type": "string", + "title": "Email" + }, + "full_name": { + "type": "string", + "title": "Full Name" + }, + "role": { + "type": "string", + "title": "Role" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + } + }, + "type": "object", + "required": [ + "id", + "email", + "full_name", + "role", + "is_active" + ], + "title": "AdminUserCreateResponse" + }, + "AgendaAssignment": { + "properties": { + "meeting_id": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "meeting_id" + ], + "title": "AgendaAssignment" + }, + "AgendaInput": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "department_name": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Department Name" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "department_name" + ], + "title": "AgendaInput" + }, + "AgendaReviewInput": { + "properties": { + "to_status": { + "type": "string", + "enum": [ + "DRAFTED", + "SUBMITTED", + "DEPT_APPROVED", + "LEGAL_REVIEWED", + "CLERK_ACCEPTED", + "ON_AGENDA", + "IN_PACKET", + "POSTED", + "HEARD", + "DISPOSED", + "ARCHIVED" + ], + "title": "To Status" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "to_status" + ], + "title": "AgendaReviewInput" + }, + "AmendmentInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "policy": { + "$ref": "#/components/schemas/PolicySelection" + }, + "proposal": { + "type": "string", + "maxLength": 20000, + "minLength": 1, + "title": "Proposal" + }, + "responsible_staff": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Responsible Staff" + }, + "status": { + "type": "string", + "enum": [ + "draft", + "review", + "adopted", + "withdrawn" + ], + "title": "Status", + "default": "draft" + }, + "review_note": { + "type": "string", + "maxLength": 5000, + "title": "Review Note", + "default": "" + }, + "adoption_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Adoption Revision" + }, + "note": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "policy", + "proposal", + "responsible_staff", + "note" + ], + "title": "AmendmentInput" + }, + "AnalysisObservation": { + "properties": { + "source": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "title": "Source" + }, + "filename": { + "type": "string", + "maxLength": 160, + "title": "Filename", + "default": "" + }, + "media_type": { + "type": "string", + "maxLength": 80, + "title": "Media Type", + "default": "" + }, + "text": { + "type": "string", + "maxLength": 4000, + "minLength": 1, + "title": "Text" + }, + "adapter": { + "type": "string", + "maxLength": 120, + "title": "Adapter", + "default": "" + }, + "citation_source_ids": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 30, + "title": "Citation Source Ids" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source", + "text" + ], + "title": "AnalysisObservation", + "description": "One draft observation, named with the adapter that actually produced it." + }, + "AnalysisRecord": { + "properties": { + "observations": { + "items": { + "$ref": "#/components/schemas/AnalysisObservation" + }, + "type": "array", + "maxItems": 30, + "title": "Observations" + }, + "cited_sections": { + "items": { + "$ref": "#/components/schemas/CitedSection" + }, + "type": "array", + "maxItems": 30, + "title": "Cited Sections" + }, + "unavailable": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 30, + "title": "Unavailable" + }, + "runtime": { + "additionalProperties": true, + "type": "object", + "title": "Runtime" + }, + "review_required": { + "type": "boolean", + "title": "Review Required", + "default": true + } + }, + "additionalProperties": false, + "type": "object", + "title": "AnalysisRecord", + "description": "The adapter output that accompanies a saved inspection draft." + }, + "ApprovalCommand": { + "properties": { + "action": { + "type": "string", + "const": "approve-records-response", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ApprovalPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "ApprovalCommand" + }, + "ApprovalPayload": { + "properties": { + "approvalNote": { + "type": "string", + "title": "Approvalnote", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "title": "ApprovalPayload" + }, + "ArchiveInput": { + "properties": { + "visibility": { + "type": "string", + "enum": [ + "public", + "closed_session" + ], + "title": "Visibility" + }, + "packet_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Packet Id" + }, + "minutes_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Minutes Id" + }, + "plain_language_summary": { + "type": "string", + "title": "Plain Language Summary", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "visibility" + ], + "title": "ArchiveInput" + }, + "ArtifactPlan": { + "properties": { + "artifact_id": { + "type": "string", + "title": "Artifact Id" + }, + "file_name": { + "type": "string", + "title": "File Name" + }, + "content": { + "type": "string", + "title": "Content" + }, + "sha256": { + "type": "string", + "title": "Sha256" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "artifact_id", + "file_name", + "content", + "sha256", + "created_at_unix_seconds" + ], + "title": "ArtifactPlan" + }, + "AssignCommand": { + "properties": { + "action": { + "type": "string", + "const": "assign-records-request", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/AssignmentPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "AssignCommand" + }, + "AssignmentPayload": { + "properties": { + "assignedTo": { + "type": "string", + "minLength": 1, + "title": "Assignedto" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "assignedTo" + ], + "title": "AssignmentPayload" + }, + "AttachDocument": { + "properties": { + "title": { + "type": "string", + "minLength": 1, + "title": "Title" + }, + "citation": { + "type": "string", + "title": "Citation", + "default": "" + }, + "file": { + "$ref": "#/components/schemas/ManagedFileReceipt" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "file" + ], + "title": "AttachDocument" + }, + "AttachReleaseCopy": { + "properties": { + "status": { + "type": "string", + "enum": [ + "release-ready copy", + "redacted copy" + ], + "title": "Status" + }, + "note": { + "type": "string", + "title": "Note", + "default": "" + }, + "added_by": { + "type": "string", + "title": "Added By", + "default": "" + }, + "file": { + "$ref": "#/components/schemas/ManagedFileReceipt" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "status", + "file" + ], + "title": "AttachReleaseCopy" + }, + "AuditChainVerification": { + "properties": { + "is_valid": { + "type": "boolean", + "title": "Is Valid" + }, + "entries_checked": { + "type": "integer", + "title": "Entries Checked" + }, + "error_message": { + "type": "string", + "title": "Error Message" + } + }, + "type": "object", + "required": [ + "is_valid", + "entries_checked", + "error_message" + ], + "title": "AuditChainVerification" + }, + "AuditLogRead": { + "properties": { + "id": { + "type": "integer", + "title": "Id" + }, + "prev_hash": { + "type": "string", + "title": "Prev Hash" + }, + "entry_hash": { + "type": "string", + "title": "Entry Hash" + }, + "timestamp": { + "type": "string", + "format": "date-time", + "title": "Timestamp" + }, + "user_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "User Id" + }, + "action": { + "type": "string", + "title": "Action" + }, + "resource_type": { + "type": "string", + "title": "Resource Type" + }, + "resource_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Resource Id" + }, + "details": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Details" + }, + "ai_generated": { + "type": "boolean", + "title": "Ai Generated" + } + }, + "type": "object", + "required": [ + "id", + "prev_hash", + "entry_hash", + "timestamp", + "user_id", + "action", + "resource_type", + "resource_id", + "details", + "ai_generated" + ], + "title": "AuditLogRead" + }, + "AuditView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "module_id": { + "type": "string", + "title": "Module Id" + }, + "action": { + "type": "string", + "title": "Action" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + }, + "previous_hash": { + "type": "string", + "title": "Previous Hash" + }, + "entry_hash": { + "type": "string", + "title": "Entry Hash" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "module_id", + "action", + "summary", + "created_at_unix_seconds", + "previous_hash", + "entry_hash" + ], + "title": "AuditView" + }, + "BearerResponse": { + "properties": { + "access_token": { + "type": "string", + "title": "Access Token" + }, + "token_type": { + "type": "string", + "title": "Token Type" + } + }, + "type": "object", + "required": [ + "access_token", + "token_type" + ], + "title": "BearerResponse" + }, + "Body_auth_jwt_login_auth_jwt_login_post": { + "properties": { + "grant_type": { + "anyOf": [ + { + "type": "string", + "pattern": "^password$" + }, + { + "type": "null" + } + ], + "title": "Grant Type" + }, + "username": { + "type": "string", + "title": "Username" + }, + "password": { + "type": "string", + "format": "password", + "title": "Password" + }, + "scope": { + "type": "string", + "title": "Scope", + "default": "" + }, + "client_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Client Id" + }, + "client_secret": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "format": "password", + "title": "Client Secret" + } + }, + "type": "object", + "required": [ + "username", + "password" + ], + "title": "Body_auth_jwt_login_auth_jwt_login_post" + }, + "Body_upload_file_datasources_upload_post": { + "properties": { + "file": { + "type": "string", + "contentMediaType": "application/octet-stream", + "title": "File" + } + }, + "type": "object", + "required": [ + "file" + ], + "title": "Body_upload_file_datasources_upload_post" + }, + "CalculateDeadlineCommand": { + "properties": { + "action": { + "type": "string", + "const": "calculate-records-deadline", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/CalculateDeadlinePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "CalculateDeadlineCommand" + }, + "CalculateDeadlinePayload": { + "properties": { + "deadlineReceivedDate": { + "type": "string", + "title": "Deadlinereceiveddate" + }, + "deadlineRuleName": { + "type": "string", + "minLength": 1, + "title": "Deadlinerulename" + }, + "deadlineDayCount": { + "type": "string", + "title": "Deadlinedaycount" + }, + "deadlineDayType": { + "type": "string", + "title": "Deadlinedaytype" + }, + "deadlineBasis": { + "type": "string", + "minLength": 1, + "title": "Deadlinebasis" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "deadlineReceivedDate", + "deadlineRuleName", + "deadlineDayCount", + "deadlineDayType", + "deadlineBasis" + ], + "title": "CalculateDeadlinePayload" + }, + "ChapterCreate": { + "properties": { + "chapter_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Chapter Id" + }, + "title_id": { + "type": "string", + "minLength": 1, + "title": "Title Id" + }, + "chapter_number": { + "type": "string", + "minLength": 1, + "title": "Chapter Number" + }, + "chapter_name": { + "type": "string", + "minLength": 1, + "title": "Chapter Name" + }, + "sort_order": { + "type": "integer", + "title": "Sort Order", + "default": 0 + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title_id", + "chapter_number", + "chapter_name" + ], + "title": "ChapterCreate", + "description": "Request body for creating a code chapter." + }, + "CitedSection": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "citation": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Citation" + }, + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "version": { + "type": "string", + "maxLength": 80, + "title": "Version", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "citation" + ], + "title": "CitedSection", + "description": "One resolved public Code section; never a caller-supplied quotation." + }, + "CityProfileCreate": { + "properties": { + "city_name": { + "type": "string", + "title": "City Name" + }, + "state": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State" + }, + "county": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "County" + }, + "population_band": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Population Band" + }, + "email_platform": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Email Platform" + }, + "has_dedicated_it": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Has Dedicated It" + }, + "monthly_request_volume": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Monthly Request Volume" + }, + "profile_data": { + "additionalProperties": true, + "type": "object", + "title": "Profile Data", + "default": {} + }, + "gap_map": { + "additionalProperties": true, + "type": "object", + "title": "Gap Map", + "default": {} + } + }, + "type": "object", + "required": [ + "city_name" + ], + "title": "CityProfileCreate" + }, + "CityProfileRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "city_name": { + "type": "string", + "title": "City Name" + }, + "state": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State" + }, + "county": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "County" + }, + "population_band": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Population Band" + }, + "email_platform": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Email Platform" + }, + "has_dedicated_it": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Has Dedicated It" + }, + "monthly_request_volume": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Monthly Request Volume" + }, + "onboarding_status": { + "type": "string", + "title": "Onboarding Status" + }, + "profile_data": { + "additionalProperties": true, + "type": "object", + "title": "Profile Data" + }, + "gap_map": { + "additionalProperties": true, + "type": "object", + "title": "Gap Map" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "city_name", + "state", + "county", + "population_band", + "email_platform", + "has_dedicated_it", + "monthly_request_volume", + "onboarding_status", + "profile_data", + "gap_map", + "created_at", + "updated_at" + ], + "title": "CityProfileRead" + }, + "CityProfileUpdate": { + "properties": { + "city_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "City Name" + }, + "state": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State" + }, + "county": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "County" + }, + "population_band": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Population Band" + }, + "email_platform": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Email Platform" + }, + "has_dedicated_it": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Has Dedicated It" + }, + "monthly_request_volume": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Monthly Request Volume" + }, + "onboarding_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Onboarding Status" + }, + "profile_data": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Profile Data" + }, + "gap_map": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Gap Map" + } + }, + "type": "object", + "title": "CityProfileUpdate" + }, + "ClarificationCommand": { + "properties": { + "action": { + "type": "string", + "const": "request-records-clarification", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ClarificationPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "ClarificationCommand" + }, + "ClarificationPayload": { + "properties": { + "clarificationNote": { + "type": "string", + "minLength": 1, + "title": "Clarificationnote" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "clarificationNote" + ], + "title": "ClarificationPayload" + }, + "Closeout": { + "properties": { + "decision_id": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Decision Id" + }, + "version_id": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Version Id" + }, + "source_id": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Source Id" + }, + "version_label": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Version Label" + }, + "body": { + "type": "string", + "maxLength": 1000000, + "minLength": 1, + "title": "Body" + }, + "effective_start": { + "type": "string", + "format": "date", + "title": "Effective Start" + }, + "effective_end": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective End" + }, + "is_current": { + "type": "boolean", + "title": "Is Current" + }, + "reconciliation_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reconciliation Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "decision_id", + "version_id", + "source_id", + "version_label", + "body", + "effective_start", + "is_current" + ], + "title": "Closeout" + }, + "CodeContext": { + "properties": { + "section_number": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Section Number" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "section_number" + ], + "title": "CodeContext" + }, + "CodeLink": { + "properties": { + "provider": { + "type": "string", + "const": "code", + "title": "Provider", + "default": "code" + }, + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "CodeLink" + }, + "CodeSearch": { + "properties": { + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "CodeSearch" + }, + "CodeSourceSelection": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "CodeSourceSelection" + }, + "CompleteArtifact": { + "properties": { + "export_path": { + "type": "string", + "minLength": 1, + "title": "Export Path" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "export_path" + ], + "title": "CompleteArtifact" + }, + "ConnectionSearch": { + "properties": { + "provider": { + "type": "string", + "enum": [ + "meetings", + "zoning" + ], + "title": "Provider" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "query" + ], + "title": "ConnectionSearch" + }, + "CoverageGapResponse": { + "properties": { + "jurisdictions_without_rules": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Jurisdictions Without Rules" + }, + "departments_without_staff": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array", + "title": "Departments Without Staff" + }, + "uncovered_categories": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Uncovered Categories" + }, + "total_gaps": { + "type": "integer", + "title": "Total Gaps" + } + }, + "type": "object", + "required": [ + "jurisdictions_without_rules", + "departments_without_staff", + "uncovered_categories", + "total_gaps" + ], + "title": "CoverageGapResponse" + }, + "DataSourceAdminRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "source_type": { + "$ref": "#/components/schemas/SourceType" + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "type": "boolean", + "title": "Schedule Enabled", + "default": true + }, + "next_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Next Sync At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "last_ingestion_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Ingestion At" + }, + "last_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Sync At" + }, + "last_sync_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Sync Status" + }, + "last_error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Error Message" + }, + "consecutive_failure_count": { + "type": "integer", + "title": "Consecutive Failure Count", + "default": 0 + }, + "sync_paused": { + "type": "boolean", + "title": "Sync Paused", + "default": false + }, + "health_status": { + "type": "string", + "title": "Health Status", + "default": "healthy" + }, + "active_failure_count": { + "type": "integer", + "title": "Active Failure Count", + "default": 0 + }, + "connector_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Connector Type" + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At" + }, + "connection_config": { + "additionalProperties": true, + "type": "object", + "title": "Connection Config" + } + }, + "type": "object", + "required": [ + "id", + "name", + "source_type", + "is_active", + "created_by", + "created_at", + "last_ingestion_at", + "connection_config" + ], + "title": "DataSourceAdminRead", + "description": "Full datasource shape including connection_config. Returned only by admin-gated endpoints." + }, + "DataSourceCreate": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "source_type": { + "$ref": "#/components/schemas/SourceType" + }, + "connection_config": { + "additionalProperties": true, + "type": "object", + "title": "Connection Config", + "default": {} + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "type": "boolean", + "title": "Schedule Enabled", + "default": true + } + }, + "type": "object", + "required": [ + "name", + "source_type" + ], + "title": "DataSourceCreate" + }, + "DataSourceRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "source_type": { + "$ref": "#/components/schemas/SourceType" + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "type": "boolean", + "title": "Schedule Enabled", + "default": true + }, + "next_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Next Sync At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "last_ingestion_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Ingestion At" + }, + "last_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Sync At" + }, + "last_sync_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Sync Status" + }, + "last_error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Error Message" + }, + "consecutive_failure_count": { + "type": "integer", + "title": "Consecutive Failure Count", + "default": 0 + }, + "sync_paused": { + "type": "boolean", + "title": "Sync Paused", + "default": false + }, + "health_status": { + "type": "string", + "title": "Health Status", + "default": "healthy" + }, + "active_failure_count": { + "type": "integer", + "title": "Active Failure Count", + "default": 0 + }, + "connector_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Connector Type" + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "name", + "source_type", + "is_active", + "created_by", + "created_at", + "last_ingestion_at" + ], + "title": "DataSourceRead", + "description": "Redacted datasource shape — safe for non-admin roles. connection_config omitted." + }, + "DataSourceUpdate": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "connection_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Connection Config" + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Schedule Enabled" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "DataSourceUpdate" + }, + "DeadlineCommand": { + "properties": { + "action": { + "type": "string", + "const": "set-records-deadline", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/DeadlinePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "DeadlineCommand" + }, + "DeadlinePayload": { + "properties": { + "deadline": { + "type": "string", + "title": "Deadline" + }, + "deadlineBasis": { + "type": "string", + "minLength": 1, + "title": "Deadlinebasis" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "deadline", + "deadlineBasis" + ], + "title": "DeadlinePayload" + }, + "Decision": { + "properties": { + "id": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Id" + }, + "outcome": { + "type": "string", + "enum": [ + "adopted", + "not_adopted", + "deferred", + "withdrawn" + ], + "title": "Outcome" + }, + "decided_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Decided At" + }, + "decision_text": { + "type": "string", + "maxLength": 1000000, + "minLength": 1, + "title": "Decision Text" + }, + "supporting_references": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Supporting References" + }, + "supersedes_decision_id": { + "anyOf": [ + { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$" + }, + { + "type": "null" + } + ], + "title": "Supersedes Decision Id" + }, + "reconciliation_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reconciliation Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "outcome", + "decision_text" + ], + "title": "Decision" + }, + "DepartmentCreate": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "code": { + "type": "string", + "title": "Code" + }, + "contact_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Contact Email" + } + }, + "type": "object", + "required": [ + "name", + "code" + ], + "title": "DepartmentCreate" + }, + "DepartmentRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "code": { + "type": "string", + "title": "Code" + }, + "contact_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Contact Email" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "name", + "code", + "contact_email", + "created_at" + ], + "title": "DepartmentRead" + }, + "DepartmentUpdate": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Code" + }, + "contact_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Contact Email" + } + }, + "type": "object", + "title": "DepartmentUpdate" + }, + "DisclosureTemplateCreate": { + "properties": { + "template_type": { + "type": "string", + "title": "Template Type" + }, + "state_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State Code" + }, + "content": { + "type": "string", + "title": "Content" + } + }, + "type": "object", + "required": [ + "template_type", + "content" + ], + "title": "DisclosureTemplateCreate" + }, + "DisclosureTemplateRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "template_type": { + "type": "string", + "title": "Template Type" + }, + "state_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State Code" + }, + "content": { + "type": "string", + "title": "Content" + }, + "version": { + "type": "integer", + "title": "Version" + }, + "updated_by": { + "type": "string", + "format": "uuid", + "title": "Updated By" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "template_type", + "state_code", + "content", + "version", + "updated_by", + "updated_at" + ], + "title": "DisclosureTemplateRead" + }, + "DisclosureTemplateRendered": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "template_type": { + "type": "string", + "title": "Template Type" + }, + "rendered_content": { + "type": "string", + "title": "Rendered Content" + }, + "has_unresolved_variables": { + "type": "boolean", + "title": "Has Unresolved Variables" + } + }, + "type": "object", + "required": [ + "id", + "template_type", + "rendered_content", + "has_unresolved_variables" + ], + "title": "DisclosureTemplateRendered" + }, + "DisclosureTemplateUpdate": { + "properties": { + "content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Content" + }, + "state_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State Code" + } + }, + "type": "object", + "title": "DisclosureTemplateUpdate" + }, + "DocumentChunkRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "chunk_index": { + "type": "integer", + "title": "Chunk Index" + }, + "content_text": { + "type": "string", + "title": "Content Text" + }, + "token_count": { + "type": "integer", + "title": "Token Count" + }, + "page_number": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Page Number" + } + }, + "type": "object", + "required": [ + "id", + "document_id", + "chunk_index", + "content_text", + "token_count", + "page_number" + ], + "title": "DocumentChunkRead" + }, + "DocumentRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "source_id": { + "type": "string", + "format": "uuid", + "title": "Source Id" + }, + "source_path": { + "type": "string", + "title": "Source Path" + }, + "filename": { + "type": "string", + "title": "Filename" + }, + "file_type": { + "type": "string", + "title": "File Type" + }, + "file_hash": { + "type": "string", + "title": "File Hash" + }, + "file_size": { + "type": "integer", + "title": "File Size" + }, + "ingestion_status": { + "$ref": "#/components/schemas/IngestionStatus" + }, + "ingestion_error": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Ingestion Error" + }, + "chunk_count": { + "type": "integer", + "title": "Chunk Count" + }, + "ingested_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Ingested At" + }, + "connector_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Connector Type" + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "source_id", + "source_path", + "filename", + "file_type", + "file_hash", + "file_size", + "ingestion_status", + "ingestion_error", + "chunk_count", + "ingested_at" + ], + "title": "DocumentRead" + }, + "DraftCommand": { + "properties": { + "action": { + "type": "string", + "const": "draft-records-response", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/DraftPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "DraftCommand" + }, + "DraftInput": { + "properties": { + "source_materials": { + "items": { + "$ref": "#/components/schemas/SourceInput" + }, + "type": "array", + "title": "Source Materials" + }, + "sentences": { + "items": { + "$ref": "#/components/schemas/SentenceInput" + }, + "type": "array", + "minItems": 1, + "title": "Sentences" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sentences" + ], + "title": "DraftInput" + }, + "DraftPayload": { + "properties": { + "responseDraft": { + "type": "string", + "minLength": 1, + "title": "Responsedraft" + }, + "citation": { + "type": "string", + "title": "Citation", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "responseDraft" + ], + "title": "DraftPayload" + }, + "ErrorModel": { + "properties": { + "detail": { + "anyOf": [ + { + "type": "string" + }, + { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + ], + "title": "Detail" + } + }, + "type": "object", + "required": [ + "detail" + ], + "title": "ErrorModel" + }, + "Evidence": { + "properties": { + "filename": { + "type": "string", + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$", + "title": "Filename" + }, + "description": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Description" + }, + "media_type": { + "type": "string", + "enum": [ + "text/plain", + "image/jpeg", + "image/png", + "image/webp", + "application/pdf", + "audio/webm", + "audio/ogg", + "audio/wav", + "audio/mpeg", + "audio/mp4" + ], + "title": "Media Type" + }, + "content_base64": { + "type": "string", + "maxLength": 14000000, + "minLength": 1, + "title": "Content Base64" + }, + "sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "filename", + "description", + "media_type", + "content_base64", + "sha256" + ], + "title": "Evidence" + }, + "EvidenceItem": { + "properties": { + "filename": { + "type": "string", + "maxLength": 151, + "minLength": 1, + "title": "Filename" + }, + "media_type": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Media Type" + }, + "description": { + "type": "string", + "maxLength": 2000, + "title": "Description", + "default": "" + }, + "content_base64": { + "type": "string", + "maxLength": 14000000, + "minLength": 1, + "title": "Content Base64" + }, + "sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "filename", + "media_type", + "content_base64", + "sha256" + ], + "title": "EvidenceItem" + }, + "EvidenceItems": { + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/EvidenceItem" + }, + "type": "array", + "maxItems": 10, + "minItems": 1, + "title": "Items" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "items" + ], + "title": "EvidenceItems" + }, + "ExemptionAccuracyReport": { + "properties": { + "category": { + "type": "string", + "title": "Category" + }, + "total_flags": { + "type": "integer", + "title": "Total Flags" + }, + "accepted": { + "type": "integer", + "title": "Accepted" + }, + "rejected": { + "type": "integer", + "title": "Rejected" + }, + "pending": { + "type": "integer", + "title": "Pending" + }, + "acceptance_rate": { + "type": "number", + "title": "Acceptance Rate" + } + }, + "type": "object", + "required": [ + "category", + "total_flags", + "accepted", + "rejected", + "pending", + "acceptance_rate" + ], + "title": "ExemptionAccuracyReport" + }, + "ExemptionDashboard": { + "properties": { + "total_flags": { + "type": "integer", + "title": "Total Flags" + }, + "by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "By Status" + }, + "by_category": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "By Category" + }, + "acceptance_rate": { + "type": "number", + "title": "Acceptance Rate" + }, + "total_rules": { + "type": "integer", + "title": "Total Rules" + }, + "active_rules": { + "type": "integer", + "title": "Active Rules" + } + }, + "type": "object", + "required": [ + "total_flags", + "by_status", + "by_category", + "acceptance_rate", + "total_rules", + "active_rules" + ], + "title": "ExemptionDashboard" + }, + "ExemptionDecisionCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-exemption-decision", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ExemptionDecisionPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "ExemptionDecisionCommand" + }, + "ExemptionDecisionPayload": { + "properties": { + "exemptionSource": { + "type": "string", + "minLength": 1, + "title": "Exemptionsource" + }, + "exemptionKind": { + "type": "string", + "minLength": 1, + "title": "Exemptionkind" + }, + "exemptionFinding": { + "type": "string", + "minLength": 1, + "title": "Exemptionfinding" + }, + "exemptionDecision": { + "type": "string", + "enum": [ + "release", + "redact", + "exempt" + ], + "title": "Exemptiondecision" + }, + "exemptionBasis": { + "type": "string", + "minLength": 1, + "title": "Exemptionbasis" + }, + "exemptionReviewer": { + "type": "string", + "title": "Exemptionreviewer", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "exemptionSource", + "exemptionKind", + "exemptionFinding", + "exemptionDecision", + "exemptionBasis" + ], + "title": "ExemptionDecisionPayload" + }, + "ExemptionDecisionView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "source": { + "type": "string", + "title": "Source" + }, + "kind": { + "type": "string", + "title": "Kind" + }, + "finding": { + "type": "string", + "title": "Finding" + }, + "decision": { + "type": "string", + "enum": [ + "release", + "redact", + "exempt" + ], + "title": "Decision" + }, + "basis": { + "type": "string", + "title": "Basis" + }, + "reviewer": { + "type": "string", + "title": "Reviewer" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "source", + "kind", + "finding", + "decision", + "basis", + "reviewer", + "created_at_unix_seconds" + ], + "title": "ExemptionDecisionView" + }, + "ExemptionFlagRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "chunk_id": { + "type": "string", + "format": "uuid", + "title": "Chunk Id" + }, + "rule_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Rule Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "category": { + "type": "string", + "title": "Category" + }, + "matched_text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Matched Text" + }, + "confidence": { + "type": "number", + "title": "Confidence" + }, + "status": { + "$ref": "#/components/schemas/FlagStatus" + }, + "reviewed_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Reviewed By" + }, + "reviewed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Reviewed At" + }, + "review_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Reason" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "chunk_id", + "rule_id", + "request_id", + "category", + "matched_text", + "confidence", + "status", + "reviewed_by", + "reviewed_at", + "review_reason", + "created_at" + ], + "title": "ExemptionFlagRead" + }, + "ExemptionFlagReview": { + "properties": { + "status": { + "$ref": "#/components/schemas/FlagStatus" + }, + "review_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Reason" + } + }, + "type": "object", + "required": [ + "status" + ], + "title": "ExemptionFlagReview" + }, + "ExemptionNoteCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-exemption-review", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ExemptionNotePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "ExemptionNoteCommand" + }, + "ExemptionNotePayload": { + "properties": { + "exemptionNote": { + "type": "string", + "minLength": 1, + "title": "Exemptionnote" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "exemptionNote" + ], + "title": "ExemptionNotePayload" + }, + "ExemptionRuleCreate": { + "properties": { + "state_code": { + "type": "string", + "title": "State Code" + }, + "category": { + "type": "string", + "title": "Category" + }, + "rule_type": { + "$ref": "#/components/schemas/RuleType" + }, + "rule_definition": { + "type": "string", + "title": "Rule Definition" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "enabled": { + "type": "boolean", + "title": "Enabled", + "default": true + } + }, + "type": "object", + "required": [ + "state_code", + "category", + "rule_type", + "rule_definition" + ], + "title": "ExemptionRuleCreate" + }, + "ExemptionRuleRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "state_code": { + "type": "string", + "title": "State Code" + }, + "category": { + "type": "string", + "title": "Category" + }, + "rule_type": { + "$ref": "#/components/schemas/RuleType" + }, + "rule_definition": { + "type": "string", + "title": "Rule Definition" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "enabled": { + "type": "boolean", + "title": "Enabled" + }, + "version": { + "type": "integer", + "title": "Version", + "default": 1 + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "state_code", + "category", + "rule_type", + "rule_definition", + "description", + "enabled", + "created_by", + "created_at" + ], + "title": "ExemptionRuleRead" + }, + "ExemptionRuleUpdate": { + "properties": { + "rule_definition": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Rule Definition" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "enabled": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Enabled" + } + }, + "type": "object", + "title": "ExemptionRuleUpdate" + }, + "ExportReceipt": { + "properties": { + "export_path": { + "type": "string", + "maxLength": 32768, + "minLength": 1, + "title": "Export Path" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "export_path" + ], + "title": "ExportReceipt" + }, + "FeeEstimateCommand": { + "properties": { + "action": { + "type": "string", + "const": "estimate-records-fee", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/FeeEstimatePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "FeeEstimateCommand" + }, + "FeeEstimatePayload": { + "properties": { + "feeEstimate": { + "type": "string", + "minLength": 1, + "title": "Feeestimate" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "feeEstimate" + ], + "title": "FeeEstimatePayload" + }, + "FeeEstimateRequest": { + "properties": { + "page_count": { + "type": "integer", + "title": "Page Count" + }, + "fee_schedule_id": { + "type": "string", + "format": "uuid", + "title": "Fee Schedule Id" + } + }, + "type": "object", + "required": [ + "page_count", + "fee_schedule_id" + ], + "title": "FeeEstimateRequest" + }, + "FeeEstimateResponse": { + "properties": { + "page_count": { + "type": "integer", + "title": "Page Count" + }, + "unit_price": { + "type": "number", + "title": "Unit Price" + }, + "total": { + "type": "number", + "title": "Total" + }, + "fee_type": { + "type": "string", + "title": "Fee Type" + }, + "description": { + "type": "string", + "title": "Description" + } + }, + "type": "object", + "required": [ + "page_count", + "unit_price", + "total", + "fee_type", + "description" + ], + "title": "FeeEstimateResponse" + }, + "FeeLineCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-fee-line", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/FeeLinePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "FeeLineCommand" + }, + "FeeLineItemCreate": { + "properties": { + "description": { + "type": "string", + "title": "Description" + }, + "quantity": { + "type": "integer", + "title": "Quantity", + "default": 1 + }, + "unit_price": { + "type": "number", + "title": "Unit Price" + }, + "fee_schedule_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Fee Schedule Id" + } + }, + "type": "object", + "required": [ + "description", + "unit_price" + ], + "title": "FeeLineItemCreate" + }, + "FeeLineItemRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "fee_schedule_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Fee Schedule Id" + }, + "description": { + "type": "string", + "title": "Description" + }, + "quantity": { + "type": "integer", + "title": "Quantity" + }, + "unit_price": { + "type": "number", + "title": "Unit Price" + }, + "total": { + "type": "number", + "title": "Total" + }, + "status": { + "type": "string", + "title": "Status" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "fee_schedule_id", + "description", + "quantity", + "unit_price", + "total", + "status", + "created_at" + ], + "title": "FeeLineItemRead" + }, + "FeeLinePayload": { + "properties": { + "feeLineDescription": { + "type": "string", + "minLength": 1, + "title": "Feelinedescription" + }, + "feeScheduleBasis": { + "type": "string", + "minLength": 1, + "title": "Feeschedulebasis" + }, + "feeLineAmount": { + "type": "string", + "title": "Feelineamount" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "feeLineDescription", + "feeScheduleBasis", + "feeLineAmount" + ], + "title": "FeeLinePayload" + }, + "FeeLineView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "description": { + "type": "string", + "title": "Description" + }, + "schedule_basis": { + "type": "string", + "title": "Schedule Basis" + }, + "amount_cents": { + "type": "integer", + "title": "Amount Cents" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "description", + "schedule_basis", + "amount_cents", + "created_at_unix_seconds" + ], + "title": "FeeLineView" + }, + "FeeScheduleCreate": { + "properties": { + "jurisdiction": { + "type": "string", + "title": "Jurisdiction" + }, + "fee_type": { + "type": "string", + "title": "Fee Type" + }, + "amount": { + "type": "number", + "title": "Amount" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "effective_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective Date" + } + }, + "type": "object", + "required": [ + "jurisdiction", + "fee_type", + "amount" + ], + "title": "FeeScheduleCreate" + }, + "FeeScheduleRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "jurisdiction": { + "type": "string", + "title": "Jurisdiction" + }, + "fee_type": { + "type": "string", + "title": "Fee Type" + }, + "amount": { + "type": "number", + "title": "Amount" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "effective_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective Date" + }, + "created_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "jurisdiction", + "fee_type", + "amount", + "description", + "effective_date", + "created_by", + "created_at" + ], + "title": "FeeScheduleRead" + }, + "FeeScheduleUpdate": { + "properties": { + "fee_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Fee Type" + }, + "amount": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Amount" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "effective_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective Date" + } + }, + "type": "object", + "title": "FeeScheduleUpdate" + }, + "FeeWaiverCommand": { + "properties": { + "action": { + "type": "string", + "const": "waive-records-fee", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/FeeWaiverPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "FeeWaiverCommand" + }, + "FeeWaiverCreateRequest": { + "properties": { + "waiver_type": { + "type": "string", + "title": "Waiver Type" + }, + "reason": { + "type": "string", + "title": "Reason" + } + }, + "type": "object", + "required": [ + "waiver_type", + "reason" + ], + "title": "FeeWaiverCreateRequest" + }, + "FeeWaiverPayload": { + "properties": { + "feeWaiverReason": { + "type": "string", + "minLength": 1, + "title": "Feewaiverreason" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "feeWaiverReason" + ], + "title": "FeeWaiverPayload" + }, + "FeeWaiverReadResponse": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "waiver_type": { + "type": "string", + "title": "Waiver Type" + }, + "reason": { + "type": "string", + "title": "Reason" + }, + "status": { + "type": "string", + "title": "Status" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + }, + "created_at": { + "type": "string", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "waiver_type", + "reason", + "status", + "created_at" + ], + "title": "FeeWaiverReadResponse" + }, + "FeeWaiverReviewRequest": { + "properties": { + "status": { + "type": "string", + "title": "Status" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + } + }, + "type": "object", + "required": [ + "status" + ], + "title": "FeeWaiverReviewRequest" + }, + "FinishCommand": { + "properties": { + "action": { + "type": "string", + "enum": [ + "fulfill-records-request", + "close-records-request" + ], + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/NativePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "FinishCommand" + }, + "FlagStatus": { + "type": "string", + "enum": [ + "flagged", + "reviewed", + "accepted", + "rejected" + ], + "title": "FlagStatus" + }, + "FormPlan": { + "properties": { + "action": { + "type": "string", + "const": "form-plan", + "title": "Action" + }, + "formName": { + "type": "string", + "maxLength": 500, + "title": "Formname", + "default": "" + }, + "fields": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 50, + "title": "Fields" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "FormPlan" + }, + "GeneratedDraft": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "model": { + "type": "string", + "minLength": 1, + "title": "Model" + }, + "previous_response_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Previous Response Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text", + "model", + "previous_response_sha256" + ], + "title": "GeneratedDraft" + }, + "HTTPValidationError": { + "properties": { + "detail": { + "items": { + "$ref": "#/components/schemas/ValidationError" + }, + "type": "array", + "title": "Detail" + } + }, + "type": "object", + "title": "HTTPValidationError" + }, + "Handoff": { + "properties": { + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "request_id" + ], + "title": "Handoff" + }, + "ImportBundleCreate": { + "properties": { + "job_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Job Id" + }, + "connector_type": { + "type": "string", + "minLength": 1, + "title": "Connector Type" + }, + "source": { + "$ref": "#/components/schemas/SourceCreate" + }, + "sources": { + "items": { + "$ref": "#/components/schemas/SourceCreate" + }, + "type": "array", + "title": "Sources" + }, + "titles": { + "items": { + "$ref": "#/components/schemas/TitleCreate" + }, + "type": "array", + "title": "Titles" + }, + "chapters": { + "items": { + "$ref": "#/components/schemas/ChapterCreate" + }, + "type": "array", + "title": "Chapters" + }, + "sections": { + "items": { + "$ref": "#/components/schemas/SectionCreate" + }, + "type": "array", + "title": "Sections" + }, + "versions": { + "items": { + "$ref": "#/components/schemas/SectionVersionCreate" + }, + "type": "array", + "title": "Versions" + }, + "provenance": { + "additionalProperties": true, + "type": "object", + "title": "Provenance" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "connector_type", + "source" + ], + "title": "ImportBundleCreate", + "description": "Request body for local fixture/file-drop import jobs." + }, + "InclusionStatus": { + "type": "string", + "enum": [ + "included", + "excluded", + "pending" + ], + "title": "InclusionStatus" + }, + "IngestionStats": { + "properties": { + "total_sources": { + "type": "integer", + "title": "Total Sources" + }, + "active_sources": { + "type": "integer", + "title": "Active Sources" + }, + "total_documents": { + "type": "integer", + "title": "Total Documents" + }, + "documents_by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Documents By Status" + }, + "total_chunks": { + "type": "integer", + "title": "Total Chunks" + } + }, + "type": "object", + "required": [ + "total_sources", + "active_sources", + "total_documents", + "documents_by_status", + "total_chunks" + ], + "title": "IngestionStats" + }, + "IngestionStatus": { + "type": "string", + "enum": [ + "pending", + "processing", + "completed", + "failed" + ], + "title": "IngestionStatus" + }, + "InitiativeInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "policy": { + "$ref": "#/components/schemas/PolicySelection" + }, + "responsible_staff": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Responsible Staff" + }, + "target": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "title": "Target" + }, + "unit": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Unit" + }, + "due_on": { + "type": "string", + "format": "date", + "title": "Due On" + }, + "status": { + "type": "string", + "enum": [ + "planned", + "active", + "completed", + "cancelled" + ], + "title": "Status", + "default": "planned" + }, + "milestones": { + "items": { + "$ref": "#/components/schemas/Milestone" + }, + "type": "array", + "maxItems": 100, + "title": "Milestones" + }, + "measurements": { + "items": { + "$ref": "#/components/schemas/Measurement" + }, + "type": "array", + "maxItems": 1000, + "title": "Measurements" + }, + "note": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "policy", + "responsible_staff", + "target", + "unit", + "due_on", + "note" + ], + "title": "InitiativeInput" + }, + "InspectionInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "property_reference": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Property Reference" + }, + "inspection_reference": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Inspection Reference" + }, + "dataset_kind": { + "type": "string", + "enum": [ + "municipal", + "fictional" + ], + "title": "Dataset Kind" + }, + "inspector_notes": { + "type": "string", + "maxLength": 10000, + "minLength": 1, + "title": "Inspector Notes" + }, + "photo_observations": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 30, + "title": "Photo Observations" + }, + "voice_notes": { + "type": "string", + "maxLength": 10000, + "title": "Voice Notes", + "default": "" + }, + "evidence": { + "items": { + "$ref": "#/components/schemas/Evidence" + }, + "type": "array", + "maxItems": 10, + "title": "Evidence" + }, + "linked_sources": { + "items": { + "$ref": "#/components/schemas/townlight_inspections__workflow_models__SourceLink" + }, + "type": "array", + "maxItems": 30, + "title": "Linked Sources" + }, + "assigned_to": { + "type": "string", + "maxLength": 255, + "title": "Assigned To", + "default": "" + }, + "staff_notes": { + "type": "string", + "maxLength": 10000, + "title": "Staff Notes", + "default": "" + }, + "notice_draft": { + "type": "string", + "maxLength": 10000, + "title": "Notice Draft", + "default": "" + }, + "review_state": { + "type": "string", + "enum": [ + "draft", + "follow_up", + "reviewed" + ], + "title": "Review State", + "default": "draft" + }, + "review_notes": { + "type": "string", + "maxLength": 4000, + "title": "Review Notes", + "default": "" + }, + "public_summary": { + "type": "string", + "maxLength": 10000, + "title": "Public Summary", + "default": "" + }, + "analysis": { + "anyOf": [ + { + "$ref": "#/components/schemas/AnalysisRecord" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "property_reference", + "inspection_reference", + "dataset_kind", + "inspector_notes" + ], + "title": "InspectionInput" + }, + "IntakeInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "project_name": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Project Name" + }, + "project_description": { + "type": "string", + "maxLength": 10000, + "minLength": 1, + "title": "Project Description" + }, + "location": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Location" + }, + "applicant_contact": { + "type": "string", + "maxLength": 2000, + "title": "Applicant Contact", + "default": "" + }, + "requirement_revision": { + "type": "string", + "format": "uuid", + "title": "Requirement Revision" + }, + "materials": { + "items": { + "$ref": "#/components/schemas/MaterialReview" + }, + "type": "array", + "maxItems": 100, + "minItems": 1, + "title": "Materials" + }, + "linked_sources": { + "items": { + "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink" + }, + "type": "array", + "maxItems": 30, + "title": "Linked Sources" + }, + "staff_notes": { + "type": "string", + "maxLength": 10000, + "title": "Staff Notes", + "default": "" + }, + "assigned_to": { + "type": "string", + "maxLength": 255, + "title": "Assigned To", + "default": "" + }, + "review_state": { + "type": "string", + "enum": [ + "draft", + "follow_up", + "reviewed" + ], + "title": "Review State", + "default": "draft" + }, + "review_notes": { + "type": "string", + "maxLength": 4000, + "title": "Review Notes", + "default": "" + }, + "public_summary": { + "type": "string", + "maxLength": 10000, + "title": "Public Summary", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "project_name", + "project_description", + "location", + "requirement_revision", + "materials" + ], + "title": "IntakeInput" + }, + "InterpretationNoteCreate": { + "properties": { + "note_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Note Id" + }, + "note_text": { + "type": "string", + "minLength": 1, + "title": "Note Text" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "note_text" + ], + "title": "InterpretationNoteCreate", + "description": "Request body for staff-only interpretation notes." + }, + "InterviewRequest": { + "properties": { + "last_answer": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Answer" + }, + "last_field": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Field" + }, + "skipped_fields": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Skipped Fields" + } + }, + "type": "object", + "title": "InterviewRequest" + }, + "InterviewResponse": { + "properties": { + "question": { + "type": "string", + "title": "Question" + }, + "target_field": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Target Field" + }, + "all_complete": { + "type": "boolean", + "title": "All Complete" + }, + "completed_fields": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Completed Fields" + }, + "onboarding_status": { + "type": "string", + "title": "Onboarding Status" + }, + "skipped_fields": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Skipped Fields" + } + }, + "type": "object", + "required": [ + "question", + "target_field", + "all_complete", + "completed_fields", + "onboarding_status", + "skipped_fields" + ], + "title": "InterviewResponse" + }, + "ManagedFileReceipt": { + "properties": { + "original_path": { + "type": "string", + "minLength": 1, + "title": "Original Path" + }, + "stored_path": { + "type": "string", + "minLength": 1, + "title": "Stored Path" + }, + "file_name": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "File Name" + }, + "sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Sha256" + }, + "size_bytes": { + "type": "integer", + "maximum": 2147483647.0, + "minimum": 0.0, + "title": "Size Bytes" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "original_path", + "stored_path", + "file_name", + "sha256", + "size_bytes" + ], + "title": "ManagedFileReceipt" + }, + "ManagedSource": { + "properties": { + "original_path": { + "type": "string", + "title": "Original Path" + }, + "stored_path": { + "type": "string", + "title": "Stored Path" + }, + "file_name": { + "type": "string", + "title": "File Name" + }, + "sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Sha256" + }, + "size_bytes": { + "type": "integer", + "minimum": 0.0, + "title": "Size Bytes" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "original_path", + "stored_path", + "file_name", + "sha256", + "size_bytes" + ], + "title": "ManagedSource" + }, + "Material": { + "properties": { + "material_id": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]{1,80}$", + "title": "Material Id" + }, + "description": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Description" + }, + "citation": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Citation" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "material_id", + "description", + "citation" + ], + "title": "Material" + }, + "MaterialReview": { + "properties": { + "material_id": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Material Id" + }, + "status": { + "type": "string", + "enum": [ + "not_reviewed", + "provided", + "missing", + "unclear" + ], + "title": "Status", + "default": "not_reviewed" + }, + "note": { + "type": "string", + "maxLength": 2000, + "title": "Note", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "material_id" + ], + "title": "MaterialReview" + }, + "Measurement": { + "properties": { + "recorded_on": { + "type": "string", + "format": "date", + "title": "Recorded On" + }, + "value": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "title": "Value" + }, + "evidence": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Evidence" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "recorded_on", + "value", + "evidence" + ], + "title": "Measurement" + }, + "MediaAnalysis": { + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/EvidenceItem" + }, + "type": "array", + "maxItems": 10, + "minItems": 1, + "title": "Items" + }, + "code_links": { + "items": { + "$ref": "#/components/schemas/CodeLink" + }, + "type": "array", + "maxItems": 30, + "title": "Code Links" + }, + "inspector_supplied_text": { + "type": "string", + "maxLength": 10000, + "title": "Inspector Supplied Text", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "items" + ], + "title": "MediaAnalysis" + }, + "MeetingInput": { + "properties": { + "title": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Title" + }, + "scheduled_start": { + "type": "string", + "format": "date-time", + "title": "Scheduled Start" + }, + "location": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Location" + }, + "meeting_type": { + "type": "string", + "enum": [ + "regular", + "special", + "emergency", + "closed_session", + "executive" + ], + "title": "Meeting Type", + "default": "regular" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "scheduled_start", + "location" + ], + "title": "MeetingInput" + }, + "MeetingLink": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + }, + "relation": { + "type": "string", + "enum": [ + "hearing", + "context", + "precedent" + ], + "title": "Relation" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256", + "relation" + ], + "title": "MeetingLink" + }, + "MeetingSearch": { + "properties": { + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "MeetingSearch" + }, + "MeetingStageInput": { + "properties": { + "to_status": { + "type": "string", + "enum": [ + "SCHEDULED", + "NOTICED", + "PACKET_POSTED", + "IN_PROGRESS", + "RECESSED", + "ADJOURNED", + "TRANSCRIPT_READY", + "MINUTES_DRAFTED", + "MINUTES_POSTED", + "MINUTES_ADOPTED", + "MINUTES_SIGNED", + "ARCHIVED", + "CANCELLED" + ], + "title": "To Status" + }, + "statutory_basis": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Statutory Basis" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "to_status" + ], + "title": "MeetingStageInput" + }, + "MeetingsSearch": { + "properties": { + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "MeetingsSearch" + }, + "MeetingsSourceSelection": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "MeetingsSourceSelection" + }, + "MessageCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-message", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/MessagePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "MessageCommand" + }, + "MessageCreate": { + "properties": { + "message_text": { + "type": "string", + "title": "Message Text" + }, + "is_internal": { + "type": "boolean", + "title": "Is Internal", + "default": false + } + }, + "type": "object", + "required": [ + "message_text" + ], + "title": "MessageCreate" + }, + "MessagePayload": { + "properties": { + "requestMessageBody": { + "type": "string", + "minLength": 1, + "title": "Requestmessagebody" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requestMessageBody" + ], + "title": "MessagePayload" + }, + "MessageRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "sender_type": { + "type": "string", + "title": "Sender Type" + }, + "sender_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Sender Id" + }, + "message_text": { + "type": "string", + "title": "Message Text" + }, + "is_internal": { + "type": "boolean", + "title": "Is Internal" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "sender_type", + "sender_id", + "message_text", + "is_internal", + "created_at" + ], + "title": "MessageRead" + }, + "MessageView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "author": { + "type": "string", + "title": "Author" + }, + "author_role": { + "type": "string", + "title": "Author Role" + }, + "body": { + "type": "string", + "title": "Body" + }, + "visibility": { + "type": "string", + "title": "Visibility" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "author", + "author_role", + "body", + "visibility", + "created_at_unix_seconds" + ], + "title": "MessageView" + }, + "Milestone": { + "properties": { + "title": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Title" + }, + "due_on": { + "type": "string", + "format": "date", + "title": "Due On" + }, + "completed_on": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Completed On" + }, + "evidence": { + "type": "string", + "maxLength": 2000, + "title": "Evidence", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "due_on" + ], + "title": "Milestone" + }, + "MinutesDecision": { + "properties": { + "action": { + "type": "string", + "enum": [ + "post", + "adopt", + "sign" + ], + "title": "Action" + }, + "note": { + "type": "string", + "title": "Note", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "MinutesDecision" + }, + "ModelRegistryCreate": { + "properties": { + "model_name": { + "type": "string", + "title": "Model Name" + }, + "model_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Version" + }, + "parameter_count": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parameter Count" + }, + "license": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License" + }, + "model_card_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Card Url" + }, + "is_active": { + "type": "boolean", + "title": "Is Active", + "default": false + }, + "context_window_size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Context Window Size" + }, + "supports_ner": { + "type": "boolean", + "title": "Supports Ner", + "default": false + }, + "supports_vision": { + "type": "boolean", + "title": "Supports Vision", + "default": false + } + }, + "type": "object", + "required": [ + "model_name" + ], + "title": "ModelRegistryCreate", + "description": "Schema for creating a new model_registry record (POST body)." + }, + "ModelRegistryRead": { + "properties": { + "id": { + "type": "integer", + "title": "Id" + }, + "model_name": { + "type": "string", + "title": "Model Name" + }, + "model_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Version" + }, + "parameter_count": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parameter Count" + }, + "license": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License" + }, + "model_card_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Card Url" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "added_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Added At" + }, + "context_window_size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Context Window Size" + }, + "supports_ner": { + "type": "boolean", + "title": "Supports Ner" + }, + "supports_vision": { + "type": "boolean", + "title": "Supports Vision" + } + }, + "type": "object", + "required": [ + "id", + "model_name", + "is_active", + "supports_ner", + "supports_vision" + ], + "title": "ModelRegistryRead", + "description": "Schema for returning a model_registry record (GET response).\n\n``from_attributes=True`` allows construction directly from an ORM instance." + }, + "ModelRegistryUpdate": { + "properties": { + "model_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Name" + }, + "model_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Version" + }, + "parameter_count": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parameter Count" + }, + "license": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License" + }, + "model_card_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Card Url" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + }, + "context_window_size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Context Window Size" + }, + "supports_ner": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Supports Ner" + }, + "supports_vision": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Supports Vision" + } + }, + "type": "object", + "title": "ModelRegistryUpdate", + "description": "Schema for partially updating a model_registry record (PATCH body).\n\nEvery field is optional so callers can send only the fields they want to\nchange." + }, + "MotionCorrection": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "reason": { + "type": "string", + "minLength": 1, + "title": "Reason" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text", + "reason" + ], + "title": "MotionCorrection" + }, + "MotionInput": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "seconded_by": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Seconded By" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text" + ], + "title": "MotionInput" + }, + "NativePayload": { + "properties": {}, + "additionalProperties": false, + "type": "object", + "title": "NativePayload" + }, + "NativeRequestRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "requester_name": { + "type": "string", + "title": "Requester Name" + }, + "requester_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Email" + }, + "requester_phone": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Phone" + }, + "requester_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Type" + }, + "date_received": { + "type": "string", + "format": "date-time", + "title": "Date Received" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "description": { + "type": "string", + "title": "Description" + }, + "status": { + "$ref": "#/components/schemas/RequestStatus" + }, + "assigned_to": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "created_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "response_draft": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Response Draft" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + }, + "estimated_fee": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Estimated Fee" + }, + "fee_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Fee Status" + }, + "fee_waiver_requested": { + "type": "boolean", + "title": "Fee Waiver Requested", + "default": false + }, + "priority": { + "type": "string", + "title": "Priority", + "default": "normal" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + }, + "closed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Closed At" + }, + "closure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Closure Reason" + }, + "desktop_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Desktop Id" + }, + "public_tracking_number": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Public Tracking Number" + }, + "submitted_via": { + "type": "string", + "title": "Submitted Via" + }, + "deadline_label": { + "type": "string", + "title": "Deadline Label" + }, + "deadline_basis": { + "type": "string", + "title": "Deadline Basis" + }, + "deadline_reviewed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Deadline Reviewed At" + } + }, + "type": "object", + "required": [ + "id", + "requester_name", + "requester_email", + "date_received", + "statutory_deadline", + "description", + "status", + "assigned_to", + "created_by", + "created_at", + "response_draft", + "review_notes", + "desktop_id", + "public_tracking_number", + "submitted_via", + "deadline_label", + "deadline_basis", + "deadline_reviewed_at" + ], + "title": "NativeRequestRead" + }, + "NoticeDocumentInput": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text" + ], + "title": "NoticeDocumentInput" + }, + "NoticeDraft": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "body": { + "type": "string", + "maxLength": 100000, + "minLength": 1, + "title": "Body" + }, + "notice_type": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Notice Type" + }, + "statutory_basis": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Statutory Basis" + }, + "event_date": { + "type": "string", + "format": "date", + "title": "Event Date" + }, + "lead_days": { + "type": "integer", + "maximum": 365.0, + "minimum": 0.0, + "title": "Lead Days" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "body", + "notice_type", + "statutory_basis", + "event_date", + "lead_days" + ], + "title": "NoticeDraft" + }, + "NoticeInput": { + "properties": { + "notice_type": { + "type": "string", + "enum": [ + "regular", + "special", + "emergency", + "closed_session", + "executive" + ], + "title": "Notice Type" + }, + "posted_at": { + "type": "string", + "format": "date-time", + "title": "Posted At" + }, + "minimum_notice_hours": { + "type": "integer", + "minimum": 0.0, + "title": "Minimum Notice Hours" + }, + "statutory_basis": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Statutory Basis" + }, + "approved_by": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Approved By" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "notice_type", + "posted_at", + "minimum_notice_hours" + ], + "title": "NoticeInput" + }, + "NoticeProofInput": { + "properties": { + "location": { + "type": "string", + "minLength": 1, + "title": "Location" + }, + "note": { + "type": "string", + "title": "Note", + "default": "" + }, + "document_delivery_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Document Delivery Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "location" + ], + "title": "NoticeProofInput" + }, + "NotificationLogRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "template_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Template Id" + }, + "recipient_email": { + "type": "string", + "title": "Recipient Email" + }, + "request_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Request Id" + }, + "channel": { + "type": "string", + "title": "Channel" + }, + "status": { + "type": "string", + "title": "Status" + }, + "sent_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Sent At" + }, + "error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Message" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "template_id", + "recipient_email", + "request_id", + "channel", + "status", + "sent_at", + "error_message", + "created_at" + ], + "title": "NotificationLogRead" + }, + "NotificationTemplateCreate": { + "properties": { + "event_type": { + "type": "string", + "title": "Event Type" + }, + "channel": { + "type": "string", + "title": "Channel", + "default": "email" + }, + "subject_template": { + "type": "string", + "title": "Subject Template" + }, + "body_template": { + "type": "string", + "title": "Body Template" + } + }, + "type": "object", + "required": [ + "event_type", + "subject_template", + "body_template" + ], + "title": "NotificationTemplateCreate" + }, + "NotificationTemplateRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "event_type": { + "type": "string", + "title": "Event Type" + }, + "channel": { + "type": "string", + "title": "Channel" + }, + "subject_template": { + "type": "string", + "title": "Subject Template" + }, + "body_template": { + "type": "string", + "title": "Body Template" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "event_type", + "channel", + "subject_template", + "body_template", + "is_active", + "created_at" + ], + "title": "NotificationTemplateRead" + }, + "NotificationTemplateUpdate": { + "properties": { + "subject_template": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Subject Template" + }, + "body_template": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Body Template" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "NotificationTemplateUpdate" + }, + "NotificationView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "notification_id": { + "type": "string", + "title": "Notification Id" + }, + "module_id": { + "type": "string", + "title": "Module Id" + }, + "record_id": { + "type": "string", + "title": "Record Id" + }, + "audience": { + "type": "string", + "title": "Audience" + }, + "channel": { + "type": "string", + "title": "Channel" + }, + "subject": { + "type": "string", + "title": "Subject" + }, + "body": { + "type": "string", + "title": "Body" + }, + "status": { + "type": "string", + "title": "Status" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + }, + "sent_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Sent At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "notification_id", + "module_id", + "record_id", + "audience", + "channel", + "subject", + "body", + "status", + "created_at_unix_seconds", + "sent_at_unix_seconds" + ], + "title": "NotificationView" + }, + "OllamaModelInfo": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Size" + }, + "details": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Details" + } + }, + "type": "object", + "required": [ + "name" + ], + "title": "OllamaModelInfo" + }, + "OllamaStatus": { + "properties": { + "status": { + "type": "string", + "title": "Status" + }, + "models": { + "items": { + "$ref": "#/components/schemas/OllamaModelInfo" + }, + "type": "array", + "title": "Models" + } + }, + "type": "object", + "required": [ + "status", + "models" + ], + "title": "OllamaStatus" + }, + "OperationalMetrics": { + "properties": { + "average_response_time_days": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Average Response Time Days" + }, + "median_response_time_days": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Median Response Time Days" + }, + "requests_by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Requests By Status" + }, + "requests_by_department": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Requests By Department" + }, + "deadline_compliance_rate": { + "type": "number", + "title": "Deadline Compliance Rate" + }, + "total_open": { + "type": "integer", + "title": "Total Open" + }, + "total_closed": { + "type": "integer", + "title": "Total Closed" + }, + "total_overdue": { + "type": "integer", + "title": "Total Overdue" + }, + "clarification_frequency": { + "type": "number", + "title": "Clarification Frequency" + }, + "top_request_topics": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Top Request Topics" + } + }, + "type": "object", + "required": [ + "average_response_time_days", + "median_response_time_days", + "requests_by_status", + "requests_by_department", + "deadline_compliance_rate", + "total_open", + "total_closed", + "total_overdue", + "clarification_frequency", + "top_request_topics" + ], + "title": "OperationalMetrics" + }, + "Outline": { + "properties": { + "title": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Title" + }, + "question_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "maxItems": 50, + "minItems": 1, + "title": "Question Ids" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "question_ids" + ], + "title": "Outline" + }, + "Packet": { + "properties": { + "expected_revision": { + "type": "string", + "format": "uuid", + "title": "Expected Revision" + }, + "visibility": { + "type": "string", + "enum": [ + "staff_only", + "records_copy" + ], + "title": "Visibility" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "expected_revision", + "visibility" + ], + "title": "Packet" + }, + "PacketInput": { + "properties": { + "agenda_item_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "title": "Agenda Item Ids" + }, + "source_files": { + "items": { + "$ref": "#/components/schemas/ManagedSource" + }, + "type": "array", + "title": "Source Files" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "agenda_item_ids" + ], + "title": "PacketInput" + }, + "Pathway": { + "properties": { + "project_type": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Project Type" + }, + "proposal": { + "type": "string", + "maxLength": 4000, + "title": "Proposal", + "default": "" + }, + "location_context": { + "type": "string", + "maxLength": 1000, + "title": "Location Context", + "default": "" + }, + "requirement_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Requirement Revision" + }, + "fee_link": { + "anyOf": [ + { + "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "project_type" + ], + "title": "Pathway" + }, + "PathwayStep": { + "properties": { + "step": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Step" + }, + "citation": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Citation" + }, + "typical_time": { + "type": "string", + "maxLength": 1000, + "title": "Typical Time", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "step", + "citation" + ], + "title": "PathwayStep" + }, + "PlainLanguageSummaryCreate": { + "properties": { + "summary_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Summary Id" + }, + "section_version_id": { + "type": "string", + "minLength": 1, + "title": "Section Version Id" + }, + "summary_text": { + "type": "string", + "minLength": 1, + "title": "Summary Text" + }, + "language_code": { + "type": "string", + "title": "Language Code", + "default": "en" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "section_version_id", + "summary_text" + ], + "title": "PlainLanguageSummaryCreate", + "description": "Request body for staff-drafted plain-language summaries." + }, + "PolicySelection": { + "properties": { + "plan_id": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Plan Id" + }, + "revision_id": { + "type": "string", + "maxLength": 36, + "minLength": 36, + "title": "Revision Id" + }, + "policy_id": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Policy Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "plan_id", + "revision_id", + "policy_id" + ], + "title": "PolicySelection" + }, + "PortalModeResponse": { + "properties": { + "mode": { + "type": "string", + "enum": [ + "public", + "private" + ], + "title": "Mode", + "description": "Active portal posture for this deployment. ``public`` = minimal resident surface (landing + authenticated records-request submission + resident registration) reachable without staff auth. ``private`` = staff-only; no public routes, no resident self-registration." + } + }, + "type": "object", + "required": [ + "mode" + ], + "title": "PortalModeResponse", + "description": "T5D — schema for ``GET /config/portal-mode``.\n\nExposed to the frontend on boot so it can branch routing without a\nuser-identity lookup. The payload is intentionally the single field\nbelow — no staff config, no user state, no schema version." + }, + "PrepareArtifact": { + "properties": { + "kind": { + "type": "string", + "enum": [ + "response", + "release-package" + ], + "title": "Kind" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "kind" + ], + "title": "PrepareArtifact" + }, + "Proof": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + }, + "filename": { + "type": "string", + "maxLength": 150, + "minLength": 1, + "title": "Filename" + }, + "content_base64": { + "type": "string", + "maxLength": 7000000, + "minLength": 1, + "title": "Content Base64" + }, + "location": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Location" + }, + "published_at": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Published At" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence", + "filename", + "content_base64", + "location", + "published_at" + ], + "title": "Proof" + }, + "Proposal": { + "properties": { + "id": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Id" + }, + "version_id": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Version Id" + }, + "meeting_id": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "ordinance_number": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Ordinance Number" + }, + "proposed_text": { + "type": "string", + "maxLength": 1000000, + "minLength": 1, + "title": "Proposed Text" + }, + "supersedes_id": { + "anyOf": [ + { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$" + }, + { + "type": "null" + } + ], + "title": "Supersedes Id" + }, + "reconciliation_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reconciliation Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "version_id", + "meeting_id", + "title", + "ordinance_number", + "proposed_text" + ], + "title": "Proposal" + }, + "PublicExplore": { + "properties": { + "goal": { + "type": "string", + "maxLength": 500, + "title": "Goal", + "default": "" + }, + "topic": { + "type": "string", + "maxLength": 160, + "title": "Topic", + "default": "" + }, + "neighborhood": { + "type": "string", + "maxLength": 255, + "title": "Neighborhood", + "default": "" + }, + "plan_type": { + "type": "string", + "maxLength": 120, + "title": "Plan Type", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "title": "PublicExplore" + }, + "PublicIntake": { + "properties": { + "requester": { + "type": "string", + "minLength": 1, + "title": "Requester" + }, + "requesterContact": { + "type": "string", + "minLength": 1, + "title": "Requestercontact" + }, + "summary": { + "type": "string", + "minLength": 1, + "title": "Summary" + }, + "deadline": { + "type": "string", + "title": "Deadline", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requester", + "requesterContact", + "summary" + ], + "title": "PublicIntake" + }, + "PublicLookup": { + "properties": { + "trackingNumber": { + "type": "string", + "minLength": 1, + "title": "Trackingnumber" + }, + "requesterContact": { + "type": "string", + "minLength": 1, + "title": "Requestercontact" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "trackingNumber", + "requesterContact" + ], + "title": "PublicLookup" + }, + "PublicMessage": { + "properties": { + "trackingNumber": { + "type": "string", + "minLength": 1, + "title": "Trackingnumber" + }, + "requesterContact": { + "type": "string", + "minLength": 1, + "title": "Requestercontact" + }, + "publicRequestMessage": { + "type": "string", + "minLength": 1, + "title": "Publicrequestmessage" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "trackingNumber", + "requesterContact", + "publicRequestMessage" + ], + "title": "PublicMessage" + }, + "PublicStatusView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "label": { + "type": "string", + "title": "Label" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "status": { + "type": "string", + "title": "Status" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "label", + "summary", + "status", + "created_at_unix_seconds" + ], + "title": "PublicStatusView" + }, + "PublicationView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "source_module": { + "type": "string", + "title": "Source Module" + }, + "source_record_id": { + "type": "string", + "title": "Source Record Id" + }, + "record_type": { + "type": "string", + "title": "Record Type" + }, + "public_payload": { + "type": "string", + "title": "Public Payload" + }, + "payload_hash": { + "type": "string", + "title": "Payload Hash" + }, + "published_at_unix_seconds": { + "type": "integer", + "title": "Published At Unix Seconds" + }, + "retracted_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Retracted At Unix Seconds" + }, + "retracted_by": { + "type": "string", + "title": "Retracted By", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "source_module", + "source_record_id", + "record_type", + "public_payload", + "payload_hash", + "published_at_unix_seconds" + ], + "title": "PublicationView" + }, + "PublishingPlan": { + "properties": { + "action": { + "type": "string", + "const": "publishing-workflow", + "title": "Action" + }, + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "hasReview": { + "type": "boolean", + "title": "Hasreview", + "default": false + }, + "hasPlainLanguage": { + "type": "boolean", + "title": "Hasplainlanguage", + "default": false + }, + "hasTranslationReview": { + "type": "boolean", + "title": "Hastranslationreview", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "PublishingPlan" + }, + "Question": { + "properties": { + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + }, + "question": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Question" + }, + "kind": { + "type": "string", + "enum": [ + "use", + "dimension" + ], + "title": "Kind" + }, + "key": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Key" + }, + "audience": { + "type": "string", + "enum": [ + "resident", + "staff" + ], + "title": "Audience", + "default": "resident" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "jurisdiction", + "query", + "question", + "kind", + "key" + ], + "title": "Question" + }, + "QuestionAnswerRequest": { + "properties": { + "question": { + "type": "string", + "minLength": 1, + "title": "Question" + }, + "section_number": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Section Number" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "question" + ], + "title": "QuestionAnswerRequest", + "description": "Request body for citation-grounded code Q&A." + }, + "RecordsDocumentView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "attachment_id": { + "type": "string", + "title": "Attachment Id" + }, + "title": { + "type": "string", + "title": "Title" + }, + "original_path": { + "type": "string", + "title": "Original Path" + }, + "stored_path": { + "type": "string", + "title": "Stored Path" + }, + "citation": { + "type": "string", + "title": "Citation" + }, + "sha256": { + "type": "string", + "title": "Sha256" + }, + "size_bytes": { + "type": "integer", + "title": "Size Bytes" + }, + "status": { + "type": "string", + "title": "Status" + }, + "added_by": { + "type": "string", + "title": "Added By" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + }, + "release_original_path": { + "type": "string", + "title": "Release Original Path", + "default": "" + }, + "release_stored_path": { + "type": "string", + "title": "Release Stored Path", + "default": "" + }, + "release_file_name": { + "type": "string", + "title": "Release File Name", + "default": "" + }, + "release_sha256": { + "type": "string", + "title": "Release Sha256", + "default": "" + }, + "release_size_bytes": { + "type": "integer", + "title": "Release Size Bytes", + "default": 0 + }, + "release_status": { + "type": "string", + "title": "Release Status", + "default": "" + }, + "release_note": { + "type": "string", + "title": "Release Note", + "default": "" + }, + "release_added_by": { + "type": "string", + "title": "Release Added By", + "default": "" + }, + "release_added_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Release Added At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "attachment_id", + "title", + "original_path", + "stored_path", + "citation", + "sha256", + "size_bytes", + "status", + "added_by", + "created_at_unix_seconds" + ], + "title": "RecordsDocumentView" + }, + "RecordsOperationRead": { + "properties": { + "action": { + "type": "string", + "title": "Action" + }, + "message": { + "type": "string", + "title": "Message" + }, + "request": { + "$ref": "#/components/schemas/RecordsView" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "message", + "request" + ], + "title": "RecordsOperationRead" + }, + "RecordsStateRead": { + "properties": { + "demo_fixture": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Demo Fixture" + }, + "records_requests": { + "items": { + "$ref": "#/components/schemas/RecordsView" + }, + "type": "array", + "title": "Records Requests" + }, + "notification_events": { + "items": { + "$ref": "#/components/schemas/NotificationView" + }, + "type": "array", + "title": "Notification Events" + }, + "publication_events": { + "items": { + "$ref": "#/components/schemas/PublicationView" + }, + "type": "array", + "title": "Publication Events" + }, + "audit_entries": { + "items": { + "$ref": "#/components/schemas/AuditView" + }, + "type": "array", + "title": "Audit Entries" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "records_requests" + ], + "title": "RecordsStateRead" + }, + "RecordsView": { + "properties": { + "request_id": { + "type": "string", + "title": "Request Id" + }, + "id": { + "type": "string", + "title": "Id" + }, + "public_tracking_number": { + "type": "string", + "title": "Public Tracking Number" + }, + "requester": { + "type": "string", + "title": "Requester" + }, + "requester_contact": { + "type": "string", + "title": "Requester Contact" + }, + "submitted_via": { + "type": "string", + "title": "Submitted Via" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "deadline": { + "type": "string", + "title": "Deadline" + }, + "deadline_basis": { + "type": "string", + "title": "Deadline Basis" + }, + "status": { + "type": "string", + "title": "Status" + }, + "assigned_to": { + "type": "string", + "title": "Assigned To" + }, + "clarification_notes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Clarification Notes" + }, + "search_notes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Search Notes" + }, + "search_sessions": { + "items": { + "$ref": "#/components/schemas/SearchReceiptView" + }, + "type": "array", + "title": "Search Sessions" + }, + "exemption_reviews": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Exemption Reviews" + }, + "exemption_decisions": { + "items": { + "$ref": "#/components/schemas/ExemptionDecisionView" + }, + "type": "array", + "title": "Exemption Decisions" + }, + "fee_estimate": { + "type": "string", + "title": "Fee Estimate" + }, + "fee_line_items": { + "items": { + "$ref": "#/components/schemas/FeeLineView" + }, + "type": "array", + "title": "Fee Line Items" + }, + "fee_waiver_reason": { + "type": "string", + "title": "Fee Waiver Reason" + }, + "citations": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Citations" + }, + "response_draft": { + "type": "string", + "title": "Response Draft" + }, + "approval_notes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Approval Notes" + }, + "exports": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Exports" + }, + "documents": { + "items": { + "$ref": "#/components/schemas/RecordsDocumentView" + }, + "type": "array", + "title": "Documents" + }, + "release_packages": { + "items": { + "$ref": "#/components/schemas/ReleasePackageView" + }, + "type": "array", + "title": "Release Packages" + }, + "timeline": { + "items": { + "$ref": "#/components/schemas/TimelineView" + }, + "type": "array", + "title": "Timeline" + }, + "public_status_events": { + "items": { + "$ref": "#/components/schemas/PublicStatusView" + }, + "type": "array", + "title": "Public Status Events" + }, + "messages": { + "items": { + "$ref": "#/components/schemas/MessageView" + }, + "type": "array", + "title": "Messages" + }, + "deadline_reviewed_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Deadline Reviewed At Unix Seconds" + }, + "approved_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Approved At Unix Seconds" + }, + "fulfilled_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Fulfilled At Unix Seconds" + }, + "closed_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Closed At Unix Seconds" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "request_id", + "id", + "public_tracking_number", + "requester", + "requester_contact", + "submitted_via", + "summary", + "deadline", + "deadline_basis", + "status", + "assigned_to", + "clarification_notes", + "search_notes", + "search_sessions", + "exemption_reviews", + "exemption_decisions", + "fee_estimate", + "fee_line_items", + "fee_waiver_reason", + "citations", + "response_draft", + "approval_notes", + "exports", + "timeline", + "public_status_events", + "messages", + "deadline_reviewed_at_unix_seconds", + "approved_at_unix_seconds", + "fulfilled_at_unix_seconds", + "closed_at_unix_seconds", + "created_at_unix_seconds" + ], + "title": "RecordsView" + }, + "ReleasePackageView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "export_path": { + "type": "string", + "title": "Export Path" + }, + "package_hash": { + "type": "string", + "title": "Package Hash" + }, + "document_count": { + "type": "integer", + "title": "Document Count" + }, + "release_artifact_count": { + "type": "integer", + "title": "Release Artifact Count" + }, + "search_session_count": { + "type": "integer", + "title": "Search Session Count" + }, + "release_count": { + "type": "integer", + "title": "Release Count" + }, + "redacted_count": { + "type": "integer", + "title": "Redacted Count" + }, + "exempt_count": { + "type": "integer", + "title": "Exempt Count" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "export_path", + "package_hash", + "document_count", + "release_artifact_count", + "search_session_count", + "release_count", + "redacted_count", + "exempt_count", + "created_at_unix_seconds" + ], + "title": "ReleasePackageView" + }, + "RepeatLookup": { + "properties": { + "property_reference": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Property Reference" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "property_reference" + ], + "title": "RepeatLookup" + }, + "RequestCreate": { + "properties": { + "requester_name": { + "type": "string", + "maxLength": 255, + "title": "Requester Name" + }, + "requester_email": { + "anyOf": [ + { + "type": "string", + "maxLength": 255 + }, + { + "type": "null" + } + ], + "title": "Requester Email" + }, + "requester_phone": { + "anyOf": [ + { + "type": "string", + "maxLength": 50 + }, + { + "type": "null" + } + ], + "title": "Requester Phone" + }, + "requester_type": { + "anyOf": [ + { + "type": "string", + "maxLength": 100 + }, + { + "type": "null" + } + ], + "title": "Requester Type" + }, + "description": { + "type": "string", + "maxLength": 10000, + "title": "Description" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "priority": { + "type": "string", + "title": "Priority", + "default": "normal" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string", + "pattern": "^(narrow|moderate|broad)$" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + } + }, + "type": "object", + "required": [ + "requester_name", + "description" + ], + "title": "RequestCreate" + }, + "RequestDocumentAdd": { + "properties": { + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "relevance_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Relevance Note" + } + }, + "type": "object", + "required": [ + "document_id" + ], + "title": "RequestDocumentAdd" + }, + "RequestDocumentRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "relevance_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Relevance Note" + }, + "exemption_flags": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Exemption Flags" + }, + "inclusion_status": { + "$ref": "#/components/schemas/InclusionStatus" + }, + "attached_at": { + "type": "string", + "format": "date-time", + "title": "Attached At" + }, + "attached_by": { + "type": "string", + "format": "uuid", + "title": "Attached By" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "document_id", + "relevance_note", + "exemption_flags", + "inclusion_status", + "attached_at", + "attached_by" + ], + "title": "RequestDocumentRead" + }, + "RequestRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "requester_name": { + "type": "string", + "title": "Requester Name" + }, + "requester_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Email" + }, + "requester_phone": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Phone" + }, + "requester_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Type" + }, + "date_received": { + "type": "string", + "format": "date-time", + "title": "Date Received" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "description": { + "type": "string", + "title": "Description" + }, + "status": { + "$ref": "#/components/schemas/RequestStatus" + }, + "assigned_to": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "created_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "response_draft": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Response Draft" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + }, + "estimated_fee": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Estimated Fee" + }, + "fee_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Fee Status" + }, + "fee_waiver_requested": { + "type": "boolean", + "title": "Fee Waiver Requested", + "default": false + }, + "priority": { + "type": "string", + "title": "Priority", + "default": "normal" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + }, + "closed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Closed At" + }, + "closure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Closure Reason" + } + }, + "type": "object", + "required": [ + "id", + "requester_name", + "requester_email", + "date_received", + "statutory_deadline", + "description", + "status", + "assigned_to", + "created_by", + "created_at", + "response_draft", + "review_notes" + ], + "title": "RequestRead" + }, + "RequestStats": { + "properties": { + "total_requests": { + "type": "integer", + "title": "Total Requests" + }, + "by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "By Status" + }, + "approaching_deadline": { + "type": "integer", + "title": "Approaching Deadline" + }, + "overdue": { + "type": "integer", + "title": "Overdue" + } + }, + "type": "object", + "required": [ + "total_requests", + "by_status", + "approaching_deadline", + "overdue" + ], + "title": "RequestStats" + }, + "RequestStatus": { + "type": "string", + "enum": [ + "received", + "clarification_needed", + "assigned", + "searching", + "in_review", + "ready_for_release", + "drafted", + "approved", + "fulfilled", + "closed" + ], + "title": "RequestStatus" + }, + "RequestUpdate": { + "properties": { + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "status": { + "anyOf": [ + { + "$ref": "#/components/schemas/RequestStatus" + }, + { + "type": "null" + } + ] + }, + "assigned_to": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "response_draft": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Response Draft" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + } + }, + "type": "object", + "title": "RequestUpdate" + }, + "RequirementBundle": { + "properties": { + "requirement_id": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]{1,100}$", + "title": "Requirement Id" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "project_type": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Project Type" + }, + "source_reference": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Source Reference" + }, + "source_date": { + "type": "string", + "format": "date", + "title": "Source Date" + }, + "effective_on": { + "type": "string", + "format": "date", + "title": "Effective On" + }, + "dataset_kind": { + "type": "string", + "enum": [ + "municipal", + "fictional" + ], + "title": "Dataset Kind" + }, + "filename": { + "type": "string", + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$", + "title": "Filename" + }, + "content_base64": { + "type": "string", + "maxLength": 14000000, + "minLength": 1, + "title": "Content Base64" + }, + "sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Sha256" + }, + "materials": { + "items": { + "$ref": "#/components/schemas/Material" + }, + "type": "array", + "maxItems": 100, + "minItems": 1, + "title": "Materials" + }, + "pathway": { + "items": { + "$ref": "#/components/schemas/PathwayStep" + }, + "type": "array", + "maxItems": 100, + "title": "Pathway" + }, + "fee_link": { + "anyOf": [ + { + "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink" + }, + { + "type": "null" + } + ] + }, + "staff_note": { + "type": "string", + "maxLength": 4000, + "title": "Staff Note", + "default": "" + }, + "change_note": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Change Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requirement_id", + "title", + "jurisdiction", + "project_type", + "source_reference", + "source_date", + "effective_on", + "dataset_kind", + "filename", + "content_base64", + "sha256", + "materials", + "change_note" + ], + "title": "RequirementBundle" + }, + "ResponseLetterCreate": { + "properties": { + "template_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Template Id" + } + }, + "type": "object", + "title": "ResponseLetterCreate" + }, + "ResponseLetterRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "template_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Template Id" + }, + "generated_content": { + "type": "string", + "title": "Generated Content" + }, + "edited_content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Edited Content" + }, + "status": { + "type": "string", + "title": "Status" + }, + "generated_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Generated By" + }, + "approved_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Approved By" + }, + "sent_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Sent At" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "template_id", + "generated_content", + "edited_content", + "status", + "generated_by", + "approved_by", + "sent_at", + "created_at" + ], + "title": "ResponseLetterRead" + }, + "ResponseLetterUpdate": { + "properties": { + "edited_content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Edited Content" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + } + }, + "type": "object", + "title": "ResponseLetterUpdate" + }, + "ReviewInput": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "body": { + "type": "string", + "maxLength": 5000, + "title": "Body", + "default": "" + }, + "hasAltText": { + "type": "boolean", + "title": "Hasalttext", + "default": false + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "en" + } + }, + "additionalProperties": false, + "type": "object", + "title": "ReviewInput" + }, + "Revision": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + }, + "document": { + "$ref": "#/components/schemas/NoticeDraft" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence", + "document" + ], + "title": "Revision" + }, + "RewriteInput": { + "properties": { + "action": { + "type": "string", + "enum": [ + "plain-language", + "language-variant" + ], + "title": "Action" + }, + "text": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Text" + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "text" + ], + "title": "RewriteInput" + }, + "RewriteResult": { + "properties": { + "action": { + "type": "string", + "enum": [ + "plain-language", + "language-variant" + ], + "title": "Action" + }, + "text": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Text" + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "" + }, + "outcome": { + "type": "string", + "enum": [ + "generated", + "unavailable" + ], + "title": "Outcome" + }, + "generated": { + "anyOf": [ + { + "type": "string", + "maxLength": 100000 + }, + { + "type": "null" + } + ], + "title": "Generated" + }, + "model": { + "anyOf": [ + { + "type": "string", + "maxLength": 200 + }, + { + "type": "null" + } + ], + "title": "Model" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "text", + "outcome" + ], + "title": "RewriteResult" + }, + "Rule": { + "properties": { + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "zone_code": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Zone Code" + }, + "key": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Key" + }, + "section_number": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Section Number" + }, + "kind": { + "type": "string", + "enum": [ + "use", + "dimension" + ], + "title": "Kind" + }, + "value": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Value" + }, + "overlay_code": { + "anyOf": [ + { + "type": "string", + "maxLength": 255 + }, + { + "type": "null" + } + ], + "title": "Overlay Code" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "jurisdiction", + "zone_code", + "key", + "section_number", + "kind", + "value" + ], + "title": "Rule" + }, + "RuleTestMatch": { + "properties": { + "matched_text": { + "type": "string", + "title": "Matched Text" + }, + "start": { + "type": "integer", + "title": "Start" + }, + "end": { + "type": "integer", + "title": "End" + } + }, + "type": "object", + "required": [ + "matched_text", + "start", + "end" + ], + "title": "RuleTestMatch" + }, + "RuleTestRequest": { + "properties": { + "sample_text": { + "type": "string", + "title": "Sample Text" + } + }, + "type": "object", + "required": [ + "sample_text" + ], + "title": "RuleTestRequest" + }, + "RuleTestResponse": { + "properties": { + "rule_id": { + "type": "string", + "format": "uuid", + "title": "Rule Id" + }, + "rule_type": { + "type": "string", + "title": "Rule Type" + }, + "matched": { + "type": "boolean", + "title": "Matched" + }, + "matches": { + "items": { + "$ref": "#/components/schemas/RuleTestMatch" + }, + "type": "array", + "title": "Matches" + } + }, + "type": "object", + "required": [ + "rule_id", + "rule_type", + "matched", + "matches" + ], + "title": "RuleTestResponse" + }, + "RuleType": { + "type": "string", + "enum": [ + "regex", + "keyword", + "llm_prompt" + ], + "title": "RuleType" + }, + "SaveReview": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "body": { + "type": "string", + "maxLength": 5000, + "title": "Body", + "default": "" + }, + "hasAltText": { + "type": "boolean", + "title": "Hasalttext", + "default": false + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "en" + }, + "ai_analysis": { + "anyOf": [ + { + "type": "string", + "maxLength": 100000 + }, + { + "type": "null" + } + ], + "title": "Ai Analysis" + }, + "ai_analysis_model": { + "anyOf": [ + { + "type": "string", + "maxLength": 200 + }, + { + "type": "null" + } + ], + "title": "Ai Analysis Model" + }, + "ai_outcome": { + "type": "string", + "enum": [ + "generated", + "unavailable", + "failed" + ], + "title": "Ai Outcome" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "ai_outcome" + ], + "title": "SaveReview" + }, + "SearchFilterOptions": { + "properties": { + "file_types": { + "items": { + "type": "string" + }, + "type": "array", + "title": "File Types" + }, + "source_names": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Source Names" + }, + "departments": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array", + "title": "Departments", + "default": [] + }, + "date_range": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Date Range" + } + }, + "type": "object", + "required": [ + "file_types", + "source_names" + ], + "title": "SearchFilterOptions" + }, + "SearchInput": { + "properties": { + "query": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "SearchInput" + }, + "SearchNoteCommand": { + "properties": { + "action": { + "type": "string", + "const": "record-records-search", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/SearchNotePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "SearchNoteCommand" + }, + "SearchNotePayload": { + "properties": { + "sourceNote": { + "type": "string", + "minLength": 1, + "title": "Sourcenote" + }, + "citation": { + "type": "string", + "title": "Citation", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sourceNote" + ], + "title": "SearchNotePayload" + }, + "SearchReceiptCommand": { + "properties": { + "action": { + "type": "string", + "const": "record-records-search-session", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/SearchReceiptPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "SearchReceiptCommand" + }, + "SearchReceiptPayload": { + "properties": { + "searchQuery": { + "type": "string", + "minLength": 1, + "title": "Searchquery" + }, + "searchLocations": { + "type": "string", + "minLength": 1, + "title": "Searchlocations" + }, + "searchResultTitle": { + "type": "string", + "minLength": 1, + "title": "Searchresulttitle" + }, + "searchResultCitation": { + "type": "string", + "minLength": 1, + "title": "Searchresultcitation" + }, + "searchResultSummary": { + "type": "string", + "minLength": 1, + "title": "Searchresultsummary" + }, + "searchResultStatus": { + "type": "string", + "title": "Searchresultstatus", + "default": "" + }, + "searchReviewer": { + "type": "string", + "title": "Searchreviewer", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "searchQuery", + "searchLocations", + "searchResultTitle", + "searchResultCitation", + "searchResultSummary" + ], + "title": "SearchReceiptPayload" + }, + "SearchReceiptView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "query": { + "type": "string", + "title": "Query" + }, + "locations": { + "type": "string", + "title": "Locations" + }, + "reviewer": { + "type": "string", + "title": "Reviewer" + }, + "results": { + "items": { + "$ref": "#/components/schemas/SearchResultView" + }, + "type": "array", + "title": "Results" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "query", + "locations", + "reviewer", + "results", + "created_at_unix_seconds" + ], + "title": "SearchReceiptView" + }, + "SearchRequest": { + "properties": { + "query": { + "type": "string", + "title": "Query" + }, + "session_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Session Id" + }, + "filters": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Filters" + }, + "limit": { + "type": "integer", + "maximum": 50.0, + "title": "Limit", + "default": 10 + }, + "synthesize": { + "type": "boolean", + "title": "Synthesize", + "default": false + } + }, + "type": "object", + "required": [ + "query" + ], + "title": "SearchRequest" + }, + "SearchResponse": { + "properties": { + "query_id": { + "type": "string", + "format": "uuid", + "title": "Query Id" + }, + "session_id": { + "type": "string", + "format": "uuid", + "title": "Session Id" + }, + "query_text": { + "type": "string", + "title": "Query Text" + }, + "results": { + "items": { + "$ref": "#/components/schemas/SearchResultItem" + }, + "type": "array", + "title": "Results" + }, + "results_count": { + "type": "integer", + "title": "Results Count" + }, + "synthesized_answer": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Synthesized Answer" + }, + "ai_generated": { + "type": "boolean", + "title": "Ai Generated", + "default": false + } + }, + "type": "object", + "required": [ + "query_id", + "session_id", + "query_text", + "results", + "results_count" + ], + "title": "SearchResponse" + }, + "SearchResultItem": { + "properties": { + "chunk_id": { + "type": "string", + "format": "uuid", + "title": "Chunk Id" + }, + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "filename": { + "type": "string", + "title": "Filename" + }, + "file_type": { + "type": "string", + "title": "File Type" + }, + "source_path": { + "type": "string", + "title": "Source Path" + }, + "page_number": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Page Number" + }, + "content_text": { + "type": "string", + "title": "Content Text" + }, + "similarity_score": { + "type": "number", + "title": "Similarity Score" + }, + "rank": { + "type": "integer", + "title": "Rank" + } + }, + "type": "object", + "required": [ + "chunk_id", + "document_id", + "filename", + "file_type", + "source_path", + "page_number", + "content_text", + "similarity_score", + "rank" + ], + "title": "SearchResultItem" + }, + "SearchResultView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "title": { + "type": "string", + "title": "Title" + }, + "citation": { + "type": "string", + "title": "Citation" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "status": { + "type": "string", + "title": "Status" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "title", + "citation", + "summary", + "status" + ], + "title": "SearchResultView" + }, + "SearchSessionRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "user_id": { + "type": "string", + "format": "uuid", + "title": "User Id" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "queries": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array", + "title": "Queries", + "default": [] + } + }, + "type": "object", + "required": [ + "id", + "user_id", + "created_at" + ], + "title": "SearchSessionRead" + }, + "SectionCreate": { + "properties": { + "section_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Section Id" + }, + "chapter_id": { + "type": "string", + "minLength": 1, + "title": "Chapter Id" + }, + "section_number": { + "type": "string", + "minLength": 1, + "title": "Section Number" + }, + "section_heading": { + "type": "string", + "minLength": 1, + "title": "Section Heading" + }, + "parent_section_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parent Section Id" + }, + "sort_order": { + "type": "integer", + "title": "Sort Order", + "default": 0 + }, + "administrative_regulation_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Administrative Regulation Refs" + }, + "resolution_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Resolution Refs" + }, + "policy_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Policy Refs" + }, + "approved_summary_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Approved Summary Refs" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "chapter_id", + "section_number", + "section_heading" + ], + "title": "SectionCreate", + "description": "Request body for creating a code section or subsection." + }, + "SectionVersionCreate": { + "properties": { + "version_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Version Id" + }, + "section_id": { + "type": "string", + "minLength": 1, + "title": "Section Id" + }, + "source_id": { + "type": "string", + "minLength": 1, + "title": "Source Id" + }, + "version_label": { + "type": "string", + "minLength": 1, + "title": "Version Label" + }, + "body": { + "type": "string", + "minLength": 1, + "title": "Body" + }, + "effective_start": { + "type": "string", + "format": "date", + "title": "Effective Start" + }, + "effective_end": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective End" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + }, + "is_current": { + "type": "boolean", + "title": "Is Current", + "default": false + }, + "adoption_event_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Adoption Event Id" + }, + "amendment_event_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Amendment Event Id" + }, + "amendment_summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Amendment Summary" + }, + "prior_version_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Prior Version Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "section_id", + "source_id", + "version_label", + "body", + "effective_start" + ], + "title": "SectionVersionCreate", + "description": "Request body for adding an immutable section version." + }, + "Selection": { + "properties": { + "recording_id": { + "type": "string", + "format": "uuid", + "title": "Recording Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "recording_id", + "expected_sha256" + ], + "title": "Selection" + }, + "SentenceInput": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "citations": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Citations" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text" + ], + "title": "SentenceInput" + }, + "ServiceAccountCreate": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole", + "default": "read_only" + } + }, + "type": "object", + "required": [ + "name" + ], + "title": "ServiceAccountCreate" + }, + "ServiceAccountCreated": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "api_key": { + "type": "string", + "title": "Api Key" + } + }, + "type": "object", + "required": [ + "id", + "name", + "role", + "created_by", + "created_at", + "is_active", + "api_key" + ], + "title": "ServiceAccountCreated", + "description": "Returned only on creation — includes the plaintext API key (shown once)." + }, + "ServiceAccountRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + } + }, + "type": "object", + "required": [ + "id", + "name", + "role", + "created_by", + "created_at", + "is_active" + ], + "title": "ServiceAccountRead" + }, + "ServiceAccountUpdate": { + "properties": { + "role": { + "anyOf": [ + { + "$ref": "#/components/schemas/UserRole" + }, + { + "type": "null" + } + ] + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "ServiceAccountUpdate" + }, + "Snapshot": { + "properties": { + "expected_revision": { + "type": "string", + "format": "uuid", + "title": "Expected Revision" + }, + "visibility": { + "type": "string", + "enum": [ + "staff_only", + "public" + ], + "title": "Visibility" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "expected_revision", + "visibility" + ], + "title": "Snapshot" + }, + "SourceCreate": { + "properties": { + "source_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Id" + }, + "name": { + "type": "string", + "minLength": 1, + "title": "Name" + }, + "publisher": { + "type": "string", + "minLength": 1, + "title": "Publisher" + }, + "source_type": { + "type": "string", + "minLength": 1, + "title": "Source Type" + }, + "source_category": { + "type": "string", + "minLength": 1, + "title": "Source Category" + }, + "source_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Url" + }, + "file_reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "File Reference" + }, + "retrieved_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Retrieved At" + }, + "retrieval_method": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Retrieval Method" + }, + "checksum": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Checksum" + }, + "source_owner": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Owner" + }, + "is_official": { + "type": "boolean", + "title": "Is Official", + "default": true + }, + "official_status_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Official Status Note" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + }, + "staff_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Staff Notes" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "name", + "publisher", + "source_type", + "source_category" + ], + "title": "SourceCreate", + "description": "Request body for registering an official or explicitly labeled source." + }, + "SourceInput": { + "properties": { + "source_id": { + "type": "string", + "minLength": 1, + "title": "Source Id" + }, + "label": { + "type": "string", + "minLength": 1, + "title": "Label" + }, + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "label", + "text" + ], + "title": "SourceInput" + }, + "SourceSnapshot": { + "properties": { + "visibility": { + "type": "string", + "enum": [ + "public", + "staff_only" + ], + "title": "Visibility" + }, + "meeting_event_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "maxItems": 50, + "title": "Meeting Event Ids" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "visibility" + ], + "title": "SourceSnapshot" + }, + "SourceType": { + "type": "string", + "enum": [ + "manual_drop", + "file_system", + "rest_api", + "odbc" + ], + "title": "SourceType" + }, + "StaffRecordsIntake": { + "properties": { + "requester": { + "type": "string", + "minLength": 1, + "title": "Requester" + }, + "summary": { + "type": "string", + "minLength": 1, + "title": "Summary" + }, + "deadline": { + "type": "string", + "title": "Deadline" + }, + "deadlineBasis": { + "type": "string", + "title": "Deadlinebasis", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requester", + "summary", + "deadline" + ], + "title": "StaffRecordsIntake", + "description": "Existing native create-records-request input; no caller-supplied actor." + }, + "StandardsExplanation": { + "properties": { + "question": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Question" + }, + "process_section": { + "type": "string", + "maxLength": 255, + "title": "Process Section", + "default": "" + }, + "zone_code": { + "type": "string", + "maxLength": 40, + "title": "Zone Code", + "default": "" + }, + "rule_types": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 10, + "title": "Rule Types" + }, + "observed": { + "additionalProperties": { + "type": "string" + }, + "type": "object", + "title": "Observed" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "question" + ], + "title": "StandardsExplanation" + }, + "SyncFailureRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "source_id": { + "type": "string", + "format": "uuid", + "title": "Source Id" + }, + "source_path": { + "type": "string", + "title": "Source Path" + }, + "error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Message" + }, + "error_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Class" + }, + "http_status_code": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Http Status Code" + }, + "retry_count": { + "type": "integer", + "title": "Retry Count" + }, + "status": { + "type": "string", + "title": "Status" + }, + "first_failed_at": { + "type": "string", + "format": "date-time", + "title": "First Failed At" + }, + "last_retried_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Retried At" + }, + "dismissed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Dismissed At" + }, + "dismissed_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Dismissed By" + } + }, + "type": "object", + "required": [ + "id", + "source_id", + "source_path", + "error_message", + "error_class", + "http_status_code", + "retry_count", + "status", + "first_failed_at", + "last_retried_at", + "dismissed_at", + "dismissed_by" + ], + "title": "SyncFailureRead" + }, + "SyncRunLogRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "source_id": { + "type": "string", + "format": "uuid", + "title": "Source Id" + }, + "started_at": { + "type": "string", + "format": "date-time", + "title": "Started At" + }, + "finished_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Finished At" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + }, + "records_attempted": { + "type": "integer", + "title": "Records Attempted" + }, + "records_succeeded": { + "type": "integer", + "title": "Records Succeeded" + }, + "records_failed": { + "type": "integer", + "title": "Records Failed" + }, + "error_summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Summary" + } + }, + "type": "object", + "required": [ + "id", + "source_id", + "started_at", + "finished_at", + "status", + "records_attempted", + "records_succeeded", + "records_failed", + "error_summary" + ], + "title": "SyncRunLogRead" + }, + "SystemStatus": { + "properties": { + "version": { + "type": "string", + "title": "Version" + }, + "database": { + "type": "string", + "title": "Database" + }, + "ollama": { + "type": "string", + "title": "Ollama" + }, + "redis": { + "type": "string", + "title": "Redis" + }, + "user_count": { + "type": "integer", + "title": "User Count" + }, + "audit_log_count": { + "type": "integer", + "title": "Audit Log Count" + }, + "suite_session": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Suite Session" + } + }, + "type": "object", + "required": [ + "version", + "database", + "ollama", + "redis", + "user_count", + "audit_log_count" + ], + "title": "SystemStatus" + }, + "TaggedPlan": { + "properties": { + "action": { + "type": "string", + "const": "tagged-pdf", + "title": "Action" + }, + "headingLevels": { + "items": { + "type": "integer", + "maximum": 4294967295.0, + "minimum": 0.0 + }, + "type": "array", + "maxItems": 50, + "title": "Headinglevels" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "TaggedPlan" + }, + "TestConnectionRequest": { + "properties": { + "source_type": { + "type": "string", + "title": "Source Type" + }, + "host": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Host" + }, + "port": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Port" + }, + "path": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Path" + }, + "username": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Username" + }, + "password": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Password" + }, + "rest_api_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Rest Api Config" + }, + "odbc_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Odbc Config" + } + }, + "type": "object", + "required": [ + "source_type" + ], + "title": "TestConnectionRequest", + "description": "Dedicated schema for test-connection. NOT the create schema.\n\nSecurity: credentials in this request body are never persisted, never\nwritten to audit logs, and never returned in the response." + }, + "TestConnectionResponse": { + "properties": { + "success": { + "type": "boolean", + "title": "Success" + }, + "message": { + "type": "string", + "title": "Message" + }, + "latency_ms": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Latency Ms" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + }, + "warning": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Warning" + }, + "differing_keys": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Differing Keys" + } + }, + "type": "object", + "required": [ + "success", + "message" + ], + "title": "TestConnectionResponse" + }, + "TimelineEventCreate": { + "properties": { + "event_type": { + "type": "string", + "title": "Event Type" + }, + "description": { + "type": "string", + "title": "Description" + }, + "internal_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Internal Note" + } + }, + "type": "object", + "required": [ + "event_type", + "description" + ], + "title": "TimelineEventCreate" + }, + "TimelineEventRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "event_type": { + "type": "string", + "title": "Event Type" + }, + "actor_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Actor Id" + }, + "actor_role": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Actor Role" + }, + "description": { + "type": "string", + "title": "Description" + }, + "internal_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Internal Note" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "event_type", + "actor_id", + "actor_role", + "description", + "internal_note", + "created_at" + ], + "title": "TimelineEventRead" + }, + "TimelineView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "action": { + "type": "string", + "title": "Action" + }, + "actor": { + "type": "string", + "title": "Actor" + }, + "note": { + "type": "string", + "title": "Note" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "action", + "actor", + "note", + "created_at_unix_seconds" + ], + "title": "TimelineView" + }, + "TitleCreate": { + "properties": { + "title_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Title Id" + }, + "title_number": { + "type": "string", + "minLength": 1, + "title": "Title Number" + }, + "title_name": { + "type": "string", + "minLength": 1, + "title": "Title Name" + }, + "sort_order": { + "type": "integer", + "title": "Sort Order", + "default": 0 + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title_number", + "title_name" + ], + "title": "TitleCreate", + "description": "Request body for creating a code title." + }, + "TranscriptInput": { + "properties": { + "source_label": { + "type": "string", + "minLength": 1, + "title": "Source Label" + }, + "transcript_text": { + "type": "string", + "minLength": 1, + "title": "Transcript Text" + }, + "correction_of_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Correction Of Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_label", + "transcript_text" + ], + "title": "TranscriptInput" + }, + "UserRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "email": { + "type": "string", + "format": "email", + "title": "Email" + }, + "is_active": { + "type": "boolean", + "title": "Is Active", + "default": true + }, + "is_superuser": { + "type": "boolean", + "title": "Is Superuser", + "default": false + }, + "is_verified": { + "type": "boolean", + "title": "Is Verified", + "default": false + }, + "full_name": { + "type": "string", + "title": "Full Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "last_login": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Login" + }, + "must_change_password": { + "type": "boolean", + "title": "Must Change Password", + "default": false + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + } + }, + "type": "object", + "required": [ + "id", + "email", + "full_name", + "role", + "created_at", + "last_login" + ], + "title": "UserRead" + }, + "UserRole": { + "type": "string", + "enum": [ + "admin", + "staff", + "reviewer", + "read_only", + "liaison", + "public" + ], + "title": "UserRole" + }, + "UserSelfUpdate": { + "properties": { + "password": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Password" + }, + "email": { + "anyOf": [ + { + "type": "string", + "format": "email" + }, + { + "type": "null" + } + ], + "title": "Email" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + }, + "is_superuser": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Superuser" + }, + "is_verified": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Verified" + }, + "full_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Full Name" + } + }, + "type": "object", + "title": "UserSelfUpdate", + "description": "Schema for user self-update via PATCH /users/me.\n\nExcludes role and department_id. Any payload containing those fields is\nrejected at parse time (HTTP 422). Role and department changes require\nadmin privileges via /admin/users/{id}." + }, + "UserUpdateRequest": { + "properties": { + "full_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Full Name" + }, + "role": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Role" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "UserUpdateRequest" + }, + "ValidationError": { + "properties": { + "loc": { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "integer" + } + ] + }, + "type": "array", + "title": "Location" + }, + "msg": { + "type": "string", + "title": "Message" + }, + "type": { + "type": "string", + "title": "Error Type" + }, + "input": { + "title": "Input" + }, + "ctx": { + "type": "object", + "title": "Context" + } + }, + "type": "object", + "required": [ + "loc", + "msg", + "type" + ], + "title": "ValidationError" + }, + "Version": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence" + ], + "title": "Version" + }, + "VoteCorrection": { + "properties": { + "vote": { + "type": "string", + "minLength": 1, + "title": "Vote" + }, + "reason": { + "type": "string", + "minLength": 1, + "title": "Reason" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "vote", + "reason" + ], + "title": "VoteCorrection" + }, + "VoteInput": { + "properties": { + "voter_name": { + "type": "string", + "minLength": 1, + "title": "Voter Name" + }, + "vote": { + "type": "string", + "minLength": 1, + "title": "Vote" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "voter_name", + "vote" + ], + "title": "VoteInput" + }, + "_ParcelLookupIn": { + "properties": { + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "jurisdiction", + "query" + ], + "title": "_ParcelLookupIn" + }, + "townlight_inspections__workflow_models__SourceLink": { + "properties": { + "provider": { + "type": "string", + "const": "code", + "title": "Provider", + "default": "code" + }, + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "SourceLink" + }, + "townlight_permitting__workflow_models__SourceLink": { + "properties": { + "provider": { + "type": "string", + "enum": [ + "code", + "zoning" + ], + "title": "Provider" + }, + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "source_id", + "expected_sha256" + ], + "title": "SourceLink" + }, + "townlight_runtime__inspections_bridge__Search": { + "properties": { + "provider": { + "type": "string", + "const": "code", + "title": "Provider" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "query" + ], + "title": "Search" + }, + "townlight_runtime__notice_bridge__Review": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + }, + "note": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence", + "note" + ], + "title": "Review" + }, + "townlight_runtime__permitting_bridge__Import": { + "properties": { + "bundle": { + "$ref": "#/components/schemas/RequirementBundle" + }, + "expected_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "bundle" + ], + "title": "Import" + }, + "townlight_runtime__permitting_bridge__Search": { + "properties": { + "provider": { + "type": "string", + "enum": [ + "code", + "zoning" + ], + "title": "Provider" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "query" + ], + "title": "Search" + }, + "townlight_runtime__planning_bridge__Import": { + "properties": { + "bundle": { + "additionalProperties": true, + "type": "object", + "title": "Bundle" + }, + "expected_previous_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Expected Previous Revision" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "bundle" + ], + "title": "Import" + }, + "townlight_runtime__planning_bridge__Search": { + "properties": { + "query": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Query" + }, + "plan_type": { + "anyOf": [ + { + "type": "string", + "maxLength": 40 + }, + { + "type": "null" + } + ], + "title": "Plan Type" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "Search" + }, + "townlight_runtime__zoning_bridge__Review": { + "properties": { + "answer": { + "type": "string", + "maxLength": 10000, + "title": "Answer", + "default": "" + }, + "notes": { + "type": "string", + "maxLength": 10000, + "title": "Notes", + "default": "" + }, + "queue_status": { + "type": "string", + "enum": [ + "open", + "in_review", + "resolved", + "closed" + ], + "title": "Queue Status", + "default": "resolved" + } + }, + "additionalProperties": false, + "type": "object", + "title": "Review" + } + }, + "securitySchemes": { + "OAuth2PasswordBearer": { + "type": "oauth2", + "flows": { + "password": { + "scopes": {}, + "tokenUrl": "auth/jwt/login" + } + } + } + } + }, + "x-townlight-component": { + "view": "meetings", + "identity": "Townlight Meetings 1.0.5", + "evidence": "source-schema-only" + } +} diff --git a/docs/beta-1/api/meetings.html b/docs/beta-1/api/meetings.html new file mode 100644 index 0000000..a0337ea --- /dev/null +++ b/docs/beta-1/api/meetings.html @@ -0,0 +1,13338 @@ +Townlight Meetings API reference
Townlight

Townlight Meetings API reference

+

Prepared source candidate, November 2, 2026. New signed Windows installed acceptance and publication remain pending.

+

Townlight Meetings 1.0.5. The HTTP host is Townlight Records 1.8.0.dev2. Component package versions and the host API version are separate identities.

+

Generated from the actual native inspections-preview composition without application lifespan, migrations or database/network access. It describes route and validation contracts; it does not establish endpoint behavior, individual authorization or installed acceptance. Standalone product applications have separate deployment boundaries.

+

Machine-readable OpenAPI schema · Operating manual and limits

+

HTTP operations

+
POST /desktop/v1/meetings-sources/search +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Search Meetings Sources",
+  "operationId": "search_meetings_sources_desktop_v1_meetings_sources_search_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MeetingsSearch"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/agenda-items +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Create Agenda Item",
+  "operationId": "create_agenda_item_desktop_v1_meetings_agenda_items_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/AgendaInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/meetings/agenda-items/{item_id} +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Get Agenda Item",
+  "operationId": "get_agenda_item_desktop_v1_meetings_agenda_items__item_id__get",
+  "parameters": [
+    {
+      "name": "item_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Item Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/agenda-items/{item_id}/meeting +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Assign Agenda",
+  "operationId": "assign_agenda_desktop_v1_meetings_agenda_items__item_id__meeting_post",
+  "parameters": [
+    {
+      "name": "item_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Item Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/AgendaAssignment"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/agenda-items/{item_id}/reviews +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Record Agenda Review",
+  "operationId": "record_agenda_review_desktop_v1_meetings_agenda_items__item_id__reviews_post",
+  "parameters": [
+    {
+      "name": "item_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Item Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/AgendaReviewInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/meetings/code-connections +
{
+  "summary": "List Code Connections",
+  "operationId": "list_code_connections_desktop_v1_meetings_code_connections_get",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/meetings/code-connections/{connection_id} +
{
+  "summary": "Get Code Connection",
+  "operationId": "get_code_connection_desktop_v1_meetings_code_connections__connection_id__get",
+  "parameters": [
+    {
+      "name": "connection_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "pattern": "^[A-Za-z0-9_-]{1,64}$",
+        "title": "Connection Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/code-connections/{connection_id}/decisions +
{
+  "summary": "Record Decision",
+  "operationId": "record_decision_desktop_v1_meetings_code_connections__connection_id__decisions_post",
+  "parameters": [
+    {
+      "name": "connection_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "pattern": "^[A-Za-z0-9_-]{1,64}$",
+        "title": "Connection Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/Decision"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/meetings +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Create Meeting",
+  "operationId": "create_meeting_desktop_v1_meetings_meetings_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MeetingInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/meetings/meetings/{meeting_id} +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Get Meeting",
+  "operationId": "get_meeting_desktop_v1_meetings_meetings__meeting_id__get",
+  "parameters": [
+    {
+      "name": "meeting_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Meeting Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/meetings/{meeting_id}/action-items +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Capture Action Item",
+  "operationId": "capture_action_item_desktop_v1_meetings_meetings__meeting_id__action_items_post",
+  "parameters": [
+    {
+      "name": "meeting_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Meeting Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/ActionItemInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/meetings/{meeting_id}/archive +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Archive Meeting",
+  "operationId": "archive_meeting_desktop_v1_meetings_meetings__meeting_id__archive_post",
+  "parameters": [
+    {
+      "name": "meeting_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Meeting Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/ArchiveInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/meetings/{meeting_id}/minutes/drafts +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Create Minutes",
+  "operationId": "create_minutes_desktop_v1_meetings_meetings__meeting_id__minutes_drafts_post",
+  "parameters": [
+    {
+      "name": "meeting_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Meeting Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/DraftInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/meetings/{meeting_id}/motions +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Capture Motion",
+  "operationId": "capture_motion_desktop_v1_meetings_meetings__meeting_id__motions_post",
+  "parameters": [
+    {
+      "name": "meeting_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Meeting Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MotionInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/meetings/{meeting_id}/notice-checks +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Check Notice",
+  "operationId": "check_notice_desktop_v1_meetings_meetings__meeting_id__notice_checks_post",
+  "parameters": [
+    {
+      "name": "meeting_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Meeting Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/NoticeInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/meetings/{meeting_id}/packet-snapshots +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Capture Packet",
+  "operationId": "capture_packet_desktop_v1_meetings_meetings__meeting_id__packet_snapshots_post",
+  "parameters": [
+    {
+      "name": "meeting_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Meeting Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/PacketInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/meetings/meetings/{meeting_id}/proceedings +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Proceedings",
+  "operationId": "proceedings_desktop_v1_meetings_meetings__meeting_id__proceedings_get",
+  "parameters": [
+    {
+      "name": "meeting_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Meeting Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/meetings/{meeting_id}/stages +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Record Meeting Stage",
+  "operationId": "record_meeting_stage_desktop_v1_meetings_meetings__meeting_id__stages_post",
+  "parameters": [
+    {
+      "name": "meeting_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Meeting Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MeetingStageInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/meetings/{meeting_id}/transcripts +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Capture Transcript",
+  "operationId": "capture_transcript_desktop_v1_meetings_meetings__meeting_id__transcripts_post",
+  "parameters": [
+    {
+      "name": "meeting_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Meeting Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/TranscriptInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/minutes/{draft_id}/decisions +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Decide Minutes",
+  "operationId": "decide_minutes_desktop_v1_meetings_minutes__draft_id__decisions_post",
+  "parameters": [
+    {
+      "name": "draft_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Draft Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MinutesDecision"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/motions/{motion_id}/corrections +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Correct Motion",
+  "operationId": "correct_motion_desktop_v1_meetings_motions__motion_id__corrections_post",
+  "parameters": [
+    {
+      "name": "motion_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Motion Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MotionCorrection"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/motions/{motion_id}/votes +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Capture Vote",
+  "operationId": "capture_vote_desktop_v1_meetings_motions__motion_id__votes_post",
+  "parameters": [
+    {
+      "name": "motion_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Motion Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/VoteInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/notices/{notice_id}/document +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Notice Document",
+  "operationId": "notice_document_desktop_v1_meetings_notices__notice_id__document_post",
+  "parameters": [
+    {
+      "name": "notice_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Notice Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/NoticeDocumentInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/notices/{notice_id}/proof +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Record Notice Proof",
+  "operationId": "record_notice_proof_desktop_v1_meetings_notices__notice_id__proof_post",
+  "parameters": [
+    {
+      "name": "notice_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Notice Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/NoticeProofInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/meetings/notices/{notice_id}/template +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Notice Template",
+  "operationId": "notice_template_desktop_v1_meetings_notices__notice_id__template_get",
+  "parameters": [
+    {
+      "name": "notice_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Notice Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/packets/{packet_id}/deliver +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Export Packet",
+  "operationId": "export_packet_desktop_v1_meetings_packets__packet_id__deliver_post",
+  "parameters": [
+    {
+      "name": "packet_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Packet Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/meetings/station/catalog +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Station Catalog",
+  "description": "Authorized name-based operator selection from canonical Meetings data.",
+  "operationId": "station_catalog_desktop_v1_meetings_station_catalog_get",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/votes/{vote_id}/corrections +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Correct Vote",
+  "operationId": "correct_vote_desktop_v1_meetings_votes__vote_id__corrections_post",
+  "parameters": [
+    {
+      "name": "vote_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Vote Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/VoteCorrection"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /public/meetings +
{
+  "tags": [
+    "public-meetings"
+  ],
+  "summary": "Public Archive Index",
+  "operationId": "public_archive_index_public_meetings_get",
+  "parameters": [
+    {
+      "name": "q",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "string",
+        "default": "",
+        "title": "Q"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "text/html": {
+          "schema": {
+            "type": "string"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /public/meetings/{record_id} +
{
+  "tags": [
+    "public-meetings"
+  ],
+  "summary": "Public Archive Detail",
+  "operationId": "public_archive_detail_public_meetings__record_id__get",
+  "parameters": [
+    {
+      "name": "record_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Record Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "text/html": {
+          "schema": {
+            "type": "string"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /public/meetings/{record_id}/{kind}.txt +
{
+  "tags": [
+    "public-meetings"
+  ],
+  "summary": "Public Archive Download",
+  "operationId": "public_archive_download_public_meetings__record_id___kind__txt_get",
+  "parameters": [
+    {
+      "name": "record_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Record Id"
+      }
+    },
+    {
+      "name": "kind",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "enum": [
+          "agenda",
+          "packet",
+          "minutes"
+        ],
+        "type": "string",
+        "title": "Kind"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+

Request and response data dictionary

+

Each schema includes the actual required fields, types, constraints and descriptions. References resolve against the machine-readable document.

+
ActionItemInput
+{
+  "properties": {
+    "description": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Description"
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "source_motion_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Motion Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "description"
+  ],
+  "title": "ActionItemInput"
+}
+
+
AdaPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "ada-title-ii",
+      "title": "Action"
+    },
+    "serviceArea": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Servicearea"
+    },
+    "hasCoordinatorReview": {
+      "type": "boolean",
+      "title": "Hascoordinatorreview",
+      "default": false
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "serviceArea"
+  ],
+  "title": "AdaPlan"
+}
+
+
AdminUserCreateRequest
+{
+  "properties": {
+    "email": {
+      "type": "string",
+      "title": "Email"
+    },
+    "password": {
+      "type": "string",
+      "title": "Password"
+    },
+    "full_name": {
+      "type": "string",
+      "title": "Full Name",
+      "default": ""
+    },
+    "role": {
+      "type": "string",
+      "title": "Role",
+      "default": "staff"
+    }
+  },
+  "type": "object",
+  "required": [
+    "email",
+    "password"
+  ],
+  "title": "AdminUserCreateRequest"
+}
+
+
AdminUserCreateResponse
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "email": {
+      "type": "string",
+      "title": "Email"
+    },
+    "full_name": {
+      "type": "string",
+      "title": "Full Name"
+    },
+    "role": {
+      "type": "string",
+      "title": "Role"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "email",
+    "full_name",
+    "role",
+    "is_active"
+  ],
+  "title": "AdminUserCreateResponse"
+}
+
+
AgendaAssignment
+{
+  "properties": {
+    "meeting_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Meeting Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "meeting_id"
+  ],
+  "title": "AgendaAssignment"
+}
+
+
AgendaInput
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "department_name": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Department Name"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "department_name"
+  ],
+  "title": "AgendaInput"
+}
+
+
AgendaReviewInput
+{
+  "properties": {
+    "to_status": {
+      "type": "string",
+      "enum": [
+        "DRAFTED",
+        "SUBMITTED",
+        "DEPT_APPROVED",
+        "LEGAL_REVIEWED",
+        "CLERK_ACCEPTED",
+        "ON_AGENDA",
+        "IN_PACKET",
+        "POSTED",
+        "HEARD",
+        "DISPOSED",
+        "ARCHIVED"
+      ],
+      "title": "To Status"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "to_status"
+  ],
+  "title": "AgendaReviewInput"
+}
+
+
AmendmentInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "policy": {
+      "$ref": "#/components/schemas/PolicySelection"
+    },
+    "proposal": {
+      "type": "string",
+      "maxLength": 20000,
+      "minLength": 1,
+      "title": "Proposal"
+    },
+    "responsible_staff": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Responsible Staff"
+    },
+    "status": {
+      "type": "string",
+      "enum": [
+        "draft",
+        "review",
+        "adopted",
+        "withdrawn"
+      ],
+      "title": "Status",
+      "default": "draft"
+    },
+    "review_note": {
+      "type": "string",
+      "maxLength": 5000,
+      "title": "Review Note",
+      "default": ""
+    },
+    "adoption_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Adoption Revision"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "policy",
+    "proposal",
+    "responsible_staff",
+    "note"
+  ],
+  "title": "AmendmentInput"
+}
+
+
AnalysisObservation
+{
+  "properties": {
+    "source": {
+      "type": "string",
+      "maxLength": 64,
+      "minLength": 1,
+      "title": "Source"
+    },
+    "filename": {
+      "type": "string",
+      "maxLength": 160,
+      "title": "Filename",
+      "default": ""
+    },
+    "media_type": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Media Type",
+      "default": ""
+    },
+    "text": {
+      "type": "string",
+      "maxLength": 4000,
+      "minLength": 1,
+      "title": "Text"
+    },
+    "adapter": {
+      "type": "string",
+      "maxLength": 120,
+      "title": "Adapter",
+      "default": ""
+    },
+    "citation_source_ids": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Citation Source Ids"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source",
+    "text"
+  ],
+  "title": "AnalysisObservation",
+  "description": "One draft observation, named with the adapter that actually produced it."
+}
+
+
AnalysisRecord
+{
+  "properties": {
+    "observations": {
+      "items": {
+        "$ref": "#/components/schemas/AnalysisObservation"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Observations"
+    },
+    "cited_sections": {
+      "items": {
+        "$ref": "#/components/schemas/CitedSection"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Cited Sections"
+    },
+    "unavailable": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Unavailable"
+    },
+    "runtime": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Runtime"
+    },
+    "review_required": {
+      "type": "boolean",
+      "title": "Review Required",
+      "default": true
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "AnalysisRecord",
+  "description": "The adapter output that accompanies a saved inspection draft."
+}
+
+
ApprovalCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "approve-records-response",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ApprovalPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "ApprovalCommand"
+}
+
+
ApprovalPayload
+{
+  "properties": {
+    "approvalNote": {
+      "type": "string",
+      "title": "Approvalnote",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "ApprovalPayload"
+}
+
+
ArchiveInput
+{
+  "properties": {
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "public",
+        "closed_session"
+      ],
+      "title": "Visibility"
+    },
+    "packet_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Packet Id"
+    },
+    "minutes_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Minutes Id"
+    },
+    "plain_language_summary": {
+      "type": "string",
+      "title": "Plain Language Summary",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "visibility"
+  ],
+  "title": "ArchiveInput"
+}
+
+
ArtifactPlan
+{
+  "properties": {
+    "artifact_id": {
+      "type": "string",
+      "title": "Artifact Id"
+    },
+    "file_name": {
+      "type": "string",
+      "title": "File Name"
+    },
+    "content": {
+      "type": "string",
+      "title": "Content"
+    },
+    "sha256": {
+      "type": "string",
+      "title": "Sha256"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "artifact_id",
+    "file_name",
+    "content",
+    "sha256",
+    "created_at_unix_seconds"
+  ],
+  "title": "ArtifactPlan"
+}
+
+
AssignCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "assign-records-request",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/AssignmentPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "AssignCommand"
+}
+
+
AssignmentPayload
+{
+  "properties": {
+    "assignedTo": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Assignedto"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "assignedTo"
+  ],
+  "title": "AssignmentPayload"
+}
+
+
AttachDocument
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation",
+      "default": ""
+    },
+    "file": {
+      "$ref": "#/components/schemas/ManagedFileReceipt"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "file"
+  ],
+  "title": "AttachDocument"
+}
+
+
AttachReleaseCopy
+{
+  "properties": {
+    "status": {
+      "type": "string",
+      "enum": [
+        "release-ready copy",
+        "redacted copy"
+      ],
+      "title": "Status"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note",
+      "default": ""
+    },
+    "added_by": {
+      "type": "string",
+      "title": "Added By",
+      "default": ""
+    },
+    "file": {
+      "$ref": "#/components/schemas/ManagedFileReceipt"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "status",
+    "file"
+  ],
+  "title": "AttachReleaseCopy"
+}
+
+
AuditChainVerification
+{
+  "properties": {
+    "is_valid": {
+      "type": "boolean",
+      "title": "Is Valid"
+    },
+    "entries_checked": {
+      "type": "integer",
+      "title": "Entries Checked"
+    },
+    "error_message": {
+      "type": "string",
+      "title": "Error Message"
+    }
+  },
+  "type": "object",
+  "required": [
+    "is_valid",
+    "entries_checked",
+    "error_message"
+  ],
+  "title": "AuditChainVerification"
+}
+
+
AuditLogRead
+{
+  "properties": {
+    "id": {
+      "type": "integer",
+      "title": "Id"
+    },
+    "prev_hash": {
+      "type": "string",
+      "title": "Prev Hash"
+    },
+    "entry_hash": {
+      "type": "string",
+      "title": "Entry Hash"
+    },
+    "timestamp": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Timestamp"
+    },
+    "user_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "User Id"
+    },
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "resource_type": {
+      "type": "string",
+      "title": "Resource Type"
+    },
+    "resource_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Resource Id"
+    },
+    "details": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Details"
+    },
+    "ai_generated": {
+      "type": "boolean",
+      "title": "Ai Generated"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "prev_hash",
+    "entry_hash",
+    "timestamp",
+    "user_id",
+    "action",
+    "resource_type",
+    "resource_id",
+    "details",
+    "ai_generated"
+  ],
+  "title": "AuditLogRead"
+}
+
+
AuditView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "module_id": {
+      "type": "string",
+      "title": "Module Id"
+    },
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    },
+    "previous_hash": {
+      "type": "string",
+      "title": "Previous Hash"
+    },
+    "entry_hash": {
+      "type": "string",
+      "title": "Entry Hash"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "module_id",
+    "action",
+    "summary",
+    "created_at_unix_seconds",
+    "previous_hash",
+    "entry_hash"
+  ],
+  "title": "AuditView"
+}
+
+
BearerResponse
+{
+  "properties": {
+    "access_token": {
+      "type": "string",
+      "title": "Access Token"
+    },
+    "token_type": {
+      "type": "string",
+      "title": "Token Type"
+    }
+  },
+  "type": "object",
+  "required": [
+    "access_token",
+    "token_type"
+  ],
+  "title": "BearerResponse"
+}
+
+
Body_auth_jwt_login_auth_jwt_login_post
+{
+  "properties": {
+    "grant_type": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^password$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Grant Type"
+    },
+    "username": {
+      "type": "string",
+      "title": "Username"
+    },
+    "password": {
+      "type": "string",
+      "format": "password",
+      "title": "Password"
+    },
+    "scope": {
+      "type": "string",
+      "title": "Scope",
+      "default": ""
+    },
+    "client_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Client Id"
+    },
+    "client_secret": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "format": "password",
+      "title": "Client Secret"
+    }
+  },
+  "type": "object",
+  "required": [
+    "username",
+    "password"
+  ],
+  "title": "Body_auth_jwt_login_auth_jwt_login_post"
+}
+
+
Body_upload_file_datasources_upload_post
+{
+  "properties": {
+    "file": {
+      "type": "string",
+      "contentMediaType": "application/octet-stream",
+      "title": "File"
+    }
+  },
+  "type": "object",
+  "required": [
+    "file"
+  ],
+  "title": "Body_upload_file_datasources_upload_post"
+}
+
+
CalculateDeadlineCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "calculate-records-deadline",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/CalculateDeadlinePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "CalculateDeadlineCommand"
+}
+
+
CalculateDeadlinePayload
+{
+  "properties": {
+    "deadlineReceivedDate": {
+      "type": "string",
+      "title": "Deadlinereceiveddate"
+    },
+    "deadlineRuleName": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Deadlinerulename"
+    },
+    "deadlineDayCount": {
+      "type": "string",
+      "title": "Deadlinedaycount"
+    },
+    "deadlineDayType": {
+      "type": "string",
+      "title": "Deadlinedaytype"
+    },
+    "deadlineBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Deadlinebasis"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "deadlineReceivedDate",
+    "deadlineRuleName",
+    "deadlineDayCount",
+    "deadlineDayType",
+    "deadlineBasis"
+  ],
+  "title": "CalculateDeadlinePayload"
+}
+
+
ChapterCreate
+{
+  "properties": {
+    "chapter_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Chapter Id"
+    },
+    "title_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title Id"
+    },
+    "chapter_number": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Chapter Number"
+    },
+    "chapter_name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Chapter Name"
+    },
+    "sort_order": {
+      "type": "integer",
+      "title": "Sort Order",
+      "default": 0
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title_id",
+    "chapter_number",
+    "chapter_name"
+  ],
+  "title": "ChapterCreate",
+  "description": "Request body for creating a code chapter."
+}
+
+
CitedSection
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "citation": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Citation"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "version": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Version",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "citation"
+  ],
+  "title": "CitedSection",
+  "description": "One resolved public Code section; never a caller-supplied quotation."
+}
+
+
CityProfileCreate
+{
+  "properties": {
+    "city_name": {
+      "type": "string",
+      "title": "City Name"
+    },
+    "state": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State"
+    },
+    "county": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "County"
+    },
+    "population_band": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Population Band"
+    },
+    "email_platform": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email Platform"
+    },
+    "has_dedicated_it": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Has Dedicated It"
+    },
+    "monthly_request_volume": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Monthly Request Volume"
+    },
+    "profile_data": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Profile Data",
+      "default": {}
+    },
+    "gap_map": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Gap Map",
+      "default": {}
+    }
+  },
+  "type": "object",
+  "required": [
+    "city_name"
+  ],
+  "title": "CityProfileCreate"
+}
+
+
CityProfileRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "city_name": {
+      "type": "string",
+      "title": "City Name"
+    },
+    "state": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State"
+    },
+    "county": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "County"
+    },
+    "population_band": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Population Band"
+    },
+    "email_platform": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email Platform"
+    },
+    "has_dedicated_it": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Has Dedicated It"
+    },
+    "monthly_request_volume": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Monthly Request Volume"
+    },
+    "onboarding_status": {
+      "type": "string",
+      "title": "Onboarding Status"
+    },
+    "profile_data": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Profile Data"
+    },
+    "gap_map": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Gap Map"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "updated_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "city_name",
+    "state",
+    "county",
+    "population_band",
+    "email_platform",
+    "has_dedicated_it",
+    "monthly_request_volume",
+    "onboarding_status",
+    "profile_data",
+    "gap_map",
+    "created_at",
+    "updated_at"
+  ],
+  "title": "CityProfileRead"
+}
+
+
CityProfileUpdate
+{
+  "properties": {
+    "city_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "City Name"
+    },
+    "state": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State"
+    },
+    "county": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "County"
+    },
+    "population_band": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Population Band"
+    },
+    "email_platform": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email Platform"
+    },
+    "has_dedicated_it": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Has Dedicated It"
+    },
+    "monthly_request_volume": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Monthly Request Volume"
+    },
+    "onboarding_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Onboarding Status"
+    },
+    "profile_data": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Profile Data"
+    },
+    "gap_map": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Gap Map"
+    }
+  },
+  "type": "object",
+  "title": "CityProfileUpdate"
+}
+
+
ClarificationCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "request-records-clarification",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ClarificationPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "ClarificationCommand"
+}
+
+
ClarificationPayload
+{
+  "properties": {
+    "clarificationNote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Clarificationnote"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "clarificationNote"
+  ],
+  "title": "ClarificationPayload"
+}
+
+
Closeout
+{
+  "properties": {
+    "decision_id": {
+      "type": "string",
+      "pattern": "^[A-Za-z0-9_-]{1,64}$",
+      "title": "Decision Id"
+    },
+    "version_id": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Version Id"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "version_label": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Version Label"
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 1000000,
+      "minLength": 1,
+      "title": "Body"
+    },
+    "effective_start": {
+      "type": "string",
+      "format": "date",
+      "title": "Effective Start"
+    },
+    "effective_end": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective End"
+    },
+    "is_current": {
+      "type": "boolean",
+      "title": "Is Current"
+    },
+    "reconciliation_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reconciliation Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "decision_id",
+    "version_id",
+    "source_id",
+    "version_label",
+    "body",
+    "effective_start",
+    "is_current"
+  ],
+  "title": "Closeout"
+}
+
+
CodeContext
+{
+  "properties": {
+    "section_number": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Section Number"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "section_number"
+  ],
+  "title": "CodeContext"
+}
+
+
CodeLink
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "const": "code",
+      "title": "Provider",
+      "default": "code"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "CodeLink"
+}
+
+
CodeSearch
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "CodeSearch"
+}
+
+
CodeSourceSelection
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 200,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "CodeSourceSelection"
+}
+
+
CompleteArtifact
+{
+  "properties": {
+    "export_path": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Export Path"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "export_path"
+  ],
+  "title": "CompleteArtifact"
+}
+
+
ConnectionSearch
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "enum": [
+        "meetings",
+        "zoning"
+      ],
+      "title": "Provider"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "query"
+  ],
+  "title": "ConnectionSearch"
+}
+
+
CoverageGapResponse
+{
+  "properties": {
+    "jurisdictions_without_rules": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Jurisdictions Without Rules"
+    },
+    "departments_without_staff": {
+      "items": {
+        "additionalProperties": true,
+        "type": "object"
+      },
+      "type": "array",
+      "title": "Departments Without Staff"
+    },
+    "uncovered_categories": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Uncovered Categories"
+    },
+    "total_gaps": {
+      "type": "integer",
+      "title": "Total Gaps"
+    }
+  },
+  "type": "object",
+  "required": [
+    "jurisdictions_without_rules",
+    "departments_without_staff",
+    "uncovered_categories",
+    "total_gaps"
+  ],
+  "title": "CoverageGapResponse"
+}
+
+
DataSourceAdminRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "source_type": {
+      "$ref": "#/components/schemas/SourceType"
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "type": "boolean",
+      "title": "Schedule Enabled",
+      "default": true
+    },
+    "next_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Next Sync At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "last_ingestion_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Ingestion At"
+    },
+    "last_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync At"
+    },
+    "last_sync_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync Status"
+    },
+    "last_error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Error Message"
+    },
+    "consecutive_failure_count": {
+      "type": "integer",
+      "title": "Consecutive Failure Count",
+      "default": 0
+    },
+    "sync_paused": {
+      "type": "boolean",
+      "title": "Sync Paused",
+      "default": false
+    },
+    "health_status": {
+      "type": "string",
+      "title": "Health Status",
+      "default": "healthy"
+    },
+    "active_failure_count": {
+      "type": "integer",
+      "title": "Active Failure Count",
+      "default": 0
+    },
+    "connector_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connector Type"
+    },
+    "updated_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Updated At"
+    },
+    "connection_config": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Connection Config"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "source_type",
+    "is_active",
+    "created_by",
+    "created_at",
+    "last_ingestion_at",
+    "connection_config"
+  ],
+  "title": "DataSourceAdminRead",
+  "description": "Full datasource shape including connection_config. Returned only by admin-gated endpoints."
+}
+
+
DataSourceCreate
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "source_type": {
+      "$ref": "#/components/schemas/SourceType"
+    },
+    "connection_config": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Connection Config",
+      "default": {}
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "type": "boolean",
+      "title": "Schedule Enabled",
+      "default": true
+    }
+  },
+  "type": "object",
+  "required": [
+    "name",
+    "source_type"
+  ],
+  "title": "DataSourceCreate"
+}
+
+
DataSourceRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "source_type": {
+      "$ref": "#/components/schemas/SourceType"
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "type": "boolean",
+      "title": "Schedule Enabled",
+      "default": true
+    },
+    "next_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Next Sync At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "last_ingestion_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Ingestion At"
+    },
+    "last_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync At"
+    },
+    "last_sync_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync Status"
+    },
+    "last_error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Error Message"
+    },
+    "consecutive_failure_count": {
+      "type": "integer",
+      "title": "Consecutive Failure Count",
+      "default": 0
+    },
+    "sync_paused": {
+      "type": "boolean",
+      "title": "Sync Paused",
+      "default": false
+    },
+    "health_status": {
+      "type": "string",
+      "title": "Health Status",
+      "default": "healthy"
+    },
+    "active_failure_count": {
+      "type": "integer",
+      "title": "Active Failure Count",
+      "default": 0
+    },
+    "connector_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connector Type"
+    },
+    "updated_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "source_type",
+    "is_active",
+    "created_by",
+    "created_at",
+    "last_ingestion_at"
+  ],
+  "title": "DataSourceRead",
+  "description": "Redacted datasource shape — safe for non-admin roles. connection_config omitted."
+}
+
+
DataSourceUpdate
+{
+  "properties": {
+    "name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Name"
+    },
+    "connection_config": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connection Config"
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Schedule Enabled"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "DataSourceUpdate"
+}
+
+
DeadlineCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "set-records-deadline",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/DeadlinePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "DeadlineCommand"
+}
+
+
DeadlinePayload
+{
+  "properties": {
+    "deadline": {
+      "type": "string",
+      "title": "Deadline"
+    },
+    "deadlineBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Deadlinebasis"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "deadline",
+    "deadlineBasis"
+  ],
+  "title": "DeadlinePayload"
+}
+
+
Decision
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "pattern": "^[A-Za-z0-9_-]{1,64}$",
+      "title": "Id"
+    },
+    "outcome": {
+      "type": "string",
+      "enum": [
+        "adopted",
+        "not_adopted",
+        "deferred",
+        "withdrawn"
+      ],
+      "title": "Outcome"
+    },
+    "decided_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Decided At"
+    },
+    "decision_text": {
+      "type": "string",
+      "maxLength": 1000000,
+      "minLength": 1,
+      "title": "Decision Text"
+    },
+    "supporting_references": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Supporting References"
+    },
+    "supersedes_decision_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^[A-Za-z0-9_-]{1,64}$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supersedes Decision Id"
+    },
+    "reconciliation_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reconciliation Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "outcome",
+    "decision_text"
+  ],
+  "title": "Decision"
+}
+
+
DepartmentCreate
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "code": {
+      "type": "string",
+      "title": "Code"
+    },
+    "contact_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Contact Email"
+    }
+  },
+  "type": "object",
+  "required": [
+    "name",
+    "code"
+  ],
+  "title": "DepartmentCreate"
+}
+
+
DepartmentRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "code": {
+      "type": "string",
+      "title": "Code"
+    },
+    "contact_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Contact Email"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "code",
+    "contact_email",
+    "created_at"
+  ],
+  "title": "DepartmentRead"
+}
+
+
DepartmentUpdate
+{
+  "properties": {
+    "name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Name"
+    },
+    "code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Code"
+    },
+    "contact_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Contact Email"
+    }
+  },
+  "type": "object",
+  "title": "DepartmentUpdate"
+}
+
+
DisclosureTemplateCreate
+{
+  "properties": {
+    "template_type": {
+      "type": "string",
+      "title": "Template Type"
+    },
+    "state_code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State Code"
+    },
+    "content": {
+      "type": "string",
+      "title": "Content"
+    }
+  },
+  "type": "object",
+  "required": [
+    "template_type",
+    "content"
+  ],
+  "title": "DisclosureTemplateCreate"
+}
+
+
DisclosureTemplateRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "template_type": {
+      "type": "string",
+      "title": "Template Type"
+    },
+    "state_code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State Code"
+    },
+    "content": {
+      "type": "string",
+      "title": "Content"
+    },
+    "version": {
+      "type": "integer",
+      "title": "Version"
+    },
+    "updated_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Updated By"
+    },
+    "updated_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "template_type",
+    "state_code",
+    "content",
+    "version",
+    "updated_by",
+    "updated_at"
+  ],
+  "title": "DisclosureTemplateRead"
+}
+
+
DisclosureTemplateRendered
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "template_type": {
+      "type": "string",
+      "title": "Template Type"
+    },
+    "rendered_content": {
+      "type": "string",
+      "title": "Rendered Content"
+    },
+    "has_unresolved_variables": {
+      "type": "boolean",
+      "title": "Has Unresolved Variables"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "template_type",
+    "rendered_content",
+    "has_unresolved_variables"
+  ],
+  "title": "DisclosureTemplateRendered"
+}
+
+
DisclosureTemplateUpdate
+{
+  "properties": {
+    "content": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Content"
+    },
+    "state_code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State Code"
+    }
+  },
+  "type": "object",
+  "title": "DisclosureTemplateUpdate"
+}
+
+
DocumentChunkRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "chunk_index": {
+      "type": "integer",
+      "title": "Chunk Index"
+    },
+    "content_text": {
+      "type": "string",
+      "title": "Content Text"
+    },
+    "token_count": {
+      "type": "integer",
+      "title": "Token Count"
+    },
+    "page_number": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Page Number"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "document_id",
+    "chunk_index",
+    "content_text",
+    "token_count",
+    "page_number"
+  ],
+  "title": "DocumentChunkRead"
+}
+
+
DocumentRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "source_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Source Id"
+    },
+    "source_path": {
+      "type": "string",
+      "title": "Source Path"
+    },
+    "filename": {
+      "type": "string",
+      "title": "Filename"
+    },
+    "file_type": {
+      "type": "string",
+      "title": "File Type"
+    },
+    "file_hash": {
+      "type": "string",
+      "title": "File Hash"
+    },
+    "file_size": {
+      "type": "integer",
+      "title": "File Size"
+    },
+    "ingestion_status": {
+      "$ref": "#/components/schemas/IngestionStatus"
+    },
+    "ingestion_error": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ingestion Error"
+    },
+    "chunk_count": {
+      "type": "integer",
+      "title": "Chunk Count"
+    },
+    "ingested_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ingested At"
+    },
+    "connector_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connector Type"
+    },
+    "updated_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "source_id",
+    "source_path",
+    "filename",
+    "file_type",
+    "file_hash",
+    "file_size",
+    "ingestion_status",
+    "ingestion_error",
+    "chunk_count",
+    "ingested_at"
+  ],
+  "title": "DocumentRead"
+}
+
+
DraftCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "draft-records-response",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/DraftPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "DraftCommand"
+}
+
+
DraftInput
+{
+  "properties": {
+    "source_materials": {
+      "items": {
+        "$ref": "#/components/schemas/SourceInput"
+      },
+      "type": "array",
+      "title": "Source Materials"
+    },
+    "sentences": {
+      "items": {
+        "$ref": "#/components/schemas/SentenceInput"
+      },
+      "type": "array",
+      "minItems": 1,
+      "title": "Sentences"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sentences"
+  ],
+  "title": "DraftInput"
+}
+
+
DraftPayload
+{
+  "properties": {
+    "responseDraft": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Responsedraft"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "responseDraft"
+  ],
+  "title": "DraftPayload"
+}
+
+
ErrorModel
+{
+  "properties": {
+    "detail": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "additionalProperties": {
+            "type": "string"
+          },
+          "type": "object"
+        }
+      ],
+      "title": "Detail"
+    }
+  },
+  "type": "object",
+  "required": [
+    "detail"
+  ],
+  "title": "ErrorModel"
+}
+
+
Evidence
+{
+  "properties": {
+    "filename": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$",
+      "title": "Filename"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Description"
+    },
+    "media_type": {
+      "type": "string",
+      "enum": [
+        "text/plain",
+        "image/jpeg",
+        "image/png",
+        "image/webp",
+        "application/pdf",
+        "audio/webm",
+        "audio/ogg",
+        "audio/wav",
+        "audio/mpeg",
+        "audio/mp4"
+      ],
+      "title": "Media Type"
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 14000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "filename",
+    "description",
+    "media_type",
+    "content_base64",
+    "sha256"
+  ],
+  "title": "Evidence"
+}
+
+
EvidenceItem
+{
+  "properties": {
+    "filename": {
+      "type": "string",
+      "maxLength": 151,
+      "minLength": 1,
+      "title": "Filename"
+    },
+    "media_type": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Media Type"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Description",
+      "default": ""
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 14000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "filename",
+    "media_type",
+    "content_base64",
+    "sha256"
+  ],
+  "title": "EvidenceItem"
+}
+
+
EvidenceItems
+{
+  "properties": {
+    "items": {
+      "items": {
+        "$ref": "#/components/schemas/EvidenceItem"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "minItems": 1,
+      "title": "Items"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "items"
+  ],
+  "title": "EvidenceItems"
+}
+
+
ExemptionAccuracyReport
+{
+  "properties": {
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "total_flags": {
+      "type": "integer",
+      "title": "Total Flags"
+    },
+    "accepted": {
+      "type": "integer",
+      "title": "Accepted"
+    },
+    "rejected": {
+      "type": "integer",
+      "title": "Rejected"
+    },
+    "pending": {
+      "type": "integer",
+      "title": "Pending"
+    },
+    "acceptance_rate": {
+      "type": "number",
+      "title": "Acceptance Rate"
+    }
+  },
+  "type": "object",
+  "required": [
+    "category",
+    "total_flags",
+    "accepted",
+    "rejected",
+    "pending",
+    "acceptance_rate"
+  ],
+  "title": "ExemptionAccuracyReport"
+}
+
+
ExemptionDashboard
+{
+  "properties": {
+    "total_flags": {
+      "type": "integer",
+      "title": "Total Flags"
+    },
+    "by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "By Status"
+    },
+    "by_category": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "By Category"
+    },
+    "acceptance_rate": {
+      "type": "number",
+      "title": "Acceptance Rate"
+    },
+    "total_rules": {
+      "type": "integer",
+      "title": "Total Rules"
+    },
+    "active_rules": {
+      "type": "integer",
+      "title": "Active Rules"
+    }
+  },
+  "type": "object",
+  "required": [
+    "total_flags",
+    "by_status",
+    "by_category",
+    "acceptance_rate",
+    "total_rules",
+    "active_rules"
+  ],
+  "title": "ExemptionDashboard"
+}
+
+
ExemptionDecisionCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-exemption-decision",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ExemptionDecisionPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "ExemptionDecisionCommand"
+}
+
+
ExemptionDecisionPayload
+{
+  "properties": {
+    "exemptionSource": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionsource"
+    },
+    "exemptionKind": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionkind"
+    },
+    "exemptionFinding": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionfinding"
+    },
+    "exemptionDecision": {
+      "type": "string",
+      "enum": [
+        "release",
+        "redact",
+        "exempt"
+      ],
+      "title": "Exemptiondecision"
+    },
+    "exemptionBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionbasis"
+    },
+    "exemptionReviewer": {
+      "type": "string",
+      "title": "Exemptionreviewer",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "exemptionSource",
+    "exemptionKind",
+    "exemptionFinding",
+    "exemptionDecision",
+    "exemptionBasis"
+  ],
+  "title": "ExemptionDecisionPayload"
+}
+
+
ExemptionDecisionView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "source": {
+      "type": "string",
+      "title": "Source"
+    },
+    "kind": {
+      "type": "string",
+      "title": "Kind"
+    },
+    "finding": {
+      "type": "string",
+      "title": "Finding"
+    },
+    "decision": {
+      "type": "string",
+      "enum": [
+        "release",
+        "redact",
+        "exempt"
+      ],
+      "title": "Decision"
+    },
+    "basis": {
+      "type": "string",
+      "title": "Basis"
+    },
+    "reviewer": {
+      "type": "string",
+      "title": "Reviewer"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "source",
+    "kind",
+    "finding",
+    "decision",
+    "basis",
+    "reviewer",
+    "created_at_unix_seconds"
+  ],
+  "title": "ExemptionDecisionView"
+}
+
+
ExemptionFlagRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "chunk_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Chunk Id"
+    },
+    "rule_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Rule Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "matched_text": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Matched Text"
+    },
+    "confidence": {
+      "type": "number",
+      "title": "Confidence"
+    },
+    "status": {
+      "$ref": "#/components/schemas/FlagStatus"
+    },
+    "reviewed_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reviewed By"
+    },
+    "reviewed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reviewed At"
+    },
+    "review_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Reason"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "chunk_id",
+    "rule_id",
+    "request_id",
+    "category",
+    "matched_text",
+    "confidence",
+    "status",
+    "reviewed_by",
+    "reviewed_at",
+    "review_reason",
+    "created_at"
+  ],
+  "title": "ExemptionFlagRead"
+}
+
+
ExemptionFlagReview
+{
+  "properties": {
+    "status": {
+      "$ref": "#/components/schemas/FlagStatus"
+    },
+    "review_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Reason"
+    }
+  },
+  "type": "object",
+  "required": [
+    "status"
+  ],
+  "title": "ExemptionFlagReview"
+}
+
+
ExemptionNoteCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-exemption-review",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ExemptionNotePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "ExemptionNoteCommand"
+}
+
+
ExemptionNotePayload
+{
+  "properties": {
+    "exemptionNote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionnote"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "exemptionNote"
+  ],
+  "title": "ExemptionNotePayload"
+}
+
+
ExemptionRuleCreate
+{
+  "properties": {
+    "state_code": {
+      "type": "string",
+      "title": "State Code"
+    },
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "rule_type": {
+      "$ref": "#/components/schemas/RuleType"
+    },
+    "rule_definition": {
+      "type": "string",
+      "title": "Rule Definition"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "enabled": {
+      "type": "boolean",
+      "title": "Enabled",
+      "default": true
+    }
+  },
+  "type": "object",
+  "required": [
+    "state_code",
+    "category",
+    "rule_type",
+    "rule_definition"
+  ],
+  "title": "ExemptionRuleCreate"
+}
+
+
ExemptionRuleRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "state_code": {
+      "type": "string",
+      "title": "State Code"
+    },
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "rule_type": {
+      "$ref": "#/components/schemas/RuleType"
+    },
+    "rule_definition": {
+      "type": "string",
+      "title": "Rule Definition"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "enabled": {
+      "type": "boolean",
+      "title": "Enabled"
+    },
+    "version": {
+      "type": "integer",
+      "title": "Version",
+      "default": 1
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "state_code",
+    "category",
+    "rule_type",
+    "rule_definition",
+    "description",
+    "enabled",
+    "created_by",
+    "created_at"
+  ],
+  "title": "ExemptionRuleRead"
+}
+
+
ExemptionRuleUpdate
+{
+  "properties": {
+    "rule_definition": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Rule Definition"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "enabled": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Enabled"
+    }
+  },
+  "type": "object",
+  "title": "ExemptionRuleUpdate"
+}
+
+
ExportReceipt
+{
+  "properties": {
+    "export_path": {
+      "type": "string",
+      "maxLength": 32768,
+      "minLength": 1,
+      "title": "Export Path"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "export_path"
+  ],
+  "title": "ExportReceipt"
+}
+
+
FeeEstimateCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "estimate-records-fee",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/FeeEstimatePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "FeeEstimateCommand"
+}
+
+
FeeEstimatePayload
+{
+  "properties": {
+    "feeEstimate": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feeestimate"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "feeEstimate"
+  ],
+  "title": "FeeEstimatePayload"
+}
+
+
FeeEstimateRequest
+{
+  "properties": {
+    "page_count": {
+      "type": "integer",
+      "title": "Page Count"
+    },
+    "fee_schedule_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Fee Schedule Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "page_count",
+    "fee_schedule_id"
+  ],
+  "title": "FeeEstimateRequest"
+}
+
+
FeeEstimateResponse
+{
+  "properties": {
+    "page_count": {
+      "type": "integer",
+      "title": "Page Count"
+    },
+    "unit_price": {
+      "type": "number",
+      "title": "Unit Price"
+    },
+    "total": {
+      "type": "number",
+      "title": "Total"
+    },
+    "fee_type": {
+      "type": "string",
+      "title": "Fee Type"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    }
+  },
+  "type": "object",
+  "required": [
+    "page_count",
+    "unit_price",
+    "total",
+    "fee_type",
+    "description"
+  ],
+  "title": "FeeEstimateResponse"
+}
+
+
FeeLineCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-fee-line",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/FeeLinePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "FeeLineCommand"
+}
+
+
FeeLineItemCreate
+{
+  "properties": {
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "quantity": {
+      "type": "integer",
+      "title": "Quantity",
+      "default": 1
+    },
+    "unit_price": {
+      "type": "number",
+      "title": "Unit Price"
+    },
+    "fee_schedule_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Schedule Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "description",
+    "unit_price"
+  ],
+  "title": "FeeLineItemCreate"
+}
+
+
FeeLineItemRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "fee_schedule_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Schedule Id"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "quantity": {
+      "type": "integer",
+      "title": "Quantity"
+    },
+    "unit_price": {
+      "type": "number",
+      "title": "Unit Price"
+    },
+    "total": {
+      "type": "number",
+      "title": "Total"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "fee_schedule_id",
+    "description",
+    "quantity",
+    "unit_price",
+    "total",
+    "status",
+    "created_at"
+  ],
+  "title": "FeeLineItemRead"
+}
+
+
FeeLinePayload
+{
+  "properties": {
+    "feeLineDescription": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feelinedescription"
+    },
+    "feeScheduleBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feeschedulebasis"
+    },
+    "feeLineAmount": {
+      "type": "string",
+      "title": "Feelineamount"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "feeLineDescription",
+    "feeScheduleBasis",
+    "feeLineAmount"
+  ],
+  "title": "FeeLinePayload"
+}
+
+
FeeLineView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "schedule_basis": {
+      "type": "string",
+      "title": "Schedule Basis"
+    },
+    "amount_cents": {
+      "type": "integer",
+      "title": "Amount Cents"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "description",
+    "schedule_basis",
+    "amount_cents",
+    "created_at_unix_seconds"
+  ],
+  "title": "FeeLineView"
+}
+
+
FeeScheduleCreate
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "title": "Jurisdiction"
+    },
+    "fee_type": {
+      "type": "string",
+      "title": "Fee Type"
+    },
+    "amount": {
+      "type": "number",
+      "title": "Amount"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "effective_date": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective Date"
+    }
+  },
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "fee_type",
+    "amount"
+  ],
+  "title": "FeeScheduleCreate"
+}
+
+
FeeScheduleRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "jurisdiction": {
+      "type": "string",
+      "title": "Jurisdiction"
+    },
+    "fee_type": {
+      "type": "string",
+      "title": "Fee Type"
+    },
+    "amount": {
+      "type": "number",
+      "title": "Amount"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "effective_date": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective Date"
+    },
+    "created_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "jurisdiction",
+    "fee_type",
+    "amount",
+    "description",
+    "effective_date",
+    "created_by",
+    "created_at"
+  ],
+  "title": "FeeScheduleRead"
+}
+
+
FeeScheduleUpdate
+{
+  "properties": {
+    "fee_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Type"
+    },
+    "amount": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Amount"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "effective_date": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective Date"
+    }
+  },
+  "type": "object",
+  "title": "FeeScheduleUpdate"
+}
+
+
FeeWaiverCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "waive-records-fee",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/FeeWaiverPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "FeeWaiverCommand"
+}
+
+
FeeWaiverCreateRequest
+{
+  "properties": {
+    "waiver_type": {
+      "type": "string",
+      "title": "Waiver Type"
+    },
+    "reason": {
+      "type": "string",
+      "title": "Reason"
+    }
+  },
+  "type": "object",
+  "required": [
+    "waiver_type",
+    "reason"
+  ],
+  "title": "FeeWaiverCreateRequest"
+}
+
+
FeeWaiverPayload
+{
+  "properties": {
+    "feeWaiverReason": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feewaiverreason"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "feeWaiverReason"
+  ],
+  "title": "FeeWaiverPayload"
+}
+
+
FeeWaiverReadResponse
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "waiver_type": {
+      "type": "string",
+      "title": "Waiver Type"
+    },
+    "reason": {
+      "type": "string",
+      "title": "Reason"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    },
+    "created_at": {
+      "type": "string",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "waiver_type",
+    "reason",
+    "status",
+    "created_at"
+  ],
+  "title": "FeeWaiverReadResponse"
+}
+
+
FeeWaiverReviewRequest
+{
+  "properties": {
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    }
+  },
+  "type": "object",
+  "required": [
+    "status"
+  ],
+  "title": "FeeWaiverReviewRequest"
+}
+
+
FinishCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "fulfill-records-request",
+        "close-records-request"
+      ],
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/NativePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "FinishCommand"
+}
+
+
FlagStatus
+{
+  "type": "string",
+  "enum": [
+    "flagged",
+    "reviewed",
+    "accepted",
+    "rejected"
+  ],
+  "title": "FlagStatus"
+}
+
+
FormPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "form-plan",
+      "title": "Action"
+    },
+    "formName": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Formname",
+      "default": ""
+    },
+    "fields": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 50,
+      "title": "Fields"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "FormPlan"
+}
+
+
GeneratedDraft
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "model": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Model"
+    },
+    "previous_response_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Previous Response Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text",
+    "model",
+    "previous_response_sha256"
+  ],
+  "title": "GeneratedDraft"
+}
+
+
HTTPValidationError
+{
+  "properties": {
+    "detail": {
+      "items": {
+        "$ref": "#/components/schemas/ValidationError"
+      },
+      "type": "array",
+      "title": "Detail"
+    }
+  },
+  "type": "object",
+  "title": "HTTPValidationError"
+}
+
+
Handoff
+{
+  "properties": {
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "request_id"
+  ],
+  "title": "Handoff"
+}
+
+
ImportBundleCreate
+{
+  "properties": {
+    "job_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Job Id"
+    },
+    "connector_type": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Connector Type"
+    },
+    "source": {
+      "$ref": "#/components/schemas/SourceCreate"
+    },
+    "sources": {
+      "items": {
+        "$ref": "#/components/schemas/SourceCreate"
+      },
+      "type": "array",
+      "title": "Sources"
+    },
+    "titles": {
+      "items": {
+        "$ref": "#/components/schemas/TitleCreate"
+      },
+      "type": "array",
+      "title": "Titles"
+    },
+    "chapters": {
+      "items": {
+        "$ref": "#/components/schemas/ChapterCreate"
+      },
+      "type": "array",
+      "title": "Chapters"
+    },
+    "sections": {
+      "items": {
+        "$ref": "#/components/schemas/SectionCreate"
+      },
+      "type": "array",
+      "title": "Sections"
+    },
+    "versions": {
+      "items": {
+        "$ref": "#/components/schemas/SectionVersionCreate"
+      },
+      "type": "array",
+      "title": "Versions"
+    },
+    "provenance": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Provenance"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "connector_type",
+    "source"
+  ],
+  "title": "ImportBundleCreate",
+  "description": "Request body for local fixture/file-drop import jobs."
+}
+
+
InclusionStatus
+{
+  "type": "string",
+  "enum": [
+    "included",
+    "excluded",
+    "pending"
+  ],
+  "title": "InclusionStatus"
+}
+
+
IngestionStats
+{
+  "properties": {
+    "total_sources": {
+      "type": "integer",
+      "title": "Total Sources"
+    },
+    "active_sources": {
+      "type": "integer",
+      "title": "Active Sources"
+    },
+    "total_documents": {
+      "type": "integer",
+      "title": "Total Documents"
+    },
+    "documents_by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "Documents By Status"
+    },
+    "total_chunks": {
+      "type": "integer",
+      "title": "Total Chunks"
+    }
+  },
+  "type": "object",
+  "required": [
+    "total_sources",
+    "active_sources",
+    "total_documents",
+    "documents_by_status",
+    "total_chunks"
+  ],
+  "title": "IngestionStats"
+}
+
+
IngestionStatus
+{
+  "type": "string",
+  "enum": [
+    "pending",
+    "processing",
+    "completed",
+    "failed"
+  ],
+  "title": "IngestionStatus"
+}
+
+
InitiativeInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "policy": {
+      "$ref": "#/components/schemas/PolicySelection"
+    },
+    "responsible_staff": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Responsible Staff"
+    },
+    "target": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "string"
+        }
+      ],
+      "title": "Target"
+    },
+    "unit": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Unit"
+    },
+    "due_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Due On"
+    },
+    "status": {
+      "type": "string",
+      "enum": [
+        "planned",
+        "active",
+        "completed",
+        "cancelled"
+      ],
+      "title": "Status",
+      "default": "planned"
+    },
+    "milestones": {
+      "items": {
+        "$ref": "#/components/schemas/Milestone"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "title": "Milestones"
+    },
+    "measurements": {
+      "items": {
+        "$ref": "#/components/schemas/Measurement"
+      },
+      "type": "array",
+      "maxItems": 1000,
+      "title": "Measurements"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "policy",
+    "responsible_staff",
+    "target",
+    "unit",
+    "due_on",
+    "note"
+  ],
+  "title": "InitiativeInput"
+}
+
+
InspectionInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "property_reference": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Property Reference"
+    },
+    "inspection_reference": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Inspection Reference"
+    },
+    "dataset_kind": {
+      "type": "string",
+      "enum": [
+        "municipal",
+        "fictional"
+      ],
+      "title": "Dataset Kind"
+    },
+    "inspector_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "minLength": 1,
+      "title": "Inspector Notes"
+    },
+    "photo_observations": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Photo Observations"
+    },
+    "voice_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Voice Notes",
+      "default": ""
+    },
+    "evidence": {
+      "items": {
+        "$ref": "#/components/schemas/Evidence"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "title": "Evidence"
+    },
+    "linked_sources": {
+      "items": {
+        "$ref": "#/components/schemas/townlight_inspections__workflow_models__SourceLink"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Linked Sources"
+    },
+    "assigned_to": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Assigned To",
+      "default": ""
+    },
+    "staff_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Staff Notes",
+      "default": ""
+    },
+    "notice_draft": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Notice Draft",
+      "default": ""
+    },
+    "review_state": {
+      "type": "string",
+      "enum": [
+        "draft",
+        "follow_up",
+        "reviewed"
+      ],
+      "title": "Review State",
+      "default": "draft"
+    },
+    "review_notes": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Review Notes",
+      "default": ""
+    },
+    "public_summary": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Public Summary",
+      "default": ""
+    },
+    "analysis": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/AnalysisRecord"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "property_reference",
+    "inspection_reference",
+    "dataset_kind",
+    "inspector_notes"
+  ],
+  "title": "InspectionInput"
+}
+
+
IntakeInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "project_name": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Project Name"
+    },
+    "project_description": {
+      "type": "string",
+      "maxLength": 10000,
+      "minLength": 1,
+      "title": "Project Description"
+    },
+    "location": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Location"
+    },
+    "applicant_contact": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Applicant Contact",
+      "default": ""
+    },
+    "requirement_revision": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Requirement Revision"
+    },
+    "materials": {
+      "items": {
+        "$ref": "#/components/schemas/MaterialReview"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "minItems": 1,
+      "title": "Materials"
+    },
+    "linked_sources": {
+      "items": {
+        "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Linked Sources"
+    },
+    "staff_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Staff Notes",
+      "default": ""
+    },
+    "assigned_to": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Assigned To",
+      "default": ""
+    },
+    "review_state": {
+      "type": "string",
+      "enum": [
+        "draft",
+        "follow_up",
+        "reviewed"
+      ],
+      "title": "Review State",
+      "default": "draft"
+    },
+    "review_notes": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Review Notes",
+      "default": ""
+    },
+    "public_summary": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Public Summary",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "project_name",
+    "project_description",
+    "location",
+    "requirement_revision",
+    "materials"
+  ],
+  "title": "IntakeInput"
+}
+
+
InterpretationNoteCreate
+{
+  "properties": {
+    "note_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Note Id"
+    },
+    "note_text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Note Text"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "note_text"
+  ],
+  "title": "InterpretationNoteCreate",
+  "description": "Request body for staff-only interpretation notes."
+}
+
+
InterviewRequest
+{
+  "properties": {
+    "last_answer": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Answer"
+    },
+    "last_field": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Field"
+    },
+    "skipped_fields": {
+      "anyOf": [
+        {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Skipped Fields"
+    }
+  },
+  "type": "object",
+  "title": "InterviewRequest"
+}
+
+
InterviewResponse
+{
+  "properties": {
+    "question": {
+      "type": "string",
+      "title": "Question"
+    },
+    "target_field": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Target Field"
+    },
+    "all_complete": {
+      "type": "boolean",
+      "title": "All Complete"
+    },
+    "completed_fields": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Completed Fields"
+    },
+    "onboarding_status": {
+      "type": "string",
+      "title": "Onboarding Status"
+    },
+    "skipped_fields": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Skipped Fields"
+    }
+  },
+  "type": "object",
+  "required": [
+    "question",
+    "target_field",
+    "all_complete",
+    "completed_fields",
+    "onboarding_status",
+    "skipped_fields"
+  ],
+  "title": "InterviewResponse"
+}
+
+
ManagedFileReceipt
+{
+  "properties": {
+    "original_path": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Original Path"
+    },
+    "stored_path": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Stored Path"
+    },
+    "file_name": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "File Name"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Sha256"
+    },
+    "size_bytes": {
+      "type": "integer",
+      "maximum": 2147483647.0,
+      "minimum": 0.0,
+      "title": "Size Bytes"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "original_path",
+    "stored_path",
+    "file_name",
+    "sha256",
+    "size_bytes"
+  ],
+  "title": "ManagedFileReceipt"
+}
+
+
ManagedSource
+{
+  "properties": {
+    "original_path": {
+      "type": "string",
+      "title": "Original Path"
+    },
+    "stored_path": {
+      "type": "string",
+      "title": "Stored Path"
+    },
+    "file_name": {
+      "type": "string",
+      "title": "File Name"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Sha256"
+    },
+    "size_bytes": {
+      "type": "integer",
+      "minimum": 0.0,
+      "title": "Size Bytes"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "original_path",
+    "stored_path",
+    "file_name",
+    "sha256",
+    "size_bytes"
+  ],
+  "title": "ManagedSource"
+}
+
+
Material
+{
+  "properties": {
+    "material_id": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9_-]{1,80}$",
+      "title": "Material Id"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Description"
+    },
+    "citation": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Citation"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "material_id",
+    "description",
+    "citation"
+  ],
+  "title": "Material"
+}
+
+
MaterialReview
+{
+  "properties": {
+    "material_id": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Material Id"
+    },
+    "status": {
+      "type": "string",
+      "enum": [
+        "not_reviewed",
+        "provided",
+        "missing",
+        "unclear"
+      ],
+      "title": "Status",
+      "default": "not_reviewed"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Note",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "material_id"
+  ],
+  "title": "MaterialReview"
+}
+
+
Measurement
+{
+  "properties": {
+    "recorded_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Recorded On"
+    },
+    "value": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "string"
+        }
+      ],
+      "title": "Value"
+    },
+    "evidence": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Evidence"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "recorded_on",
+    "value",
+    "evidence"
+  ],
+  "title": "Measurement"
+}
+
+
MediaAnalysis
+{
+  "properties": {
+    "items": {
+      "items": {
+        "$ref": "#/components/schemas/EvidenceItem"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "minItems": 1,
+      "title": "Items"
+    },
+    "code_links": {
+      "items": {
+        "$ref": "#/components/schemas/CodeLink"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Code Links"
+    },
+    "inspector_supplied_text": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Inspector Supplied Text",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "items"
+  ],
+  "title": "MediaAnalysis"
+}
+
+
MeetingInput
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "scheduled_start": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Scheduled Start"
+    },
+    "location": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Location"
+    },
+    "meeting_type": {
+      "type": "string",
+      "enum": [
+        "regular",
+        "special",
+        "emergency",
+        "closed_session",
+        "executive"
+      ],
+      "title": "Meeting Type",
+      "default": "regular"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "scheduled_start",
+    "location"
+  ],
+  "title": "MeetingInput"
+}
+
+
MeetingLink
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 200,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    },
+    "relation": {
+      "type": "string",
+      "enum": [
+        "hearing",
+        "context",
+        "precedent"
+      ],
+      "title": "Relation"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256",
+    "relation"
+  ],
+  "title": "MeetingLink"
+}
+
+
MeetingSearch
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "MeetingSearch"
+}
+
+
MeetingStageInput
+{
+  "properties": {
+    "to_status": {
+      "type": "string",
+      "enum": [
+        "SCHEDULED",
+        "NOTICED",
+        "PACKET_POSTED",
+        "IN_PROGRESS",
+        "RECESSED",
+        "ADJOURNED",
+        "TRANSCRIPT_READY",
+        "MINUTES_DRAFTED",
+        "MINUTES_POSTED",
+        "MINUTES_ADOPTED",
+        "MINUTES_SIGNED",
+        "ARCHIVED",
+        "CANCELLED"
+      ],
+      "title": "To Status"
+    },
+    "statutory_basis": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Basis"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "to_status"
+  ],
+  "title": "MeetingStageInput"
+}
+
+
MeetingsSearch
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "MeetingsSearch"
+}
+
+
MeetingsSourceSelection
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 200,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "MeetingsSourceSelection"
+}
+
+
MessageCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-message",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/MessagePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "MessageCommand"
+}
+
+
MessageCreate
+{
+  "properties": {
+    "message_text": {
+      "type": "string",
+      "title": "Message Text"
+    },
+    "is_internal": {
+      "type": "boolean",
+      "title": "Is Internal",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "message_text"
+  ],
+  "title": "MessageCreate"
+}
+
+
MessagePayload
+{
+  "properties": {
+    "requestMessageBody": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestmessagebody"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requestMessageBody"
+  ],
+  "title": "MessagePayload"
+}
+
+
MessageRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "sender_type": {
+      "type": "string",
+      "title": "Sender Type"
+    },
+    "sender_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sender Id"
+    },
+    "message_text": {
+      "type": "string",
+      "title": "Message Text"
+    },
+    "is_internal": {
+      "type": "boolean",
+      "title": "Is Internal"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "sender_type",
+    "sender_id",
+    "message_text",
+    "is_internal",
+    "created_at"
+  ],
+  "title": "MessageRead"
+}
+
+
MessageView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "author": {
+      "type": "string",
+      "title": "Author"
+    },
+    "author_role": {
+      "type": "string",
+      "title": "Author Role"
+    },
+    "body": {
+      "type": "string",
+      "title": "Body"
+    },
+    "visibility": {
+      "type": "string",
+      "title": "Visibility"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "author",
+    "author_role",
+    "body",
+    "visibility",
+    "created_at_unix_seconds"
+  ],
+  "title": "MessageView"
+}
+
+
Milestone
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "due_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Due On"
+    },
+    "completed_on": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Completed On"
+    },
+    "evidence": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Evidence",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "due_on"
+  ],
+  "title": "Milestone"
+}
+
+
MinutesDecision
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "post",
+        "adopt",
+        "sign"
+      ],
+      "title": "Action"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "MinutesDecision"
+}
+
+
ModelRegistryCreate
+{
+  "properties": {
+    "model_name": {
+      "type": "string",
+      "title": "Model Name"
+    },
+    "model_version": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Version"
+    },
+    "parameter_count": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parameter Count"
+    },
+    "license": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "License"
+    },
+    "model_card_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Card Url"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active",
+      "default": false
+    },
+    "context_window_size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Context Window Size"
+    },
+    "supports_ner": {
+      "type": "boolean",
+      "title": "Supports Ner",
+      "default": false
+    },
+    "supports_vision": {
+      "type": "boolean",
+      "title": "Supports Vision",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "model_name"
+  ],
+  "title": "ModelRegistryCreate",
+  "description": "Schema for creating a new model_registry record (POST body)."
+}
+
+
ModelRegistryRead
+{
+  "properties": {
+    "id": {
+      "type": "integer",
+      "title": "Id"
+    },
+    "model_name": {
+      "type": "string",
+      "title": "Model Name"
+    },
+    "model_version": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Version"
+    },
+    "parameter_count": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parameter Count"
+    },
+    "license": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "License"
+    },
+    "model_card_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Card Url"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "added_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Added At"
+    },
+    "context_window_size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Context Window Size"
+    },
+    "supports_ner": {
+      "type": "boolean",
+      "title": "Supports Ner"
+    },
+    "supports_vision": {
+      "type": "boolean",
+      "title": "Supports Vision"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "model_name",
+    "is_active",
+    "supports_ner",
+    "supports_vision"
+  ],
+  "title": "ModelRegistryRead",
+  "description": "Schema for returning a model_registry record (GET response).\n\n``from_attributes=True`` allows construction directly from an ORM instance."
+}
+
+
ModelRegistryUpdate
+{
+  "properties": {
+    "model_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Name"
+    },
+    "model_version": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Version"
+    },
+    "parameter_count": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parameter Count"
+    },
+    "license": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "License"
+    },
+    "model_card_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Card Url"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    },
+    "context_window_size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Context Window Size"
+    },
+    "supports_ner": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supports Ner"
+    },
+    "supports_vision": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supports Vision"
+    }
+  },
+  "type": "object",
+  "title": "ModelRegistryUpdate",
+  "description": "Schema for partially updating a model_registry record (PATCH body).\n\nEvery field is optional so callers can send only the fields they want to\nchange."
+}
+
+
MotionCorrection
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "reason": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Reason"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text",
+    "reason"
+  ],
+  "title": "MotionCorrection"
+}
+
+
MotionInput
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "seconded_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "minLength": 1
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Seconded By"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text"
+  ],
+  "title": "MotionInput"
+}
+
+
NativePayload
+{
+  "properties": {},
+  "additionalProperties": false,
+  "type": "object",
+  "title": "NativePayload"
+}
+
+
NativeRequestRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "requester_name": {
+      "type": "string",
+      "title": "Requester Name"
+    },
+    "requester_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Email"
+    },
+    "requester_phone": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Phone"
+    },
+    "requester_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Type"
+    },
+    "date_received": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Date Received"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "status": {
+      "$ref": "#/components/schemas/RequestStatus"
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "created_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "response_draft": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Response Draft"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    },
+    "estimated_fee": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Estimated Fee"
+    },
+    "fee_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Status"
+    },
+    "fee_waiver_requested": {
+      "type": "boolean",
+      "title": "Fee Waiver Requested",
+      "default": false
+    },
+    "priority": {
+      "type": "string",
+      "title": "Priority",
+      "default": "normal"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    },
+    "closed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closed At"
+    },
+    "closure_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closure Reason"
+    },
+    "desktop_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Desktop Id"
+    },
+    "public_tracking_number": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Public Tracking Number"
+    },
+    "submitted_via": {
+      "type": "string",
+      "title": "Submitted Via"
+    },
+    "deadline_label": {
+      "type": "string",
+      "title": "Deadline Label"
+    },
+    "deadline_basis": {
+      "type": "string",
+      "title": "Deadline Basis"
+    },
+    "deadline_reviewed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Deadline Reviewed At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "requester_name",
+    "requester_email",
+    "date_received",
+    "statutory_deadline",
+    "description",
+    "status",
+    "assigned_to",
+    "created_by",
+    "created_at",
+    "response_draft",
+    "review_notes",
+    "desktop_id",
+    "public_tracking_number",
+    "submitted_via",
+    "deadline_label",
+    "deadline_basis",
+    "deadline_reviewed_at"
+  ],
+  "title": "NativeRequestRead"
+}
+
+
NoticeDocumentInput
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text"
+  ],
+  "title": "NoticeDocumentInput"
+}
+
+
NoticeDraft
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 100000,
+      "minLength": 1,
+      "title": "Body"
+    },
+    "notice_type": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Notice Type"
+    },
+    "statutory_basis": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Statutory Basis"
+    },
+    "event_date": {
+      "type": "string",
+      "format": "date",
+      "title": "Event Date"
+    },
+    "lead_days": {
+      "type": "integer",
+      "maximum": 365.0,
+      "minimum": 0.0,
+      "title": "Lead Days"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "body",
+    "notice_type",
+    "statutory_basis",
+    "event_date",
+    "lead_days"
+  ],
+  "title": "NoticeDraft"
+}
+
+
NoticeInput
+{
+  "properties": {
+    "notice_type": {
+      "type": "string",
+      "enum": [
+        "regular",
+        "special",
+        "emergency",
+        "closed_session",
+        "executive"
+      ],
+      "title": "Notice Type"
+    },
+    "posted_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Posted At"
+    },
+    "minimum_notice_hours": {
+      "type": "integer",
+      "minimum": 0.0,
+      "title": "Minimum Notice Hours"
+    },
+    "statutory_basis": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Basis"
+    },
+    "approved_by": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Approved By"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "notice_type",
+    "posted_at",
+    "minimum_notice_hours"
+  ],
+  "title": "NoticeInput"
+}
+
+
NoticeProofInput
+{
+  "properties": {
+    "location": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Location"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note",
+      "default": ""
+    },
+    "document_delivery_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Document Delivery Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "location"
+  ],
+  "title": "NoticeProofInput"
+}
+
+
NotificationLogRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "template_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Template Id"
+    },
+    "recipient_email": {
+      "type": "string",
+      "title": "Recipient Email"
+    },
+    "request_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Request Id"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "sent_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sent At"
+    },
+    "error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Message"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "template_id",
+    "recipient_email",
+    "request_id",
+    "channel",
+    "status",
+    "sent_at",
+    "error_message",
+    "created_at"
+  ],
+  "title": "NotificationLogRead"
+}
+
+
NotificationTemplateCreate
+{
+  "properties": {
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel",
+      "default": "email"
+    },
+    "subject_template": {
+      "type": "string",
+      "title": "Subject Template"
+    },
+    "body_template": {
+      "type": "string",
+      "title": "Body Template"
+    }
+  },
+  "type": "object",
+  "required": [
+    "event_type",
+    "subject_template",
+    "body_template"
+  ],
+  "title": "NotificationTemplateCreate"
+}
+
+
NotificationTemplateRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel"
+    },
+    "subject_template": {
+      "type": "string",
+      "title": "Subject Template"
+    },
+    "body_template": {
+      "type": "string",
+      "title": "Body Template"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "event_type",
+    "channel",
+    "subject_template",
+    "body_template",
+    "is_active",
+    "created_at"
+  ],
+  "title": "NotificationTemplateRead"
+}
+
+
NotificationTemplateUpdate
+{
+  "properties": {
+    "subject_template": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Subject Template"
+    },
+    "body_template": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Body Template"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "NotificationTemplateUpdate"
+}
+
+
NotificationView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "notification_id": {
+      "type": "string",
+      "title": "Notification Id"
+    },
+    "module_id": {
+      "type": "string",
+      "title": "Module Id"
+    },
+    "record_id": {
+      "type": "string",
+      "title": "Record Id"
+    },
+    "audience": {
+      "type": "string",
+      "title": "Audience"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel"
+    },
+    "subject": {
+      "type": "string",
+      "title": "Subject"
+    },
+    "body": {
+      "type": "string",
+      "title": "Body"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    },
+    "sent_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sent At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "notification_id",
+    "module_id",
+    "record_id",
+    "audience",
+    "channel",
+    "subject",
+    "body",
+    "status",
+    "created_at_unix_seconds",
+    "sent_at_unix_seconds"
+  ],
+  "title": "NotificationView"
+}
+
+
OllamaModelInfo
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Size"
+    },
+    "details": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Details"
+    }
+  },
+  "type": "object",
+  "required": [
+    "name"
+  ],
+  "title": "OllamaModelInfo"
+}
+
+
OllamaStatus
+{
+  "properties": {
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "models": {
+      "items": {
+        "$ref": "#/components/schemas/OllamaModelInfo"
+      },
+      "type": "array",
+      "title": "Models"
+    }
+  },
+  "type": "object",
+  "required": [
+    "status",
+    "models"
+  ],
+  "title": "OllamaStatus"
+}
+
+
OperationalMetrics
+{
+  "properties": {
+    "average_response_time_days": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Average Response Time Days"
+    },
+    "median_response_time_days": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Median Response Time Days"
+    },
+    "requests_by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "Requests By Status"
+    },
+    "requests_by_department": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "Requests By Department"
+    },
+    "deadline_compliance_rate": {
+      "type": "number",
+      "title": "Deadline Compliance Rate"
+    },
+    "total_open": {
+      "type": "integer",
+      "title": "Total Open"
+    },
+    "total_closed": {
+      "type": "integer",
+      "title": "Total Closed"
+    },
+    "total_overdue": {
+      "type": "integer",
+      "title": "Total Overdue"
+    },
+    "clarification_frequency": {
+      "type": "number",
+      "title": "Clarification Frequency"
+    },
+    "top_request_topics": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Top Request Topics"
+    }
+  },
+  "type": "object",
+  "required": [
+    "average_response_time_days",
+    "median_response_time_days",
+    "requests_by_status",
+    "requests_by_department",
+    "deadline_compliance_rate",
+    "total_open",
+    "total_closed",
+    "total_overdue",
+    "clarification_frequency",
+    "top_request_topics"
+  ],
+  "title": "OperationalMetrics"
+}
+
+
Outline
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "question_ids": {
+      "items": {
+        "type": "string",
+        "format": "uuid"
+      },
+      "type": "array",
+      "maxItems": 50,
+      "minItems": 1,
+      "title": "Question Ids"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "question_ids"
+  ],
+  "title": "Outline"
+}
+
+
Packet
+{
+  "properties": {
+    "expected_revision": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Expected Revision"
+    },
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "staff_only",
+        "records_copy"
+      ],
+      "title": "Visibility"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "expected_revision",
+    "visibility"
+  ],
+  "title": "Packet"
+}
+
+
PacketInput
+{
+  "properties": {
+    "agenda_item_ids": {
+      "items": {
+        "type": "string",
+        "format": "uuid"
+      },
+      "type": "array",
+      "title": "Agenda Item Ids"
+    },
+    "source_files": {
+      "items": {
+        "$ref": "#/components/schemas/ManagedSource"
+      },
+      "type": "array",
+      "title": "Source Files"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "agenda_item_ids"
+  ],
+  "title": "PacketInput"
+}
+
+
Pathway
+{
+  "properties": {
+    "project_type": {
+      "type": "string",
+      "maxLength": 120,
+      "minLength": 1,
+      "title": "Project Type"
+    },
+    "proposal": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Proposal",
+      "default": ""
+    },
+    "location_context": {
+      "type": "string",
+      "maxLength": 1000,
+      "title": "Location Context",
+      "default": ""
+    },
+    "requirement_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requirement Revision"
+    },
+    "fee_link": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "project_type"
+  ],
+  "title": "Pathway"
+}
+
+
PathwayStep
+{
+  "properties": {
+    "step": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Step"
+    },
+    "citation": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Citation"
+    },
+    "typical_time": {
+      "type": "string",
+      "maxLength": 1000,
+      "title": "Typical Time",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "step",
+    "citation"
+  ],
+  "title": "PathwayStep"
+}
+
+
PlainLanguageSummaryCreate
+{
+  "properties": {
+    "summary_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Summary Id"
+    },
+    "section_version_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Version Id"
+    },
+    "summary_text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Summary Text"
+    },
+    "language_code": {
+      "type": "string",
+      "title": "Language Code",
+      "default": "en"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "section_version_id",
+    "summary_text"
+  ],
+  "title": "PlainLanguageSummaryCreate",
+  "description": "Request body for staff-drafted plain-language summaries."
+}
+
+
PolicySelection
+{
+  "properties": {
+    "plan_id": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Plan Id"
+    },
+    "revision_id": {
+      "type": "string",
+      "maxLength": 36,
+      "minLength": 36,
+      "title": "Revision Id"
+    },
+    "policy_id": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Policy Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "plan_id",
+    "revision_id",
+    "policy_id"
+  ],
+  "title": "PolicySelection"
+}
+
+
PortalModeResponse
+{
+  "properties": {
+    "mode": {
+      "type": "string",
+      "enum": [
+        "public",
+        "private"
+      ],
+      "title": "Mode",
+      "description": "Active portal posture for this deployment. ``public`` = minimal resident surface (landing + authenticated records-request submission + resident registration) reachable without staff auth. ``private`` = staff-only; no public routes, no resident self-registration."
+    }
+  },
+  "type": "object",
+  "required": [
+    "mode"
+  ],
+  "title": "PortalModeResponse",
+  "description": "T5D — schema for ``GET /config/portal-mode``.\n\nExposed to the frontend on boot so it can branch routing without a\nuser-identity lookup. The payload is intentionally the single field\nbelow — no staff config, no user state, no schema version."
+}
+
+
PrepareArtifact
+{
+  "properties": {
+    "kind": {
+      "type": "string",
+      "enum": [
+        "response",
+        "release-package"
+      ],
+      "title": "Kind"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "kind"
+  ],
+  "title": "PrepareArtifact"
+}
+
+
Proof
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    },
+    "filename": {
+      "type": "string",
+      "maxLength": 150,
+      "minLength": 1,
+      "title": "Filename"
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 7000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "location": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Location"
+    },
+    "published_at": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Published At"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence",
+    "filename",
+    "content_base64",
+    "location",
+    "published_at"
+  ],
+  "title": "Proof"
+}
+
+
Proposal
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "pattern": "^[A-Za-z0-9_-]{1,64}$",
+      "title": "Id"
+    },
+    "version_id": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Version Id"
+    },
+    "meeting_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Meeting Id"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "ordinance_number": {
+      "type": "string",
+      "maxLength": 120,
+      "minLength": 1,
+      "title": "Ordinance Number"
+    },
+    "proposed_text": {
+      "type": "string",
+      "maxLength": 1000000,
+      "minLength": 1,
+      "title": "Proposed Text"
+    },
+    "supersedes_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^[A-Za-z0-9_-]{1,64}$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supersedes Id"
+    },
+    "reconciliation_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reconciliation Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "version_id",
+    "meeting_id",
+    "title",
+    "ordinance_number",
+    "proposed_text"
+  ],
+  "title": "Proposal"
+}
+
+
PublicExplore
+{
+  "properties": {
+    "goal": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Goal",
+      "default": ""
+    },
+    "topic": {
+      "type": "string",
+      "maxLength": 160,
+      "title": "Topic",
+      "default": ""
+    },
+    "neighborhood": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Neighborhood",
+      "default": ""
+    },
+    "plan_type": {
+      "type": "string",
+      "maxLength": 120,
+      "title": "Plan Type",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "PublicExplore"
+}
+
+
PublicIntake
+{
+  "properties": {
+    "requester": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requester"
+    },
+    "requesterContact": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestercontact"
+    },
+    "summary": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Summary"
+    },
+    "deadline": {
+      "type": "string",
+      "title": "Deadline",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requester",
+    "requesterContact",
+    "summary"
+  ],
+  "title": "PublicIntake"
+}
+
+
PublicLookup
+{
+  "properties": {
+    "trackingNumber": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Trackingnumber"
+    },
+    "requesterContact": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestercontact"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "trackingNumber",
+    "requesterContact"
+  ],
+  "title": "PublicLookup"
+}
+
+
PublicMessage
+{
+  "properties": {
+    "trackingNumber": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Trackingnumber"
+    },
+    "requesterContact": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestercontact"
+    },
+    "publicRequestMessage": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Publicrequestmessage"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "trackingNumber",
+    "requesterContact",
+    "publicRequestMessage"
+  ],
+  "title": "PublicMessage"
+}
+
+
PublicStatusView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "label": {
+      "type": "string",
+      "title": "Label"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "label",
+    "summary",
+    "status",
+    "created_at_unix_seconds"
+  ],
+  "title": "PublicStatusView"
+}
+
+
PublicationView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "source_module": {
+      "type": "string",
+      "title": "Source Module"
+    },
+    "source_record_id": {
+      "type": "string",
+      "title": "Source Record Id"
+    },
+    "record_type": {
+      "type": "string",
+      "title": "Record Type"
+    },
+    "public_payload": {
+      "type": "string",
+      "title": "Public Payload"
+    },
+    "payload_hash": {
+      "type": "string",
+      "title": "Payload Hash"
+    },
+    "published_at_unix_seconds": {
+      "type": "integer",
+      "title": "Published At Unix Seconds"
+    },
+    "retracted_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Retracted At Unix Seconds"
+    },
+    "retracted_by": {
+      "type": "string",
+      "title": "Retracted By",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "source_module",
+    "source_record_id",
+    "record_type",
+    "public_payload",
+    "payload_hash",
+    "published_at_unix_seconds"
+  ],
+  "title": "PublicationView"
+}
+
+
PublishingPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "publishing-workflow",
+      "title": "Action"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "hasReview": {
+      "type": "boolean",
+      "title": "Hasreview",
+      "default": false
+    },
+    "hasPlainLanguage": {
+      "type": "boolean",
+      "title": "Hasplainlanguage",
+      "default": false
+    },
+    "hasTranslationReview": {
+      "type": "boolean",
+      "title": "Hastranslationreview",
+      "default": false
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "PublishingPlan"
+}
+
+
Question
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    },
+    "question": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Question"
+    },
+    "kind": {
+      "type": "string",
+      "enum": [
+        "use",
+        "dimension"
+      ],
+      "title": "Kind"
+    },
+    "key": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Key"
+    },
+    "audience": {
+      "type": "string",
+      "enum": [
+        "resident",
+        "staff"
+      ],
+      "title": "Audience",
+      "default": "resident"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "query",
+    "question",
+    "kind",
+    "key"
+  ],
+  "title": "Question"
+}
+
+
QuestionAnswerRequest
+{
+  "properties": {
+    "question": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Question"
+    },
+    "section_number": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Section Number"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "question"
+  ],
+  "title": "QuestionAnswerRequest",
+  "description": "Request body for citation-grounded code Q&A."
+}
+
+
RecordsDocumentView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "attachment_id": {
+      "type": "string",
+      "title": "Attachment Id"
+    },
+    "title": {
+      "type": "string",
+      "title": "Title"
+    },
+    "original_path": {
+      "type": "string",
+      "title": "Original Path"
+    },
+    "stored_path": {
+      "type": "string",
+      "title": "Stored Path"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation"
+    },
+    "sha256": {
+      "type": "string",
+      "title": "Sha256"
+    },
+    "size_bytes": {
+      "type": "integer",
+      "title": "Size Bytes"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "added_by": {
+      "type": "string",
+      "title": "Added By"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    },
+    "release_original_path": {
+      "type": "string",
+      "title": "Release Original Path",
+      "default": ""
+    },
+    "release_stored_path": {
+      "type": "string",
+      "title": "Release Stored Path",
+      "default": ""
+    },
+    "release_file_name": {
+      "type": "string",
+      "title": "Release File Name",
+      "default": ""
+    },
+    "release_sha256": {
+      "type": "string",
+      "title": "Release Sha256",
+      "default": ""
+    },
+    "release_size_bytes": {
+      "type": "integer",
+      "title": "Release Size Bytes",
+      "default": 0
+    },
+    "release_status": {
+      "type": "string",
+      "title": "Release Status",
+      "default": ""
+    },
+    "release_note": {
+      "type": "string",
+      "title": "Release Note",
+      "default": ""
+    },
+    "release_added_by": {
+      "type": "string",
+      "title": "Release Added By",
+      "default": ""
+    },
+    "release_added_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Release Added At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "attachment_id",
+    "title",
+    "original_path",
+    "stored_path",
+    "citation",
+    "sha256",
+    "size_bytes",
+    "status",
+    "added_by",
+    "created_at_unix_seconds"
+  ],
+  "title": "RecordsDocumentView"
+}
+
+
RecordsOperationRead
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "message": {
+      "type": "string",
+      "title": "Message"
+    },
+    "request": {
+      "$ref": "#/components/schemas/RecordsView"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "message",
+    "request"
+  ],
+  "title": "RecordsOperationRead"
+}
+
+
RecordsStateRead
+{
+  "properties": {
+    "demo_fixture": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Demo Fixture"
+    },
+    "records_requests": {
+      "items": {
+        "$ref": "#/components/schemas/RecordsView"
+      },
+      "type": "array",
+      "title": "Records Requests"
+    },
+    "notification_events": {
+      "items": {
+        "$ref": "#/components/schemas/NotificationView"
+      },
+      "type": "array",
+      "title": "Notification Events"
+    },
+    "publication_events": {
+      "items": {
+        "$ref": "#/components/schemas/PublicationView"
+      },
+      "type": "array",
+      "title": "Publication Events"
+    },
+    "audit_entries": {
+      "items": {
+        "$ref": "#/components/schemas/AuditView"
+      },
+      "type": "array",
+      "title": "Audit Entries"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "records_requests"
+  ],
+  "title": "RecordsStateRead"
+}
+
+
RecordsView
+{
+  "properties": {
+    "request_id": {
+      "type": "string",
+      "title": "Request Id"
+    },
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "public_tracking_number": {
+      "type": "string",
+      "title": "Public Tracking Number"
+    },
+    "requester": {
+      "type": "string",
+      "title": "Requester"
+    },
+    "requester_contact": {
+      "type": "string",
+      "title": "Requester Contact"
+    },
+    "submitted_via": {
+      "type": "string",
+      "title": "Submitted Via"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "deadline": {
+      "type": "string",
+      "title": "Deadline"
+    },
+    "deadline_basis": {
+      "type": "string",
+      "title": "Deadline Basis"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "assigned_to": {
+      "type": "string",
+      "title": "Assigned To"
+    },
+    "clarification_notes": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Clarification Notes"
+    },
+    "search_notes": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Search Notes"
+    },
+    "search_sessions": {
+      "items": {
+        "$ref": "#/components/schemas/SearchReceiptView"
+      },
+      "type": "array",
+      "title": "Search Sessions"
+    },
+    "exemption_reviews": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Exemption Reviews"
+    },
+    "exemption_decisions": {
+      "items": {
+        "$ref": "#/components/schemas/ExemptionDecisionView"
+      },
+      "type": "array",
+      "title": "Exemption Decisions"
+    },
+    "fee_estimate": {
+      "type": "string",
+      "title": "Fee Estimate"
+    },
+    "fee_line_items": {
+      "items": {
+        "$ref": "#/components/schemas/FeeLineView"
+      },
+      "type": "array",
+      "title": "Fee Line Items"
+    },
+    "fee_waiver_reason": {
+      "type": "string",
+      "title": "Fee Waiver Reason"
+    },
+    "citations": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Citations"
+    },
+    "response_draft": {
+      "type": "string",
+      "title": "Response Draft"
+    },
+    "approval_notes": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Approval Notes"
+    },
+    "exports": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Exports"
+    },
+    "documents": {
+      "items": {
+        "$ref": "#/components/schemas/RecordsDocumentView"
+      },
+      "type": "array",
+      "title": "Documents"
+    },
+    "release_packages": {
+      "items": {
+        "$ref": "#/components/schemas/ReleasePackageView"
+      },
+      "type": "array",
+      "title": "Release Packages"
+    },
+    "timeline": {
+      "items": {
+        "$ref": "#/components/schemas/TimelineView"
+      },
+      "type": "array",
+      "title": "Timeline"
+    },
+    "public_status_events": {
+      "items": {
+        "$ref": "#/components/schemas/PublicStatusView"
+      },
+      "type": "array",
+      "title": "Public Status Events"
+    },
+    "messages": {
+      "items": {
+        "$ref": "#/components/schemas/MessageView"
+      },
+      "type": "array",
+      "title": "Messages"
+    },
+    "deadline_reviewed_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Deadline Reviewed At Unix Seconds"
+    },
+    "approved_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Approved At Unix Seconds"
+    },
+    "fulfilled_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fulfilled At Unix Seconds"
+    },
+    "closed_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closed At Unix Seconds"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "request_id",
+    "id",
+    "public_tracking_number",
+    "requester",
+    "requester_contact",
+    "submitted_via",
+    "summary",
+    "deadline",
+    "deadline_basis",
+    "status",
+    "assigned_to",
+    "clarification_notes",
+    "search_notes",
+    "search_sessions",
+    "exemption_reviews",
+    "exemption_decisions",
+    "fee_estimate",
+    "fee_line_items",
+    "fee_waiver_reason",
+    "citations",
+    "response_draft",
+    "approval_notes",
+    "exports",
+    "timeline",
+    "public_status_events",
+    "messages",
+    "deadline_reviewed_at_unix_seconds",
+    "approved_at_unix_seconds",
+    "fulfilled_at_unix_seconds",
+    "closed_at_unix_seconds",
+    "created_at_unix_seconds"
+  ],
+  "title": "RecordsView"
+}
+
+
ReleasePackageView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "export_path": {
+      "type": "string",
+      "title": "Export Path"
+    },
+    "package_hash": {
+      "type": "string",
+      "title": "Package Hash"
+    },
+    "document_count": {
+      "type": "integer",
+      "title": "Document Count"
+    },
+    "release_artifact_count": {
+      "type": "integer",
+      "title": "Release Artifact Count"
+    },
+    "search_session_count": {
+      "type": "integer",
+      "title": "Search Session Count"
+    },
+    "release_count": {
+      "type": "integer",
+      "title": "Release Count"
+    },
+    "redacted_count": {
+      "type": "integer",
+      "title": "Redacted Count"
+    },
+    "exempt_count": {
+      "type": "integer",
+      "title": "Exempt Count"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "export_path",
+    "package_hash",
+    "document_count",
+    "release_artifact_count",
+    "search_session_count",
+    "release_count",
+    "redacted_count",
+    "exempt_count",
+    "created_at_unix_seconds"
+  ],
+  "title": "ReleasePackageView"
+}
+
+
RepeatLookup
+{
+  "properties": {
+    "property_reference": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Property Reference"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "property_reference"
+  ],
+  "title": "RepeatLookup"
+}
+
+
RequestCreate
+{
+  "properties": {
+    "requester_name": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Requester Name"
+    },
+    "requester_email": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 255
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Email"
+    },
+    "requester_phone": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 50
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Phone"
+    },
+    "requester_type": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 100
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Type"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Description"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "priority": {
+      "type": "string",
+      "title": "Priority",
+      "default": "normal"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^(narrow|moderate|broad)$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "requester_name",
+    "description"
+  ],
+  "title": "RequestCreate"
+}
+
+
RequestDocumentAdd
+{
+  "properties": {
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "relevance_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Relevance Note"
+    }
+  },
+  "type": "object",
+  "required": [
+    "document_id"
+  ],
+  "title": "RequestDocumentAdd"
+}
+
+
RequestDocumentRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "relevance_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Relevance Note"
+    },
+    "exemption_flags": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Exemption Flags"
+    },
+    "inclusion_status": {
+      "$ref": "#/components/schemas/InclusionStatus"
+    },
+    "attached_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Attached At"
+    },
+    "attached_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Attached By"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "document_id",
+    "relevance_note",
+    "exemption_flags",
+    "inclusion_status",
+    "attached_at",
+    "attached_by"
+  ],
+  "title": "RequestDocumentRead"
+}
+
+
RequestRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "requester_name": {
+      "type": "string",
+      "title": "Requester Name"
+    },
+    "requester_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Email"
+    },
+    "requester_phone": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Phone"
+    },
+    "requester_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Type"
+    },
+    "date_received": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Date Received"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "status": {
+      "$ref": "#/components/schemas/RequestStatus"
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "created_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "response_draft": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Response Draft"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    },
+    "estimated_fee": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Estimated Fee"
+    },
+    "fee_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Status"
+    },
+    "fee_waiver_requested": {
+      "type": "boolean",
+      "title": "Fee Waiver Requested",
+      "default": false
+    },
+    "priority": {
+      "type": "string",
+      "title": "Priority",
+      "default": "normal"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    },
+    "closed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closed At"
+    },
+    "closure_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closure Reason"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "requester_name",
+    "requester_email",
+    "date_received",
+    "statutory_deadline",
+    "description",
+    "status",
+    "assigned_to",
+    "created_by",
+    "created_at",
+    "response_draft",
+    "review_notes"
+  ],
+  "title": "RequestRead"
+}
+
+
RequestStats
+{
+  "properties": {
+    "total_requests": {
+      "type": "integer",
+      "title": "Total Requests"
+    },
+    "by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "By Status"
+    },
+    "approaching_deadline": {
+      "type": "integer",
+      "title": "Approaching Deadline"
+    },
+    "overdue": {
+      "type": "integer",
+      "title": "Overdue"
+    }
+  },
+  "type": "object",
+  "required": [
+    "total_requests",
+    "by_status",
+    "approaching_deadline",
+    "overdue"
+  ],
+  "title": "RequestStats"
+}
+
+
RequestStatus
+{
+  "type": "string",
+  "enum": [
+    "received",
+    "clarification_needed",
+    "assigned",
+    "searching",
+    "in_review",
+    "ready_for_release",
+    "drafted",
+    "approved",
+    "fulfilled",
+    "closed"
+  ],
+  "title": "RequestStatus"
+}
+
+
RequestUpdate
+{
+  "properties": {
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/RequestStatus"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "response_draft": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Response Draft"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    }
+  },
+  "type": "object",
+  "title": "RequestUpdate"
+}
+
+
RequirementBundle
+{
+  "properties": {
+    "requirement_id": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9_-]{1,100}$",
+      "title": "Requirement Id"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "project_type": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Project Type"
+    },
+    "source_reference": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Source Reference"
+    },
+    "source_date": {
+      "type": "string",
+      "format": "date",
+      "title": "Source Date"
+    },
+    "effective_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Effective On"
+    },
+    "dataset_kind": {
+      "type": "string",
+      "enum": [
+        "municipal",
+        "fictional"
+      ],
+      "title": "Dataset Kind"
+    },
+    "filename": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$",
+      "title": "Filename"
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 14000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Sha256"
+    },
+    "materials": {
+      "items": {
+        "$ref": "#/components/schemas/Material"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "minItems": 1,
+      "title": "Materials"
+    },
+    "pathway": {
+      "items": {
+        "$ref": "#/components/schemas/PathwayStep"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "title": "Pathway"
+    },
+    "fee_link": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    },
+    "staff_note": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Staff Note",
+      "default": ""
+    },
+    "change_note": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Change Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requirement_id",
+    "title",
+    "jurisdiction",
+    "project_type",
+    "source_reference",
+    "source_date",
+    "effective_on",
+    "dataset_kind",
+    "filename",
+    "content_base64",
+    "sha256",
+    "materials",
+    "change_note"
+  ],
+  "title": "RequirementBundle"
+}
+
+
ResponseLetterCreate
+{
+  "properties": {
+    "template_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Template Id"
+    }
+  },
+  "type": "object",
+  "title": "ResponseLetterCreate"
+}
+
+
ResponseLetterRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "template_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Template Id"
+    },
+    "generated_content": {
+      "type": "string",
+      "title": "Generated Content"
+    },
+    "edited_content": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Edited Content"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "generated_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Generated By"
+    },
+    "approved_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Approved By"
+    },
+    "sent_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sent At"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "template_id",
+    "generated_content",
+    "edited_content",
+    "status",
+    "generated_by",
+    "approved_by",
+    "sent_at",
+    "created_at"
+  ],
+  "title": "ResponseLetterRead"
+}
+
+
ResponseLetterUpdate
+{
+  "properties": {
+    "edited_content": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Edited Content"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Status"
+    }
+  },
+  "type": "object",
+  "title": "ResponseLetterUpdate"
+}
+
+
ReviewInput
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 5000,
+      "title": "Body",
+      "default": ""
+    },
+    "hasAltText": {
+      "type": "boolean",
+      "title": "Hasalttext",
+      "default": false
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": "en"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "ReviewInput"
+}
+
+
Revision
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    },
+    "document": {
+      "$ref": "#/components/schemas/NoticeDraft"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence",
+    "document"
+  ],
+  "title": "Revision"
+}
+
+
RewriteInput
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "plain-language",
+        "language-variant"
+      ],
+      "title": "Action"
+    },
+    "text": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Text"
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "text"
+  ],
+  "title": "RewriteInput"
+}
+
+
RewriteResult
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "plain-language",
+        "language-variant"
+      ],
+      "title": "Action"
+    },
+    "text": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Text"
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": ""
+    },
+    "outcome": {
+      "type": "string",
+      "enum": [
+        "generated",
+        "unavailable"
+      ],
+      "title": "Outcome"
+    },
+    "generated": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 100000
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Generated"
+    },
+    "model": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 200
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "text",
+    "outcome"
+  ],
+  "title": "RewriteResult"
+}
+
+
Rule
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "zone_code": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Zone Code"
+    },
+    "key": {
+      "type": "string",
+      "maxLength": 120,
+      "minLength": 1,
+      "title": "Key"
+    },
+    "section_number": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Section Number"
+    },
+    "kind": {
+      "type": "string",
+      "enum": [
+        "use",
+        "dimension"
+      ],
+      "title": "Kind"
+    },
+    "value": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Value"
+    },
+    "overlay_code": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 255
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Overlay Code"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "zone_code",
+    "key",
+    "section_number",
+    "kind",
+    "value"
+  ],
+  "title": "Rule"
+}
+
+
RuleTestMatch
+{
+  "properties": {
+    "matched_text": {
+      "type": "string",
+      "title": "Matched Text"
+    },
+    "start": {
+      "type": "integer",
+      "title": "Start"
+    },
+    "end": {
+      "type": "integer",
+      "title": "End"
+    }
+  },
+  "type": "object",
+  "required": [
+    "matched_text",
+    "start",
+    "end"
+  ],
+  "title": "RuleTestMatch"
+}
+
+
RuleTestRequest
+{
+  "properties": {
+    "sample_text": {
+      "type": "string",
+      "title": "Sample Text"
+    }
+  },
+  "type": "object",
+  "required": [
+    "sample_text"
+  ],
+  "title": "RuleTestRequest"
+}
+
+
RuleTestResponse
+{
+  "properties": {
+    "rule_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Rule Id"
+    },
+    "rule_type": {
+      "type": "string",
+      "title": "Rule Type"
+    },
+    "matched": {
+      "type": "boolean",
+      "title": "Matched"
+    },
+    "matches": {
+      "items": {
+        "$ref": "#/components/schemas/RuleTestMatch"
+      },
+      "type": "array",
+      "title": "Matches"
+    }
+  },
+  "type": "object",
+  "required": [
+    "rule_id",
+    "rule_type",
+    "matched",
+    "matches"
+  ],
+  "title": "RuleTestResponse"
+}
+
+
RuleType
+{
+  "type": "string",
+  "enum": [
+    "regex",
+    "keyword",
+    "llm_prompt"
+  ],
+  "title": "RuleType"
+}
+
+
SaveReview
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 5000,
+      "title": "Body",
+      "default": ""
+    },
+    "hasAltText": {
+      "type": "boolean",
+      "title": "Hasalttext",
+      "default": false
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": "en"
+    },
+    "ai_analysis": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 100000
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ai Analysis"
+    },
+    "ai_analysis_model": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 200
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ai Analysis Model"
+    },
+    "ai_outcome": {
+      "type": "string",
+      "enum": [
+        "generated",
+        "unavailable",
+        "failed"
+      ],
+      "title": "Ai Outcome"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "ai_outcome"
+  ],
+  "title": "SaveReview"
+}
+
+
SearchFilterOptions
+{
+  "properties": {
+    "file_types": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "File Types"
+    },
+    "source_names": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Source Names"
+    },
+    "departments": {
+      "items": {
+        "additionalProperties": true,
+        "type": "object"
+      },
+      "type": "array",
+      "title": "Departments",
+      "default": []
+    },
+    "date_range": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Date Range"
+    }
+  },
+  "type": "object",
+  "required": [
+    "file_types",
+    "source_names"
+  ],
+  "title": "SearchFilterOptions"
+}
+
+
SearchInput
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "SearchInput"
+}
+
+
SearchNoteCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "record-records-search",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/SearchNotePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "SearchNoteCommand"
+}
+
+
SearchNotePayload
+{
+  "properties": {
+    "sourceNote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Sourcenote"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sourceNote"
+  ],
+  "title": "SearchNotePayload"
+}
+
+
SearchReceiptCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "record-records-search-session",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/SearchReceiptPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "SearchReceiptCommand"
+}
+
+
SearchReceiptPayload
+{
+  "properties": {
+    "searchQuery": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchquery"
+    },
+    "searchLocations": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchlocations"
+    },
+    "searchResultTitle": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchresulttitle"
+    },
+    "searchResultCitation": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchresultcitation"
+    },
+    "searchResultSummary": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchresultsummary"
+    },
+    "searchResultStatus": {
+      "type": "string",
+      "title": "Searchresultstatus",
+      "default": ""
+    },
+    "searchReviewer": {
+      "type": "string",
+      "title": "Searchreviewer",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "searchQuery",
+    "searchLocations",
+    "searchResultTitle",
+    "searchResultCitation",
+    "searchResultSummary"
+  ],
+  "title": "SearchReceiptPayload"
+}
+
+
SearchReceiptView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "query": {
+      "type": "string",
+      "title": "Query"
+    },
+    "locations": {
+      "type": "string",
+      "title": "Locations"
+    },
+    "reviewer": {
+      "type": "string",
+      "title": "Reviewer"
+    },
+    "results": {
+      "items": {
+        "$ref": "#/components/schemas/SearchResultView"
+      },
+      "type": "array",
+      "title": "Results"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "query",
+    "locations",
+    "reviewer",
+    "results",
+    "created_at_unix_seconds"
+  ],
+  "title": "SearchReceiptView"
+}
+
+
SearchRequest
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "title": "Query"
+    },
+    "session_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Session Id"
+    },
+    "filters": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Filters"
+    },
+    "limit": {
+      "type": "integer",
+      "maximum": 50.0,
+      "title": "Limit",
+      "default": 10
+    },
+    "synthesize": {
+      "type": "boolean",
+      "title": "Synthesize",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "SearchRequest"
+}
+
+
SearchResponse
+{
+  "properties": {
+    "query_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Query Id"
+    },
+    "session_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Session Id"
+    },
+    "query_text": {
+      "type": "string",
+      "title": "Query Text"
+    },
+    "results": {
+      "items": {
+        "$ref": "#/components/schemas/SearchResultItem"
+      },
+      "type": "array",
+      "title": "Results"
+    },
+    "results_count": {
+      "type": "integer",
+      "title": "Results Count"
+    },
+    "synthesized_answer": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Synthesized Answer"
+    },
+    "ai_generated": {
+      "type": "boolean",
+      "title": "Ai Generated",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "query_id",
+    "session_id",
+    "query_text",
+    "results",
+    "results_count"
+  ],
+  "title": "SearchResponse"
+}
+
+
SearchResultItem
+{
+  "properties": {
+    "chunk_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Chunk Id"
+    },
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "filename": {
+      "type": "string",
+      "title": "Filename"
+    },
+    "file_type": {
+      "type": "string",
+      "title": "File Type"
+    },
+    "source_path": {
+      "type": "string",
+      "title": "Source Path"
+    },
+    "page_number": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Page Number"
+    },
+    "content_text": {
+      "type": "string",
+      "title": "Content Text"
+    },
+    "similarity_score": {
+      "type": "number",
+      "title": "Similarity Score"
+    },
+    "rank": {
+      "type": "integer",
+      "title": "Rank"
+    }
+  },
+  "type": "object",
+  "required": [
+    "chunk_id",
+    "document_id",
+    "filename",
+    "file_type",
+    "source_path",
+    "page_number",
+    "content_text",
+    "similarity_score",
+    "rank"
+  ],
+  "title": "SearchResultItem"
+}
+
+
SearchResultView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "title": {
+      "type": "string",
+      "title": "Title"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "title",
+    "citation",
+    "summary",
+    "status"
+  ],
+  "title": "SearchResultView"
+}
+
+
SearchSessionRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "user_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "User Id"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "queries": {
+      "items": {
+        "additionalProperties": true,
+        "type": "object"
+      },
+      "type": "array",
+      "title": "Queries",
+      "default": []
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "user_id",
+    "created_at"
+  ],
+  "title": "SearchSessionRead"
+}
+
+
SectionCreate
+{
+  "properties": {
+    "section_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Section Id"
+    },
+    "chapter_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Chapter Id"
+    },
+    "section_number": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Number"
+    },
+    "section_heading": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Heading"
+    },
+    "parent_section_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parent Section Id"
+    },
+    "sort_order": {
+      "type": "integer",
+      "title": "Sort Order",
+      "default": 0
+    },
+    "administrative_regulation_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Administrative Regulation Refs"
+    },
+    "resolution_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Resolution Refs"
+    },
+    "policy_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Policy Refs"
+    },
+    "approved_summary_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Approved Summary Refs"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "chapter_id",
+    "section_number",
+    "section_heading"
+  ],
+  "title": "SectionCreate",
+  "description": "Request body for creating a code section or subsection."
+}
+
+
SectionVersionCreate
+{
+  "properties": {
+    "version_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Version Id"
+    },
+    "section_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Id"
+    },
+    "source_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "version_label": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Version Label"
+    },
+    "body": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Body"
+    },
+    "effective_start": {
+      "type": "string",
+      "format": "date",
+      "title": "Effective Start"
+    },
+    "effective_end": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective End"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    },
+    "is_current": {
+      "type": "boolean",
+      "title": "Is Current",
+      "default": false
+    },
+    "adoption_event_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Adoption Event Id"
+    },
+    "amendment_event_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Amendment Event Id"
+    },
+    "amendment_summary": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Amendment Summary"
+    },
+    "prior_version_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Prior Version Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "section_id",
+    "source_id",
+    "version_label",
+    "body",
+    "effective_start"
+  ],
+  "title": "SectionVersionCreate",
+  "description": "Request body for adding an immutable section version."
+}
+
+
Selection
+{
+  "properties": {
+    "recording_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Recording Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "recording_id",
+    "expected_sha256"
+  ],
+  "title": "Selection"
+}
+
+
SentenceInput
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "citations": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Citations"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text"
+  ],
+  "title": "SentenceInput"
+}
+
+
ServiceAccountCreate
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole",
+      "default": "read_only"
+    }
+  },
+  "type": "object",
+  "required": [
+    "name"
+  ],
+  "title": "ServiceAccountCreate"
+}
+
+
ServiceAccountCreated
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "api_key": {
+      "type": "string",
+      "title": "Api Key"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "role",
+    "created_by",
+    "created_at",
+    "is_active",
+    "api_key"
+  ],
+  "title": "ServiceAccountCreated",
+  "description": "Returned only on creation — includes the plaintext API key (shown once)."
+}
+
+
ServiceAccountRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "role",
+    "created_by",
+    "created_at",
+    "is_active"
+  ],
+  "title": "ServiceAccountRead"
+}
+
+
ServiceAccountUpdate
+{
+  "properties": {
+    "role": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/UserRole"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "ServiceAccountUpdate"
+}
+
+
Snapshot
+{
+  "properties": {
+    "expected_revision": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Expected Revision"
+    },
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "staff_only",
+        "public"
+      ],
+      "title": "Visibility"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "expected_revision",
+    "visibility"
+  ],
+  "title": "Snapshot"
+}
+
+
SourceCreate
+{
+  "properties": {
+    "source_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Id"
+    },
+    "name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Name"
+    },
+    "publisher": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Publisher"
+    },
+    "source_type": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Type"
+    },
+    "source_category": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Category"
+    },
+    "source_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Url"
+    },
+    "file_reference": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "File Reference"
+    },
+    "retrieved_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Retrieved At"
+    },
+    "retrieval_method": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Retrieval Method"
+    },
+    "checksum": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Checksum"
+    },
+    "source_owner": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Owner"
+    },
+    "is_official": {
+      "type": "boolean",
+      "title": "Is Official",
+      "default": true
+    },
+    "official_status_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Official Status Note"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    },
+    "staff_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Staff Notes"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "name",
+    "publisher",
+    "source_type",
+    "source_category"
+  ],
+  "title": "SourceCreate",
+  "description": "Request body for registering an official or explicitly labeled source."
+}
+
+
SourceInput
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "label": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Label"
+    },
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "label",
+    "text"
+  ],
+  "title": "SourceInput"
+}
+
+
SourceSnapshot
+{
+  "properties": {
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "public",
+        "staff_only"
+      ],
+      "title": "Visibility"
+    },
+    "meeting_event_ids": {
+      "items": {
+        "type": "string",
+        "format": "uuid"
+      },
+      "type": "array",
+      "maxItems": 50,
+      "title": "Meeting Event Ids"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "visibility"
+  ],
+  "title": "SourceSnapshot"
+}
+
+
SourceType
+{
+  "type": "string",
+  "enum": [
+    "manual_drop",
+    "file_system",
+    "rest_api",
+    "odbc"
+  ],
+  "title": "SourceType"
+}
+
+
StaffRecordsIntake
+{
+  "properties": {
+    "requester": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requester"
+    },
+    "summary": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Summary"
+    },
+    "deadline": {
+      "type": "string",
+      "title": "Deadline"
+    },
+    "deadlineBasis": {
+      "type": "string",
+      "title": "Deadlinebasis",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requester",
+    "summary",
+    "deadline"
+  ],
+  "title": "StaffRecordsIntake",
+  "description": "Existing native create-records-request input; no caller-supplied actor."
+}
+
+
StandardsExplanation
+{
+  "properties": {
+    "question": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Question"
+    },
+    "process_section": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Process Section",
+      "default": ""
+    },
+    "zone_code": {
+      "type": "string",
+      "maxLength": 40,
+      "title": "Zone Code",
+      "default": ""
+    },
+    "rule_types": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "title": "Rule Types"
+    },
+    "observed": {
+      "additionalProperties": {
+        "type": "string"
+      },
+      "type": "object",
+      "title": "Observed"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "question"
+  ],
+  "title": "StandardsExplanation"
+}
+
+
SyncFailureRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "source_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Source Id"
+    },
+    "source_path": {
+      "type": "string",
+      "title": "Source Path"
+    },
+    "error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Message"
+    },
+    "error_class": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Class"
+    },
+    "http_status_code": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Http Status Code"
+    },
+    "retry_count": {
+      "type": "integer",
+      "title": "Retry Count"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "first_failed_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "First Failed At"
+    },
+    "last_retried_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Retried At"
+    },
+    "dismissed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Dismissed At"
+    },
+    "dismissed_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Dismissed By"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "source_id",
+    "source_path",
+    "error_message",
+    "error_class",
+    "http_status_code",
+    "retry_count",
+    "status",
+    "first_failed_at",
+    "last_retried_at",
+    "dismissed_at",
+    "dismissed_by"
+  ],
+  "title": "SyncFailureRead"
+}
+
+
SyncRunLogRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "source_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Source Id"
+    },
+    "started_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Started At"
+    },
+    "finished_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Finished At"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Status"
+    },
+    "records_attempted": {
+      "type": "integer",
+      "title": "Records Attempted"
+    },
+    "records_succeeded": {
+      "type": "integer",
+      "title": "Records Succeeded"
+    },
+    "records_failed": {
+      "type": "integer",
+      "title": "Records Failed"
+    },
+    "error_summary": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Summary"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "source_id",
+    "started_at",
+    "finished_at",
+    "status",
+    "records_attempted",
+    "records_succeeded",
+    "records_failed",
+    "error_summary"
+  ],
+  "title": "SyncRunLogRead"
+}
+
+
SystemStatus
+{
+  "properties": {
+    "version": {
+      "type": "string",
+      "title": "Version"
+    },
+    "database": {
+      "type": "string",
+      "title": "Database"
+    },
+    "ollama": {
+      "type": "string",
+      "title": "Ollama"
+    },
+    "redis": {
+      "type": "string",
+      "title": "Redis"
+    },
+    "user_count": {
+      "type": "integer",
+      "title": "User Count"
+    },
+    "audit_log_count": {
+      "type": "integer",
+      "title": "Audit Log Count"
+    },
+    "suite_session": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Suite Session"
+    }
+  },
+  "type": "object",
+  "required": [
+    "version",
+    "database",
+    "ollama",
+    "redis",
+    "user_count",
+    "audit_log_count"
+  ],
+  "title": "SystemStatus"
+}
+
+
TaggedPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "tagged-pdf",
+      "title": "Action"
+    },
+    "headingLevels": {
+      "items": {
+        "type": "integer",
+        "maximum": 4294967295.0,
+        "minimum": 0.0
+      },
+      "type": "array",
+      "maxItems": 50,
+      "title": "Headinglevels"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "TaggedPlan"
+}
+
+
TestConnectionRequest
+{
+  "properties": {
+    "source_type": {
+      "type": "string",
+      "title": "Source Type"
+    },
+    "host": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Host"
+    },
+    "port": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Port"
+    },
+    "path": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Path"
+    },
+    "username": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Username"
+    },
+    "password": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Password"
+    },
+    "rest_api_config": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Rest Api Config"
+    },
+    "odbc_config": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Odbc Config"
+    }
+  },
+  "type": "object",
+  "required": [
+    "source_type"
+  ],
+  "title": "TestConnectionRequest",
+  "description": "Dedicated schema for test-connection. NOT the create schema.\n\nSecurity: credentials in this request body are never persisted, never\nwritten to audit logs, and never returned in the response."
+}
+
+
TestConnectionResponse
+{
+  "properties": {
+    "success": {
+      "type": "boolean",
+      "title": "Success"
+    },
+    "message": {
+      "type": "string",
+      "title": "Message"
+    },
+    "latency_ms": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Latency Ms"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Status"
+    },
+    "warning": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Warning"
+    },
+    "differing_keys": {
+      "anyOf": [
+        {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Differing Keys"
+    }
+  },
+  "type": "object",
+  "required": [
+    "success",
+    "message"
+  ],
+  "title": "TestConnectionResponse"
+}
+
+
TimelineEventCreate
+{
+  "properties": {
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "internal_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Internal Note"
+    }
+  },
+  "type": "object",
+  "required": [
+    "event_type",
+    "description"
+  ],
+  "title": "TimelineEventCreate"
+}
+
+
TimelineEventRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "actor_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Actor Id"
+    },
+    "actor_role": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Actor Role"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "internal_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Internal Note"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "event_type",
+    "actor_id",
+    "actor_role",
+    "description",
+    "internal_note",
+    "created_at"
+  ],
+  "title": "TimelineEventRead"
+}
+
+
TimelineView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "actor": {
+      "type": "string",
+      "title": "Actor"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "action",
+    "actor",
+    "note",
+    "created_at_unix_seconds"
+  ],
+  "title": "TimelineView"
+}
+
+
TitleCreate
+{
+  "properties": {
+    "title_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Title Id"
+    },
+    "title_number": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title Number"
+    },
+    "title_name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title Name"
+    },
+    "sort_order": {
+      "type": "integer",
+      "title": "Sort Order",
+      "default": 0
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title_number",
+    "title_name"
+  ],
+  "title": "TitleCreate",
+  "description": "Request body for creating a code title."
+}
+
+
TranscriptInput
+{
+  "properties": {
+    "source_label": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Label"
+    },
+    "transcript_text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Transcript Text"
+    },
+    "correction_of_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Correction Of Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_label",
+    "transcript_text"
+  ],
+  "title": "TranscriptInput"
+}
+
+
UserRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "email": {
+      "type": "string",
+      "format": "email",
+      "title": "Email"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active",
+      "default": true
+    },
+    "is_superuser": {
+      "type": "boolean",
+      "title": "Is Superuser",
+      "default": false
+    },
+    "is_verified": {
+      "type": "boolean",
+      "title": "Is Verified",
+      "default": false
+    },
+    "full_name": {
+      "type": "string",
+      "title": "Full Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "last_login": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Login"
+    },
+    "must_change_password": {
+      "type": "boolean",
+      "title": "Must Change Password",
+      "default": false
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "email",
+    "full_name",
+    "role",
+    "created_at",
+    "last_login"
+  ],
+  "title": "UserRead"
+}
+
+
UserRole
+{
+  "type": "string",
+  "enum": [
+    "admin",
+    "staff",
+    "reviewer",
+    "read_only",
+    "liaison",
+    "public"
+  ],
+  "title": "UserRole"
+}
+
+
UserSelfUpdate
+{
+  "properties": {
+    "password": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Password"
+    },
+    "email": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "email"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    },
+    "is_superuser": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Superuser"
+    },
+    "is_verified": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Verified"
+    },
+    "full_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Full Name"
+    }
+  },
+  "type": "object",
+  "title": "UserSelfUpdate",
+  "description": "Schema for user self-update via PATCH /users/me.\n\nExcludes role and department_id. Any payload containing those fields is\nrejected at parse time (HTTP 422). Role and department changes require\nadmin privileges via /admin/users/{id}."
+}
+
+
UserUpdateRequest
+{
+  "properties": {
+    "full_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Full Name"
+    },
+    "role": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Role"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "UserUpdateRequest"
+}
+
+
ValidationError
+{
+  "properties": {
+    "loc": {
+      "items": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "integer"
+          }
+        ]
+      },
+      "type": "array",
+      "title": "Location"
+    },
+    "msg": {
+      "type": "string",
+      "title": "Message"
+    },
+    "type": {
+      "type": "string",
+      "title": "Error Type"
+    },
+    "input": {
+      "title": "Input"
+    },
+    "ctx": {
+      "type": "object",
+      "title": "Context"
+    }
+  },
+  "type": "object",
+  "required": [
+    "loc",
+    "msg",
+    "type"
+  ],
+  "title": "ValidationError"
+}
+
+
Version
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence"
+  ],
+  "title": "Version"
+}
+
+
VoteCorrection
+{
+  "properties": {
+    "vote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Vote"
+    },
+    "reason": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Reason"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "vote",
+    "reason"
+  ],
+  "title": "VoteCorrection"
+}
+
+
VoteInput
+{
+  "properties": {
+    "voter_name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Voter Name"
+    },
+    "vote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Vote"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "voter_name",
+    "vote"
+  ],
+  "title": "VoteInput"
+}
+
+
_ParcelLookupIn
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "query"
+  ],
+  "title": "_ParcelLookupIn"
+}
+
+
townlight_inspections__workflow_models__SourceLink
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "const": "code",
+      "title": "Provider",
+      "default": "code"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "SourceLink"
+}
+
+
townlight_permitting__workflow_models__SourceLink
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "enum": [
+        "code",
+        "zoning"
+      ],
+      "title": "Provider"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "SourceLink"
+}
+
+
townlight_runtime__inspections_bridge__Search
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "const": "code",
+      "title": "Provider"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "query"
+  ],
+  "title": "Search"
+}
+
+
townlight_runtime__notice_bridge__Review
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence",
+    "note"
+  ],
+  "title": "Review"
+}
+
+
townlight_runtime__permitting_bridge__Import
+{
+  "properties": {
+    "bundle": {
+      "$ref": "#/components/schemas/RequirementBundle"
+    },
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "bundle"
+  ],
+  "title": "Import"
+}
+
+
townlight_runtime__permitting_bridge__Search
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "enum": [
+        "code",
+        "zoning"
+      ],
+      "title": "Provider"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "query"
+  ],
+  "title": "Search"
+}
+
+
townlight_runtime__planning_bridge__Import
+{
+  "properties": {
+    "bundle": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Bundle"
+    },
+    "expected_previous_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Previous Revision"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "bundle"
+  ],
+  "title": "Import"
+}
+
+
townlight_runtime__planning_bridge__Search
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Query"
+    },
+    "plan_type": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 40
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Plan Type"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "Search"
+}
+
+
townlight_runtime__zoning_bridge__Review
+{
+  "properties": {
+    "answer": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Answer",
+      "default": ""
+    },
+    "notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Notes",
+      "default": ""
+    },
+    "queue_status": {
+      "type": "string",
+      "enum": [
+        "open",
+        "in_review",
+        "resolved",
+        "closed"
+      ],
+      "title": "Queue Status",
+      "default": "resolved"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "Review"
+}
+
Townlight · AGPL-3.0-only · Source schema evidence only
\ No newline at end of file diff --git a/docs/beta-1/api/notice-openapi.json b/docs/beta-1/api/notice-openapi.json new file mode 100644 index 0000000..a0f6902 --- /dev/null +++ b/docs/beta-1/api/notice-openapi.json @@ -0,0 +1,11619 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "Townlight Records", + "description": "Prepared source schema for the actual native composition; installed acceptance remains pending. Exported without lifespan, migrations or database/network access.", + "version": "1.8.0.dev2" + }, + "paths": { + "/desktop/v1/notice/notices": { + "get": { + "tags": [ + "native-notice" + ], + "summary": "Inventory", + "operationId": "inventory_desktop_v1_notice_notices_get", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "tags": [ + "native-notice" + ], + "summary": "Create", + "operationId": "create_desktop_v1_notice_notices_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NoticeDraft" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/notice/notices/{notice_id}": { + "get": { + "tags": [ + "native-notice" + ], + "summary": "Read", + "operationId": "read_desktop_v1_notice_notices__notice_id__get", + "parameters": [ + { + "name": "notice_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Notice Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/notice/notices/{notice_id}/revisions": { + "post": { + "tags": [ + "native-notice" + ], + "summary": "Edit", + "operationId": "edit_desktop_v1_notice_notices__notice_id__revisions_post", + "parameters": [ + { + "name": "notice_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Notice Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Revision" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/notice/notices/{notice_id}/review": { + "post": { + "tags": [ + "native-notice" + ], + "summary": "Review", + "operationId": "review_desktop_v1_notice_notices__notice_id__review_post", + "parameters": [ + { + "name": "notice_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Notice Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/townlight_runtime__notice_bridge__Review" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/notice/notices/{notice_id}/approval": { + "post": { + "tags": [ + "native-notice" + ], + "summary": "Approve", + "operationId": "approve_desktop_v1_notice_notices__notice_id__approval_post", + "parameters": [ + { + "name": "notice_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Notice Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Version" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/notice/notices/{notice_id}/proof": { + "post": { + "tags": [ + "native-notice" + ], + "summary": "Proof", + "operationId": "proof_desktop_v1_notice_notices__notice_id__proof_post", + "parameters": [ + { + "name": "notice_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Notice Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Proof" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/notice/notices/{notice_id}/archive": { + "post": { + "tags": [ + "native-notice" + ], + "summary": "Archive", + "operationId": "archive_desktop_v1_notice_notices__notice_id__archive_post", + "parameters": [ + { + "name": "notice_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Notice Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Version" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/notice/archives/{archive_id}": { + "get": { + "tags": [ + "native-notice" + ], + "summary": "Export", + "operationId": "export_desktop_v1_notice_archives__archive_id__get", + "parameters": [ + { + "name": "archive_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Archive Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/notice/archives/{archive_id}/records": { + "post": { + "tags": [ + "native-notice" + ], + "summary": "Handoff", + "operationId": "handoff_desktop_v1_notice_archives__archive_id__records_post", + "parameters": [ + { + "name": "archive_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Archive Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Handoff" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "ActionItemInput": { + "properties": { + "description": { + "type": "string", + "minLength": 1, + "title": "Description" + }, + "assigned_to": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "source_motion_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Source Motion Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "description" + ], + "title": "ActionItemInput" + }, + "AdaPlan": { + "properties": { + "action": { + "type": "string", + "const": "ada-title-ii", + "title": "Action" + }, + "serviceArea": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Servicearea" + }, + "hasCoordinatorReview": { + "type": "boolean", + "title": "Hascoordinatorreview", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "serviceArea" + ], + "title": "AdaPlan" + }, + "AdminUserCreateRequest": { + "properties": { + "email": { + "type": "string", + "title": "Email" + }, + "password": { + "type": "string", + "title": "Password" + }, + "full_name": { + "type": "string", + "title": "Full Name", + "default": "" + }, + "role": { + "type": "string", + "title": "Role", + "default": "staff" + } + }, + "type": "object", + "required": [ + "email", + "password" + ], + "title": "AdminUserCreateRequest" + }, + "AdminUserCreateResponse": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "email": { + "type": "string", + "title": "Email" + }, + "full_name": { + "type": "string", + "title": "Full Name" + }, + "role": { + "type": "string", + "title": "Role" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + } + }, + "type": "object", + "required": [ + "id", + "email", + "full_name", + "role", + "is_active" + ], + "title": "AdminUserCreateResponse" + }, + "AgendaAssignment": { + "properties": { + "meeting_id": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "meeting_id" + ], + "title": "AgendaAssignment" + }, + "AgendaInput": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "department_name": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Department Name" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "department_name" + ], + "title": "AgendaInput" + }, + "AgendaReviewInput": { + "properties": { + "to_status": { + "type": "string", + "enum": [ + "DRAFTED", + "SUBMITTED", + "DEPT_APPROVED", + "LEGAL_REVIEWED", + "CLERK_ACCEPTED", + "ON_AGENDA", + "IN_PACKET", + "POSTED", + "HEARD", + "DISPOSED", + "ARCHIVED" + ], + "title": "To Status" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "to_status" + ], + "title": "AgendaReviewInput" + }, + "AmendmentInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "policy": { + "$ref": "#/components/schemas/PolicySelection" + }, + "proposal": { + "type": "string", + "maxLength": 20000, + "minLength": 1, + "title": "Proposal" + }, + "responsible_staff": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Responsible Staff" + }, + "status": { + "type": "string", + "enum": [ + "draft", + "review", + "adopted", + "withdrawn" + ], + "title": "Status", + "default": "draft" + }, + "review_note": { + "type": "string", + "maxLength": 5000, + "title": "Review Note", + "default": "" + }, + "adoption_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Adoption Revision" + }, + "note": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "policy", + "proposal", + "responsible_staff", + "note" + ], + "title": "AmendmentInput" + }, + "AnalysisObservation": { + "properties": { + "source": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "title": "Source" + }, + "filename": { + "type": "string", + "maxLength": 160, + "title": "Filename", + "default": "" + }, + "media_type": { + "type": "string", + "maxLength": 80, + "title": "Media Type", + "default": "" + }, + "text": { + "type": "string", + "maxLength": 4000, + "minLength": 1, + "title": "Text" + }, + "adapter": { + "type": "string", + "maxLength": 120, + "title": "Adapter", + "default": "" + }, + "citation_source_ids": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 30, + "title": "Citation Source Ids" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source", + "text" + ], + "title": "AnalysisObservation", + "description": "One draft observation, named with the adapter that actually produced it." + }, + "AnalysisRecord": { + "properties": { + "observations": { + "items": { + "$ref": "#/components/schemas/AnalysisObservation" + }, + "type": "array", + "maxItems": 30, + "title": "Observations" + }, + "cited_sections": { + "items": { + "$ref": "#/components/schemas/CitedSection" + }, + "type": "array", + "maxItems": 30, + "title": "Cited Sections" + }, + "unavailable": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 30, + "title": "Unavailable" + }, + "runtime": { + "additionalProperties": true, + "type": "object", + "title": "Runtime" + }, + "review_required": { + "type": "boolean", + "title": "Review Required", + "default": true + } + }, + "additionalProperties": false, + "type": "object", + "title": "AnalysisRecord", + "description": "The adapter output that accompanies a saved inspection draft." + }, + "ApprovalCommand": { + "properties": { + "action": { + "type": "string", + "const": "approve-records-response", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ApprovalPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "ApprovalCommand" + }, + "ApprovalPayload": { + "properties": { + "approvalNote": { + "type": "string", + "title": "Approvalnote", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "title": "ApprovalPayload" + }, + "ArchiveInput": { + "properties": { + "visibility": { + "type": "string", + "enum": [ + "public", + "closed_session" + ], + "title": "Visibility" + }, + "packet_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Packet Id" + }, + "minutes_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Minutes Id" + }, + "plain_language_summary": { + "type": "string", + "title": "Plain Language Summary", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "visibility" + ], + "title": "ArchiveInput" + }, + "ArtifactPlan": { + "properties": { + "artifact_id": { + "type": "string", + "title": "Artifact Id" + }, + "file_name": { + "type": "string", + "title": "File Name" + }, + "content": { + "type": "string", + "title": "Content" + }, + "sha256": { + "type": "string", + "title": "Sha256" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "artifact_id", + "file_name", + "content", + "sha256", + "created_at_unix_seconds" + ], + "title": "ArtifactPlan" + }, + "AssignCommand": { + "properties": { + "action": { + "type": "string", + "const": "assign-records-request", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/AssignmentPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "AssignCommand" + }, + "AssignmentPayload": { + "properties": { + "assignedTo": { + "type": "string", + "minLength": 1, + "title": "Assignedto" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "assignedTo" + ], + "title": "AssignmentPayload" + }, + "AttachDocument": { + "properties": { + "title": { + "type": "string", + "minLength": 1, + "title": "Title" + }, + "citation": { + "type": "string", + "title": "Citation", + "default": "" + }, + "file": { + "$ref": "#/components/schemas/ManagedFileReceipt" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "file" + ], + "title": "AttachDocument" + }, + "AttachReleaseCopy": { + "properties": { + "status": { + "type": "string", + "enum": [ + "release-ready copy", + "redacted copy" + ], + "title": "Status" + }, + "note": { + "type": "string", + "title": "Note", + "default": "" + }, + "added_by": { + "type": "string", + "title": "Added By", + "default": "" + }, + "file": { + "$ref": "#/components/schemas/ManagedFileReceipt" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "status", + "file" + ], + "title": "AttachReleaseCopy" + }, + "AuditChainVerification": { + "properties": { + "is_valid": { + "type": "boolean", + "title": "Is Valid" + }, + "entries_checked": { + "type": "integer", + "title": "Entries Checked" + }, + "error_message": { + "type": "string", + "title": "Error Message" + } + }, + "type": "object", + "required": [ + "is_valid", + "entries_checked", + "error_message" + ], + "title": "AuditChainVerification" + }, + "AuditLogRead": { + "properties": { + "id": { + "type": "integer", + "title": "Id" + }, + "prev_hash": { + "type": "string", + "title": "Prev Hash" + }, + "entry_hash": { + "type": "string", + "title": "Entry Hash" + }, + "timestamp": { + "type": "string", + "format": "date-time", + "title": "Timestamp" + }, + "user_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "User Id" + }, + "action": { + "type": "string", + "title": "Action" + }, + "resource_type": { + "type": "string", + "title": "Resource Type" + }, + "resource_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Resource Id" + }, + "details": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Details" + }, + "ai_generated": { + "type": "boolean", + "title": "Ai Generated" + } + }, + "type": "object", + "required": [ + "id", + "prev_hash", + "entry_hash", + "timestamp", + "user_id", + "action", + "resource_type", + "resource_id", + "details", + "ai_generated" + ], + "title": "AuditLogRead" + }, + "AuditView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "module_id": { + "type": "string", + "title": "Module Id" + }, + "action": { + "type": "string", + "title": "Action" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + }, + "previous_hash": { + "type": "string", + "title": "Previous Hash" + }, + "entry_hash": { + "type": "string", + "title": "Entry Hash" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "module_id", + "action", + "summary", + "created_at_unix_seconds", + "previous_hash", + "entry_hash" + ], + "title": "AuditView" + }, + "BearerResponse": { + "properties": { + "access_token": { + "type": "string", + "title": "Access Token" + }, + "token_type": { + "type": "string", + "title": "Token Type" + } + }, + "type": "object", + "required": [ + "access_token", + "token_type" + ], + "title": "BearerResponse" + }, + "Body_auth_jwt_login_auth_jwt_login_post": { + "properties": { + "grant_type": { + "anyOf": [ + { + "type": "string", + "pattern": "^password$" + }, + { + "type": "null" + } + ], + "title": "Grant Type" + }, + "username": { + "type": "string", + "title": "Username" + }, + "password": { + "type": "string", + "format": "password", + "title": "Password" + }, + "scope": { + "type": "string", + "title": "Scope", + "default": "" + }, + "client_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Client Id" + }, + "client_secret": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "format": "password", + "title": "Client Secret" + } + }, + "type": "object", + "required": [ + "username", + "password" + ], + "title": "Body_auth_jwt_login_auth_jwt_login_post" + }, + "Body_upload_file_datasources_upload_post": { + "properties": { + "file": { + "type": "string", + "contentMediaType": "application/octet-stream", + "title": "File" + } + }, + "type": "object", + "required": [ + "file" + ], + "title": "Body_upload_file_datasources_upload_post" + }, + "CalculateDeadlineCommand": { + "properties": { + "action": { + "type": "string", + "const": "calculate-records-deadline", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/CalculateDeadlinePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "CalculateDeadlineCommand" + }, + "CalculateDeadlinePayload": { + "properties": { + "deadlineReceivedDate": { + "type": "string", + "title": "Deadlinereceiveddate" + }, + "deadlineRuleName": { + "type": "string", + "minLength": 1, + "title": "Deadlinerulename" + }, + "deadlineDayCount": { + "type": "string", + "title": "Deadlinedaycount" + }, + "deadlineDayType": { + "type": "string", + "title": "Deadlinedaytype" + }, + "deadlineBasis": { + "type": "string", + "minLength": 1, + "title": "Deadlinebasis" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "deadlineReceivedDate", + "deadlineRuleName", + "deadlineDayCount", + "deadlineDayType", + "deadlineBasis" + ], + "title": "CalculateDeadlinePayload" + }, + "ChapterCreate": { + "properties": { + "chapter_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Chapter Id" + }, + "title_id": { + "type": "string", + "minLength": 1, + "title": "Title Id" + }, + "chapter_number": { + "type": "string", + "minLength": 1, + "title": "Chapter Number" + }, + "chapter_name": { + "type": "string", + "minLength": 1, + "title": "Chapter Name" + }, + "sort_order": { + "type": "integer", + "title": "Sort Order", + "default": 0 + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title_id", + "chapter_number", + "chapter_name" + ], + "title": "ChapterCreate", + "description": "Request body for creating a code chapter." + }, + "CitedSection": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "citation": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Citation" + }, + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "version": { + "type": "string", + "maxLength": 80, + "title": "Version", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "citation" + ], + "title": "CitedSection", + "description": "One resolved public Code section; never a caller-supplied quotation." + }, + "CityProfileCreate": { + "properties": { + "city_name": { + "type": "string", + "title": "City Name" + }, + "state": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State" + }, + "county": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "County" + }, + "population_band": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Population Band" + }, + "email_platform": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Email Platform" + }, + "has_dedicated_it": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Has Dedicated It" + }, + "monthly_request_volume": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Monthly Request Volume" + }, + "profile_data": { + "additionalProperties": true, + "type": "object", + "title": "Profile Data", + "default": {} + }, + "gap_map": { + "additionalProperties": true, + "type": "object", + "title": "Gap Map", + "default": {} + } + }, + "type": "object", + "required": [ + "city_name" + ], + "title": "CityProfileCreate" + }, + "CityProfileRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "city_name": { + "type": "string", + "title": "City Name" + }, + "state": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State" + }, + "county": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "County" + }, + "population_band": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Population Band" + }, + "email_platform": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Email Platform" + }, + "has_dedicated_it": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Has Dedicated It" + }, + "monthly_request_volume": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Monthly Request Volume" + }, + "onboarding_status": { + "type": "string", + "title": "Onboarding Status" + }, + "profile_data": { + "additionalProperties": true, + "type": "object", + "title": "Profile Data" + }, + "gap_map": { + "additionalProperties": true, + "type": "object", + "title": "Gap Map" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "city_name", + "state", + "county", + "population_band", + "email_platform", + "has_dedicated_it", + "monthly_request_volume", + "onboarding_status", + "profile_data", + "gap_map", + "created_at", + "updated_at" + ], + "title": "CityProfileRead" + }, + "CityProfileUpdate": { + "properties": { + "city_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "City Name" + }, + "state": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State" + }, + "county": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "County" + }, + "population_band": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Population Band" + }, + "email_platform": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Email Platform" + }, + "has_dedicated_it": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Has Dedicated It" + }, + "monthly_request_volume": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Monthly Request Volume" + }, + "onboarding_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Onboarding Status" + }, + "profile_data": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Profile Data" + }, + "gap_map": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Gap Map" + } + }, + "type": "object", + "title": "CityProfileUpdate" + }, + "ClarificationCommand": { + "properties": { + "action": { + "type": "string", + "const": "request-records-clarification", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ClarificationPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "ClarificationCommand" + }, + "ClarificationPayload": { + "properties": { + "clarificationNote": { + "type": "string", + "minLength": 1, + "title": "Clarificationnote" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "clarificationNote" + ], + "title": "ClarificationPayload" + }, + "Closeout": { + "properties": { + "decision_id": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Decision Id" + }, + "version_id": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Version Id" + }, + "source_id": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Source Id" + }, + "version_label": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Version Label" + }, + "body": { + "type": "string", + "maxLength": 1000000, + "minLength": 1, + "title": "Body" + }, + "effective_start": { + "type": "string", + "format": "date", + "title": "Effective Start" + }, + "effective_end": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective End" + }, + "is_current": { + "type": "boolean", + "title": "Is Current" + }, + "reconciliation_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reconciliation Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "decision_id", + "version_id", + "source_id", + "version_label", + "body", + "effective_start", + "is_current" + ], + "title": "Closeout" + }, + "CodeContext": { + "properties": { + "section_number": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Section Number" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "section_number" + ], + "title": "CodeContext" + }, + "CodeLink": { + "properties": { + "provider": { + "type": "string", + "const": "code", + "title": "Provider", + "default": "code" + }, + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "CodeLink" + }, + "CodeSearch": { + "properties": { + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "CodeSearch" + }, + "CodeSourceSelection": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "CodeSourceSelection" + }, + "CompleteArtifact": { + "properties": { + "export_path": { + "type": "string", + "minLength": 1, + "title": "Export Path" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "export_path" + ], + "title": "CompleteArtifact" + }, + "ConnectionSearch": { + "properties": { + "provider": { + "type": "string", + "enum": [ + "meetings", + "zoning" + ], + "title": "Provider" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "query" + ], + "title": "ConnectionSearch" + }, + "CoverageGapResponse": { + "properties": { + "jurisdictions_without_rules": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Jurisdictions Without Rules" + }, + "departments_without_staff": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array", + "title": "Departments Without Staff" + }, + "uncovered_categories": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Uncovered Categories" + }, + "total_gaps": { + "type": "integer", + "title": "Total Gaps" + } + }, + "type": "object", + "required": [ + "jurisdictions_without_rules", + "departments_without_staff", + "uncovered_categories", + "total_gaps" + ], + "title": "CoverageGapResponse" + }, + "DataSourceAdminRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "source_type": { + "$ref": "#/components/schemas/SourceType" + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "type": "boolean", + "title": "Schedule Enabled", + "default": true + }, + "next_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Next Sync At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "last_ingestion_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Ingestion At" + }, + "last_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Sync At" + }, + "last_sync_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Sync Status" + }, + "last_error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Error Message" + }, + "consecutive_failure_count": { + "type": "integer", + "title": "Consecutive Failure Count", + "default": 0 + }, + "sync_paused": { + "type": "boolean", + "title": "Sync Paused", + "default": false + }, + "health_status": { + "type": "string", + "title": "Health Status", + "default": "healthy" + }, + "active_failure_count": { + "type": "integer", + "title": "Active Failure Count", + "default": 0 + }, + "connector_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Connector Type" + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At" + }, + "connection_config": { + "additionalProperties": true, + "type": "object", + "title": "Connection Config" + } + }, + "type": "object", + "required": [ + "id", + "name", + "source_type", + "is_active", + "created_by", + "created_at", + "last_ingestion_at", + "connection_config" + ], + "title": "DataSourceAdminRead", + "description": "Full datasource shape including connection_config. Returned only by admin-gated endpoints." + }, + "DataSourceCreate": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "source_type": { + "$ref": "#/components/schemas/SourceType" + }, + "connection_config": { + "additionalProperties": true, + "type": "object", + "title": "Connection Config", + "default": {} + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "type": "boolean", + "title": "Schedule Enabled", + "default": true + } + }, + "type": "object", + "required": [ + "name", + "source_type" + ], + "title": "DataSourceCreate" + }, + "DataSourceRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "source_type": { + "$ref": "#/components/schemas/SourceType" + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "type": "boolean", + "title": "Schedule Enabled", + "default": true + }, + "next_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Next Sync At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "last_ingestion_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Ingestion At" + }, + "last_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Sync At" + }, + "last_sync_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Sync Status" + }, + "last_error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Error Message" + }, + "consecutive_failure_count": { + "type": "integer", + "title": "Consecutive Failure Count", + "default": 0 + }, + "sync_paused": { + "type": "boolean", + "title": "Sync Paused", + "default": false + }, + "health_status": { + "type": "string", + "title": "Health Status", + "default": "healthy" + }, + "active_failure_count": { + "type": "integer", + "title": "Active Failure Count", + "default": 0 + }, + "connector_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Connector Type" + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "name", + "source_type", + "is_active", + "created_by", + "created_at", + "last_ingestion_at" + ], + "title": "DataSourceRead", + "description": "Redacted datasource shape — safe for non-admin roles. connection_config omitted." + }, + "DataSourceUpdate": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "connection_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Connection Config" + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Schedule Enabled" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "DataSourceUpdate" + }, + "DeadlineCommand": { + "properties": { + "action": { + "type": "string", + "const": "set-records-deadline", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/DeadlinePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "DeadlineCommand" + }, + "DeadlinePayload": { + "properties": { + "deadline": { + "type": "string", + "title": "Deadline" + }, + "deadlineBasis": { + "type": "string", + "minLength": 1, + "title": "Deadlinebasis" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "deadline", + "deadlineBasis" + ], + "title": "DeadlinePayload" + }, + "Decision": { + "properties": { + "id": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Id" + }, + "outcome": { + "type": "string", + "enum": [ + "adopted", + "not_adopted", + "deferred", + "withdrawn" + ], + "title": "Outcome" + }, + "decided_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Decided At" + }, + "decision_text": { + "type": "string", + "maxLength": 1000000, + "minLength": 1, + "title": "Decision Text" + }, + "supporting_references": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Supporting References" + }, + "supersedes_decision_id": { + "anyOf": [ + { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$" + }, + { + "type": "null" + } + ], + "title": "Supersedes Decision Id" + }, + "reconciliation_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reconciliation Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "outcome", + "decision_text" + ], + "title": "Decision" + }, + "DepartmentCreate": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "code": { + "type": "string", + "title": "Code" + }, + "contact_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Contact Email" + } + }, + "type": "object", + "required": [ + "name", + "code" + ], + "title": "DepartmentCreate" + }, + "DepartmentRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "code": { + "type": "string", + "title": "Code" + }, + "contact_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Contact Email" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "name", + "code", + "contact_email", + "created_at" + ], + "title": "DepartmentRead" + }, + "DepartmentUpdate": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Code" + }, + "contact_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Contact Email" + } + }, + "type": "object", + "title": "DepartmentUpdate" + }, + "DisclosureTemplateCreate": { + "properties": { + "template_type": { + "type": "string", + "title": "Template Type" + }, + "state_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State Code" + }, + "content": { + "type": "string", + "title": "Content" + } + }, + "type": "object", + "required": [ + "template_type", + "content" + ], + "title": "DisclosureTemplateCreate" + }, + "DisclosureTemplateRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "template_type": { + "type": "string", + "title": "Template Type" + }, + "state_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State Code" + }, + "content": { + "type": "string", + "title": "Content" + }, + "version": { + "type": "integer", + "title": "Version" + }, + "updated_by": { + "type": "string", + "format": "uuid", + "title": "Updated By" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "template_type", + "state_code", + "content", + "version", + "updated_by", + "updated_at" + ], + "title": "DisclosureTemplateRead" + }, + "DisclosureTemplateRendered": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "template_type": { + "type": "string", + "title": "Template Type" + }, + "rendered_content": { + "type": "string", + "title": "Rendered Content" + }, + "has_unresolved_variables": { + "type": "boolean", + "title": "Has Unresolved Variables" + } + }, + "type": "object", + "required": [ + "id", + "template_type", + "rendered_content", + "has_unresolved_variables" + ], + "title": "DisclosureTemplateRendered" + }, + "DisclosureTemplateUpdate": { + "properties": { + "content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Content" + }, + "state_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State Code" + } + }, + "type": "object", + "title": "DisclosureTemplateUpdate" + }, + "DocumentChunkRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "chunk_index": { + "type": "integer", + "title": "Chunk Index" + }, + "content_text": { + "type": "string", + "title": "Content Text" + }, + "token_count": { + "type": "integer", + "title": "Token Count" + }, + "page_number": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Page Number" + } + }, + "type": "object", + "required": [ + "id", + "document_id", + "chunk_index", + "content_text", + "token_count", + "page_number" + ], + "title": "DocumentChunkRead" + }, + "DocumentRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "source_id": { + "type": "string", + "format": "uuid", + "title": "Source Id" + }, + "source_path": { + "type": "string", + "title": "Source Path" + }, + "filename": { + "type": "string", + "title": "Filename" + }, + "file_type": { + "type": "string", + "title": "File Type" + }, + "file_hash": { + "type": "string", + "title": "File Hash" + }, + "file_size": { + "type": "integer", + "title": "File Size" + }, + "ingestion_status": { + "$ref": "#/components/schemas/IngestionStatus" + }, + "ingestion_error": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Ingestion Error" + }, + "chunk_count": { + "type": "integer", + "title": "Chunk Count" + }, + "ingested_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Ingested At" + }, + "connector_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Connector Type" + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "source_id", + "source_path", + "filename", + "file_type", + "file_hash", + "file_size", + "ingestion_status", + "ingestion_error", + "chunk_count", + "ingested_at" + ], + "title": "DocumentRead" + }, + "DraftCommand": { + "properties": { + "action": { + "type": "string", + "const": "draft-records-response", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/DraftPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "DraftCommand" + }, + "DraftInput": { + "properties": { + "source_materials": { + "items": { + "$ref": "#/components/schemas/SourceInput" + }, + "type": "array", + "title": "Source Materials" + }, + "sentences": { + "items": { + "$ref": "#/components/schemas/SentenceInput" + }, + "type": "array", + "minItems": 1, + "title": "Sentences" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sentences" + ], + "title": "DraftInput" + }, + "DraftPayload": { + "properties": { + "responseDraft": { + "type": "string", + "minLength": 1, + "title": "Responsedraft" + }, + "citation": { + "type": "string", + "title": "Citation", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "responseDraft" + ], + "title": "DraftPayload" + }, + "ErrorModel": { + "properties": { + "detail": { + "anyOf": [ + { + "type": "string" + }, + { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + ], + "title": "Detail" + } + }, + "type": "object", + "required": [ + "detail" + ], + "title": "ErrorModel" + }, + "Evidence": { + "properties": { + "filename": { + "type": "string", + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$", + "title": "Filename" + }, + "description": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Description" + }, + "media_type": { + "type": "string", + "enum": [ + "text/plain", + "image/jpeg", + "image/png", + "image/webp", + "application/pdf", + "audio/webm", + "audio/ogg", + "audio/wav", + "audio/mpeg", + "audio/mp4" + ], + "title": "Media Type" + }, + "content_base64": { + "type": "string", + "maxLength": 14000000, + "minLength": 1, + "title": "Content Base64" + }, + "sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "filename", + "description", + "media_type", + "content_base64", + "sha256" + ], + "title": "Evidence" + }, + "EvidenceItem": { + "properties": { + "filename": { + "type": "string", + "maxLength": 151, + "minLength": 1, + "title": "Filename" + }, + "media_type": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Media Type" + }, + "description": { + "type": "string", + "maxLength": 2000, + "title": "Description", + "default": "" + }, + "content_base64": { + "type": "string", + "maxLength": 14000000, + "minLength": 1, + "title": "Content Base64" + }, + "sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "filename", + "media_type", + "content_base64", + "sha256" + ], + "title": "EvidenceItem" + }, + "EvidenceItems": { + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/EvidenceItem" + }, + "type": "array", + "maxItems": 10, + "minItems": 1, + "title": "Items" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "items" + ], + "title": "EvidenceItems" + }, + "ExemptionAccuracyReport": { + "properties": { + "category": { + "type": "string", + "title": "Category" + }, + "total_flags": { + "type": "integer", + "title": "Total Flags" + }, + "accepted": { + "type": "integer", + "title": "Accepted" + }, + "rejected": { + "type": "integer", + "title": "Rejected" + }, + "pending": { + "type": "integer", + "title": "Pending" + }, + "acceptance_rate": { + "type": "number", + "title": "Acceptance Rate" + } + }, + "type": "object", + "required": [ + "category", + "total_flags", + "accepted", + "rejected", + "pending", + "acceptance_rate" + ], + "title": "ExemptionAccuracyReport" + }, + "ExemptionDashboard": { + "properties": { + "total_flags": { + "type": "integer", + "title": "Total Flags" + }, + "by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "By Status" + }, + "by_category": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "By Category" + }, + "acceptance_rate": { + "type": "number", + "title": "Acceptance Rate" + }, + "total_rules": { + "type": "integer", + "title": "Total Rules" + }, + "active_rules": { + "type": "integer", + "title": "Active Rules" + } + }, + "type": "object", + "required": [ + "total_flags", + "by_status", + "by_category", + "acceptance_rate", + "total_rules", + "active_rules" + ], + "title": "ExemptionDashboard" + }, + "ExemptionDecisionCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-exemption-decision", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ExemptionDecisionPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "ExemptionDecisionCommand" + }, + "ExemptionDecisionPayload": { + "properties": { + "exemptionSource": { + "type": "string", + "minLength": 1, + "title": "Exemptionsource" + }, + "exemptionKind": { + "type": "string", + "minLength": 1, + "title": "Exemptionkind" + }, + "exemptionFinding": { + "type": "string", + "minLength": 1, + "title": "Exemptionfinding" + }, + "exemptionDecision": { + "type": "string", + "enum": [ + "release", + "redact", + "exempt" + ], + "title": "Exemptiondecision" + }, + "exemptionBasis": { + "type": "string", + "minLength": 1, + "title": "Exemptionbasis" + }, + "exemptionReviewer": { + "type": "string", + "title": "Exemptionreviewer", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "exemptionSource", + "exemptionKind", + "exemptionFinding", + "exemptionDecision", + "exemptionBasis" + ], + "title": "ExemptionDecisionPayload" + }, + "ExemptionDecisionView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "source": { + "type": "string", + "title": "Source" + }, + "kind": { + "type": "string", + "title": "Kind" + }, + "finding": { + "type": "string", + "title": "Finding" + }, + "decision": { + "type": "string", + "enum": [ + "release", + "redact", + "exempt" + ], + "title": "Decision" + }, + "basis": { + "type": "string", + "title": "Basis" + }, + "reviewer": { + "type": "string", + "title": "Reviewer" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "source", + "kind", + "finding", + "decision", + "basis", + "reviewer", + "created_at_unix_seconds" + ], + "title": "ExemptionDecisionView" + }, + "ExemptionFlagRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "chunk_id": { + "type": "string", + "format": "uuid", + "title": "Chunk Id" + }, + "rule_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Rule Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "category": { + "type": "string", + "title": "Category" + }, + "matched_text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Matched Text" + }, + "confidence": { + "type": "number", + "title": "Confidence" + }, + "status": { + "$ref": "#/components/schemas/FlagStatus" + }, + "reviewed_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Reviewed By" + }, + "reviewed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Reviewed At" + }, + "review_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Reason" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "chunk_id", + "rule_id", + "request_id", + "category", + "matched_text", + "confidence", + "status", + "reviewed_by", + "reviewed_at", + "review_reason", + "created_at" + ], + "title": "ExemptionFlagRead" + }, + "ExemptionFlagReview": { + "properties": { + "status": { + "$ref": "#/components/schemas/FlagStatus" + }, + "review_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Reason" + } + }, + "type": "object", + "required": [ + "status" + ], + "title": "ExemptionFlagReview" + }, + "ExemptionNoteCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-exemption-review", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ExemptionNotePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "ExemptionNoteCommand" + }, + "ExemptionNotePayload": { + "properties": { + "exemptionNote": { + "type": "string", + "minLength": 1, + "title": "Exemptionnote" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "exemptionNote" + ], + "title": "ExemptionNotePayload" + }, + "ExemptionRuleCreate": { + "properties": { + "state_code": { + "type": "string", + "title": "State Code" + }, + "category": { + "type": "string", + "title": "Category" + }, + "rule_type": { + "$ref": "#/components/schemas/RuleType" + }, + "rule_definition": { + "type": "string", + "title": "Rule Definition" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "enabled": { + "type": "boolean", + "title": "Enabled", + "default": true + } + }, + "type": "object", + "required": [ + "state_code", + "category", + "rule_type", + "rule_definition" + ], + "title": "ExemptionRuleCreate" + }, + "ExemptionRuleRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "state_code": { + "type": "string", + "title": "State Code" + }, + "category": { + "type": "string", + "title": "Category" + }, + "rule_type": { + "$ref": "#/components/schemas/RuleType" + }, + "rule_definition": { + "type": "string", + "title": "Rule Definition" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "enabled": { + "type": "boolean", + "title": "Enabled" + }, + "version": { + "type": "integer", + "title": "Version", + "default": 1 + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "state_code", + "category", + "rule_type", + "rule_definition", + "description", + "enabled", + "created_by", + "created_at" + ], + "title": "ExemptionRuleRead" + }, + "ExemptionRuleUpdate": { + "properties": { + "rule_definition": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Rule Definition" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "enabled": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Enabled" + } + }, + "type": "object", + "title": "ExemptionRuleUpdate" + }, + "ExportReceipt": { + "properties": { + "export_path": { + "type": "string", + "maxLength": 32768, + "minLength": 1, + "title": "Export Path" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "export_path" + ], + "title": "ExportReceipt" + }, + "FeeEstimateCommand": { + "properties": { + "action": { + "type": "string", + "const": "estimate-records-fee", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/FeeEstimatePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "FeeEstimateCommand" + }, + "FeeEstimatePayload": { + "properties": { + "feeEstimate": { + "type": "string", + "minLength": 1, + "title": "Feeestimate" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "feeEstimate" + ], + "title": "FeeEstimatePayload" + }, + "FeeEstimateRequest": { + "properties": { + "page_count": { + "type": "integer", + "title": "Page Count" + }, + "fee_schedule_id": { + "type": "string", + "format": "uuid", + "title": "Fee Schedule Id" + } + }, + "type": "object", + "required": [ + "page_count", + "fee_schedule_id" + ], + "title": "FeeEstimateRequest" + }, + "FeeEstimateResponse": { + "properties": { + "page_count": { + "type": "integer", + "title": "Page Count" + }, + "unit_price": { + "type": "number", + "title": "Unit Price" + }, + "total": { + "type": "number", + "title": "Total" + }, + "fee_type": { + "type": "string", + "title": "Fee Type" + }, + "description": { + "type": "string", + "title": "Description" + } + }, + "type": "object", + "required": [ + "page_count", + "unit_price", + "total", + "fee_type", + "description" + ], + "title": "FeeEstimateResponse" + }, + "FeeLineCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-fee-line", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/FeeLinePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "FeeLineCommand" + }, + "FeeLineItemCreate": { + "properties": { + "description": { + "type": "string", + "title": "Description" + }, + "quantity": { + "type": "integer", + "title": "Quantity", + "default": 1 + }, + "unit_price": { + "type": "number", + "title": "Unit Price" + }, + "fee_schedule_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Fee Schedule Id" + } + }, + "type": "object", + "required": [ + "description", + "unit_price" + ], + "title": "FeeLineItemCreate" + }, + "FeeLineItemRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "fee_schedule_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Fee Schedule Id" + }, + "description": { + "type": "string", + "title": "Description" + }, + "quantity": { + "type": "integer", + "title": "Quantity" + }, + "unit_price": { + "type": "number", + "title": "Unit Price" + }, + "total": { + "type": "number", + "title": "Total" + }, + "status": { + "type": "string", + "title": "Status" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "fee_schedule_id", + "description", + "quantity", + "unit_price", + "total", + "status", + "created_at" + ], + "title": "FeeLineItemRead" + }, + "FeeLinePayload": { + "properties": { + "feeLineDescription": { + "type": "string", + "minLength": 1, + "title": "Feelinedescription" + }, + "feeScheduleBasis": { + "type": "string", + "minLength": 1, + "title": "Feeschedulebasis" + }, + "feeLineAmount": { + "type": "string", + "title": "Feelineamount" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "feeLineDescription", + "feeScheduleBasis", + "feeLineAmount" + ], + "title": "FeeLinePayload" + }, + "FeeLineView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "description": { + "type": "string", + "title": "Description" + }, + "schedule_basis": { + "type": "string", + "title": "Schedule Basis" + }, + "amount_cents": { + "type": "integer", + "title": "Amount Cents" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "description", + "schedule_basis", + "amount_cents", + "created_at_unix_seconds" + ], + "title": "FeeLineView" + }, + "FeeScheduleCreate": { + "properties": { + "jurisdiction": { + "type": "string", + "title": "Jurisdiction" + }, + "fee_type": { + "type": "string", + "title": "Fee Type" + }, + "amount": { + "type": "number", + "title": "Amount" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "effective_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective Date" + } + }, + "type": "object", + "required": [ + "jurisdiction", + "fee_type", + "amount" + ], + "title": "FeeScheduleCreate" + }, + "FeeScheduleRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "jurisdiction": { + "type": "string", + "title": "Jurisdiction" + }, + "fee_type": { + "type": "string", + "title": "Fee Type" + }, + "amount": { + "type": "number", + "title": "Amount" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "effective_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective Date" + }, + "created_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "jurisdiction", + "fee_type", + "amount", + "description", + "effective_date", + "created_by", + "created_at" + ], + "title": "FeeScheduleRead" + }, + "FeeScheduleUpdate": { + "properties": { + "fee_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Fee Type" + }, + "amount": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Amount" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "effective_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective Date" + } + }, + "type": "object", + "title": "FeeScheduleUpdate" + }, + "FeeWaiverCommand": { + "properties": { + "action": { + "type": "string", + "const": "waive-records-fee", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/FeeWaiverPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "FeeWaiverCommand" + }, + "FeeWaiverCreateRequest": { + "properties": { + "waiver_type": { + "type": "string", + "title": "Waiver Type" + }, + "reason": { + "type": "string", + "title": "Reason" + } + }, + "type": "object", + "required": [ + "waiver_type", + "reason" + ], + "title": "FeeWaiverCreateRequest" + }, + "FeeWaiverPayload": { + "properties": { + "feeWaiverReason": { + "type": "string", + "minLength": 1, + "title": "Feewaiverreason" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "feeWaiverReason" + ], + "title": "FeeWaiverPayload" + }, + "FeeWaiverReadResponse": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "waiver_type": { + "type": "string", + "title": "Waiver Type" + }, + "reason": { + "type": "string", + "title": "Reason" + }, + "status": { + "type": "string", + "title": "Status" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + }, + "created_at": { + "type": "string", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "waiver_type", + "reason", + "status", + "created_at" + ], + "title": "FeeWaiverReadResponse" + }, + "FeeWaiverReviewRequest": { + "properties": { + "status": { + "type": "string", + "title": "Status" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + } + }, + "type": "object", + "required": [ + "status" + ], + "title": "FeeWaiverReviewRequest" + }, + "FinishCommand": { + "properties": { + "action": { + "type": "string", + "enum": [ + "fulfill-records-request", + "close-records-request" + ], + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/NativePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "FinishCommand" + }, + "FlagStatus": { + "type": "string", + "enum": [ + "flagged", + "reviewed", + "accepted", + "rejected" + ], + "title": "FlagStatus" + }, + "FormPlan": { + "properties": { + "action": { + "type": "string", + "const": "form-plan", + "title": "Action" + }, + "formName": { + "type": "string", + "maxLength": 500, + "title": "Formname", + "default": "" + }, + "fields": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 50, + "title": "Fields" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "FormPlan" + }, + "GeneratedDraft": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "model": { + "type": "string", + "minLength": 1, + "title": "Model" + }, + "previous_response_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Previous Response Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text", + "model", + "previous_response_sha256" + ], + "title": "GeneratedDraft" + }, + "HTTPValidationError": { + "properties": { + "detail": { + "items": { + "$ref": "#/components/schemas/ValidationError" + }, + "type": "array", + "title": "Detail" + } + }, + "type": "object", + "title": "HTTPValidationError" + }, + "Handoff": { + "properties": { + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "request_id" + ], + "title": "Handoff" + }, + "ImportBundleCreate": { + "properties": { + "job_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Job Id" + }, + "connector_type": { + "type": "string", + "minLength": 1, + "title": "Connector Type" + }, + "source": { + "$ref": "#/components/schemas/SourceCreate" + }, + "sources": { + "items": { + "$ref": "#/components/schemas/SourceCreate" + }, + "type": "array", + "title": "Sources" + }, + "titles": { + "items": { + "$ref": "#/components/schemas/TitleCreate" + }, + "type": "array", + "title": "Titles" + }, + "chapters": { + "items": { + "$ref": "#/components/schemas/ChapterCreate" + }, + "type": "array", + "title": "Chapters" + }, + "sections": { + "items": { + "$ref": "#/components/schemas/SectionCreate" + }, + "type": "array", + "title": "Sections" + }, + "versions": { + "items": { + "$ref": "#/components/schemas/SectionVersionCreate" + }, + "type": "array", + "title": "Versions" + }, + "provenance": { + "additionalProperties": true, + "type": "object", + "title": "Provenance" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "connector_type", + "source" + ], + "title": "ImportBundleCreate", + "description": "Request body for local fixture/file-drop import jobs." + }, + "InclusionStatus": { + "type": "string", + "enum": [ + "included", + "excluded", + "pending" + ], + "title": "InclusionStatus" + }, + "IngestionStats": { + "properties": { + "total_sources": { + "type": "integer", + "title": "Total Sources" + }, + "active_sources": { + "type": "integer", + "title": "Active Sources" + }, + "total_documents": { + "type": "integer", + "title": "Total Documents" + }, + "documents_by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Documents By Status" + }, + "total_chunks": { + "type": "integer", + "title": "Total Chunks" + } + }, + "type": "object", + "required": [ + "total_sources", + "active_sources", + "total_documents", + "documents_by_status", + "total_chunks" + ], + "title": "IngestionStats" + }, + "IngestionStatus": { + "type": "string", + "enum": [ + "pending", + "processing", + "completed", + "failed" + ], + "title": "IngestionStatus" + }, + "InitiativeInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "policy": { + "$ref": "#/components/schemas/PolicySelection" + }, + "responsible_staff": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Responsible Staff" + }, + "target": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "title": "Target" + }, + "unit": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Unit" + }, + "due_on": { + "type": "string", + "format": "date", + "title": "Due On" + }, + "status": { + "type": "string", + "enum": [ + "planned", + "active", + "completed", + "cancelled" + ], + "title": "Status", + "default": "planned" + }, + "milestones": { + "items": { + "$ref": "#/components/schemas/Milestone" + }, + "type": "array", + "maxItems": 100, + "title": "Milestones" + }, + "measurements": { + "items": { + "$ref": "#/components/schemas/Measurement" + }, + "type": "array", + "maxItems": 1000, + "title": "Measurements" + }, + "note": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "policy", + "responsible_staff", + "target", + "unit", + "due_on", + "note" + ], + "title": "InitiativeInput" + }, + "InspectionInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "property_reference": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Property Reference" + }, + "inspection_reference": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Inspection Reference" + }, + "dataset_kind": { + "type": "string", + "enum": [ + "municipal", + "fictional" + ], + "title": "Dataset Kind" + }, + "inspector_notes": { + "type": "string", + "maxLength": 10000, + "minLength": 1, + "title": "Inspector Notes" + }, + "photo_observations": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 30, + "title": "Photo Observations" + }, + "voice_notes": { + "type": "string", + "maxLength": 10000, + "title": "Voice Notes", + "default": "" + }, + "evidence": { + "items": { + "$ref": "#/components/schemas/Evidence" + }, + "type": "array", + "maxItems": 10, + "title": "Evidence" + }, + "linked_sources": { + "items": { + "$ref": "#/components/schemas/townlight_inspections__workflow_models__SourceLink" + }, + "type": "array", + "maxItems": 30, + "title": "Linked Sources" + }, + "assigned_to": { + "type": "string", + "maxLength": 255, + "title": "Assigned To", + "default": "" + }, + "staff_notes": { + "type": "string", + "maxLength": 10000, + "title": "Staff Notes", + "default": "" + }, + "notice_draft": { + "type": "string", + "maxLength": 10000, + "title": "Notice Draft", + "default": "" + }, + "review_state": { + "type": "string", + "enum": [ + "draft", + "follow_up", + "reviewed" + ], + "title": "Review State", + "default": "draft" + }, + "review_notes": { + "type": "string", + "maxLength": 4000, + "title": "Review Notes", + "default": "" + }, + "public_summary": { + "type": "string", + "maxLength": 10000, + "title": "Public Summary", + "default": "" + }, + "analysis": { + "anyOf": [ + { + "$ref": "#/components/schemas/AnalysisRecord" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "property_reference", + "inspection_reference", + "dataset_kind", + "inspector_notes" + ], + "title": "InspectionInput" + }, + "IntakeInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "project_name": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Project Name" + }, + "project_description": { + "type": "string", + "maxLength": 10000, + "minLength": 1, + "title": "Project Description" + }, + "location": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Location" + }, + "applicant_contact": { + "type": "string", + "maxLength": 2000, + "title": "Applicant Contact", + "default": "" + }, + "requirement_revision": { + "type": "string", + "format": "uuid", + "title": "Requirement Revision" + }, + "materials": { + "items": { + "$ref": "#/components/schemas/MaterialReview" + }, + "type": "array", + "maxItems": 100, + "minItems": 1, + "title": "Materials" + }, + "linked_sources": { + "items": { + "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink" + }, + "type": "array", + "maxItems": 30, + "title": "Linked Sources" + }, + "staff_notes": { + "type": "string", + "maxLength": 10000, + "title": "Staff Notes", + "default": "" + }, + "assigned_to": { + "type": "string", + "maxLength": 255, + "title": "Assigned To", + "default": "" + }, + "review_state": { + "type": "string", + "enum": [ + "draft", + "follow_up", + "reviewed" + ], + "title": "Review State", + "default": "draft" + }, + "review_notes": { + "type": "string", + "maxLength": 4000, + "title": "Review Notes", + "default": "" + }, + "public_summary": { + "type": "string", + "maxLength": 10000, + "title": "Public Summary", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "project_name", + "project_description", + "location", + "requirement_revision", + "materials" + ], + "title": "IntakeInput" + }, + "InterpretationNoteCreate": { + "properties": { + "note_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Note Id" + }, + "note_text": { + "type": "string", + "minLength": 1, + "title": "Note Text" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "note_text" + ], + "title": "InterpretationNoteCreate", + "description": "Request body for staff-only interpretation notes." + }, + "InterviewRequest": { + "properties": { + "last_answer": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Answer" + }, + "last_field": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Field" + }, + "skipped_fields": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Skipped Fields" + } + }, + "type": "object", + "title": "InterviewRequest" + }, + "InterviewResponse": { + "properties": { + "question": { + "type": "string", + "title": "Question" + }, + "target_field": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Target Field" + }, + "all_complete": { + "type": "boolean", + "title": "All Complete" + }, + "completed_fields": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Completed Fields" + }, + "onboarding_status": { + "type": "string", + "title": "Onboarding Status" + }, + "skipped_fields": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Skipped Fields" + } + }, + "type": "object", + "required": [ + "question", + "target_field", + "all_complete", + "completed_fields", + "onboarding_status", + "skipped_fields" + ], + "title": "InterviewResponse" + }, + "ManagedFileReceipt": { + "properties": { + "original_path": { + "type": "string", + "minLength": 1, + "title": "Original Path" + }, + "stored_path": { + "type": "string", + "minLength": 1, + "title": "Stored Path" + }, + "file_name": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "File Name" + }, + "sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Sha256" + }, + "size_bytes": { + "type": "integer", + "maximum": 2147483647.0, + "minimum": 0.0, + "title": "Size Bytes" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "original_path", + "stored_path", + "file_name", + "sha256", + "size_bytes" + ], + "title": "ManagedFileReceipt" + }, + "ManagedSource": { + "properties": { + "original_path": { + "type": "string", + "title": "Original Path" + }, + "stored_path": { + "type": "string", + "title": "Stored Path" + }, + "file_name": { + "type": "string", + "title": "File Name" + }, + "sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Sha256" + }, + "size_bytes": { + "type": "integer", + "minimum": 0.0, + "title": "Size Bytes" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "original_path", + "stored_path", + "file_name", + "sha256", + "size_bytes" + ], + "title": "ManagedSource" + }, + "Material": { + "properties": { + "material_id": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]{1,80}$", + "title": "Material Id" + }, + "description": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Description" + }, + "citation": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Citation" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "material_id", + "description", + "citation" + ], + "title": "Material" + }, + "MaterialReview": { + "properties": { + "material_id": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Material Id" + }, + "status": { + "type": "string", + "enum": [ + "not_reviewed", + "provided", + "missing", + "unclear" + ], + "title": "Status", + "default": "not_reviewed" + }, + "note": { + "type": "string", + "maxLength": 2000, + "title": "Note", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "material_id" + ], + "title": "MaterialReview" + }, + "Measurement": { + "properties": { + "recorded_on": { + "type": "string", + "format": "date", + "title": "Recorded On" + }, + "value": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "title": "Value" + }, + "evidence": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Evidence" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "recorded_on", + "value", + "evidence" + ], + "title": "Measurement" + }, + "MediaAnalysis": { + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/EvidenceItem" + }, + "type": "array", + "maxItems": 10, + "minItems": 1, + "title": "Items" + }, + "code_links": { + "items": { + "$ref": "#/components/schemas/CodeLink" + }, + "type": "array", + "maxItems": 30, + "title": "Code Links" + }, + "inspector_supplied_text": { + "type": "string", + "maxLength": 10000, + "title": "Inspector Supplied Text", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "items" + ], + "title": "MediaAnalysis" + }, + "MeetingInput": { + "properties": { + "title": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Title" + }, + "scheduled_start": { + "type": "string", + "format": "date-time", + "title": "Scheduled Start" + }, + "location": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Location" + }, + "meeting_type": { + "type": "string", + "enum": [ + "regular", + "special", + "emergency", + "closed_session", + "executive" + ], + "title": "Meeting Type", + "default": "regular" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "scheduled_start", + "location" + ], + "title": "MeetingInput" + }, + "MeetingLink": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + }, + "relation": { + "type": "string", + "enum": [ + "hearing", + "context", + "precedent" + ], + "title": "Relation" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256", + "relation" + ], + "title": "MeetingLink" + }, + "MeetingSearch": { + "properties": { + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "MeetingSearch" + }, + "MeetingStageInput": { + "properties": { + "to_status": { + "type": "string", + "enum": [ + "SCHEDULED", + "NOTICED", + "PACKET_POSTED", + "IN_PROGRESS", + "RECESSED", + "ADJOURNED", + "TRANSCRIPT_READY", + "MINUTES_DRAFTED", + "MINUTES_POSTED", + "MINUTES_ADOPTED", + "MINUTES_SIGNED", + "ARCHIVED", + "CANCELLED" + ], + "title": "To Status" + }, + "statutory_basis": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Statutory Basis" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "to_status" + ], + "title": "MeetingStageInput" + }, + "MeetingsSearch": { + "properties": { + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "MeetingsSearch" + }, + "MeetingsSourceSelection": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "MeetingsSourceSelection" + }, + "MessageCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-message", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/MessagePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "MessageCommand" + }, + "MessageCreate": { + "properties": { + "message_text": { + "type": "string", + "title": "Message Text" + }, + "is_internal": { + "type": "boolean", + "title": "Is Internal", + "default": false + } + }, + "type": "object", + "required": [ + "message_text" + ], + "title": "MessageCreate" + }, + "MessagePayload": { + "properties": { + "requestMessageBody": { + "type": "string", + "minLength": 1, + "title": "Requestmessagebody" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requestMessageBody" + ], + "title": "MessagePayload" + }, + "MessageRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "sender_type": { + "type": "string", + "title": "Sender Type" + }, + "sender_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Sender Id" + }, + "message_text": { + "type": "string", + "title": "Message Text" + }, + "is_internal": { + "type": "boolean", + "title": "Is Internal" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "sender_type", + "sender_id", + "message_text", + "is_internal", + "created_at" + ], + "title": "MessageRead" + }, + "MessageView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "author": { + "type": "string", + "title": "Author" + }, + "author_role": { + "type": "string", + "title": "Author Role" + }, + "body": { + "type": "string", + "title": "Body" + }, + "visibility": { + "type": "string", + "title": "Visibility" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "author", + "author_role", + "body", + "visibility", + "created_at_unix_seconds" + ], + "title": "MessageView" + }, + "Milestone": { + "properties": { + "title": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Title" + }, + "due_on": { + "type": "string", + "format": "date", + "title": "Due On" + }, + "completed_on": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Completed On" + }, + "evidence": { + "type": "string", + "maxLength": 2000, + "title": "Evidence", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "due_on" + ], + "title": "Milestone" + }, + "MinutesDecision": { + "properties": { + "action": { + "type": "string", + "enum": [ + "post", + "adopt", + "sign" + ], + "title": "Action" + }, + "note": { + "type": "string", + "title": "Note", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "MinutesDecision" + }, + "ModelRegistryCreate": { + "properties": { + "model_name": { + "type": "string", + "title": "Model Name" + }, + "model_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Version" + }, + "parameter_count": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parameter Count" + }, + "license": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License" + }, + "model_card_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Card Url" + }, + "is_active": { + "type": "boolean", + "title": "Is Active", + "default": false + }, + "context_window_size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Context Window Size" + }, + "supports_ner": { + "type": "boolean", + "title": "Supports Ner", + "default": false + }, + "supports_vision": { + "type": "boolean", + "title": "Supports Vision", + "default": false + } + }, + "type": "object", + "required": [ + "model_name" + ], + "title": "ModelRegistryCreate", + "description": "Schema for creating a new model_registry record (POST body)." + }, + "ModelRegistryRead": { + "properties": { + "id": { + "type": "integer", + "title": "Id" + }, + "model_name": { + "type": "string", + "title": "Model Name" + }, + "model_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Version" + }, + "parameter_count": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parameter Count" + }, + "license": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License" + }, + "model_card_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Card Url" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "added_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Added At" + }, + "context_window_size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Context Window Size" + }, + "supports_ner": { + "type": "boolean", + "title": "Supports Ner" + }, + "supports_vision": { + "type": "boolean", + "title": "Supports Vision" + } + }, + "type": "object", + "required": [ + "id", + "model_name", + "is_active", + "supports_ner", + "supports_vision" + ], + "title": "ModelRegistryRead", + "description": "Schema for returning a model_registry record (GET response).\n\n``from_attributes=True`` allows construction directly from an ORM instance." + }, + "ModelRegistryUpdate": { + "properties": { + "model_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Name" + }, + "model_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Version" + }, + "parameter_count": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parameter Count" + }, + "license": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License" + }, + "model_card_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Card Url" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + }, + "context_window_size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Context Window Size" + }, + "supports_ner": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Supports Ner" + }, + "supports_vision": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Supports Vision" + } + }, + "type": "object", + "title": "ModelRegistryUpdate", + "description": "Schema for partially updating a model_registry record (PATCH body).\n\nEvery field is optional so callers can send only the fields they want to\nchange." + }, + "MotionCorrection": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "reason": { + "type": "string", + "minLength": 1, + "title": "Reason" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text", + "reason" + ], + "title": "MotionCorrection" + }, + "MotionInput": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "seconded_by": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Seconded By" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text" + ], + "title": "MotionInput" + }, + "NativePayload": { + "properties": {}, + "additionalProperties": false, + "type": "object", + "title": "NativePayload" + }, + "NativeRequestRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "requester_name": { + "type": "string", + "title": "Requester Name" + }, + "requester_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Email" + }, + "requester_phone": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Phone" + }, + "requester_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Type" + }, + "date_received": { + "type": "string", + "format": "date-time", + "title": "Date Received" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "description": { + "type": "string", + "title": "Description" + }, + "status": { + "$ref": "#/components/schemas/RequestStatus" + }, + "assigned_to": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "created_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "response_draft": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Response Draft" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + }, + "estimated_fee": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Estimated Fee" + }, + "fee_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Fee Status" + }, + "fee_waiver_requested": { + "type": "boolean", + "title": "Fee Waiver Requested", + "default": false + }, + "priority": { + "type": "string", + "title": "Priority", + "default": "normal" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + }, + "closed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Closed At" + }, + "closure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Closure Reason" + }, + "desktop_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Desktop Id" + }, + "public_tracking_number": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Public Tracking Number" + }, + "submitted_via": { + "type": "string", + "title": "Submitted Via" + }, + "deadline_label": { + "type": "string", + "title": "Deadline Label" + }, + "deadline_basis": { + "type": "string", + "title": "Deadline Basis" + }, + "deadline_reviewed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Deadline Reviewed At" + } + }, + "type": "object", + "required": [ + "id", + "requester_name", + "requester_email", + "date_received", + "statutory_deadline", + "description", + "status", + "assigned_to", + "created_by", + "created_at", + "response_draft", + "review_notes", + "desktop_id", + "public_tracking_number", + "submitted_via", + "deadline_label", + "deadline_basis", + "deadline_reviewed_at" + ], + "title": "NativeRequestRead" + }, + "NoticeDocumentInput": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text" + ], + "title": "NoticeDocumentInput" + }, + "NoticeDraft": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "body": { + "type": "string", + "maxLength": 100000, + "minLength": 1, + "title": "Body" + }, + "notice_type": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Notice Type" + }, + "statutory_basis": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Statutory Basis" + }, + "event_date": { + "type": "string", + "format": "date", + "title": "Event Date" + }, + "lead_days": { + "type": "integer", + "maximum": 365.0, + "minimum": 0.0, + "title": "Lead Days" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "body", + "notice_type", + "statutory_basis", + "event_date", + "lead_days" + ], + "title": "NoticeDraft" + }, + "NoticeInput": { + "properties": { + "notice_type": { + "type": "string", + "enum": [ + "regular", + "special", + "emergency", + "closed_session", + "executive" + ], + "title": "Notice Type" + }, + "posted_at": { + "type": "string", + "format": "date-time", + "title": "Posted At" + }, + "minimum_notice_hours": { + "type": "integer", + "minimum": 0.0, + "title": "Minimum Notice Hours" + }, + "statutory_basis": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Statutory Basis" + }, + "approved_by": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Approved By" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "notice_type", + "posted_at", + "minimum_notice_hours" + ], + "title": "NoticeInput" + }, + "NoticeProofInput": { + "properties": { + "location": { + "type": "string", + "minLength": 1, + "title": "Location" + }, + "note": { + "type": "string", + "title": "Note", + "default": "" + }, + "document_delivery_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Document Delivery Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "location" + ], + "title": "NoticeProofInput" + }, + "NotificationLogRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "template_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Template Id" + }, + "recipient_email": { + "type": "string", + "title": "Recipient Email" + }, + "request_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Request Id" + }, + "channel": { + "type": "string", + "title": "Channel" + }, + "status": { + "type": "string", + "title": "Status" + }, + "sent_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Sent At" + }, + "error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Message" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "template_id", + "recipient_email", + "request_id", + "channel", + "status", + "sent_at", + "error_message", + "created_at" + ], + "title": "NotificationLogRead" + }, + "NotificationTemplateCreate": { + "properties": { + "event_type": { + "type": "string", + "title": "Event Type" + }, + "channel": { + "type": "string", + "title": "Channel", + "default": "email" + }, + "subject_template": { + "type": "string", + "title": "Subject Template" + }, + "body_template": { + "type": "string", + "title": "Body Template" + } + }, + "type": "object", + "required": [ + "event_type", + "subject_template", + "body_template" + ], + "title": "NotificationTemplateCreate" + }, + "NotificationTemplateRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "event_type": { + "type": "string", + "title": "Event Type" + }, + "channel": { + "type": "string", + "title": "Channel" + }, + "subject_template": { + "type": "string", + "title": "Subject Template" + }, + "body_template": { + "type": "string", + "title": "Body Template" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "event_type", + "channel", + "subject_template", + "body_template", + "is_active", + "created_at" + ], + "title": "NotificationTemplateRead" + }, + "NotificationTemplateUpdate": { + "properties": { + "subject_template": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Subject Template" + }, + "body_template": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Body Template" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "NotificationTemplateUpdate" + }, + "NotificationView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "notification_id": { + "type": "string", + "title": "Notification Id" + }, + "module_id": { + "type": "string", + "title": "Module Id" + }, + "record_id": { + "type": "string", + "title": "Record Id" + }, + "audience": { + "type": "string", + "title": "Audience" + }, + "channel": { + "type": "string", + "title": "Channel" + }, + "subject": { + "type": "string", + "title": "Subject" + }, + "body": { + "type": "string", + "title": "Body" + }, + "status": { + "type": "string", + "title": "Status" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + }, + "sent_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Sent At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "notification_id", + "module_id", + "record_id", + "audience", + "channel", + "subject", + "body", + "status", + "created_at_unix_seconds", + "sent_at_unix_seconds" + ], + "title": "NotificationView" + }, + "OllamaModelInfo": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Size" + }, + "details": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Details" + } + }, + "type": "object", + "required": [ + "name" + ], + "title": "OllamaModelInfo" + }, + "OllamaStatus": { + "properties": { + "status": { + "type": "string", + "title": "Status" + }, + "models": { + "items": { + "$ref": "#/components/schemas/OllamaModelInfo" + }, + "type": "array", + "title": "Models" + } + }, + "type": "object", + "required": [ + "status", + "models" + ], + "title": "OllamaStatus" + }, + "OperationalMetrics": { + "properties": { + "average_response_time_days": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Average Response Time Days" + }, + "median_response_time_days": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Median Response Time Days" + }, + "requests_by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Requests By Status" + }, + "requests_by_department": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Requests By Department" + }, + "deadline_compliance_rate": { + "type": "number", + "title": "Deadline Compliance Rate" + }, + "total_open": { + "type": "integer", + "title": "Total Open" + }, + "total_closed": { + "type": "integer", + "title": "Total Closed" + }, + "total_overdue": { + "type": "integer", + "title": "Total Overdue" + }, + "clarification_frequency": { + "type": "number", + "title": "Clarification Frequency" + }, + "top_request_topics": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Top Request Topics" + } + }, + "type": "object", + "required": [ + "average_response_time_days", + "median_response_time_days", + "requests_by_status", + "requests_by_department", + "deadline_compliance_rate", + "total_open", + "total_closed", + "total_overdue", + "clarification_frequency", + "top_request_topics" + ], + "title": "OperationalMetrics" + }, + "Outline": { + "properties": { + "title": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Title" + }, + "question_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "maxItems": 50, + "minItems": 1, + "title": "Question Ids" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "question_ids" + ], + "title": "Outline" + }, + "Packet": { + "properties": { + "expected_revision": { + "type": "string", + "format": "uuid", + "title": "Expected Revision" + }, + "visibility": { + "type": "string", + "enum": [ + "staff_only", + "records_copy" + ], + "title": "Visibility" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "expected_revision", + "visibility" + ], + "title": "Packet" + }, + "PacketInput": { + "properties": { + "agenda_item_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "title": "Agenda Item Ids" + }, + "source_files": { + "items": { + "$ref": "#/components/schemas/ManagedSource" + }, + "type": "array", + "title": "Source Files" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "agenda_item_ids" + ], + "title": "PacketInput" + }, + "Pathway": { + "properties": { + "project_type": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Project Type" + }, + "proposal": { + "type": "string", + "maxLength": 4000, + "title": "Proposal", + "default": "" + }, + "location_context": { + "type": "string", + "maxLength": 1000, + "title": "Location Context", + "default": "" + }, + "requirement_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Requirement Revision" + }, + "fee_link": { + "anyOf": [ + { + "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "project_type" + ], + "title": "Pathway" + }, + "PathwayStep": { + "properties": { + "step": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Step" + }, + "citation": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Citation" + }, + "typical_time": { + "type": "string", + "maxLength": 1000, + "title": "Typical Time", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "step", + "citation" + ], + "title": "PathwayStep" + }, + "PlainLanguageSummaryCreate": { + "properties": { + "summary_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Summary Id" + }, + "section_version_id": { + "type": "string", + "minLength": 1, + "title": "Section Version Id" + }, + "summary_text": { + "type": "string", + "minLength": 1, + "title": "Summary Text" + }, + "language_code": { + "type": "string", + "title": "Language Code", + "default": "en" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "section_version_id", + "summary_text" + ], + "title": "PlainLanguageSummaryCreate", + "description": "Request body for staff-drafted plain-language summaries." + }, + "PolicySelection": { + "properties": { + "plan_id": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Plan Id" + }, + "revision_id": { + "type": "string", + "maxLength": 36, + "minLength": 36, + "title": "Revision Id" + }, + "policy_id": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Policy Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "plan_id", + "revision_id", + "policy_id" + ], + "title": "PolicySelection" + }, + "PortalModeResponse": { + "properties": { + "mode": { + "type": "string", + "enum": [ + "public", + "private" + ], + "title": "Mode", + "description": "Active portal posture for this deployment. ``public`` = minimal resident surface (landing + authenticated records-request submission + resident registration) reachable without staff auth. ``private`` = staff-only; no public routes, no resident self-registration." + } + }, + "type": "object", + "required": [ + "mode" + ], + "title": "PortalModeResponse", + "description": "T5D — schema for ``GET /config/portal-mode``.\n\nExposed to the frontend on boot so it can branch routing without a\nuser-identity lookup. The payload is intentionally the single field\nbelow — no staff config, no user state, no schema version." + }, + "PrepareArtifact": { + "properties": { + "kind": { + "type": "string", + "enum": [ + "response", + "release-package" + ], + "title": "Kind" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "kind" + ], + "title": "PrepareArtifact" + }, + "Proof": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + }, + "filename": { + "type": "string", + "maxLength": 150, + "minLength": 1, + "title": "Filename" + }, + "content_base64": { + "type": "string", + "maxLength": 7000000, + "minLength": 1, + "title": "Content Base64" + }, + "location": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Location" + }, + "published_at": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Published At" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence", + "filename", + "content_base64", + "location", + "published_at" + ], + "title": "Proof" + }, + "Proposal": { + "properties": { + "id": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Id" + }, + "version_id": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Version Id" + }, + "meeting_id": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "ordinance_number": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Ordinance Number" + }, + "proposed_text": { + "type": "string", + "maxLength": 1000000, + "minLength": 1, + "title": "Proposed Text" + }, + "supersedes_id": { + "anyOf": [ + { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$" + }, + { + "type": "null" + } + ], + "title": "Supersedes Id" + }, + "reconciliation_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reconciliation Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "version_id", + "meeting_id", + "title", + "ordinance_number", + "proposed_text" + ], + "title": "Proposal" + }, + "PublicExplore": { + "properties": { + "goal": { + "type": "string", + "maxLength": 500, + "title": "Goal", + "default": "" + }, + "topic": { + "type": "string", + "maxLength": 160, + "title": "Topic", + "default": "" + }, + "neighborhood": { + "type": "string", + "maxLength": 255, + "title": "Neighborhood", + "default": "" + }, + "plan_type": { + "type": "string", + "maxLength": 120, + "title": "Plan Type", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "title": "PublicExplore" + }, + "PublicIntake": { + "properties": { + "requester": { + "type": "string", + "minLength": 1, + "title": "Requester" + }, + "requesterContact": { + "type": "string", + "minLength": 1, + "title": "Requestercontact" + }, + "summary": { + "type": "string", + "minLength": 1, + "title": "Summary" + }, + "deadline": { + "type": "string", + "title": "Deadline", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requester", + "requesterContact", + "summary" + ], + "title": "PublicIntake" + }, + "PublicLookup": { + "properties": { + "trackingNumber": { + "type": "string", + "minLength": 1, + "title": "Trackingnumber" + }, + "requesterContact": { + "type": "string", + "minLength": 1, + "title": "Requestercontact" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "trackingNumber", + "requesterContact" + ], + "title": "PublicLookup" + }, + "PublicMessage": { + "properties": { + "trackingNumber": { + "type": "string", + "minLength": 1, + "title": "Trackingnumber" + }, + "requesterContact": { + "type": "string", + "minLength": 1, + "title": "Requestercontact" + }, + "publicRequestMessage": { + "type": "string", + "minLength": 1, + "title": "Publicrequestmessage" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "trackingNumber", + "requesterContact", + "publicRequestMessage" + ], + "title": "PublicMessage" + }, + "PublicStatusView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "label": { + "type": "string", + "title": "Label" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "status": { + "type": "string", + "title": "Status" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "label", + "summary", + "status", + "created_at_unix_seconds" + ], + "title": "PublicStatusView" + }, + "PublicationView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "source_module": { + "type": "string", + "title": "Source Module" + }, + "source_record_id": { + "type": "string", + "title": "Source Record Id" + }, + "record_type": { + "type": "string", + "title": "Record Type" + }, + "public_payload": { + "type": "string", + "title": "Public Payload" + }, + "payload_hash": { + "type": "string", + "title": "Payload Hash" + }, + "published_at_unix_seconds": { + "type": "integer", + "title": "Published At Unix Seconds" + }, + "retracted_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Retracted At Unix Seconds" + }, + "retracted_by": { + "type": "string", + "title": "Retracted By", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "source_module", + "source_record_id", + "record_type", + "public_payload", + "payload_hash", + "published_at_unix_seconds" + ], + "title": "PublicationView" + }, + "PublishingPlan": { + "properties": { + "action": { + "type": "string", + "const": "publishing-workflow", + "title": "Action" + }, + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "hasReview": { + "type": "boolean", + "title": "Hasreview", + "default": false + }, + "hasPlainLanguage": { + "type": "boolean", + "title": "Hasplainlanguage", + "default": false + }, + "hasTranslationReview": { + "type": "boolean", + "title": "Hastranslationreview", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "PublishingPlan" + }, + "Question": { + "properties": { + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + }, + "question": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Question" + }, + "kind": { + "type": "string", + "enum": [ + "use", + "dimension" + ], + "title": "Kind" + }, + "key": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Key" + }, + "audience": { + "type": "string", + "enum": [ + "resident", + "staff" + ], + "title": "Audience", + "default": "resident" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "jurisdiction", + "query", + "question", + "kind", + "key" + ], + "title": "Question" + }, + "QuestionAnswerRequest": { + "properties": { + "question": { + "type": "string", + "minLength": 1, + "title": "Question" + }, + "section_number": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Section Number" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "question" + ], + "title": "QuestionAnswerRequest", + "description": "Request body for citation-grounded code Q&A." + }, + "RecordsDocumentView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "attachment_id": { + "type": "string", + "title": "Attachment Id" + }, + "title": { + "type": "string", + "title": "Title" + }, + "original_path": { + "type": "string", + "title": "Original Path" + }, + "stored_path": { + "type": "string", + "title": "Stored Path" + }, + "citation": { + "type": "string", + "title": "Citation" + }, + "sha256": { + "type": "string", + "title": "Sha256" + }, + "size_bytes": { + "type": "integer", + "title": "Size Bytes" + }, + "status": { + "type": "string", + "title": "Status" + }, + "added_by": { + "type": "string", + "title": "Added By" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + }, + "release_original_path": { + "type": "string", + "title": "Release Original Path", + "default": "" + }, + "release_stored_path": { + "type": "string", + "title": "Release Stored Path", + "default": "" + }, + "release_file_name": { + "type": "string", + "title": "Release File Name", + "default": "" + }, + "release_sha256": { + "type": "string", + "title": "Release Sha256", + "default": "" + }, + "release_size_bytes": { + "type": "integer", + "title": "Release Size Bytes", + "default": 0 + }, + "release_status": { + "type": "string", + "title": "Release Status", + "default": "" + }, + "release_note": { + "type": "string", + "title": "Release Note", + "default": "" + }, + "release_added_by": { + "type": "string", + "title": "Release Added By", + "default": "" + }, + "release_added_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Release Added At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "attachment_id", + "title", + "original_path", + "stored_path", + "citation", + "sha256", + "size_bytes", + "status", + "added_by", + "created_at_unix_seconds" + ], + "title": "RecordsDocumentView" + }, + "RecordsOperationRead": { + "properties": { + "action": { + "type": "string", + "title": "Action" + }, + "message": { + "type": "string", + "title": "Message" + }, + "request": { + "$ref": "#/components/schemas/RecordsView" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "message", + "request" + ], + "title": "RecordsOperationRead" + }, + "RecordsStateRead": { + "properties": { + "demo_fixture": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Demo Fixture" + }, + "records_requests": { + "items": { + "$ref": "#/components/schemas/RecordsView" + }, + "type": "array", + "title": "Records Requests" + }, + "notification_events": { + "items": { + "$ref": "#/components/schemas/NotificationView" + }, + "type": "array", + "title": "Notification Events" + }, + "publication_events": { + "items": { + "$ref": "#/components/schemas/PublicationView" + }, + "type": "array", + "title": "Publication Events" + }, + "audit_entries": { + "items": { + "$ref": "#/components/schemas/AuditView" + }, + "type": "array", + "title": "Audit Entries" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "records_requests" + ], + "title": "RecordsStateRead" + }, + "RecordsView": { + "properties": { + "request_id": { + "type": "string", + "title": "Request Id" + }, + "id": { + "type": "string", + "title": "Id" + }, + "public_tracking_number": { + "type": "string", + "title": "Public Tracking Number" + }, + "requester": { + "type": "string", + "title": "Requester" + }, + "requester_contact": { + "type": "string", + "title": "Requester Contact" + }, + "submitted_via": { + "type": "string", + "title": "Submitted Via" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "deadline": { + "type": "string", + "title": "Deadline" + }, + "deadline_basis": { + "type": "string", + "title": "Deadline Basis" + }, + "status": { + "type": "string", + "title": "Status" + }, + "assigned_to": { + "type": "string", + "title": "Assigned To" + }, + "clarification_notes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Clarification Notes" + }, + "search_notes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Search Notes" + }, + "search_sessions": { + "items": { + "$ref": "#/components/schemas/SearchReceiptView" + }, + "type": "array", + "title": "Search Sessions" + }, + "exemption_reviews": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Exemption Reviews" + }, + "exemption_decisions": { + "items": { + "$ref": "#/components/schemas/ExemptionDecisionView" + }, + "type": "array", + "title": "Exemption Decisions" + }, + "fee_estimate": { + "type": "string", + "title": "Fee Estimate" + }, + "fee_line_items": { + "items": { + "$ref": "#/components/schemas/FeeLineView" + }, + "type": "array", + "title": "Fee Line Items" + }, + "fee_waiver_reason": { + "type": "string", + "title": "Fee Waiver Reason" + }, + "citations": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Citations" + }, + "response_draft": { + "type": "string", + "title": "Response Draft" + }, + "approval_notes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Approval Notes" + }, + "exports": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Exports" + }, + "documents": { + "items": { + "$ref": "#/components/schemas/RecordsDocumentView" + }, + "type": "array", + "title": "Documents" + }, + "release_packages": { + "items": { + "$ref": "#/components/schemas/ReleasePackageView" + }, + "type": "array", + "title": "Release Packages" + }, + "timeline": { + "items": { + "$ref": "#/components/schemas/TimelineView" + }, + "type": "array", + "title": "Timeline" + }, + "public_status_events": { + "items": { + "$ref": "#/components/schemas/PublicStatusView" + }, + "type": "array", + "title": "Public Status Events" + }, + "messages": { + "items": { + "$ref": "#/components/schemas/MessageView" + }, + "type": "array", + "title": "Messages" + }, + "deadline_reviewed_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Deadline Reviewed At Unix Seconds" + }, + "approved_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Approved At Unix Seconds" + }, + "fulfilled_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Fulfilled At Unix Seconds" + }, + "closed_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Closed At Unix Seconds" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "request_id", + "id", + "public_tracking_number", + "requester", + "requester_contact", + "submitted_via", + "summary", + "deadline", + "deadline_basis", + "status", + "assigned_to", + "clarification_notes", + "search_notes", + "search_sessions", + "exemption_reviews", + "exemption_decisions", + "fee_estimate", + "fee_line_items", + "fee_waiver_reason", + "citations", + "response_draft", + "approval_notes", + "exports", + "timeline", + "public_status_events", + "messages", + "deadline_reviewed_at_unix_seconds", + "approved_at_unix_seconds", + "fulfilled_at_unix_seconds", + "closed_at_unix_seconds", + "created_at_unix_seconds" + ], + "title": "RecordsView" + }, + "ReleasePackageView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "export_path": { + "type": "string", + "title": "Export Path" + }, + "package_hash": { + "type": "string", + "title": "Package Hash" + }, + "document_count": { + "type": "integer", + "title": "Document Count" + }, + "release_artifact_count": { + "type": "integer", + "title": "Release Artifact Count" + }, + "search_session_count": { + "type": "integer", + "title": "Search Session Count" + }, + "release_count": { + "type": "integer", + "title": "Release Count" + }, + "redacted_count": { + "type": "integer", + "title": "Redacted Count" + }, + "exempt_count": { + "type": "integer", + "title": "Exempt Count" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "export_path", + "package_hash", + "document_count", + "release_artifact_count", + "search_session_count", + "release_count", + "redacted_count", + "exempt_count", + "created_at_unix_seconds" + ], + "title": "ReleasePackageView" + }, + "RepeatLookup": { + "properties": { + "property_reference": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Property Reference" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "property_reference" + ], + "title": "RepeatLookup" + }, + "RequestCreate": { + "properties": { + "requester_name": { + "type": "string", + "maxLength": 255, + "title": "Requester Name" + }, + "requester_email": { + "anyOf": [ + { + "type": "string", + "maxLength": 255 + }, + { + "type": "null" + } + ], + "title": "Requester Email" + }, + "requester_phone": { + "anyOf": [ + { + "type": "string", + "maxLength": 50 + }, + { + "type": "null" + } + ], + "title": "Requester Phone" + }, + "requester_type": { + "anyOf": [ + { + "type": "string", + "maxLength": 100 + }, + { + "type": "null" + } + ], + "title": "Requester Type" + }, + "description": { + "type": "string", + "maxLength": 10000, + "title": "Description" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "priority": { + "type": "string", + "title": "Priority", + "default": "normal" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string", + "pattern": "^(narrow|moderate|broad)$" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + } + }, + "type": "object", + "required": [ + "requester_name", + "description" + ], + "title": "RequestCreate" + }, + "RequestDocumentAdd": { + "properties": { + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "relevance_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Relevance Note" + } + }, + "type": "object", + "required": [ + "document_id" + ], + "title": "RequestDocumentAdd" + }, + "RequestDocumentRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "relevance_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Relevance Note" + }, + "exemption_flags": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Exemption Flags" + }, + "inclusion_status": { + "$ref": "#/components/schemas/InclusionStatus" + }, + "attached_at": { + "type": "string", + "format": "date-time", + "title": "Attached At" + }, + "attached_by": { + "type": "string", + "format": "uuid", + "title": "Attached By" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "document_id", + "relevance_note", + "exemption_flags", + "inclusion_status", + "attached_at", + "attached_by" + ], + "title": "RequestDocumentRead" + }, + "RequestRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "requester_name": { + "type": "string", + "title": "Requester Name" + }, + "requester_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Email" + }, + "requester_phone": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Phone" + }, + "requester_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Type" + }, + "date_received": { + "type": "string", + "format": "date-time", + "title": "Date Received" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "description": { + "type": "string", + "title": "Description" + }, + "status": { + "$ref": "#/components/schemas/RequestStatus" + }, + "assigned_to": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "created_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "response_draft": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Response Draft" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + }, + "estimated_fee": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Estimated Fee" + }, + "fee_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Fee Status" + }, + "fee_waiver_requested": { + "type": "boolean", + "title": "Fee Waiver Requested", + "default": false + }, + "priority": { + "type": "string", + "title": "Priority", + "default": "normal" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + }, + "closed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Closed At" + }, + "closure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Closure Reason" + } + }, + "type": "object", + "required": [ + "id", + "requester_name", + "requester_email", + "date_received", + "statutory_deadline", + "description", + "status", + "assigned_to", + "created_by", + "created_at", + "response_draft", + "review_notes" + ], + "title": "RequestRead" + }, + "RequestStats": { + "properties": { + "total_requests": { + "type": "integer", + "title": "Total Requests" + }, + "by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "By Status" + }, + "approaching_deadline": { + "type": "integer", + "title": "Approaching Deadline" + }, + "overdue": { + "type": "integer", + "title": "Overdue" + } + }, + "type": "object", + "required": [ + "total_requests", + "by_status", + "approaching_deadline", + "overdue" + ], + "title": "RequestStats" + }, + "RequestStatus": { + "type": "string", + "enum": [ + "received", + "clarification_needed", + "assigned", + "searching", + "in_review", + "ready_for_release", + "drafted", + "approved", + "fulfilled", + "closed" + ], + "title": "RequestStatus" + }, + "RequestUpdate": { + "properties": { + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "status": { + "anyOf": [ + { + "$ref": "#/components/schemas/RequestStatus" + }, + { + "type": "null" + } + ] + }, + "assigned_to": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "response_draft": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Response Draft" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + } + }, + "type": "object", + "title": "RequestUpdate" + }, + "RequirementBundle": { + "properties": { + "requirement_id": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]{1,100}$", + "title": "Requirement Id" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "project_type": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Project Type" + }, + "source_reference": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Source Reference" + }, + "source_date": { + "type": "string", + "format": "date", + "title": "Source Date" + }, + "effective_on": { + "type": "string", + "format": "date", + "title": "Effective On" + }, + "dataset_kind": { + "type": "string", + "enum": [ + "municipal", + "fictional" + ], + "title": "Dataset Kind" + }, + "filename": { + "type": "string", + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$", + "title": "Filename" + }, + "content_base64": { + "type": "string", + "maxLength": 14000000, + "minLength": 1, + "title": "Content Base64" + }, + "sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Sha256" + }, + "materials": { + "items": { + "$ref": "#/components/schemas/Material" + }, + "type": "array", + "maxItems": 100, + "minItems": 1, + "title": "Materials" + }, + "pathway": { + "items": { + "$ref": "#/components/schemas/PathwayStep" + }, + "type": "array", + "maxItems": 100, + "title": "Pathway" + }, + "fee_link": { + "anyOf": [ + { + "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink" + }, + { + "type": "null" + } + ] + }, + "staff_note": { + "type": "string", + "maxLength": 4000, + "title": "Staff Note", + "default": "" + }, + "change_note": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Change Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requirement_id", + "title", + "jurisdiction", + "project_type", + "source_reference", + "source_date", + "effective_on", + "dataset_kind", + "filename", + "content_base64", + "sha256", + "materials", + "change_note" + ], + "title": "RequirementBundle" + }, + "ResponseLetterCreate": { + "properties": { + "template_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Template Id" + } + }, + "type": "object", + "title": "ResponseLetterCreate" + }, + "ResponseLetterRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "template_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Template Id" + }, + "generated_content": { + "type": "string", + "title": "Generated Content" + }, + "edited_content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Edited Content" + }, + "status": { + "type": "string", + "title": "Status" + }, + "generated_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Generated By" + }, + "approved_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Approved By" + }, + "sent_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Sent At" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "template_id", + "generated_content", + "edited_content", + "status", + "generated_by", + "approved_by", + "sent_at", + "created_at" + ], + "title": "ResponseLetterRead" + }, + "ResponseLetterUpdate": { + "properties": { + "edited_content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Edited Content" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + } + }, + "type": "object", + "title": "ResponseLetterUpdate" + }, + "ReviewInput": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "body": { + "type": "string", + "maxLength": 5000, + "title": "Body", + "default": "" + }, + "hasAltText": { + "type": "boolean", + "title": "Hasalttext", + "default": false + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "en" + } + }, + "additionalProperties": false, + "type": "object", + "title": "ReviewInput" + }, + "Revision": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + }, + "document": { + "$ref": "#/components/schemas/NoticeDraft" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence", + "document" + ], + "title": "Revision" + }, + "RewriteInput": { + "properties": { + "action": { + "type": "string", + "enum": [ + "plain-language", + "language-variant" + ], + "title": "Action" + }, + "text": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Text" + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "text" + ], + "title": "RewriteInput" + }, + "RewriteResult": { + "properties": { + "action": { + "type": "string", + "enum": [ + "plain-language", + "language-variant" + ], + "title": "Action" + }, + "text": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Text" + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "" + }, + "outcome": { + "type": "string", + "enum": [ + "generated", + "unavailable" + ], + "title": "Outcome" + }, + "generated": { + "anyOf": [ + { + "type": "string", + "maxLength": 100000 + }, + { + "type": "null" + } + ], + "title": "Generated" + }, + "model": { + "anyOf": [ + { + "type": "string", + "maxLength": 200 + }, + { + "type": "null" + } + ], + "title": "Model" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "text", + "outcome" + ], + "title": "RewriteResult" + }, + "Rule": { + "properties": { + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "zone_code": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Zone Code" + }, + "key": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Key" + }, + "section_number": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Section Number" + }, + "kind": { + "type": "string", + "enum": [ + "use", + "dimension" + ], + "title": "Kind" + }, + "value": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Value" + }, + "overlay_code": { + "anyOf": [ + { + "type": "string", + "maxLength": 255 + }, + { + "type": "null" + } + ], + "title": "Overlay Code" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "jurisdiction", + "zone_code", + "key", + "section_number", + "kind", + "value" + ], + "title": "Rule" + }, + "RuleTestMatch": { + "properties": { + "matched_text": { + "type": "string", + "title": "Matched Text" + }, + "start": { + "type": "integer", + "title": "Start" + }, + "end": { + "type": "integer", + "title": "End" + } + }, + "type": "object", + "required": [ + "matched_text", + "start", + "end" + ], + "title": "RuleTestMatch" + }, + "RuleTestRequest": { + "properties": { + "sample_text": { + "type": "string", + "title": "Sample Text" + } + }, + "type": "object", + "required": [ + "sample_text" + ], + "title": "RuleTestRequest" + }, + "RuleTestResponse": { + "properties": { + "rule_id": { + "type": "string", + "format": "uuid", + "title": "Rule Id" + }, + "rule_type": { + "type": "string", + "title": "Rule Type" + }, + "matched": { + "type": "boolean", + "title": "Matched" + }, + "matches": { + "items": { + "$ref": "#/components/schemas/RuleTestMatch" + }, + "type": "array", + "title": "Matches" + } + }, + "type": "object", + "required": [ + "rule_id", + "rule_type", + "matched", + "matches" + ], + "title": "RuleTestResponse" + }, + "RuleType": { + "type": "string", + "enum": [ + "regex", + "keyword", + "llm_prompt" + ], + "title": "RuleType" + }, + "SaveReview": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "body": { + "type": "string", + "maxLength": 5000, + "title": "Body", + "default": "" + }, + "hasAltText": { + "type": "boolean", + "title": "Hasalttext", + "default": false + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "en" + }, + "ai_analysis": { + "anyOf": [ + { + "type": "string", + "maxLength": 100000 + }, + { + "type": "null" + } + ], + "title": "Ai Analysis" + }, + "ai_analysis_model": { + "anyOf": [ + { + "type": "string", + "maxLength": 200 + }, + { + "type": "null" + } + ], + "title": "Ai Analysis Model" + }, + "ai_outcome": { + "type": "string", + "enum": [ + "generated", + "unavailable", + "failed" + ], + "title": "Ai Outcome" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "ai_outcome" + ], + "title": "SaveReview" + }, + "SearchFilterOptions": { + "properties": { + "file_types": { + "items": { + "type": "string" + }, + "type": "array", + "title": "File Types" + }, + "source_names": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Source Names" + }, + "departments": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array", + "title": "Departments", + "default": [] + }, + "date_range": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Date Range" + } + }, + "type": "object", + "required": [ + "file_types", + "source_names" + ], + "title": "SearchFilterOptions" + }, + "SearchInput": { + "properties": { + "query": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "SearchInput" + }, + "SearchNoteCommand": { + "properties": { + "action": { + "type": "string", + "const": "record-records-search", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/SearchNotePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "SearchNoteCommand" + }, + "SearchNotePayload": { + "properties": { + "sourceNote": { + "type": "string", + "minLength": 1, + "title": "Sourcenote" + }, + "citation": { + "type": "string", + "title": "Citation", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sourceNote" + ], + "title": "SearchNotePayload" + }, + "SearchReceiptCommand": { + "properties": { + "action": { + "type": "string", + "const": "record-records-search-session", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/SearchReceiptPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "SearchReceiptCommand" + }, + "SearchReceiptPayload": { + "properties": { + "searchQuery": { + "type": "string", + "minLength": 1, + "title": "Searchquery" + }, + "searchLocations": { + "type": "string", + "minLength": 1, + "title": "Searchlocations" + }, + "searchResultTitle": { + "type": "string", + "minLength": 1, + "title": "Searchresulttitle" + }, + "searchResultCitation": { + "type": "string", + "minLength": 1, + "title": "Searchresultcitation" + }, + "searchResultSummary": { + "type": "string", + "minLength": 1, + "title": "Searchresultsummary" + }, + "searchResultStatus": { + "type": "string", + "title": "Searchresultstatus", + "default": "" + }, + "searchReviewer": { + "type": "string", + "title": "Searchreviewer", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "searchQuery", + "searchLocations", + "searchResultTitle", + "searchResultCitation", + "searchResultSummary" + ], + "title": "SearchReceiptPayload" + }, + "SearchReceiptView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "query": { + "type": "string", + "title": "Query" + }, + "locations": { + "type": "string", + "title": "Locations" + }, + "reviewer": { + "type": "string", + "title": "Reviewer" + }, + "results": { + "items": { + "$ref": "#/components/schemas/SearchResultView" + }, + "type": "array", + "title": "Results" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "query", + "locations", + "reviewer", + "results", + "created_at_unix_seconds" + ], + "title": "SearchReceiptView" + }, + "SearchRequest": { + "properties": { + "query": { + "type": "string", + "title": "Query" + }, + "session_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Session Id" + }, + "filters": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Filters" + }, + "limit": { + "type": "integer", + "maximum": 50.0, + "title": "Limit", + "default": 10 + }, + "synthesize": { + "type": "boolean", + "title": "Synthesize", + "default": false + } + }, + "type": "object", + "required": [ + "query" + ], + "title": "SearchRequest" + }, + "SearchResponse": { + "properties": { + "query_id": { + "type": "string", + "format": "uuid", + "title": "Query Id" + }, + "session_id": { + "type": "string", + "format": "uuid", + "title": "Session Id" + }, + "query_text": { + "type": "string", + "title": "Query Text" + }, + "results": { + "items": { + "$ref": "#/components/schemas/SearchResultItem" + }, + "type": "array", + "title": "Results" + }, + "results_count": { + "type": "integer", + "title": "Results Count" + }, + "synthesized_answer": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Synthesized Answer" + }, + "ai_generated": { + "type": "boolean", + "title": "Ai Generated", + "default": false + } + }, + "type": "object", + "required": [ + "query_id", + "session_id", + "query_text", + "results", + "results_count" + ], + "title": "SearchResponse" + }, + "SearchResultItem": { + "properties": { + "chunk_id": { + "type": "string", + "format": "uuid", + "title": "Chunk Id" + }, + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "filename": { + "type": "string", + "title": "Filename" + }, + "file_type": { + "type": "string", + "title": "File Type" + }, + "source_path": { + "type": "string", + "title": "Source Path" + }, + "page_number": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Page Number" + }, + "content_text": { + "type": "string", + "title": "Content Text" + }, + "similarity_score": { + "type": "number", + "title": "Similarity Score" + }, + "rank": { + "type": "integer", + "title": "Rank" + } + }, + "type": "object", + "required": [ + "chunk_id", + "document_id", + "filename", + "file_type", + "source_path", + "page_number", + "content_text", + "similarity_score", + "rank" + ], + "title": "SearchResultItem" + }, + "SearchResultView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "title": { + "type": "string", + "title": "Title" + }, + "citation": { + "type": "string", + "title": "Citation" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "status": { + "type": "string", + "title": "Status" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "title", + "citation", + "summary", + "status" + ], + "title": "SearchResultView" + }, + "SearchSessionRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "user_id": { + "type": "string", + "format": "uuid", + "title": "User Id" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "queries": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array", + "title": "Queries", + "default": [] + } + }, + "type": "object", + "required": [ + "id", + "user_id", + "created_at" + ], + "title": "SearchSessionRead" + }, + "SectionCreate": { + "properties": { + "section_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Section Id" + }, + "chapter_id": { + "type": "string", + "minLength": 1, + "title": "Chapter Id" + }, + "section_number": { + "type": "string", + "minLength": 1, + "title": "Section Number" + }, + "section_heading": { + "type": "string", + "minLength": 1, + "title": "Section Heading" + }, + "parent_section_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parent Section Id" + }, + "sort_order": { + "type": "integer", + "title": "Sort Order", + "default": 0 + }, + "administrative_regulation_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Administrative Regulation Refs" + }, + "resolution_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Resolution Refs" + }, + "policy_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Policy Refs" + }, + "approved_summary_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Approved Summary Refs" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "chapter_id", + "section_number", + "section_heading" + ], + "title": "SectionCreate", + "description": "Request body for creating a code section or subsection." + }, + "SectionVersionCreate": { + "properties": { + "version_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Version Id" + }, + "section_id": { + "type": "string", + "minLength": 1, + "title": "Section Id" + }, + "source_id": { + "type": "string", + "minLength": 1, + "title": "Source Id" + }, + "version_label": { + "type": "string", + "minLength": 1, + "title": "Version Label" + }, + "body": { + "type": "string", + "minLength": 1, + "title": "Body" + }, + "effective_start": { + "type": "string", + "format": "date", + "title": "Effective Start" + }, + "effective_end": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective End" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + }, + "is_current": { + "type": "boolean", + "title": "Is Current", + "default": false + }, + "adoption_event_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Adoption Event Id" + }, + "amendment_event_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Amendment Event Id" + }, + "amendment_summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Amendment Summary" + }, + "prior_version_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Prior Version Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "section_id", + "source_id", + "version_label", + "body", + "effective_start" + ], + "title": "SectionVersionCreate", + "description": "Request body for adding an immutable section version." + }, + "Selection": { + "properties": { + "recording_id": { + "type": "string", + "format": "uuid", + "title": "Recording Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "recording_id", + "expected_sha256" + ], + "title": "Selection" + }, + "SentenceInput": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "citations": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Citations" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text" + ], + "title": "SentenceInput" + }, + "ServiceAccountCreate": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole", + "default": "read_only" + } + }, + "type": "object", + "required": [ + "name" + ], + "title": "ServiceAccountCreate" + }, + "ServiceAccountCreated": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "api_key": { + "type": "string", + "title": "Api Key" + } + }, + "type": "object", + "required": [ + "id", + "name", + "role", + "created_by", + "created_at", + "is_active", + "api_key" + ], + "title": "ServiceAccountCreated", + "description": "Returned only on creation — includes the plaintext API key (shown once)." + }, + "ServiceAccountRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + } + }, + "type": "object", + "required": [ + "id", + "name", + "role", + "created_by", + "created_at", + "is_active" + ], + "title": "ServiceAccountRead" + }, + "ServiceAccountUpdate": { + "properties": { + "role": { + "anyOf": [ + { + "$ref": "#/components/schemas/UserRole" + }, + { + "type": "null" + } + ] + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "ServiceAccountUpdate" + }, + "Snapshot": { + "properties": { + "expected_revision": { + "type": "string", + "format": "uuid", + "title": "Expected Revision" + }, + "visibility": { + "type": "string", + "enum": [ + "staff_only", + "public" + ], + "title": "Visibility" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "expected_revision", + "visibility" + ], + "title": "Snapshot" + }, + "SourceCreate": { + "properties": { + "source_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Id" + }, + "name": { + "type": "string", + "minLength": 1, + "title": "Name" + }, + "publisher": { + "type": "string", + "minLength": 1, + "title": "Publisher" + }, + "source_type": { + "type": "string", + "minLength": 1, + "title": "Source Type" + }, + "source_category": { + "type": "string", + "minLength": 1, + "title": "Source Category" + }, + "source_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Url" + }, + "file_reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "File Reference" + }, + "retrieved_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Retrieved At" + }, + "retrieval_method": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Retrieval Method" + }, + "checksum": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Checksum" + }, + "source_owner": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Owner" + }, + "is_official": { + "type": "boolean", + "title": "Is Official", + "default": true + }, + "official_status_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Official Status Note" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + }, + "staff_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Staff Notes" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "name", + "publisher", + "source_type", + "source_category" + ], + "title": "SourceCreate", + "description": "Request body for registering an official or explicitly labeled source." + }, + "SourceInput": { + "properties": { + "source_id": { + "type": "string", + "minLength": 1, + "title": "Source Id" + }, + "label": { + "type": "string", + "minLength": 1, + "title": "Label" + }, + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "label", + "text" + ], + "title": "SourceInput" + }, + "SourceSnapshot": { + "properties": { + "visibility": { + "type": "string", + "enum": [ + "public", + "staff_only" + ], + "title": "Visibility" + }, + "meeting_event_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "maxItems": 50, + "title": "Meeting Event Ids" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "visibility" + ], + "title": "SourceSnapshot" + }, + "SourceType": { + "type": "string", + "enum": [ + "manual_drop", + "file_system", + "rest_api", + "odbc" + ], + "title": "SourceType" + }, + "StaffRecordsIntake": { + "properties": { + "requester": { + "type": "string", + "minLength": 1, + "title": "Requester" + }, + "summary": { + "type": "string", + "minLength": 1, + "title": "Summary" + }, + "deadline": { + "type": "string", + "title": "Deadline" + }, + "deadlineBasis": { + "type": "string", + "title": "Deadlinebasis", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requester", + "summary", + "deadline" + ], + "title": "StaffRecordsIntake", + "description": "Existing native create-records-request input; no caller-supplied actor." + }, + "StandardsExplanation": { + "properties": { + "question": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Question" + }, + "process_section": { + "type": "string", + "maxLength": 255, + "title": "Process Section", + "default": "" + }, + "zone_code": { + "type": "string", + "maxLength": 40, + "title": "Zone Code", + "default": "" + }, + "rule_types": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 10, + "title": "Rule Types" + }, + "observed": { + "additionalProperties": { + "type": "string" + }, + "type": "object", + "title": "Observed" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "question" + ], + "title": "StandardsExplanation" + }, + "SyncFailureRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "source_id": { + "type": "string", + "format": "uuid", + "title": "Source Id" + }, + "source_path": { + "type": "string", + "title": "Source Path" + }, + "error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Message" + }, + "error_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Class" + }, + "http_status_code": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Http Status Code" + }, + "retry_count": { + "type": "integer", + "title": "Retry Count" + }, + "status": { + "type": "string", + "title": "Status" + }, + "first_failed_at": { + "type": "string", + "format": "date-time", + "title": "First Failed At" + }, + "last_retried_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Retried At" + }, + "dismissed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Dismissed At" + }, + "dismissed_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Dismissed By" + } + }, + "type": "object", + "required": [ + "id", + "source_id", + "source_path", + "error_message", + "error_class", + "http_status_code", + "retry_count", + "status", + "first_failed_at", + "last_retried_at", + "dismissed_at", + "dismissed_by" + ], + "title": "SyncFailureRead" + }, + "SyncRunLogRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "source_id": { + "type": "string", + "format": "uuid", + "title": "Source Id" + }, + "started_at": { + "type": "string", + "format": "date-time", + "title": "Started At" + }, + "finished_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Finished At" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + }, + "records_attempted": { + "type": "integer", + "title": "Records Attempted" + }, + "records_succeeded": { + "type": "integer", + "title": "Records Succeeded" + }, + "records_failed": { + "type": "integer", + "title": "Records Failed" + }, + "error_summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Summary" + } + }, + "type": "object", + "required": [ + "id", + "source_id", + "started_at", + "finished_at", + "status", + "records_attempted", + "records_succeeded", + "records_failed", + "error_summary" + ], + "title": "SyncRunLogRead" + }, + "SystemStatus": { + "properties": { + "version": { + "type": "string", + "title": "Version" + }, + "database": { + "type": "string", + "title": "Database" + }, + "ollama": { + "type": "string", + "title": "Ollama" + }, + "redis": { + "type": "string", + "title": "Redis" + }, + "user_count": { + "type": "integer", + "title": "User Count" + }, + "audit_log_count": { + "type": "integer", + "title": "Audit Log Count" + }, + "suite_session": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Suite Session" + } + }, + "type": "object", + "required": [ + "version", + "database", + "ollama", + "redis", + "user_count", + "audit_log_count" + ], + "title": "SystemStatus" + }, + "TaggedPlan": { + "properties": { + "action": { + "type": "string", + "const": "tagged-pdf", + "title": "Action" + }, + "headingLevels": { + "items": { + "type": "integer", + "maximum": 4294967295.0, + "minimum": 0.0 + }, + "type": "array", + "maxItems": 50, + "title": "Headinglevels" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "TaggedPlan" + }, + "TestConnectionRequest": { + "properties": { + "source_type": { + "type": "string", + "title": "Source Type" + }, + "host": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Host" + }, + "port": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Port" + }, + "path": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Path" + }, + "username": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Username" + }, + "password": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Password" + }, + "rest_api_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Rest Api Config" + }, + "odbc_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Odbc Config" + } + }, + "type": "object", + "required": [ + "source_type" + ], + "title": "TestConnectionRequest", + "description": "Dedicated schema for test-connection. NOT the create schema.\n\nSecurity: credentials in this request body are never persisted, never\nwritten to audit logs, and never returned in the response." + }, + "TestConnectionResponse": { + "properties": { + "success": { + "type": "boolean", + "title": "Success" + }, + "message": { + "type": "string", + "title": "Message" + }, + "latency_ms": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Latency Ms" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + }, + "warning": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Warning" + }, + "differing_keys": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Differing Keys" + } + }, + "type": "object", + "required": [ + "success", + "message" + ], + "title": "TestConnectionResponse" + }, + "TimelineEventCreate": { + "properties": { + "event_type": { + "type": "string", + "title": "Event Type" + }, + "description": { + "type": "string", + "title": "Description" + }, + "internal_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Internal Note" + } + }, + "type": "object", + "required": [ + "event_type", + "description" + ], + "title": "TimelineEventCreate" + }, + "TimelineEventRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "event_type": { + "type": "string", + "title": "Event Type" + }, + "actor_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Actor Id" + }, + "actor_role": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Actor Role" + }, + "description": { + "type": "string", + "title": "Description" + }, + "internal_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Internal Note" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "event_type", + "actor_id", + "actor_role", + "description", + "internal_note", + "created_at" + ], + "title": "TimelineEventRead" + }, + "TimelineView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "action": { + "type": "string", + "title": "Action" + }, + "actor": { + "type": "string", + "title": "Actor" + }, + "note": { + "type": "string", + "title": "Note" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "action", + "actor", + "note", + "created_at_unix_seconds" + ], + "title": "TimelineView" + }, + "TitleCreate": { + "properties": { + "title_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Title Id" + }, + "title_number": { + "type": "string", + "minLength": 1, + "title": "Title Number" + }, + "title_name": { + "type": "string", + "minLength": 1, + "title": "Title Name" + }, + "sort_order": { + "type": "integer", + "title": "Sort Order", + "default": 0 + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title_number", + "title_name" + ], + "title": "TitleCreate", + "description": "Request body for creating a code title." + }, + "TranscriptInput": { + "properties": { + "source_label": { + "type": "string", + "minLength": 1, + "title": "Source Label" + }, + "transcript_text": { + "type": "string", + "minLength": 1, + "title": "Transcript Text" + }, + "correction_of_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Correction Of Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_label", + "transcript_text" + ], + "title": "TranscriptInput" + }, + "UserRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "email": { + "type": "string", + "format": "email", + "title": "Email" + }, + "is_active": { + "type": "boolean", + "title": "Is Active", + "default": true + }, + "is_superuser": { + "type": "boolean", + "title": "Is Superuser", + "default": false + }, + "is_verified": { + "type": "boolean", + "title": "Is Verified", + "default": false + }, + "full_name": { + "type": "string", + "title": "Full Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "last_login": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Login" + }, + "must_change_password": { + "type": "boolean", + "title": "Must Change Password", + "default": false + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + } + }, + "type": "object", + "required": [ + "id", + "email", + "full_name", + "role", + "created_at", + "last_login" + ], + "title": "UserRead" + }, + "UserRole": { + "type": "string", + "enum": [ + "admin", + "staff", + "reviewer", + "read_only", + "liaison", + "public" + ], + "title": "UserRole" + }, + "UserSelfUpdate": { + "properties": { + "password": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Password" + }, + "email": { + "anyOf": [ + { + "type": "string", + "format": "email" + }, + { + "type": "null" + } + ], + "title": "Email" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + }, + "is_superuser": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Superuser" + }, + "is_verified": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Verified" + }, + "full_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Full Name" + } + }, + "type": "object", + "title": "UserSelfUpdate", + "description": "Schema for user self-update via PATCH /users/me.\n\nExcludes role and department_id. Any payload containing those fields is\nrejected at parse time (HTTP 422). Role and department changes require\nadmin privileges via /admin/users/{id}." + }, + "UserUpdateRequest": { + "properties": { + "full_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Full Name" + }, + "role": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Role" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "UserUpdateRequest" + }, + "ValidationError": { + "properties": { + "loc": { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "integer" + } + ] + }, + "type": "array", + "title": "Location" + }, + "msg": { + "type": "string", + "title": "Message" + }, + "type": { + "type": "string", + "title": "Error Type" + }, + "input": { + "title": "Input" + }, + "ctx": { + "type": "object", + "title": "Context" + } + }, + "type": "object", + "required": [ + "loc", + "msg", + "type" + ], + "title": "ValidationError" + }, + "Version": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence" + ], + "title": "Version" + }, + "VoteCorrection": { + "properties": { + "vote": { + "type": "string", + "minLength": 1, + "title": "Vote" + }, + "reason": { + "type": "string", + "minLength": 1, + "title": "Reason" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "vote", + "reason" + ], + "title": "VoteCorrection" + }, + "VoteInput": { + "properties": { + "voter_name": { + "type": "string", + "minLength": 1, + "title": "Voter Name" + }, + "vote": { + "type": "string", + "minLength": 1, + "title": "Vote" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "voter_name", + "vote" + ], + "title": "VoteInput" + }, + "_ParcelLookupIn": { + "properties": { + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "jurisdiction", + "query" + ], + "title": "_ParcelLookupIn" + }, + "townlight_inspections__workflow_models__SourceLink": { + "properties": { + "provider": { + "type": "string", + "const": "code", + "title": "Provider", + "default": "code" + }, + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "SourceLink" + }, + "townlight_permitting__workflow_models__SourceLink": { + "properties": { + "provider": { + "type": "string", + "enum": [ + "code", + "zoning" + ], + "title": "Provider" + }, + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "source_id", + "expected_sha256" + ], + "title": "SourceLink" + }, + "townlight_runtime__inspections_bridge__Search": { + "properties": { + "provider": { + "type": "string", + "const": "code", + "title": "Provider" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "query" + ], + "title": "Search" + }, + "townlight_runtime__notice_bridge__Review": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + }, + "note": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence", + "note" + ], + "title": "Review" + }, + "townlight_runtime__permitting_bridge__Import": { + "properties": { + "bundle": { + "$ref": "#/components/schemas/RequirementBundle" + }, + "expected_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "bundle" + ], + "title": "Import" + }, + "townlight_runtime__permitting_bridge__Search": { + "properties": { + "provider": { + "type": "string", + "enum": [ + "code", + "zoning" + ], + "title": "Provider" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "query" + ], + "title": "Search" + }, + "townlight_runtime__planning_bridge__Import": { + "properties": { + "bundle": { + "additionalProperties": true, + "type": "object", + "title": "Bundle" + }, + "expected_previous_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Expected Previous Revision" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "bundle" + ], + "title": "Import" + }, + "townlight_runtime__planning_bridge__Search": { + "properties": { + "query": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Query" + }, + "plan_type": { + "anyOf": [ + { + "type": "string", + "maxLength": 40 + }, + { + "type": "null" + } + ], + "title": "Plan Type" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "Search" + }, + "townlight_runtime__zoning_bridge__Review": { + "properties": { + "answer": { + "type": "string", + "maxLength": 10000, + "title": "Answer", + "default": "" + }, + "notes": { + "type": "string", + "maxLength": 10000, + "title": "Notes", + "default": "" + }, + "queue_status": { + "type": "string", + "enum": [ + "open", + "in_review", + "resolved", + "closed" + ], + "title": "Queue Status", + "default": "resolved" + } + }, + "additionalProperties": false, + "type": "object", + "title": "Review" + } + }, + "securitySchemes": { + "OAuth2PasswordBearer": { + "type": "oauth2", + "flows": { + "password": { + "scopes": {}, + "tokenUrl": "auth/jwt/login" + } + } + } + } + }, + "x-townlight-component": { + "view": "notice", + "identity": "Townlight Notice 0.3.0", + "evidence": "source-schema-only" + } +} diff --git a/docs/beta-1/api/notice.html b/docs/beta-1/api/notice.html new file mode 100644 index 0000000..275a264 --- /dev/null +++ b/docs/beta-1/api/notice.html @@ -0,0 +1,12100 @@ +Townlight Notice API reference
Townlight

Townlight Notice API reference

+

Prepared source candidate, November 2, 2026. New signed Windows installed acceptance and publication remain pending.

+

Townlight Notice 0.3.0. The HTTP host is Townlight Records 1.8.0.dev2. Component package versions and the host API version are separate identities.

+

Generated from the actual native inspections-preview composition without application lifespan, migrations or database/network access. It describes route and validation contracts; it does not establish endpoint behavior, individual authorization or installed acceptance. Standalone product applications have separate deployment boundaries.

+

Machine-readable OpenAPI schema · Operating manual and limits

+

HTTP operations

+
GET /desktop/v1/notice/archives/{archive_id} +
{
+  "tags": [
+    "native-notice"
+  ],
+  "summary": "Export",
+  "operationId": "export_desktop_v1_notice_archives__archive_id__get",
+  "parameters": [
+    {
+      "name": "archive_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Archive Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/notice/archives/{archive_id}/records +
{
+  "tags": [
+    "native-notice"
+  ],
+  "summary": "Handoff",
+  "operationId": "handoff_desktop_v1_notice_archives__archive_id__records_post",
+  "parameters": [
+    {
+      "name": "archive_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Archive Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/Handoff"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/notice/notices +
{
+  "tags": [
+    "native-notice"
+  ],
+  "summary": "Inventory",
+  "operationId": "inventory_desktop_v1_notice_notices_get",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/notice/notices +
{
+  "tags": [
+    "native-notice"
+  ],
+  "summary": "Create",
+  "operationId": "create_desktop_v1_notice_notices_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/NoticeDraft"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/notice/notices/{notice_id} +
{
+  "tags": [
+    "native-notice"
+  ],
+  "summary": "Read",
+  "operationId": "read_desktop_v1_notice_notices__notice_id__get",
+  "parameters": [
+    {
+      "name": "notice_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Notice Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/notice/notices/{notice_id}/approval +
{
+  "tags": [
+    "native-notice"
+  ],
+  "summary": "Approve",
+  "operationId": "approve_desktop_v1_notice_notices__notice_id__approval_post",
+  "parameters": [
+    {
+      "name": "notice_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Notice Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/Version"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/notice/notices/{notice_id}/archive +
{
+  "tags": [
+    "native-notice"
+  ],
+  "summary": "Archive",
+  "operationId": "archive_desktop_v1_notice_notices__notice_id__archive_post",
+  "parameters": [
+    {
+      "name": "notice_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Notice Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/Version"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/notice/notices/{notice_id}/proof +
{
+  "tags": [
+    "native-notice"
+  ],
+  "summary": "Proof",
+  "operationId": "proof_desktop_v1_notice_notices__notice_id__proof_post",
+  "parameters": [
+    {
+      "name": "notice_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Notice Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/Proof"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/notice/notices/{notice_id}/review +
{
+  "tags": [
+    "native-notice"
+  ],
+  "summary": "Review",
+  "operationId": "review_desktop_v1_notice_notices__notice_id__review_post",
+  "parameters": [
+    {
+      "name": "notice_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Notice Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/townlight_runtime__notice_bridge__Review"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/notice/notices/{notice_id}/revisions +
{
+  "tags": [
+    "native-notice"
+  ],
+  "summary": "Edit",
+  "operationId": "edit_desktop_v1_notice_notices__notice_id__revisions_post",
+  "parameters": [
+    {
+      "name": "notice_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Notice Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/Revision"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+

Request and response data dictionary

+

Each schema includes the actual required fields, types, constraints and descriptions. References resolve against the machine-readable document.

+
ActionItemInput
+{
+  "properties": {
+    "description": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Description"
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "source_motion_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Motion Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "description"
+  ],
+  "title": "ActionItemInput"
+}
+
+
AdaPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "ada-title-ii",
+      "title": "Action"
+    },
+    "serviceArea": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Servicearea"
+    },
+    "hasCoordinatorReview": {
+      "type": "boolean",
+      "title": "Hascoordinatorreview",
+      "default": false
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "serviceArea"
+  ],
+  "title": "AdaPlan"
+}
+
+
AdminUserCreateRequest
+{
+  "properties": {
+    "email": {
+      "type": "string",
+      "title": "Email"
+    },
+    "password": {
+      "type": "string",
+      "title": "Password"
+    },
+    "full_name": {
+      "type": "string",
+      "title": "Full Name",
+      "default": ""
+    },
+    "role": {
+      "type": "string",
+      "title": "Role",
+      "default": "staff"
+    }
+  },
+  "type": "object",
+  "required": [
+    "email",
+    "password"
+  ],
+  "title": "AdminUserCreateRequest"
+}
+
+
AdminUserCreateResponse
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "email": {
+      "type": "string",
+      "title": "Email"
+    },
+    "full_name": {
+      "type": "string",
+      "title": "Full Name"
+    },
+    "role": {
+      "type": "string",
+      "title": "Role"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "email",
+    "full_name",
+    "role",
+    "is_active"
+  ],
+  "title": "AdminUserCreateResponse"
+}
+
+
AgendaAssignment
+{
+  "properties": {
+    "meeting_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Meeting Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "meeting_id"
+  ],
+  "title": "AgendaAssignment"
+}
+
+
AgendaInput
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "department_name": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Department Name"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "department_name"
+  ],
+  "title": "AgendaInput"
+}
+
+
AgendaReviewInput
+{
+  "properties": {
+    "to_status": {
+      "type": "string",
+      "enum": [
+        "DRAFTED",
+        "SUBMITTED",
+        "DEPT_APPROVED",
+        "LEGAL_REVIEWED",
+        "CLERK_ACCEPTED",
+        "ON_AGENDA",
+        "IN_PACKET",
+        "POSTED",
+        "HEARD",
+        "DISPOSED",
+        "ARCHIVED"
+      ],
+      "title": "To Status"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "to_status"
+  ],
+  "title": "AgendaReviewInput"
+}
+
+
AmendmentInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "policy": {
+      "$ref": "#/components/schemas/PolicySelection"
+    },
+    "proposal": {
+      "type": "string",
+      "maxLength": 20000,
+      "minLength": 1,
+      "title": "Proposal"
+    },
+    "responsible_staff": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Responsible Staff"
+    },
+    "status": {
+      "type": "string",
+      "enum": [
+        "draft",
+        "review",
+        "adopted",
+        "withdrawn"
+      ],
+      "title": "Status",
+      "default": "draft"
+    },
+    "review_note": {
+      "type": "string",
+      "maxLength": 5000,
+      "title": "Review Note",
+      "default": ""
+    },
+    "adoption_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Adoption Revision"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "policy",
+    "proposal",
+    "responsible_staff",
+    "note"
+  ],
+  "title": "AmendmentInput"
+}
+
+
AnalysisObservation
+{
+  "properties": {
+    "source": {
+      "type": "string",
+      "maxLength": 64,
+      "minLength": 1,
+      "title": "Source"
+    },
+    "filename": {
+      "type": "string",
+      "maxLength": 160,
+      "title": "Filename",
+      "default": ""
+    },
+    "media_type": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Media Type",
+      "default": ""
+    },
+    "text": {
+      "type": "string",
+      "maxLength": 4000,
+      "minLength": 1,
+      "title": "Text"
+    },
+    "adapter": {
+      "type": "string",
+      "maxLength": 120,
+      "title": "Adapter",
+      "default": ""
+    },
+    "citation_source_ids": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Citation Source Ids"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source",
+    "text"
+  ],
+  "title": "AnalysisObservation",
+  "description": "One draft observation, named with the adapter that actually produced it."
+}
+
+
AnalysisRecord
+{
+  "properties": {
+    "observations": {
+      "items": {
+        "$ref": "#/components/schemas/AnalysisObservation"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Observations"
+    },
+    "cited_sections": {
+      "items": {
+        "$ref": "#/components/schemas/CitedSection"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Cited Sections"
+    },
+    "unavailable": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Unavailable"
+    },
+    "runtime": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Runtime"
+    },
+    "review_required": {
+      "type": "boolean",
+      "title": "Review Required",
+      "default": true
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "AnalysisRecord",
+  "description": "The adapter output that accompanies a saved inspection draft."
+}
+
+
ApprovalCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "approve-records-response",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ApprovalPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "ApprovalCommand"
+}
+
+
ApprovalPayload
+{
+  "properties": {
+    "approvalNote": {
+      "type": "string",
+      "title": "Approvalnote",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "ApprovalPayload"
+}
+
+
ArchiveInput
+{
+  "properties": {
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "public",
+        "closed_session"
+      ],
+      "title": "Visibility"
+    },
+    "packet_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Packet Id"
+    },
+    "minutes_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Minutes Id"
+    },
+    "plain_language_summary": {
+      "type": "string",
+      "title": "Plain Language Summary",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "visibility"
+  ],
+  "title": "ArchiveInput"
+}
+
+
ArtifactPlan
+{
+  "properties": {
+    "artifact_id": {
+      "type": "string",
+      "title": "Artifact Id"
+    },
+    "file_name": {
+      "type": "string",
+      "title": "File Name"
+    },
+    "content": {
+      "type": "string",
+      "title": "Content"
+    },
+    "sha256": {
+      "type": "string",
+      "title": "Sha256"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "artifact_id",
+    "file_name",
+    "content",
+    "sha256",
+    "created_at_unix_seconds"
+  ],
+  "title": "ArtifactPlan"
+}
+
+
AssignCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "assign-records-request",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/AssignmentPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "AssignCommand"
+}
+
+
AssignmentPayload
+{
+  "properties": {
+    "assignedTo": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Assignedto"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "assignedTo"
+  ],
+  "title": "AssignmentPayload"
+}
+
+
AttachDocument
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation",
+      "default": ""
+    },
+    "file": {
+      "$ref": "#/components/schemas/ManagedFileReceipt"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "file"
+  ],
+  "title": "AttachDocument"
+}
+
+
AttachReleaseCopy
+{
+  "properties": {
+    "status": {
+      "type": "string",
+      "enum": [
+        "release-ready copy",
+        "redacted copy"
+      ],
+      "title": "Status"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note",
+      "default": ""
+    },
+    "added_by": {
+      "type": "string",
+      "title": "Added By",
+      "default": ""
+    },
+    "file": {
+      "$ref": "#/components/schemas/ManagedFileReceipt"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "status",
+    "file"
+  ],
+  "title": "AttachReleaseCopy"
+}
+
+
AuditChainVerification
+{
+  "properties": {
+    "is_valid": {
+      "type": "boolean",
+      "title": "Is Valid"
+    },
+    "entries_checked": {
+      "type": "integer",
+      "title": "Entries Checked"
+    },
+    "error_message": {
+      "type": "string",
+      "title": "Error Message"
+    }
+  },
+  "type": "object",
+  "required": [
+    "is_valid",
+    "entries_checked",
+    "error_message"
+  ],
+  "title": "AuditChainVerification"
+}
+
+
AuditLogRead
+{
+  "properties": {
+    "id": {
+      "type": "integer",
+      "title": "Id"
+    },
+    "prev_hash": {
+      "type": "string",
+      "title": "Prev Hash"
+    },
+    "entry_hash": {
+      "type": "string",
+      "title": "Entry Hash"
+    },
+    "timestamp": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Timestamp"
+    },
+    "user_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "User Id"
+    },
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "resource_type": {
+      "type": "string",
+      "title": "Resource Type"
+    },
+    "resource_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Resource Id"
+    },
+    "details": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Details"
+    },
+    "ai_generated": {
+      "type": "boolean",
+      "title": "Ai Generated"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "prev_hash",
+    "entry_hash",
+    "timestamp",
+    "user_id",
+    "action",
+    "resource_type",
+    "resource_id",
+    "details",
+    "ai_generated"
+  ],
+  "title": "AuditLogRead"
+}
+
+
AuditView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "module_id": {
+      "type": "string",
+      "title": "Module Id"
+    },
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    },
+    "previous_hash": {
+      "type": "string",
+      "title": "Previous Hash"
+    },
+    "entry_hash": {
+      "type": "string",
+      "title": "Entry Hash"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "module_id",
+    "action",
+    "summary",
+    "created_at_unix_seconds",
+    "previous_hash",
+    "entry_hash"
+  ],
+  "title": "AuditView"
+}
+
+
BearerResponse
+{
+  "properties": {
+    "access_token": {
+      "type": "string",
+      "title": "Access Token"
+    },
+    "token_type": {
+      "type": "string",
+      "title": "Token Type"
+    }
+  },
+  "type": "object",
+  "required": [
+    "access_token",
+    "token_type"
+  ],
+  "title": "BearerResponse"
+}
+
+
Body_auth_jwt_login_auth_jwt_login_post
+{
+  "properties": {
+    "grant_type": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^password$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Grant Type"
+    },
+    "username": {
+      "type": "string",
+      "title": "Username"
+    },
+    "password": {
+      "type": "string",
+      "format": "password",
+      "title": "Password"
+    },
+    "scope": {
+      "type": "string",
+      "title": "Scope",
+      "default": ""
+    },
+    "client_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Client Id"
+    },
+    "client_secret": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "format": "password",
+      "title": "Client Secret"
+    }
+  },
+  "type": "object",
+  "required": [
+    "username",
+    "password"
+  ],
+  "title": "Body_auth_jwt_login_auth_jwt_login_post"
+}
+
+
Body_upload_file_datasources_upload_post
+{
+  "properties": {
+    "file": {
+      "type": "string",
+      "contentMediaType": "application/octet-stream",
+      "title": "File"
+    }
+  },
+  "type": "object",
+  "required": [
+    "file"
+  ],
+  "title": "Body_upload_file_datasources_upload_post"
+}
+
+
CalculateDeadlineCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "calculate-records-deadline",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/CalculateDeadlinePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "CalculateDeadlineCommand"
+}
+
+
CalculateDeadlinePayload
+{
+  "properties": {
+    "deadlineReceivedDate": {
+      "type": "string",
+      "title": "Deadlinereceiveddate"
+    },
+    "deadlineRuleName": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Deadlinerulename"
+    },
+    "deadlineDayCount": {
+      "type": "string",
+      "title": "Deadlinedaycount"
+    },
+    "deadlineDayType": {
+      "type": "string",
+      "title": "Deadlinedaytype"
+    },
+    "deadlineBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Deadlinebasis"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "deadlineReceivedDate",
+    "deadlineRuleName",
+    "deadlineDayCount",
+    "deadlineDayType",
+    "deadlineBasis"
+  ],
+  "title": "CalculateDeadlinePayload"
+}
+
+
ChapterCreate
+{
+  "properties": {
+    "chapter_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Chapter Id"
+    },
+    "title_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title Id"
+    },
+    "chapter_number": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Chapter Number"
+    },
+    "chapter_name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Chapter Name"
+    },
+    "sort_order": {
+      "type": "integer",
+      "title": "Sort Order",
+      "default": 0
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title_id",
+    "chapter_number",
+    "chapter_name"
+  ],
+  "title": "ChapterCreate",
+  "description": "Request body for creating a code chapter."
+}
+
+
CitedSection
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "citation": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Citation"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "version": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Version",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "citation"
+  ],
+  "title": "CitedSection",
+  "description": "One resolved public Code section; never a caller-supplied quotation."
+}
+
+
CityProfileCreate
+{
+  "properties": {
+    "city_name": {
+      "type": "string",
+      "title": "City Name"
+    },
+    "state": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State"
+    },
+    "county": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "County"
+    },
+    "population_band": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Population Band"
+    },
+    "email_platform": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email Platform"
+    },
+    "has_dedicated_it": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Has Dedicated It"
+    },
+    "monthly_request_volume": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Monthly Request Volume"
+    },
+    "profile_data": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Profile Data",
+      "default": {}
+    },
+    "gap_map": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Gap Map",
+      "default": {}
+    }
+  },
+  "type": "object",
+  "required": [
+    "city_name"
+  ],
+  "title": "CityProfileCreate"
+}
+
+
CityProfileRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "city_name": {
+      "type": "string",
+      "title": "City Name"
+    },
+    "state": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State"
+    },
+    "county": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "County"
+    },
+    "population_band": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Population Band"
+    },
+    "email_platform": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email Platform"
+    },
+    "has_dedicated_it": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Has Dedicated It"
+    },
+    "monthly_request_volume": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Monthly Request Volume"
+    },
+    "onboarding_status": {
+      "type": "string",
+      "title": "Onboarding Status"
+    },
+    "profile_data": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Profile Data"
+    },
+    "gap_map": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Gap Map"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "updated_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "city_name",
+    "state",
+    "county",
+    "population_band",
+    "email_platform",
+    "has_dedicated_it",
+    "monthly_request_volume",
+    "onboarding_status",
+    "profile_data",
+    "gap_map",
+    "created_at",
+    "updated_at"
+  ],
+  "title": "CityProfileRead"
+}
+
+
CityProfileUpdate
+{
+  "properties": {
+    "city_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "City Name"
+    },
+    "state": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State"
+    },
+    "county": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "County"
+    },
+    "population_band": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Population Band"
+    },
+    "email_platform": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email Platform"
+    },
+    "has_dedicated_it": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Has Dedicated It"
+    },
+    "monthly_request_volume": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Monthly Request Volume"
+    },
+    "onboarding_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Onboarding Status"
+    },
+    "profile_data": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Profile Data"
+    },
+    "gap_map": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Gap Map"
+    }
+  },
+  "type": "object",
+  "title": "CityProfileUpdate"
+}
+
+
ClarificationCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "request-records-clarification",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ClarificationPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "ClarificationCommand"
+}
+
+
ClarificationPayload
+{
+  "properties": {
+    "clarificationNote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Clarificationnote"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "clarificationNote"
+  ],
+  "title": "ClarificationPayload"
+}
+
+
Closeout
+{
+  "properties": {
+    "decision_id": {
+      "type": "string",
+      "pattern": "^[A-Za-z0-9_-]{1,64}$",
+      "title": "Decision Id"
+    },
+    "version_id": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Version Id"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "version_label": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Version Label"
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 1000000,
+      "minLength": 1,
+      "title": "Body"
+    },
+    "effective_start": {
+      "type": "string",
+      "format": "date",
+      "title": "Effective Start"
+    },
+    "effective_end": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective End"
+    },
+    "is_current": {
+      "type": "boolean",
+      "title": "Is Current"
+    },
+    "reconciliation_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reconciliation Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "decision_id",
+    "version_id",
+    "source_id",
+    "version_label",
+    "body",
+    "effective_start",
+    "is_current"
+  ],
+  "title": "Closeout"
+}
+
+
CodeContext
+{
+  "properties": {
+    "section_number": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Section Number"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "section_number"
+  ],
+  "title": "CodeContext"
+}
+
+
CodeLink
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "const": "code",
+      "title": "Provider",
+      "default": "code"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "CodeLink"
+}
+
+
CodeSearch
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "CodeSearch"
+}
+
+
CodeSourceSelection
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 200,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "CodeSourceSelection"
+}
+
+
CompleteArtifact
+{
+  "properties": {
+    "export_path": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Export Path"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "export_path"
+  ],
+  "title": "CompleteArtifact"
+}
+
+
ConnectionSearch
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "enum": [
+        "meetings",
+        "zoning"
+      ],
+      "title": "Provider"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "query"
+  ],
+  "title": "ConnectionSearch"
+}
+
+
CoverageGapResponse
+{
+  "properties": {
+    "jurisdictions_without_rules": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Jurisdictions Without Rules"
+    },
+    "departments_without_staff": {
+      "items": {
+        "additionalProperties": true,
+        "type": "object"
+      },
+      "type": "array",
+      "title": "Departments Without Staff"
+    },
+    "uncovered_categories": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Uncovered Categories"
+    },
+    "total_gaps": {
+      "type": "integer",
+      "title": "Total Gaps"
+    }
+  },
+  "type": "object",
+  "required": [
+    "jurisdictions_without_rules",
+    "departments_without_staff",
+    "uncovered_categories",
+    "total_gaps"
+  ],
+  "title": "CoverageGapResponse"
+}
+
+
DataSourceAdminRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "source_type": {
+      "$ref": "#/components/schemas/SourceType"
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "type": "boolean",
+      "title": "Schedule Enabled",
+      "default": true
+    },
+    "next_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Next Sync At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "last_ingestion_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Ingestion At"
+    },
+    "last_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync At"
+    },
+    "last_sync_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync Status"
+    },
+    "last_error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Error Message"
+    },
+    "consecutive_failure_count": {
+      "type": "integer",
+      "title": "Consecutive Failure Count",
+      "default": 0
+    },
+    "sync_paused": {
+      "type": "boolean",
+      "title": "Sync Paused",
+      "default": false
+    },
+    "health_status": {
+      "type": "string",
+      "title": "Health Status",
+      "default": "healthy"
+    },
+    "active_failure_count": {
+      "type": "integer",
+      "title": "Active Failure Count",
+      "default": 0
+    },
+    "connector_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connector Type"
+    },
+    "updated_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Updated At"
+    },
+    "connection_config": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Connection Config"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "source_type",
+    "is_active",
+    "created_by",
+    "created_at",
+    "last_ingestion_at",
+    "connection_config"
+  ],
+  "title": "DataSourceAdminRead",
+  "description": "Full datasource shape including connection_config. Returned only by admin-gated endpoints."
+}
+
+
DataSourceCreate
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "source_type": {
+      "$ref": "#/components/schemas/SourceType"
+    },
+    "connection_config": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Connection Config",
+      "default": {}
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "type": "boolean",
+      "title": "Schedule Enabled",
+      "default": true
+    }
+  },
+  "type": "object",
+  "required": [
+    "name",
+    "source_type"
+  ],
+  "title": "DataSourceCreate"
+}
+
+
DataSourceRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "source_type": {
+      "$ref": "#/components/schemas/SourceType"
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "type": "boolean",
+      "title": "Schedule Enabled",
+      "default": true
+    },
+    "next_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Next Sync At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "last_ingestion_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Ingestion At"
+    },
+    "last_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync At"
+    },
+    "last_sync_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync Status"
+    },
+    "last_error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Error Message"
+    },
+    "consecutive_failure_count": {
+      "type": "integer",
+      "title": "Consecutive Failure Count",
+      "default": 0
+    },
+    "sync_paused": {
+      "type": "boolean",
+      "title": "Sync Paused",
+      "default": false
+    },
+    "health_status": {
+      "type": "string",
+      "title": "Health Status",
+      "default": "healthy"
+    },
+    "active_failure_count": {
+      "type": "integer",
+      "title": "Active Failure Count",
+      "default": 0
+    },
+    "connector_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connector Type"
+    },
+    "updated_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "source_type",
+    "is_active",
+    "created_by",
+    "created_at",
+    "last_ingestion_at"
+  ],
+  "title": "DataSourceRead",
+  "description": "Redacted datasource shape — safe for non-admin roles. connection_config omitted."
+}
+
+
DataSourceUpdate
+{
+  "properties": {
+    "name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Name"
+    },
+    "connection_config": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connection Config"
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Schedule Enabled"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "DataSourceUpdate"
+}
+
+
DeadlineCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "set-records-deadline",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/DeadlinePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "DeadlineCommand"
+}
+
+
DeadlinePayload
+{
+  "properties": {
+    "deadline": {
+      "type": "string",
+      "title": "Deadline"
+    },
+    "deadlineBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Deadlinebasis"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "deadline",
+    "deadlineBasis"
+  ],
+  "title": "DeadlinePayload"
+}
+
+
Decision
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "pattern": "^[A-Za-z0-9_-]{1,64}$",
+      "title": "Id"
+    },
+    "outcome": {
+      "type": "string",
+      "enum": [
+        "adopted",
+        "not_adopted",
+        "deferred",
+        "withdrawn"
+      ],
+      "title": "Outcome"
+    },
+    "decided_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Decided At"
+    },
+    "decision_text": {
+      "type": "string",
+      "maxLength": 1000000,
+      "minLength": 1,
+      "title": "Decision Text"
+    },
+    "supporting_references": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Supporting References"
+    },
+    "supersedes_decision_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^[A-Za-z0-9_-]{1,64}$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supersedes Decision Id"
+    },
+    "reconciliation_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reconciliation Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "outcome",
+    "decision_text"
+  ],
+  "title": "Decision"
+}
+
+
DepartmentCreate
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "code": {
+      "type": "string",
+      "title": "Code"
+    },
+    "contact_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Contact Email"
+    }
+  },
+  "type": "object",
+  "required": [
+    "name",
+    "code"
+  ],
+  "title": "DepartmentCreate"
+}
+
+
DepartmentRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "code": {
+      "type": "string",
+      "title": "Code"
+    },
+    "contact_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Contact Email"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "code",
+    "contact_email",
+    "created_at"
+  ],
+  "title": "DepartmentRead"
+}
+
+
DepartmentUpdate
+{
+  "properties": {
+    "name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Name"
+    },
+    "code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Code"
+    },
+    "contact_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Contact Email"
+    }
+  },
+  "type": "object",
+  "title": "DepartmentUpdate"
+}
+
+
DisclosureTemplateCreate
+{
+  "properties": {
+    "template_type": {
+      "type": "string",
+      "title": "Template Type"
+    },
+    "state_code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State Code"
+    },
+    "content": {
+      "type": "string",
+      "title": "Content"
+    }
+  },
+  "type": "object",
+  "required": [
+    "template_type",
+    "content"
+  ],
+  "title": "DisclosureTemplateCreate"
+}
+
+
DisclosureTemplateRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "template_type": {
+      "type": "string",
+      "title": "Template Type"
+    },
+    "state_code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State Code"
+    },
+    "content": {
+      "type": "string",
+      "title": "Content"
+    },
+    "version": {
+      "type": "integer",
+      "title": "Version"
+    },
+    "updated_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Updated By"
+    },
+    "updated_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "template_type",
+    "state_code",
+    "content",
+    "version",
+    "updated_by",
+    "updated_at"
+  ],
+  "title": "DisclosureTemplateRead"
+}
+
+
DisclosureTemplateRendered
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "template_type": {
+      "type": "string",
+      "title": "Template Type"
+    },
+    "rendered_content": {
+      "type": "string",
+      "title": "Rendered Content"
+    },
+    "has_unresolved_variables": {
+      "type": "boolean",
+      "title": "Has Unresolved Variables"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "template_type",
+    "rendered_content",
+    "has_unresolved_variables"
+  ],
+  "title": "DisclosureTemplateRendered"
+}
+
+
DisclosureTemplateUpdate
+{
+  "properties": {
+    "content": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Content"
+    },
+    "state_code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State Code"
+    }
+  },
+  "type": "object",
+  "title": "DisclosureTemplateUpdate"
+}
+
+
DocumentChunkRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "chunk_index": {
+      "type": "integer",
+      "title": "Chunk Index"
+    },
+    "content_text": {
+      "type": "string",
+      "title": "Content Text"
+    },
+    "token_count": {
+      "type": "integer",
+      "title": "Token Count"
+    },
+    "page_number": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Page Number"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "document_id",
+    "chunk_index",
+    "content_text",
+    "token_count",
+    "page_number"
+  ],
+  "title": "DocumentChunkRead"
+}
+
+
DocumentRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "source_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Source Id"
+    },
+    "source_path": {
+      "type": "string",
+      "title": "Source Path"
+    },
+    "filename": {
+      "type": "string",
+      "title": "Filename"
+    },
+    "file_type": {
+      "type": "string",
+      "title": "File Type"
+    },
+    "file_hash": {
+      "type": "string",
+      "title": "File Hash"
+    },
+    "file_size": {
+      "type": "integer",
+      "title": "File Size"
+    },
+    "ingestion_status": {
+      "$ref": "#/components/schemas/IngestionStatus"
+    },
+    "ingestion_error": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ingestion Error"
+    },
+    "chunk_count": {
+      "type": "integer",
+      "title": "Chunk Count"
+    },
+    "ingested_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ingested At"
+    },
+    "connector_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connector Type"
+    },
+    "updated_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "source_id",
+    "source_path",
+    "filename",
+    "file_type",
+    "file_hash",
+    "file_size",
+    "ingestion_status",
+    "ingestion_error",
+    "chunk_count",
+    "ingested_at"
+  ],
+  "title": "DocumentRead"
+}
+
+
DraftCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "draft-records-response",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/DraftPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "DraftCommand"
+}
+
+
DraftInput
+{
+  "properties": {
+    "source_materials": {
+      "items": {
+        "$ref": "#/components/schemas/SourceInput"
+      },
+      "type": "array",
+      "title": "Source Materials"
+    },
+    "sentences": {
+      "items": {
+        "$ref": "#/components/schemas/SentenceInput"
+      },
+      "type": "array",
+      "minItems": 1,
+      "title": "Sentences"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sentences"
+  ],
+  "title": "DraftInput"
+}
+
+
DraftPayload
+{
+  "properties": {
+    "responseDraft": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Responsedraft"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "responseDraft"
+  ],
+  "title": "DraftPayload"
+}
+
+
ErrorModel
+{
+  "properties": {
+    "detail": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "additionalProperties": {
+            "type": "string"
+          },
+          "type": "object"
+        }
+      ],
+      "title": "Detail"
+    }
+  },
+  "type": "object",
+  "required": [
+    "detail"
+  ],
+  "title": "ErrorModel"
+}
+
+
Evidence
+{
+  "properties": {
+    "filename": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$",
+      "title": "Filename"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Description"
+    },
+    "media_type": {
+      "type": "string",
+      "enum": [
+        "text/plain",
+        "image/jpeg",
+        "image/png",
+        "image/webp",
+        "application/pdf",
+        "audio/webm",
+        "audio/ogg",
+        "audio/wav",
+        "audio/mpeg",
+        "audio/mp4"
+      ],
+      "title": "Media Type"
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 14000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "filename",
+    "description",
+    "media_type",
+    "content_base64",
+    "sha256"
+  ],
+  "title": "Evidence"
+}
+
+
EvidenceItem
+{
+  "properties": {
+    "filename": {
+      "type": "string",
+      "maxLength": 151,
+      "minLength": 1,
+      "title": "Filename"
+    },
+    "media_type": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Media Type"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Description",
+      "default": ""
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 14000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "filename",
+    "media_type",
+    "content_base64",
+    "sha256"
+  ],
+  "title": "EvidenceItem"
+}
+
+
EvidenceItems
+{
+  "properties": {
+    "items": {
+      "items": {
+        "$ref": "#/components/schemas/EvidenceItem"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "minItems": 1,
+      "title": "Items"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "items"
+  ],
+  "title": "EvidenceItems"
+}
+
+
ExemptionAccuracyReport
+{
+  "properties": {
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "total_flags": {
+      "type": "integer",
+      "title": "Total Flags"
+    },
+    "accepted": {
+      "type": "integer",
+      "title": "Accepted"
+    },
+    "rejected": {
+      "type": "integer",
+      "title": "Rejected"
+    },
+    "pending": {
+      "type": "integer",
+      "title": "Pending"
+    },
+    "acceptance_rate": {
+      "type": "number",
+      "title": "Acceptance Rate"
+    }
+  },
+  "type": "object",
+  "required": [
+    "category",
+    "total_flags",
+    "accepted",
+    "rejected",
+    "pending",
+    "acceptance_rate"
+  ],
+  "title": "ExemptionAccuracyReport"
+}
+
+
ExemptionDashboard
+{
+  "properties": {
+    "total_flags": {
+      "type": "integer",
+      "title": "Total Flags"
+    },
+    "by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "By Status"
+    },
+    "by_category": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "By Category"
+    },
+    "acceptance_rate": {
+      "type": "number",
+      "title": "Acceptance Rate"
+    },
+    "total_rules": {
+      "type": "integer",
+      "title": "Total Rules"
+    },
+    "active_rules": {
+      "type": "integer",
+      "title": "Active Rules"
+    }
+  },
+  "type": "object",
+  "required": [
+    "total_flags",
+    "by_status",
+    "by_category",
+    "acceptance_rate",
+    "total_rules",
+    "active_rules"
+  ],
+  "title": "ExemptionDashboard"
+}
+
+
ExemptionDecisionCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-exemption-decision",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ExemptionDecisionPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "ExemptionDecisionCommand"
+}
+
+
ExemptionDecisionPayload
+{
+  "properties": {
+    "exemptionSource": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionsource"
+    },
+    "exemptionKind": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionkind"
+    },
+    "exemptionFinding": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionfinding"
+    },
+    "exemptionDecision": {
+      "type": "string",
+      "enum": [
+        "release",
+        "redact",
+        "exempt"
+      ],
+      "title": "Exemptiondecision"
+    },
+    "exemptionBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionbasis"
+    },
+    "exemptionReviewer": {
+      "type": "string",
+      "title": "Exemptionreviewer",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "exemptionSource",
+    "exemptionKind",
+    "exemptionFinding",
+    "exemptionDecision",
+    "exemptionBasis"
+  ],
+  "title": "ExemptionDecisionPayload"
+}
+
+
ExemptionDecisionView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "source": {
+      "type": "string",
+      "title": "Source"
+    },
+    "kind": {
+      "type": "string",
+      "title": "Kind"
+    },
+    "finding": {
+      "type": "string",
+      "title": "Finding"
+    },
+    "decision": {
+      "type": "string",
+      "enum": [
+        "release",
+        "redact",
+        "exempt"
+      ],
+      "title": "Decision"
+    },
+    "basis": {
+      "type": "string",
+      "title": "Basis"
+    },
+    "reviewer": {
+      "type": "string",
+      "title": "Reviewer"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "source",
+    "kind",
+    "finding",
+    "decision",
+    "basis",
+    "reviewer",
+    "created_at_unix_seconds"
+  ],
+  "title": "ExemptionDecisionView"
+}
+
+
ExemptionFlagRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "chunk_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Chunk Id"
+    },
+    "rule_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Rule Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "matched_text": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Matched Text"
+    },
+    "confidence": {
+      "type": "number",
+      "title": "Confidence"
+    },
+    "status": {
+      "$ref": "#/components/schemas/FlagStatus"
+    },
+    "reviewed_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reviewed By"
+    },
+    "reviewed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reviewed At"
+    },
+    "review_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Reason"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "chunk_id",
+    "rule_id",
+    "request_id",
+    "category",
+    "matched_text",
+    "confidence",
+    "status",
+    "reviewed_by",
+    "reviewed_at",
+    "review_reason",
+    "created_at"
+  ],
+  "title": "ExemptionFlagRead"
+}
+
+
ExemptionFlagReview
+{
+  "properties": {
+    "status": {
+      "$ref": "#/components/schemas/FlagStatus"
+    },
+    "review_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Reason"
+    }
+  },
+  "type": "object",
+  "required": [
+    "status"
+  ],
+  "title": "ExemptionFlagReview"
+}
+
+
ExemptionNoteCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-exemption-review",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ExemptionNotePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "ExemptionNoteCommand"
+}
+
+
ExemptionNotePayload
+{
+  "properties": {
+    "exemptionNote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionnote"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "exemptionNote"
+  ],
+  "title": "ExemptionNotePayload"
+}
+
+
ExemptionRuleCreate
+{
+  "properties": {
+    "state_code": {
+      "type": "string",
+      "title": "State Code"
+    },
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "rule_type": {
+      "$ref": "#/components/schemas/RuleType"
+    },
+    "rule_definition": {
+      "type": "string",
+      "title": "Rule Definition"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "enabled": {
+      "type": "boolean",
+      "title": "Enabled",
+      "default": true
+    }
+  },
+  "type": "object",
+  "required": [
+    "state_code",
+    "category",
+    "rule_type",
+    "rule_definition"
+  ],
+  "title": "ExemptionRuleCreate"
+}
+
+
ExemptionRuleRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "state_code": {
+      "type": "string",
+      "title": "State Code"
+    },
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "rule_type": {
+      "$ref": "#/components/schemas/RuleType"
+    },
+    "rule_definition": {
+      "type": "string",
+      "title": "Rule Definition"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "enabled": {
+      "type": "boolean",
+      "title": "Enabled"
+    },
+    "version": {
+      "type": "integer",
+      "title": "Version",
+      "default": 1
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "state_code",
+    "category",
+    "rule_type",
+    "rule_definition",
+    "description",
+    "enabled",
+    "created_by",
+    "created_at"
+  ],
+  "title": "ExemptionRuleRead"
+}
+
+
ExemptionRuleUpdate
+{
+  "properties": {
+    "rule_definition": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Rule Definition"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "enabled": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Enabled"
+    }
+  },
+  "type": "object",
+  "title": "ExemptionRuleUpdate"
+}
+
+
ExportReceipt
+{
+  "properties": {
+    "export_path": {
+      "type": "string",
+      "maxLength": 32768,
+      "minLength": 1,
+      "title": "Export Path"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "export_path"
+  ],
+  "title": "ExportReceipt"
+}
+
+
FeeEstimateCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "estimate-records-fee",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/FeeEstimatePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "FeeEstimateCommand"
+}
+
+
FeeEstimatePayload
+{
+  "properties": {
+    "feeEstimate": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feeestimate"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "feeEstimate"
+  ],
+  "title": "FeeEstimatePayload"
+}
+
+
FeeEstimateRequest
+{
+  "properties": {
+    "page_count": {
+      "type": "integer",
+      "title": "Page Count"
+    },
+    "fee_schedule_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Fee Schedule Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "page_count",
+    "fee_schedule_id"
+  ],
+  "title": "FeeEstimateRequest"
+}
+
+
FeeEstimateResponse
+{
+  "properties": {
+    "page_count": {
+      "type": "integer",
+      "title": "Page Count"
+    },
+    "unit_price": {
+      "type": "number",
+      "title": "Unit Price"
+    },
+    "total": {
+      "type": "number",
+      "title": "Total"
+    },
+    "fee_type": {
+      "type": "string",
+      "title": "Fee Type"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    }
+  },
+  "type": "object",
+  "required": [
+    "page_count",
+    "unit_price",
+    "total",
+    "fee_type",
+    "description"
+  ],
+  "title": "FeeEstimateResponse"
+}
+
+
FeeLineCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-fee-line",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/FeeLinePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "FeeLineCommand"
+}
+
+
FeeLineItemCreate
+{
+  "properties": {
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "quantity": {
+      "type": "integer",
+      "title": "Quantity",
+      "default": 1
+    },
+    "unit_price": {
+      "type": "number",
+      "title": "Unit Price"
+    },
+    "fee_schedule_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Schedule Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "description",
+    "unit_price"
+  ],
+  "title": "FeeLineItemCreate"
+}
+
+
FeeLineItemRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "fee_schedule_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Schedule Id"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "quantity": {
+      "type": "integer",
+      "title": "Quantity"
+    },
+    "unit_price": {
+      "type": "number",
+      "title": "Unit Price"
+    },
+    "total": {
+      "type": "number",
+      "title": "Total"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "fee_schedule_id",
+    "description",
+    "quantity",
+    "unit_price",
+    "total",
+    "status",
+    "created_at"
+  ],
+  "title": "FeeLineItemRead"
+}
+
+
FeeLinePayload
+{
+  "properties": {
+    "feeLineDescription": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feelinedescription"
+    },
+    "feeScheduleBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feeschedulebasis"
+    },
+    "feeLineAmount": {
+      "type": "string",
+      "title": "Feelineamount"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "feeLineDescription",
+    "feeScheduleBasis",
+    "feeLineAmount"
+  ],
+  "title": "FeeLinePayload"
+}
+
+
FeeLineView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "schedule_basis": {
+      "type": "string",
+      "title": "Schedule Basis"
+    },
+    "amount_cents": {
+      "type": "integer",
+      "title": "Amount Cents"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "description",
+    "schedule_basis",
+    "amount_cents",
+    "created_at_unix_seconds"
+  ],
+  "title": "FeeLineView"
+}
+
+
FeeScheduleCreate
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "title": "Jurisdiction"
+    },
+    "fee_type": {
+      "type": "string",
+      "title": "Fee Type"
+    },
+    "amount": {
+      "type": "number",
+      "title": "Amount"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "effective_date": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective Date"
+    }
+  },
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "fee_type",
+    "amount"
+  ],
+  "title": "FeeScheduleCreate"
+}
+
+
FeeScheduleRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "jurisdiction": {
+      "type": "string",
+      "title": "Jurisdiction"
+    },
+    "fee_type": {
+      "type": "string",
+      "title": "Fee Type"
+    },
+    "amount": {
+      "type": "number",
+      "title": "Amount"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "effective_date": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective Date"
+    },
+    "created_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "jurisdiction",
+    "fee_type",
+    "amount",
+    "description",
+    "effective_date",
+    "created_by",
+    "created_at"
+  ],
+  "title": "FeeScheduleRead"
+}
+
+
FeeScheduleUpdate
+{
+  "properties": {
+    "fee_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Type"
+    },
+    "amount": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Amount"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "effective_date": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective Date"
+    }
+  },
+  "type": "object",
+  "title": "FeeScheduleUpdate"
+}
+
+
FeeWaiverCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "waive-records-fee",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/FeeWaiverPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "FeeWaiverCommand"
+}
+
+
FeeWaiverCreateRequest
+{
+  "properties": {
+    "waiver_type": {
+      "type": "string",
+      "title": "Waiver Type"
+    },
+    "reason": {
+      "type": "string",
+      "title": "Reason"
+    }
+  },
+  "type": "object",
+  "required": [
+    "waiver_type",
+    "reason"
+  ],
+  "title": "FeeWaiverCreateRequest"
+}
+
+
FeeWaiverPayload
+{
+  "properties": {
+    "feeWaiverReason": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feewaiverreason"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "feeWaiverReason"
+  ],
+  "title": "FeeWaiverPayload"
+}
+
+
FeeWaiverReadResponse
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "waiver_type": {
+      "type": "string",
+      "title": "Waiver Type"
+    },
+    "reason": {
+      "type": "string",
+      "title": "Reason"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    },
+    "created_at": {
+      "type": "string",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "waiver_type",
+    "reason",
+    "status",
+    "created_at"
+  ],
+  "title": "FeeWaiverReadResponse"
+}
+
+
FeeWaiverReviewRequest
+{
+  "properties": {
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    }
+  },
+  "type": "object",
+  "required": [
+    "status"
+  ],
+  "title": "FeeWaiverReviewRequest"
+}
+
+
FinishCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "fulfill-records-request",
+        "close-records-request"
+      ],
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/NativePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "FinishCommand"
+}
+
+
FlagStatus
+{
+  "type": "string",
+  "enum": [
+    "flagged",
+    "reviewed",
+    "accepted",
+    "rejected"
+  ],
+  "title": "FlagStatus"
+}
+
+
FormPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "form-plan",
+      "title": "Action"
+    },
+    "formName": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Formname",
+      "default": ""
+    },
+    "fields": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 50,
+      "title": "Fields"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "FormPlan"
+}
+
+
GeneratedDraft
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "model": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Model"
+    },
+    "previous_response_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Previous Response Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text",
+    "model",
+    "previous_response_sha256"
+  ],
+  "title": "GeneratedDraft"
+}
+
+
HTTPValidationError
+{
+  "properties": {
+    "detail": {
+      "items": {
+        "$ref": "#/components/schemas/ValidationError"
+      },
+      "type": "array",
+      "title": "Detail"
+    }
+  },
+  "type": "object",
+  "title": "HTTPValidationError"
+}
+
+
Handoff
+{
+  "properties": {
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "request_id"
+  ],
+  "title": "Handoff"
+}
+
+
ImportBundleCreate
+{
+  "properties": {
+    "job_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Job Id"
+    },
+    "connector_type": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Connector Type"
+    },
+    "source": {
+      "$ref": "#/components/schemas/SourceCreate"
+    },
+    "sources": {
+      "items": {
+        "$ref": "#/components/schemas/SourceCreate"
+      },
+      "type": "array",
+      "title": "Sources"
+    },
+    "titles": {
+      "items": {
+        "$ref": "#/components/schemas/TitleCreate"
+      },
+      "type": "array",
+      "title": "Titles"
+    },
+    "chapters": {
+      "items": {
+        "$ref": "#/components/schemas/ChapterCreate"
+      },
+      "type": "array",
+      "title": "Chapters"
+    },
+    "sections": {
+      "items": {
+        "$ref": "#/components/schemas/SectionCreate"
+      },
+      "type": "array",
+      "title": "Sections"
+    },
+    "versions": {
+      "items": {
+        "$ref": "#/components/schemas/SectionVersionCreate"
+      },
+      "type": "array",
+      "title": "Versions"
+    },
+    "provenance": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Provenance"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "connector_type",
+    "source"
+  ],
+  "title": "ImportBundleCreate",
+  "description": "Request body for local fixture/file-drop import jobs."
+}
+
+
InclusionStatus
+{
+  "type": "string",
+  "enum": [
+    "included",
+    "excluded",
+    "pending"
+  ],
+  "title": "InclusionStatus"
+}
+
+
IngestionStats
+{
+  "properties": {
+    "total_sources": {
+      "type": "integer",
+      "title": "Total Sources"
+    },
+    "active_sources": {
+      "type": "integer",
+      "title": "Active Sources"
+    },
+    "total_documents": {
+      "type": "integer",
+      "title": "Total Documents"
+    },
+    "documents_by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "Documents By Status"
+    },
+    "total_chunks": {
+      "type": "integer",
+      "title": "Total Chunks"
+    }
+  },
+  "type": "object",
+  "required": [
+    "total_sources",
+    "active_sources",
+    "total_documents",
+    "documents_by_status",
+    "total_chunks"
+  ],
+  "title": "IngestionStats"
+}
+
+
IngestionStatus
+{
+  "type": "string",
+  "enum": [
+    "pending",
+    "processing",
+    "completed",
+    "failed"
+  ],
+  "title": "IngestionStatus"
+}
+
+
InitiativeInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "policy": {
+      "$ref": "#/components/schemas/PolicySelection"
+    },
+    "responsible_staff": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Responsible Staff"
+    },
+    "target": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "string"
+        }
+      ],
+      "title": "Target"
+    },
+    "unit": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Unit"
+    },
+    "due_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Due On"
+    },
+    "status": {
+      "type": "string",
+      "enum": [
+        "planned",
+        "active",
+        "completed",
+        "cancelled"
+      ],
+      "title": "Status",
+      "default": "planned"
+    },
+    "milestones": {
+      "items": {
+        "$ref": "#/components/schemas/Milestone"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "title": "Milestones"
+    },
+    "measurements": {
+      "items": {
+        "$ref": "#/components/schemas/Measurement"
+      },
+      "type": "array",
+      "maxItems": 1000,
+      "title": "Measurements"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "policy",
+    "responsible_staff",
+    "target",
+    "unit",
+    "due_on",
+    "note"
+  ],
+  "title": "InitiativeInput"
+}
+
+
InspectionInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "property_reference": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Property Reference"
+    },
+    "inspection_reference": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Inspection Reference"
+    },
+    "dataset_kind": {
+      "type": "string",
+      "enum": [
+        "municipal",
+        "fictional"
+      ],
+      "title": "Dataset Kind"
+    },
+    "inspector_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "minLength": 1,
+      "title": "Inspector Notes"
+    },
+    "photo_observations": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Photo Observations"
+    },
+    "voice_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Voice Notes",
+      "default": ""
+    },
+    "evidence": {
+      "items": {
+        "$ref": "#/components/schemas/Evidence"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "title": "Evidence"
+    },
+    "linked_sources": {
+      "items": {
+        "$ref": "#/components/schemas/townlight_inspections__workflow_models__SourceLink"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Linked Sources"
+    },
+    "assigned_to": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Assigned To",
+      "default": ""
+    },
+    "staff_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Staff Notes",
+      "default": ""
+    },
+    "notice_draft": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Notice Draft",
+      "default": ""
+    },
+    "review_state": {
+      "type": "string",
+      "enum": [
+        "draft",
+        "follow_up",
+        "reviewed"
+      ],
+      "title": "Review State",
+      "default": "draft"
+    },
+    "review_notes": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Review Notes",
+      "default": ""
+    },
+    "public_summary": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Public Summary",
+      "default": ""
+    },
+    "analysis": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/AnalysisRecord"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "property_reference",
+    "inspection_reference",
+    "dataset_kind",
+    "inspector_notes"
+  ],
+  "title": "InspectionInput"
+}
+
+
IntakeInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "project_name": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Project Name"
+    },
+    "project_description": {
+      "type": "string",
+      "maxLength": 10000,
+      "minLength": 1,
+      "title": "Project Description"
+    },
+    "location": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Location"
+    },
+    "applicant_contact": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Applicant Contact",
+      "default": ""
+    },
+    "requirement_revision": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Requirement Revision"
+    },
+    "materials": {
+      "items": {
+        "$ref": "#/components/schemas/MaterialReview"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "minItems": 1,
+      "title": "Materials"
+    },
+    "linked_sources": {
+      "items": {
+        "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Linked Sources"
+    },
+    "staff_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Staff Notes",
+      "default": ""
+    },
+    "assigned_to": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Assigned To",
+      "default": ""
+    },
+    "review_state": {
+      "type": "string",
+      "enum": [
+        "draft",
+        "follow_up",
+        "reviewed"
+      ],
+      "title": "Review State",
+      "default": "draft"
+    },
+    "review_notes": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Review Notes",
+      "default": ""
+    },
+    "public_summary": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Public Summary",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "project_name",
+    "project_description",
+    "location",
+    "requirement_revision",
+    "materials"
+  ],
+  "title": "IntakeInput"
+}
+
+
InterpretationNoteCreate
+{
+  "properties": {
+    "note_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Note Id"
+    },
+    "note_text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Note Text"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "note_text"
+  ],
+  "title": "InterpretationNoteCreate",
+  "description": "Request body for staff-only interpretation notes."
+}
+
+
InterviewRequest
+{
+  "properties": {
+    "last_answer": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Answer"
+    },
+    "last_field": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Field"
+    },
+    "skipped_fields": {
+      "anyOf": [
+        {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Skipped Fields"
+    }
+  },
+  "type": "object",
+  "title": "InterviewRequest"
+}
+
+
InterviewResponse
+{
+  "properties": {
+    "question": {
+      "type": "string",
+      "title": "Question"
+    },
+    "target_field": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Target Field"
+    },
+    "all_complete": {
+      "type": "boolean",
+      "title": "All Complete"
+    },
+    "completed_fields": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Completed Fields"
+    },
+    "onboarding_status": {
+      "type": "string",
+      "title": "Onboarding Status"
+    },
+    "skipped_fields": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Skipped Fields"
+    }
+  },
+  "type": "object",
+  "required": [
+    "question",
+    "target_field",
+    "all_complete",
+    "completed_fields",
+    "onboarding_status",
+    "skipped_fields"
+  ],
+  "title": "InterviewResponse"
+}
+
+
ManagedFileReceipt
+{
+  "properties": {
+    "original_path": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Original Path"
+    },
+    "stored_path": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Stored Path"
+    },
+    "file_name": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "File Name"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Sha256"
+    },
+    "size_bytes": {
+      "type": "integer",
+      "maximum": 2147483647.0,
+      "minimum": 0.0,
+      "title": "Size Bytes"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "original_path",
+    "stored_path",
+    "file_name",
+    "sha256",
+    "size_bytes"
+  ],
+  "title": "ManagedFileReceipt"
+}
+
+
ManagedSource
+{
+  "properties": {
+    "original_path": {
+      "type": "string",
+      "title": "Original Path"
+    },
+    "stored_path": {
+      "type": "string",
+      "title": "Stored Path"
+    },
+    "file_name": {
+      "type": "string",
+      "title": "File Name"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Sha256"
+    },
+    "size_bytes": {
+      "type": "integer",
+      "minimum": 0.0,
+      "title": "Size Bytes"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "original_path",
+    "stored_path",
+    "file_name",
+    "sha256",
+    "size_bytes"
+  ],
+  "title": "ManagedSource"
+}
+
+
Material
+{
+  "properties": {
+    "material_id": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9_-]{1,80}$",
+      "title": "Material Id"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Description"
+    },
+    "citation": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Citation"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "material_id",
+    "description",
+    "citation"
+  ],
+  "title": "Material"
+}
+
+
MaterialReview
+{
+  "properties": {
+    "material_id": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Material Id"
+    },
+    "status": {
+      "type": "string",
+      "enum": [
+        "not_reviewed",
+        "provided",
+        "missing",
+        "unclear"
+      ],
+      "title": "Status",
+      "default": "not_reviewed"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Note",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "material_id"
+  ],
+  "title": "MaterialReview"
+}
+
+
Measurement
+{
+  "properties": {
+    "recorded_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Recorded On"
+    },
+    "value": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "string"
+        }
+      ],
+      "title": "Value"
+    },
+    "evidence": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Evidence"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "recorded_on",
+    "value",
+    "evidence"
+  ],
+  "title": "Measurement"
+}
+
+
MediaAnalysis
+{
+  "properties": {
+    "items": {
+      "items": {
+        "$ref": "#/components/schemas/EvidenceItem"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "minItems": 1,
+      "title": "Items"
+    },
+    "code_links": {
+      "items": {
+        "$ref": "#/components/schemas/CodeLink"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Code Links"
+    },
+    "inspector_supplied_text": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Inspector Supplied Text",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "items"
+  ],
+  "title": "MediaAnalysis"
+}
+
+
MeetingInput
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "scheduled_start": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Scheduled Start"
+    },
+    "location": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Location"
+    },
+    "meeting_type": {
+      "type": "string",
+      "enum": [
+        "regular",
+        "special",
+        "emergency",
+        "closed_session",
+        "executive"
+      ],
+      "title": "Meeting Type",
+      "default": "regular"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "scheduled_start",
+    "location"
+  ],
+  "title": "MeetingInput"
+}
+
+
MeetingLink
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 200,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    },
+    "relation": {
+      "type": "string",
+      "enum": [
+        "hearing",
+        "context",
+        "precedent"
+      ],
+      "title": "Relation"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256",
+    "relation"
+  ],
+  "title": "MeetingLink"
+}
+
+
MeetingSearch
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "MeetingSearch"
+}
+
+
MeetingStageInput
+{
+  "properties": {
+    "to_status": {
+      "type": "string",
+      "enum": [
+        "SCHEDULED",
+        "NOTICED",
+        "PACKET_POSTED",
+        "IN_PROGRESS",
+        "RECESSED",
+        "ADJOURNED",
+        "TRANSCRIPT_READY",
+        "MINUTES_DRAFTED",
+        "MINUTES_POSTED",
+        "MINUTES_ADOPTED",
+        "MINUTES_SIGNED",
+        "ARCHIVED",
+        "CANCELLED"
+      ],
+      "title": "To Status"
+    },
+    "statutory_basis": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Basis"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "to_status"
+  ],
+  "title": "MeetingStageInput"
+}
+
+
MeetingsSearch
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "MeetingsSearch"
+}
+
+
MeetingsSourceSelection
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 200,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "MeetingsSourceSelection"
+}
+
+
MessageCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-message",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/MessagePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "MessageCommand"
+}
+
+
MessageCreate
+{
+  "properties": {
+    "message_text": {
+      "type": "string",
+      "title": "Message Text"
+    },
+    "is_internal": {
+      "type": "boolean",
+      "title": "Is Internal",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "message_text"
+  ],
+  "title": "MessageCreate"
+}
+
+
MessagePayload
+{
+  "properties": {
+    "requestMessageBody": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestmessagebody"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requestMessageBody"
+  ],
+  "title": "MessagePayload"
+}
+
+
MessageRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "sender_type": {
+      "type": "string",
+      "title": "Sender Type"
+    },
+    "sender_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sender Id"
+    },
+    "message_text": {
+      "type": "string",
+      "title": "Message Text"
+    },
+    "is_internal": {
+      "type": "boolean",
+      "title": "Is Internal"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "sender_type",
+    "sender_id",
+    "message_text",
+    "is_internal",
+    "created_at"
+  ],
+  "title": "MessageRead"
+}
+
+
MessageView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "author": {
+      "type": "string",
+      "title": "Author"
+    },
+    "author_role": {
+      "type": "string",
+      "title": "Author Role"
+    },
+    "body": {
+      "type": "string",
+      "title": "Body"
+    },
+    "visibility": {
+      "type": "string",
+      "title": "Visibility"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "author",
+    "author_role",
+    "body",
+    "visibility",
+    "created_at_unix_seconds"
+  ],
+  "title": "MessageView"
+}
+
+
Milestone
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "due_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Due On"
+    },
+    "completed_on": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Completed On"
+    },
+    "evidence": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Evidence",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "due_on"
+  ],
+  "title": "Milestone"
+}
+
+
MinutesDecision
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "post",
+        "adopt",
+        "sign"
+      ],
+      "title": "Action"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "MinutesDecision"
+}
+
+
ModelRegistryCreate
+{
+  "properties": {
+    "model_name": {
+      "type": "string",
+      "title": "Model Name"
+    },
+    "model_version": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Version"
+    },
+    "parameter_count": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parameter Count"
+    },
+    "license": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "License"
+    },
+    "model_card_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Card Url"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active",
+      "default": false
+    },
+    "context_window_size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Context Window Size"
+    },
+    "supports_ner": {
+      "type": "boolean",
+      "title": "Supports Ner",
+      "default": false
+    },
+    "supports_vision": {
+      "type": "boolean",
+      "title": "Supports Vision",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "model_name"
+  ],
+  "title": "ModelRegistryCreate",
+  "description": "Schema for creating a new model_registry record (POST body)."
+}
+
+
ModelRegistryRead
+{
+  "properties": {
+    "id": {
+      "type": "integer",
+      "title": "Id"
+    },
+    "model_name": {
+      "type": "string",
+      "title": "Model Name"
+    },
+    "model_version": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Version"
+    },
+    "parameter_count": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parameter Count"
+    },
+    "license": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "License"
+    },
+    "model_card_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Card Url"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "added_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Added At"
+    },
+    "context_window_size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Context Window Size"
+    },
+    "supports_ner": {
+      "type": "boolean",
+      "title": "Supports Ner"
+    },
+    "supports_vision": {
+      "type": "boolean",
+      "title": "Supports Vision"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "model_name",
+    "is_active",
+    "supports_ner",
+    "supports_vision"
+  ],
+  "title": "ModelRegistryRead",
+  "description": "Schema for returning a model_registry record (GET response).\n\n``from_attributes=True`` allows construction directly from an ORM instance."
+}
+
+
ModelRegistryUpdate
+{
+  "properties": {
+    "model_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Name"
+    },
+    "model_version": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Version"
+    },
+    "parameter_count": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parameter Count"
+    },
+    "license": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "License"
+    },
+    "model_card_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Card Url"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    },
+    "context_window_size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Context Window Size"
+    },
+    "supports_ner": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supports Ner"
+    },
+    "supports_vision": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supports Vision"
+    }
+  },
+  "type": "object",
+  "title": "ModelRegistryUpdate",
+  "description": "Schema for partially updating a model_registry record (PATCH body).\n\nEvery field is optional so callers can send only the fields they want to\nchange."
+}
+
+
MotionCorrection
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "reason": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Reason"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text",
+    "reason"
+  ],
+  "title": "MotionCorrection"
+}
+
+
MotionInput
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "seconded_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "minLength": 1
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Seconded By"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text"
+  ],
+  "title": "MotionInput"
+}
+
+
NativePayload
+{
+  "properties": {},
+  "additionalProperties": false,
+  "type": "object",
+  "title": "NativePayload"
+}
+
+
NativeRequestRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "requester_name": {
+      "type": "string",
+      "title": "Requester Name"
+    },
+    "requester_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Email"
+    },
+    "requester_phone": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Phone"
+    },
+    "requester_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Type"
+    },
+    "date_received": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Date Received"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "status": {
+      "$ref": "#/components/schemas/RequestStatus"
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "created_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "response_draft": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Response Draft"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    },
+    "estimated_fee": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Estimated Fee"
+    },
+    "fee_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Status"
+    },
+    "fee_waiver_requested": {
+      "type": "boolean",
+      "title": "Fee Waiver Requested",
+      "default": false
+    },
+    "priority": {
+      "type": "string",
+      "title": "Priority",
+      "default": "normal"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    },
+    "closed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closed At"
+    },
+    "closure_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closure Reason"
+    },
+    "desktop_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Desktop Id"
+    },
+    "public_tracking_number": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Public Tracking Number"
+    },
+    "submitted_via": {
+      "type": "string",
+      "title": "Submitted Via"
+    },
+    "deadline_label": {
+      "type": "string",
+      "title": "Deadline Label"
+    },
+    "deadline_basis": {
+      "type": "string",
+      "title": "Deadline Basis"
+    },
+    "deadline_reviewed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Deadline Reviewed At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "requester_name",
+    "requester_email",
+    "date_received",
+    "statutory_deadline",
+    "description",
+    "status",
+    "assigned_to",
+    "created_by",
+    "created_at",
+    "response_draft",
+    "review_notes",
+    "desktop_id",
+    "public_tracking_number",
+    "submitted_via",
+    "deadline_label",
+    "deadline_basis",
+    "deadline_reviewed_at"
+  ],
+  "title": "NativeRequestRead"
+}
+
+
NoticeDocumentInput
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text"
+  ],
+  "title": "NoticeDocumentInput"
+}
+
+
NoticeDraft
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 100000,
+      "minLength": 1,
+      "title": "Body"
+    },
+    "notice_type": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Notice Type"
+    },
+    "statutory_basis": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Statutory Basis"
+    },
+    "event_date": {
+      "type": "string",
+      "format": "date",
+      "title": "Event Date"
+    },
+    "lead_days": {
+      "type": "integer",
+      "maximum": 365.0,
+      "minimum": 0.0,
+      "title": "Lead Days"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "body",
+    "notice_type",
+    "statutory_basis",
+    "event_date",
+    "lead_days"
+  ],
+  "title": "NoticeDraft"
+}
+
+
NoticeInput
+{
+  "properties": {
+    "notice_type": {
+      "type": "string",
+      "enum": [
+        "regular",
+        "special",
+        "emergency",
+        "closed_session",
+        "executive"
+      ],
+      "title": "Notice Type"
+    },
+    "posted_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Posted At"
+    },
+    "minimum_notice_hours": {
+      "type": "integer",
+      "minimum": 0.0,
+      "title": "Minimum Notice Hours"
+    },
+    "statutory_basis": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Basis"
+    },
+    "approved_by": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Approved By"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "notice_type",
+    "posted_at",
+    "minimum_notice_hours"
+  ],
+  "title": "NoticeInput"
+}
+
+
NoticeProofInput
+{
+  "properties": {
+    "location": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Location"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note",
+      "default": ""
+    },
+    "document_delivery_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Document Delivery Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "location"
+  ],
+  "title": "NoticeProofInput"
+}
+
+
NotificationLogRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "template_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Template Id"
+    },
+    "recipient_email": {
+      "type": "string",
+      "title": "Recipient Email"
+    },
+    "request_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Request Id"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "sent_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sent At"
+    },
+    "error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Message"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "template_id",
+    "recipient_email",
+    "request_id",
+    "channel",
+    "status",
+    "sent_at",
+    "error_message",
+    "created_at"
+  ],
+  "title": "NotificationLogRead"
+}
+
+
NotificationTemplateCreate
+{
+  "properties": {
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel",
+      "default": "email"
+    },
+    "subject_template": {
+      "type": "string",
+      "title": "Subject Template"
+    },
+    "body_template": {
+      "type": "string",
+      "title": "Body Template"
+    }
+  },
+  "type": "object",
+  "required": [
+    "event_type",
+    "subject_template",
+    "body_template"
+  ],
+  "title": "NotificationTemplateCreate"
+}
+
+
NotificationTemplateRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel"
+    },
+    "subject_template": {
+      "type": "string",
+      "title": "Subject Template"
+    },
+    "body_template": {
+      "type": "string",
+      "title": "Body Template"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "event_type",
+    "channel",
+    "subject_template",
+    "body_template",
+    "is_active",
+    "created_at"
+  ],
+  "title": "NotificationTemplateRead"
+}
+
+
NotificationTemplateUpdate
+{
+  "properties": {
+    "subject_template": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Subject Template"
+    },
+    "body_template": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Body Template"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "NotificationTemplateUpdate"
+}
+
+
NotificationView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "notification_id": {
+      "type": "string",
+      "title": "Notification Id"
+    },
+    "module_id": {
+      "type": "string",
+      "title": "Module Id"
+    },
+    "record_id": {
+      "type": "string",
+      "title": "Record Id"
+    },
+    "audience": {
+      "type": "string",
+      "title": "Audience"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel"
+    },
+    "subject": {
+      "type": "string",
+      "title": "Subject"
+    },
+    "body": {
+      "type": "string",
+      "title": "Body"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    },
+    "sent_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sent At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "notification_id",
+    "module_id",
+    "record_id",
+    "audience",
+    "channel",
+    "subject",
+    "body",
+    "status",
+    "created_at_unix_seconds",
+    "sent_at_unix_seconds"
+  ],
+  "title": "NotificationView"
+}
+
+
OllamaModelInfo
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Size"
+    },
+    "details": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Details"
+    }
+  },
+  "type": "object",
+  "required": [
+    "name"
+  ],
+  "title": "OllamaModelInfo"
+}
+
+
OllamaStatus
+{
+  "properties": {
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "models": {
+      "items": {
+        "$ref": "#/components/schemas/OllamaModelInfo"
+      },
+      "type": "array",
+      "title": "Models"
+    }
+  },
+  "type": "object",
+  "required": [
+    "status",
+    "models"
+  ],
+  "title": "OllamaStatus"
+}
+
+
OperationalMetrics
+{
+  "properties": {
+    "average_response_time_days": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Average Response Time Days"
+    },
+    "median_response_time_days": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Median Response Time Days"
+    },
+    "requests_by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "Requests By Status"
+    },
+    "requests_by_department": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "Requests By Department"
+    },
+    "deadline_compliance_rate": {
+      "type": "number",
+      "title": "Deadline Compliance Rate"
+    },
+    "total_open": {
+      "type": "integer",
+      "title": "Total Open"
+    },
+    "total_closed": {
+      "type": "integer",
+      "title": "Total Closed"
+    },
+    "total_overdue": {
+      "type": "integer",
+      "title": "Total Overdue"
+    },
+    "clarification_frequency": {
+      "type": "number",
+      "title": "Clarification Frequency"
+    },
+    "top_request_topics": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Top Request Topics"
+    }
+  },
+  "type": "object",
+  "required": [
+    "average_response_time_days",
+    "median_response_time_days",
+    "requests_by_status",
+    "requests_by_department",
+    "deadline_compliance_rate",
+    "total_open",
+    "total_closed",
+    "total_overdue",
+    "clarification_frequency",
+    "top_request_topics"
+  ],
+  "title": "OperationalMetrics"
+}
+
+
Outline
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "question_ids": {
+      "items": {
+        "type": "string",
+        "format": "uuid"
+      },
+      "type": "array",
+      "maxItems": 50,
+      "minItems": 1,
+      "title": "Question Ids"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "question_ids"
+  ],
+  "title": "Outline"
+}
+
+
Packet
+{
+  "properties": {
+    "expected_revision": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Expected Revision"
+    },
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "staff_only",
+        "records_copy"
+      ],
+      "title": "Visibility"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "expected_revision",
+    "visibility"
+  ],
+  "title": "Packet"
+}
+
+
PacketInput
+{
+  "properties": {
+    "agenda_item_ids": {
+      "items": {
+        "type": "string",
+        "format": "uuid"
+      },
+      "type": "array",
+      "title": "Agenda Item Ids"
+    },
+    "source_files": {
+      "items": {
+        "$ref": "#/components/schemas/ManagedSource"
+      },
+      "type": "array",
+      "title": "Source Files"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "agenda_item_ids"
+  ],
+  "title": "PacketInput"
+}
+
+
Pathway
+{
+  "properties": {
+    "project_type": {
+      "type": "string",
+      "maxLength": 120,
+      "minLength": 1,
+      "title": "Project Type"
+    },
+    "proposal": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Proposal",
+      "default": ""
+    },
+    "location_context": {
+      "type": "string",
+      "maxLength": 1000,
+      "title": "Location Context",
+      "default": ""
+    },
+    "requirement_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requirement Revision"
+    },
+    "fee_link": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "project_type"
+  ],
+  "title": "Pathway"
+}
+
+
PathwayStep
+{
+  "properties": {
+    "step": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Step"
+    },
+    "citation": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Citation"
+    },
+    "typical_time": {
+      "type": "string",
+      "maxLength": 1000,
+      "title": "Typical Time",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "step",
+    "citation"
+  ],
+  "title": "PathwayStep"
+}
+
+
PlainLanguageSummaryCreate
+{
+  "properties": {
+    "summary_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Summary Id"
+    },
+    "section_version_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Version Id"
+    },
+    "summary_text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Summary Text"
+    },
+    "language_code": {
+      "type": "string",
+      "title": "Language Code",
+      "default": "en"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "section_version_id",
+    "summary_text"
+  ],
+  "title": "PlainLanguageSummaryCreate",
+  "description": "Request body for staff-drafted plain-language summaries."
+}
+
+
PolicySelection
+{
+  "properties": {
+    "plan_id": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Plan Id"
+    },
+    "revision_id": {
+      "type": "string",
+      "maxLength": 36,
+      "minLength": 36,
+      "title": "Revision Id"
+    },
+    "policy_id": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Policy Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "plan_id",
+    "revision_id",
+    "policy_id"
+  ],
+  "title": "PolicySelection"
+}
+
+
PortalModeResponse
+{
+  "properties": {
+    "mode": {
+      "type": "string",
+      "enum": [
+        "public",
+        "private"
+      ],
+      "title": "Mode",
+      "description": "Active portal posture for this deployment. ``public`` = minimal resident surface (landing + authenticated records-request submission + resident registration) reachable without staff auth. ``private`` = staff-only; no public routes, no resident self-registration."
+    }
+  },
+  "type": "object",
+  "required": [
+    "mode"
+  ],
+  "title": "PortalModeResponse",
+  "description": "T5D — schema for ``GET /config/portal-mode``.\n\nExposed to the frontend on boot so it can branch routing without a\nuser-identity lookup. The payload is intentionally the single field\nbelow — no staff config, no user state, no schema version."
+}
+
+
PrepareArtifact
+{
+  "properties": {
+    "kind": {
+      "type": "string",
+      "enum": [
+        "response",
+        "release-package"
+      ],
+      "title": "Kind"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "kind"
+  ],
+  "title": "PrepareArtifact"
+}
+
+
Proof
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    },
+    "filename": {
+      "type": "string",
+      "maxLength": 150,
+      "minLength": 1,
+      "title": "Filename"
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 7000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "location": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Location"
+    },
+    "published_at": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Published At"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence",
+    "filename",
+    "content_base64",
+    "location",
+    "published_at"
+  ],
+  "title": "Proof"
+}
+
+
Proposal
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "pattern": "^[A-Za-z0-9_-]{1,64}$",
+      "title": "Id"
+    },
+    "version_id": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Version Id"
+    },
+    "meeting_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Meeting Id"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "ordinance_number": {
+      "type": "string",
+      "maxLength": 120,
+      "minLength": 1,
+      "title": "Ordinance Number"
+    },
+    "proposed_text": {
+      "type": "string",
+      "maxLength": 1000000,
+      "minLength": 1,
+      "title": "Proposed Text"
+    },
+    "supersedes_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^[A-Za-z0-9_-]{1,64}$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supersedes Id"
+    },
+    "reconciliation_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reconciliation Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "version_id",
+    "meeting_id",
+    "title",
+    "ordinance_number",
+    "proposed_text"
+  ],
+  "title": "Proposal"
+}
+
+
PublicExplore
+{
+  "properties": {
+    "goal": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Goal",
+      "default": ""
+    },
+    "topic": {
+      "type": "string",
+      "maxLength": 160,
+      "title": "Topic",
+      "default": ""
+    },
+    "neighborhood": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Neighborhood",
+      "default": ""
+    },
+    "plan_type": {
+      "type": "string",
+      "maxLength": 120,
+      "title": "Plan Type",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "PublicExplore"
+}
+
+
PublicIntake
+{
+  "properties": {
+    "requester": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requester"
+    },
+    "requesterContact": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestercontact"
+    },
+    "summary": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Summary"
+    },
+    "deadline": {
+      "type": "string",
+      "title": "Deadline",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requester",
+    "requesterContact",
+    "summary"
+  ],
+  "title": "PublicIntake"
+}
+
+
PublicLookup
+{
+  "properties": {
+    "trackingNumber": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Trackingnumber"
+    },
+    "requesterContact": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestercontact"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "trackingNumber",
+    "requesterContact"
+  ],
+  "title": "PublicLookup"
+}
+
+
PublicMessage
+{
+  "properties": {
+    "trackingNumber": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Trackingnumber"
+    },
+    "requesterContact": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestercontact"
+    },
+    "publicRequestMessage": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Publicrequestmessage"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "trackingNumber",
+    "requesterContact",
+    "publicRequestMessage"
+  ],
+  "title": "PublicMessage"
+}
+
+
PublicStatusView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "label": {
+      "type": "string",
+      "title": "Label"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "label",
+    "summary",
+    "status",
+    "created_at_unix_seconds"
+  ],
+  "title": "PublicStatusView"
+}
+
+
PublicationView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "source_module": {
+      "type": "string",
+      "title": "Source Module"
+    },
+    "source_record_id": {
+      "type": "string",
+      "title": "Source Record Id"
+    },
+    "record_type": {
+      "type": "string",
+      "title": "Record Type"
+    },
+    "public_payload": {
+      "type": "string",
+      "title": "Public Payload"
+    },
+    "payload_hash": {
+      "type": "string",
+      "title": "Payload Hash"
+    },
+    "published_at_unix_seconds": {
+      "type": "integer",
+      "title": "Published At Unix Seconds"
+    },
+    "retracted_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Retracted At Unix Seconds"
+    },
+    "retracted_by": {
+      "type": "string",
+      "title": "Retracted By",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "source_module",
+    "source_record_id",
+    "record_type",
+    "public_payload",
+    "payload_hash",
+    "published_at_unix_seconds"
+  ],
+  "title": "PublicationView"
+}
+
+
PublishingPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "publishing-workflow",
+      "title": "Action"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "hasReview": {
+      "type": "boolean",
+      "title": "Hasreview",
+      "default": false
+    },
+    "hasPlainLanguage": {
+      "type": "boolean",
+      "title": "Hasplainlanguage",
+      "default": false
+    },
+    "hasTranslationReview": {
+      "type": "boolean",
+      "title": "Hastranslationreview",
+      "default": false
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "PublishingPlan"
+}
+
+
Question
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    },
+    "question": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Question"
+    },
+    "kind": {
+      "type": "string",
+      "enum": [
+        "use",
+        "dimension"
+      ],
+      "title": "Kind"
+    },
+    "key": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Key"
+    },
+    "audience": {
+      "type": "string",
+      "enum": [
+        "resident",
+        "staff"
+      ],
+      "title": "Audience",
+      "default": "resident"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "query",
+    "question",
+    "kind",
+    "key"
+  ],
+  "title": "Question"
+}
+
+
QuestionAnswerRequest
+{
+  "properties": {
+    "question": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Question"
+    },
+    "section_number": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Section Number"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "question"
+  ],
+  "title": "QuestionAnswerRequest",
+  "description": "Request body for citation-grounded code Q&A."
+}
+
+
RecordsDocumentView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "attachment_id": {
+      "type": "string",
+      "title": "Attachment Id"
+    },
+    "title": {
+      "type": "string",
+      "title": "Title"
+    },
+    "original_path": {
+      "type": "string",
+      "title": "Original Path"
+    },
+    "stored_path": {
+      "type": "string",
+      "title": "Stored Path"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation"
+    },
+    "sha256": {
+      "type": "string",
+      "title": "Sha256"
+    },
+    "size_bytes": {
+      "type": "integer",
+      "title": "Size Bytes"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "added_by": {
+      "type": "string",
+      "title": "Added By"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    },
+    "release_original_path": {
+      "type": "string",
+      "title": "Release Original Path",
+      "default": ""
+    },
+    "release_stored_path": {
+      "type": "string",
+      "title": "Release Stored Path",
+      "default": ""
+    },
+    "release_file_name": {
+      "type": "string",
+      "title": "Release File Name",
+      "default": ""
+    },
+    "release_sha256": {
+      "type": "string",
+      "title": "Release Sha256",
+      "default": ""
+    },
+    "release_size_bytes": {
+      "type": "integer",
+      "title": "Release Size Bytes",
+      "default": 0
+    },
+    "release_status": {
+      "type": "string",
+      "title": "Release Status",
+      "default": ""
+    },
+    "release_note": {
+      "type": "string",
+      "title": "Release Note",
+      "default": ""
+    },
+    "release_added_by": {
+      "type": "string",
+      "title": "Release Added By",
+      "default": ""
+    },
+    "release_added_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Release Added At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "attachment_id",
+    "title",
+    "original_path",
+    "stored_path",
+    "citation",
+    "sha256",
+    "size_bytes",
+    "status",
+    "added_by",
+    "created_at_unix_seconds"
+  ],
+  "title": "RecordsDocumentView"
+}
+
+
RecordsOperationRead
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "message": {
+      "type": "string",
+      "title": "Message"
+    },
+    "request": {
+      "$ref": "#/components/schemas/RecordsView"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "message",
+    "request"
+  ],
+  "title": "RecordsOperationRead"
+}
+
+
RecordsStateRead
+{
+  "properties": {
+    "demo_fixture": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Demo Fixture"
+    },
+    "records_requests": {
+      "items": {
+        "$ref": "#/components/schemas/RecordsView"
+      },
+      "type": "array",
+      "title": "Records Requests"
+    },
+    "notification_events": {
+      "items": {
+        "$ref": "#/components/schemas/NotificationView"
+      },
+      "type": "array",
+      "title": "Notification Events"
+    },
+    "publication_events": {
+      "items": {
+        "$ref": "#/components/schemas/PublicationView"
+      },
+      "type": "array",
+      "title": "Publication Events"
+    },
+    "audit_entries": {
+      "items": {
+        "$ref": "#/components/schemas/AuditView"
+      },
+      "type": "array",
+      "title": "Audit Entries"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "records_requests"
+  ],
+  "title": "RecordsStateRead"
+}
+
+
RecordsView
+{
+  "properties": {
+    "request_id": {
+      "type": "string",
+      "title": "Request Id"
+    },
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "public_tracking_number": {
+      "type": "string",
+      "title": "Public Tracking Number"
+    },
+    "requester": {
+      "type": "string",
+      "title": "Requester"
+    },
+    "requester_contact": {
+      "type": "string",
+      "title": "Requester Contact"
+    },
+    "submitted_via": {
+      "type": "string",
+      "title": "Submitted Via"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "deadline": {
+      "type": "string",
+      "title": "Deadline"
+    },
+    "deadline_basis": {
+      "type": "string",
+      "title": "Deadline Basis"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "assigned_to": {
+      "type": "string",
+      "title": "Assigned To"
+    },
+    "clarification_notes": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Clarification Notes"
+    },
+    "search_notes": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Search Notes"
+    },
+    "search_sessions": {
+      "items": {
+        "$ref": "#/components/schemas/SearchReceiptView"
+      },
+      "type": "array",
+      "title": "Search Sessions"
+    },
+    "exemption_reviews": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Exemption Reviews"
+    },
+    "exemption_decisions": {
+      "items": {
+        "$ref": "#/components/schemas/ExemptionDecisionView"
+      },
+      "type": "array",
+      "title": "Exemption Decisions"
+    },
+    "fee_estimate": {
+      "type": "string",
+      "title": "Fee Estimate"
+    },
+    "fee_line_items": {
+      "items": {
+        "$ref": "#/components/schemas/FeeLineView"
+      },
+      "type": "array",
+      "title": "Fee Line Items"
+    },
+    "fee_waiver_reason": {
+      "type": "string",
+      "title": "Fee Waiver Reason"
+    },
+    "citations": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Citations"
+    },
+    "response_draft": {
+      "type": "string",
+      "title": "Response Draft"
+    },
+    "approval_notes": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Approval Notes"
+    },
+    "exports": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Exports"
+    },
+    "documents": {
+      "items": {
+        "$ref": "#/components/schemas/RecordsDocumentView"
+      },
+      "type": "array",
+      "title": "Documents"
+    },
+    "release_packages": {
+      "items": {
+        "$ref": "#/components/schemas/ReleasePackageView"
+      },
+      "type": "array",
+      "title": "Release Packages"
+    },
+    "timeline": {
+      "items": {
+        "$ref": "#/components/schemas/TimelineView"
+      },
+      "type": "array",
+      "title": "Timeline"
+    },
+    "public_status_events": {
+      "items": {
+        "$ref": "#/components/schemas/PublicStatusView"
+      },
+      "type": "array",
+      "title": "Public Status Events"
+    },
+    "messages": {
+      "items": {
+        "$ref": "#/components/schemas/MessageView"
+      },
+      "type": "array",
+      "title": "Messages"
+    },
+    "deadline_reviewed_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Deadline Reviewed At Unix Seconds"
+    },
+    "approved_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Approved At Unix Seconds"
+    },
+    "fulfilled_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fulfilled At Unix Seconds"
+    },
+    "closed_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closed At Unix Seconds"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "request_id",
+    "id",
+    "public_tracking_number",
+    "requester",
+    "requester_contact",
+    "submitted_via",
+    "summary",
+    "deadline",
+    "deadline_basis",
+    "status",
+    "assigned_to",
+    "clarification_notes",
+    "search_notes",
+    "search_sessions",
+    "exemption_reviews",
+    "exemption_decisions",
+    "fee_estimate",
+    "fee_line_items",
+    "fee_waiver_reason",
+    "citations",
+    "response_draft",
+    "approval_notes",
+    "exports",
+    "timeline",
+    "public_status_events",
+    "messages",
+    "deadline_reviewed_at_unix_seconds",
+    "approved_at_unix_seconds",
+    "fulfilled_at_unix_seconds",
+    "closed_at_unix_seconds",
+    "created_at_unix_seconds"
+  ],
+  "title": "RecordsView"
+}
+
+
ReleasePackageView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "export_path": {
+      "type": "string",
+      "title": "Export Path"
+    },
+    "package_hash": {
+      "type": "string",
+      "title": "Package Hash"
+    },
+    "document_count": {
+      "type": "integer",
+      "title": "Document Count"
+    },
+    "release_artifact_count": {
+      "type": "integer",
+      "title": "Release Artifact Count"
+    },
+    "search_session_count": {
+      "type": "integer",
+      "title": "Search Session Count"
+    },
+    "release_count": {
+      "type": "integer",
+      "title": "Release Count"
+    },
+    "redacted_count": {
+      "type": "integer",
+      "title": "Redacted Count"
+    },
+    "exempt_count": {
+      "type": "integer",
+      "title": "Exempt Count"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "export_path",
+    "package_hash",
+    "document_count",
+    "release_artifact_count",
+    "search_session_count",
+    "release_count",
+    "redacted_count",
+    "exempt_count",
+    "created_at_unix_seconds"
+  ],
+  "title": "ReleasePackageView"
+}
+
+
RepeatLookup
+{
+  "properties": {
+    "property_reference": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Property Reference"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "property_reference"
+  ],
+  "title": "RepeatLookup"
+}
+
+
RequestCreate
+{
+  "properties": {
+    "requester_name": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Requester Name"
+    },
+    "requester_email": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 255
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Email"
+    },
+    "requester_phone": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 50
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Phone"
+    },
+    "requester_type": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 100
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Type"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Description"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "priority": {
+      "type": "string",
+      "title": "Priority",
+      "default": "normal"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^(narrow|moderate|broad)$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "requester_name",
+    "description"
+  ],
+  "title": "RequestCreate"
+}
+
+
RequestDocumentAdd
+{
+  "properties": {
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "relevance_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Relevance Note"
+    }
+  },
+  "type": "object",
+  "required": [
+    "document_id"
+  ],
+  "title": "RequestDocumentAdd"
+}
+
+
RequestDocumentRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "relevance_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Relevance Note"
+    },
+    "exemption_flags": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Exemption Flags"
+    },
+    "inclusion_status": {
+      "$ref": "#/components/schemas/InclusionStatus"
+    },
+    "attached_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Attached At"
+    },
+    "attached_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Attached By"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "document_id",
+    "relevance_note",
+    "exemption_flags",
+    "inclusion_status",
+    "attached_at",
+    "attached_by"
+  ],
+  "title": "RequestDocumentRead"
+}
+
+
RequestRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "requester_name": {
+      "type": "string",
+      "title": "Requester Name"
+    },
+    "requester_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Email"
+    },
+    "requester_phone": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Phone"
+    },
+    "requester_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Type"
+    },
+    "date_received": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Date Received"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "status": {
+      "$ref": "#/components/schemas/RequestStatus"
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "created_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "response_draft": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Response Draft"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    },
+    "estimated_fee": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Estimated Fee"
+    },
+    "fee_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Status"
+    },
+    "fee_waiver_requested": {
+      "type": "boolean",
+      "title": "Fee Waiver Requested",
+      "default": false
+    },
+    "priority": {
+      "type": "string",
+      "title": "Priority",
+      "default": "normal"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    },
+    "closed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closed At"
+    },
+    "closure_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closure Reason"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "requester_name",
+    "requester_email",
+    "date_received",
+    "statutory_deadline",
+    "description",
+    "status",
+    "assigned_to",
+    "created_by",
+    "created_at",
+    "response_draft",
+    "review_notes"
+  ],
+  "title": "RequestRead"
+}
+
+
RequestStats
+{
+  "properties": {
+    "total_requests": {
+      "type": "integer",
+      "title": "Total Requests"
+    },
+    "by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "By Status"
+    },
+    "approaching_deadline": {
+      "type": "integer",
+      "title": "Approaching Deadline"
+    },
+    "overdue": {
+      "type": "integer",
+      "title": "Overdue"
+    }
+  },
+  "type": "object",
+  "required": [
+    "total_requests",
+    "by_status",
+    "approaching_deadline",
+    "overdue"
+  ],
+  "title": "RequestStats"
+}
+
+
RequestStatus
+{
+  "type": "string",
+  "enum": [
+    "received",
+    "clarification_needed",
+    "assigned",
+    "searching",
+    "in_review",
+    "ready_for_release",
+    "drafted",
+    "approved",
+    "fulfilled",
+    "closed"
+  ],
+  "title": "RequestStatus"
+}
+
+
RequestUpdate
+{
+  "properties": {
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/RequestStatus"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "response_draft": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Response Draft"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    }
+  },
+  "type": "object",
+  "title": "RequestUpdate"
+}
+
+
RequirementBundle
+{
+  "properties": {
+    "requirement_id": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9_-]{1,100}$",
+      "title": "Requirement Id"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "project_type": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Project Type"
+    },
+    "source_reference": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Source Reference"
+    },
+    "source_date": {
+      "type": "string",
+      "format": "date",
+      "title": "Source Date"
+    },
+    "effective_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Effective On"
+    },
+    "dataset_kind": {
+      "type": "string",
+      "enum": [
+        "municipal",
+        "fictional"
+      ],
+      "title": "Dataset Kind"
+    },
+    "filename": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$",
+      "title": "Filename"
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 14000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Sha256"
+    },
+    "materials": {
+      "items": {
+        "$ref": "#/components/schemas/Material"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "minItems": 1,
+      "title": "Materials"
+    },
+    "pathway": {
+      "items": {
+        "$ref": "#/components/schemas/PathwayStep"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "title": "Pathway"
+    },
+    "fee_link": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    },
+    "staff_note": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Staff Note",
+      "default": ""
+    },
+    "change_note": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Change Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requirement_id",
+    "title",
+    "jurisdiction",
+    "project_type",
+    "source_reference",
+    "source_date",
+    "effective_on",
+    "dataset_kind",
+    "filename",
+    "content_base64",
+    "sha256",
+    "materials",
+    "change_note"
+  ],
+  "title": "RequirementBundle"
+}
+
+
ResponseLetterCreate
+{
+  "properties": {
+    "template_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Template Id"
+    }
+  },
+  "type": "object",
+  "title": "ResponseLetterCreate"
+}
+
+
ResponseLetterRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "template_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Template Id"
+    },
+    "generated_content": {
+      "type": "string",
+      "title": "Generated Content"
+    },
+    "edited_content": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Edited Content"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "generated_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Generated By"
+    },
+    "approved_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Approved By"
+    },
+    "sent_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sent At"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "template_id",
+    "generated_content",
+    "edited_content",
+    "status",
+    "generated_by",
+    "approved_by",
+    "sent_at",
+    "created_at"
+  ],
+  "title": "ResponseLetterRead"
+}
+
+
ResponseLetterUpdate
+{
+  "properties": {
+    "edited_content": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Edited Content"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Status"
+    }
+  },
+  "type": "object",
+  "title": "ResponseLetterUpdate"
+}
+
+
ReviewInput
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 5000,
+      "title": "Body",
+      "default": ""
+    },
+    "hasAltText": {
+      "type": "boolean",
+      "title": "Hasalttext",
+      "default": false
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": "en"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "ReviewInput"
+}
+
+
Revision
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    },
+    "document": {
+      "$ref": "#/components/schemas/NoticeDraft"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence",
+    "document"
+  ],
+  "title": "Revision"
+}
+
+
RewriteInput
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "plain-language",
+        "language-variant"
+      ],
+      "title": "Action"
+    },
+    "text": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Text"
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "text"
+  ],
+  "title": "RewriteInput"
+}
+
+
RewriteResult
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "plain-language",
+        "language-variant"
+      ],
+      "title": "Action"
+    },
+    "text": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Text"
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": ""
+    },
+    "outcome": {
+      "type": "string",
+      "enum": [
+        "generated",
+        "unavailable"
+      ],
+      "title": "Outcome"
+    },
+    "generated": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 100000
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Generated"
+    },
+    "model": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 200
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "text",
+    "outcome"
+  ],
+  "title": "RewriteResult"
+}
+
+
Rule
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "zone_code": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Zone Code"
+    },
+    "key": {
+      "type": "string",
+      "maxLength": 120,
+      "minLength": 1,
+      "title": "Key"
+    },
+    "section_number": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Section Number"
+    },
+    "kind": {
+      "type": "string",
+      "enum": [
+        "use",
+        "dimension"
+      ],
+      "title": "Kind"
+    },
+    "value": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Value"
+    },
+    "overlay_code": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 255
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Overlay Code"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "zone_code",
+    "key",
+    "section_number",
+    "kind",
+    "value"
+  ],
+  "title": "Rule"
+}
+
+
RuleTestMatch
+{
+  "properties": {
+    "matched_text": {
+      "type": "string",
+      "title": "Matched Text"
+    },
+    "start": {
+      "type": "integer",
+      "title": "Start"
+    },
+    "end": {
+      "type": "integer",
+      "title": "End"
+    }
+  },
+  "type": "object",
+  "required": [
+    "matched_text",
+    "start",
+    "end"
+  ],
+  "title": "RuleTestMatch"
+}
+
+
RuleTestRequest
+{
+  "properties": {
+    "sample_text": {
+      "type": "string",
+      "title": "Sample Text"
+    }
+  },
+  "type": "object",
+  "required": [
+    "sample_text"
+  ],
+  "title": "RuleTestRequest"
+}
+
+
RuleTestResponse
+{
+  "properties": {
+    "rule_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Rule Id"
+    },
+    "rule_type": {
+      "type": "string",
+      "title": "Rule Type"
+    },
+    "matched": {
+      "type": "boolean",
+      "title": "Matched"
+    },
+    "matches": {
+      "items": {
+        "$ref": "#/components/schemas/RuleTestMatch"
+      },
+      "type": "array",
+      "title": "Matches"
+    }
+  },
+  "type": "object",
+  "required": [
+    "rule_id",
+    "rule_type",
+    "matched",
+    "matches"
+  ],
+  "title": "RuleTestResponse"
+}
+
+
RuleType
+{
+  "type": "string",
+  "enum": [
+    "regex",
+    "keyword",
+    "llm_prompt"
+  ],
+  "title": "RuleType"
+}
+
+
SaveReview
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 5000,
+      "title": "Body",
+      "default": ""
+    },
+    "hasAltText": {
+      "type": "boolean",
+      "title": "Hasalttext",
+      "default": false
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": "en"
+    },
+    "ai_analysis": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 100000
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ai Analysis"
+    },
+    "ai_analysis_model": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 200
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ai Analysis Model"
+    },
+    "ai_outcome": {
+      "type": "string",
+      "enum": [
+        "generated",
+        "unavailable",
+        "failed"
+      ],
+      "title": "Ai Outcome"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "ai_outcome"
+  ],
+  "title": "SaveReview"
+}
+
+
SearchFilterOptions
+{
+  "properties": {
+    "file_types": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "File Types"
+    },
+    "source_names": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Source Names"
+    },
+    "departments": {
+      "items": {
+        "additionalProperties": true,
+        "type": "object"
+      },
+      "type": "array",
+      "title": "Departments",
+      "default": []
+    },
+    "date_range": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Date Range"
+    }
+  },
+  "type": "object",
+  "required": [
+    "file_types",
+    "source_names"
+  ],
+  "title": "SearchFilterOptions"
+}
+
+
SearchInput
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "SearchInput"
+}
+
+
SearchNoteCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "record-records-search",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/SearchNotePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "SearchNoteCommand"
+}
+
+
SearchNotePayload
+{
+  "properties": {
+    "sourceNote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Sourcenote"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sourceNote"
+  ],
+  "title": "SearchNotePayload"
+}
+
+
SearchReceiptCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "record-records-search-session",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/SearchReceiptPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "SearchReceiptCommand"
+}
+
+
SearchReceiptPayload
+{
+  "properties": {
+    "searchQuery": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchquery"
+    },
+    "searchLocations": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchlocations"
+    },
+    "searchResultTitle": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchresulttitle"
+    },
+    "searchResultCitation": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchresultcitation"
+    },
+    "searchResultSummary": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchresultsummary"
+    },
+    "searchResultStatus": {
+      "type": "string",
+      "title": "Searchresultstatus",
+      "default": ""
+    },
+    "searchReviewer": {
+      "type": "string",
+      "title": "Searchreviewer",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "searchQuery",
+    "searchLocations",
+    "searchResultTitle",
+    "searchResultCitation",
+    "searchResultSummary"
+  ],
+  "title": "SearchReceiptPayload"
+}
+
+
SearchReceiptView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "query": {
+      "type": "string",
+      "title": "Query"
+    },
+    "locations": {
+      "type": "string",
+      "title": "Locations"
+    },
+    "reviewer": {
+      "type": "string",
+      "title": "Reviewer"
+    },
+    "results": {
+      "items": {
+        "$ref": "#/components/schemas/SearchResultView"
+      },
+      "type": "array",
+      "title": "Results"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "query",
+    "locations",
+    "reviewer",
+    "results",
+    "created_at_unix_seconds"
+  ],
+  "title": "SearchReceiptView"
+}
+
+
SearchRequest
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "title": "Query"
+    },
+    "session_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Session Id"
+    },
+    "filters": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Filters"
+    },
+    "limit": {
+      "type": "integer",
+      "maximum": 50.0,
+      "title": "Limit",
+      "default": 10
+    },
+    "synthesize": {
+      "type": "boolean",
+      "title": "Synthesize",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "SearchRequest"
+}
+
+
SearchResponse
+{
+  "properties": {
+    "query_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Query Id"
+    },
+    "session_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Session Id"
+    },
+    "query_text": {
+      "type": "string",
+      "title": "Query Text"
+    },
+    "results": {
+      "items": {
+        "$ref": "#/components/schemas/SearchResultItem"
+      },
+      "type": "array",
+      "title": "Results"
+    },
+    "results_count": {
+      "type": "integer",
+      "title": "Results Count"
+    },
+    "synthesized_answer": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Synthesized Answer"
+    },
+    "ai_generated": {
+      "type": "boolean",
+      "title": "Ai Generated",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "query_id",
+    "session_id",
+    "query_text",
+    "results",
+    "results_count"
+  ],
+  "title": "SearchResponse"
+}
+
+
SearchResultItem
+{
+  "properties": {
+    "chunk_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Chunk Id"
+    },
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "filename": {
+      "type": "string",
+      "title": "Filename"
+    },
+    "file_type": {
+      "type": "string",
+      "title": "File Type"
+    },
+    "source_path": {
+      "type": "string",
+      "title": "Source Path"
+    },
+    "page_number": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Page Number"
+    },
+    "content_text": {
+      "type": "string",
+      "title": "Content Text"
+    },
+    "similarity_score": {
+      "type": "number",
+      "title": "Similarity Score"
+    },
+    "rank": {
+      "type": "integer",
+      "title": "Rank"
+    }
+  },
+  "type": "object",
+  "required": [
+    "chunk_id",
+    "document_id",
+    "filename",
+    "file_type",
+    "source_path",
+    "page_number",
+    "content_text",
+    "similarity_score",
+    "rank"
+  ],
+  "title": "SearchResultItem"
+}
+
+
SearchResultView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "title": {
+      "type": "string",
+      "title": "Title"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "title",
+    "citation",
+    "summary",
+    "status"
+  ],
+  "title": "SearchResultView"
+}
+
+
SearchSessionRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "user_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "User Id"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "queries": {
+      "items": {
+        "additionalProperties": true,
+        "type": "object"
+      },
+      "type": "array",
+      "title": "Queries",
+      "default": []
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "user_id",
+    "created_at"
+  ],
+  "title": "SearchSessionRead"
+}
+
+
SectionCreate
+{
+  "properties": {
+    "section_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Section Id"
+    },
+    "chapter_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Chapter Id"
+    },
+    "section_number": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Number"
+    },
+    "section_heading": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Heading"
+    },
+    "parent_section_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parent Section Id"
+    },
+    "sort_order": {
+      "type": "integer",
+      "title": "Sort Order",
+      "default": 0
+    },
+    "administrative_regulation_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Administrative Regulation Refs"
+    },
+    "resolution_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Resolution Refs"
+    },
+    "policy_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Policy Refs"
+    },
+    "approved_summary_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Approved Summary Refs"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "chapter_id",
+    "section_number",
+    "section_heading"
+  ],
+  "title": "SectionCreate",
+  "description": "Request body for creating a code section or subsection."
+}
+
+
SectionVersionCreate
+{
+  "properties": {
+    "version_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Version Id"
+    },
+    "section_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Id"
+    },
+    "source_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "version_label": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Version Label"
+    },
+    "body": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Body"
+    },
+    "effective_start": {
+      "type": "string",
+      "format": "date",
+      "title": "Effective Start"
+    },
+    "effective_end": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective End"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    },
+    "is_current": {
+      "type": "boolean",
+      "title": "Is Current",
+      "default": false
+    },
+    "adoption_event_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Adoption Event Id"
+    },
+    "amendment_event_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Amendment Event Id"
+    },
+    "amendment_summary": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Amendment Summary"
+    },
+    "prior_version_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Prior Version Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "section_id",
+    "source_id",
+    "version_label",
+    "body",
+    "effective_start"
+  ],
+  "title": "SectionVersionCreate",
+  "description": "Request body for adding an immutable section version."
+}
+
+
Selection
+{
+  "properties": {
+    "recording_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Recording Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "recording_id",
+    "expected_sha256"
+  ],
+  "title": "Selection"
+}
+
+
SentenceInput
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "citations": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Citations"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text"
+  ],
+  "title": "SentenceInput"
+}
+
+
ServiceAccountCreate
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole",
+      "default": "read_only"
+    }
+  },
+  "type": "object",
+  "required": [
+    "name"
+  ],
+  "title": "ServiceAccountCreate"
+}
+
+
ServiceAccountCreated
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "api_key": {
+      "type": "string",
+      "title": "Api Key"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "role",
+    "created_by",
+    "created_at",
+    "is_active",
+    "api_key"
+  ],
+  "title": "ServiceAccountCreated",
+  "description": "Returned only on creation — includes the plaintext API key (shown once)."
+}
+
+
ServiceAccountRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "role",
+    "created_by",
+    "created_at",
+    "is_active"
+  ],
+  "title": "ServiceAccountRead"
+}
+
+
ServiceAccountUpdate
+{
+  "properties": {
+    "role": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/UserRole"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "ServiceAccountUpdate"
+}
+
+
Snapshot
+{
+  "properties": {
+    "expected_revision": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Expected Revision"
+    },
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "staff_only",
+        "public"
+      ],
+      "title": "Visibility"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "expected_revision",
+    "visibility"
+  ],
+  "title": "Snapshot"
+}
+
+
SourceCreate
+{
+  "properties": {
+    "source_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Id"
+    },
+    "name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Name"
+    },
+    "publisher": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Publisher"
+    },
+    "source_type": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Type"
+    },
+    "source_category": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Category"
+    },
+    "source_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Url"
+    },
+    "file_reference": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "File Reference"
+    },
+    "retrieved_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Retrieved At"
+    },
+    "retrieval_method": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Retrieval Method"
+    },
+    "checksum": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Checksum"
+    },
+    "source_owner": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Owner"
+    },
+    "is_official": {
+      "type": "boolean",
+      "title": "Is Official",
+      "default": true
+    },
+    "official_status_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Official Status Note"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    },
+    "staff_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Staff Notes"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "name",
+    "publisher",
+    "source_type",
+    "source_category"
+  ],
+  "title": "SourceCreate",
+  "description": "Request body for registering an official or explicitly labeled source."
+}
+
+
SourceInput
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "label": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Label"
+    },
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "label",
+    "text"
+  ],
+  "title": "SourceInput"
+}
+
+
SourceSnapshot
+{
+  "properties": {
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "public",
+        "staff_only"
+      ],
+      "title": "Visibility"
+    },
+    "meeting_event_ids": {
+      "items": {
+        "type": "string",
+        "format": "uuid"
+      },
+      "type": "array",
+      "maxItems": 50,
+      "title": "Meeting Event Ids"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "visibility"
+  ],
+  "title": "SourceSnapshot"
+}
+
+
SourceType
+{
+  "type": "string",
+  "enum": [
+    "manual_drop",
+    "file_system",
+    "rest_api",
+    "odbc"
+  ],
+  "title": "SourceType"
+}
+
+
StaffRecordsIntake
+{
+  "properties": {
+    "requester": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requester"
+    },
+    "summary": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Summary"
+    },
+    "deadline": {
+      "type": "string",
+      "title": "Deadline"
+    },
+    "deadlineBasis": {
+      "type": "string",
+      "title": "Deadlinebasis",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requester",
+    "summary",
+    "deadline"
+  ],
+  "title": "StaffRecordsIntake",
+  "description": "Existing native create-records-request input; no caller-supplied actor."
+}
+
+
StandardsExplanation
+{
+  "properties": {
+    "question": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Question"
+    },
+    "process_section": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Process Section",
+      "default": ""
+    },
+    "zone_code": {
+      "type": "string",
+      "maxLength": 40,
+      "title": "Zone Code",
+      "default": ""
+    },
+    "rule_types": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "title": "Rule Types"
+    },
+    "observed": {
+      "additionalProperties": {
+        "type": "string"
+      },
+      "type": "object",
+      "title": "Observed"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "question"
+  ],
+  "title": "StandardsExplanation"
+}
+
+
SyncFailureRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "source_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Source Id"
+    },
+    "source_path": {
+      "type": "string",
+      "title": "Source Path"
+    },
+    "error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Message"
+    },
+    "error_class": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Class"
+    },
+    "http_status_code": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Http Status Code"
+    },
+    "retry_count": {
+      "type": "integer",
+      "title": "Retry Count"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "first_failed_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "First Failed At"
+    },
+    "last_retried_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Retried At"
+    },
+    "dismissed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Dismissed At"
+    },
+    "dismissed_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Dismissed By"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "source_id",
+    "source_path",
+    "error_message",
+    "error_class",
+    "http_status_code",
+    "retry_count",
+    "status",
+    "first_failed_at",
+    "last_retried_at",
+    "dismissed_at",
+    "dismissed_by"
+  ],
+  "title": "SyncFailureRead"
+}
+
+
SyncRunLogRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "source_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Source Id"
+    },
+    "started_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Started At"
+    },
+    "finished_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Finished At"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Status"
+    },
+    "records_attempted": {
+      "type": "integer",
+      "title": "Records Attempted"
+    },
+    "records_succeeded": {
+      "type": "integer",
+      "title": "Records Succeeded"
+    },
+    "records_failed": {
+      "type": "integer",
+      "title": "Records Failed"
+    },
+    "error_summary": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Summary"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "source_id",
+    "started_at",
+    "finished_at",
+    "status",
+    "records_attempted",
+    "records_succeeded",
+    "records_failed",
+    "error_summary"
+  ],
+  "title": "SyncRunLogRead"
+}
+
+
SystemStatus
+{
+  "properties": {
+    "version": {
+      "type": "string",
+      "title": "Version"
+    },
+    "database": {
+      "type": "string",
+      "title": "Database"
+    },
+    "ollama": {
+      "type": "string",
+      "title": "Ollama"
+    },
+    "redis": {
+      "type": "string",
+      "title": "Redis"
+    },
+    "user_count": {
+      "type": "integer",
+      "title": "User Count"
+    },
+    "audit_log_count": {
+      "type": "integer",
+      "title": "Audit Log Count"
+    },
+    "suite_session": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Suite Session"
+    }
+  },
+  "type": "object",
+  "required": [
+    "version",
+    "database",
+    "ollama",
+    "redis",
+    "user_count",
+    "audit_log_count"
+  ],
+  "title": "SystemStatus"
+}
+
+
TaggedPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "tagged-pdf",
+      "title": "Action"
+    },
+    "headingLevels": {
+      "items": {
+        "type": "integer",
+        "maximum": 4294967295.0,
+        "minimum": 0.0
+      },
+      "type": "array",
+      "maxItems": 50,
+      "title": "Headinglevels"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "TaggedPlan"
+}
+
+
TestConnectionRequest
+{
+  "properties": {
+    "source_type": {
+      "type": "string",
+      "title": "Source Type"
+    },
+    "host": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Host"
+    },
+    "port": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Port"
+    },
+    "path": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Path"
+    },
+    "username": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Username"
+    },
+    "password": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Password"
+    },
+    "rest_api_config": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Rest Api Config"
+    },
+    "odbc_config": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Odbc Config"
+    }
+  },
+  "type": "object",
+  "required": [
+    "source_type"
+  ],
+  "title": "TestConnectionRequest",
+  "description": "Dedicated schema for test-connection. NOT the create schema.\n\nSecurity: credentials in this request body are never persisted, never\nwritten to audit logs, and never returned in the response."
+}
+
+
TestConnectionResponse
+{
+  "properties": {
+    "success": {
+      "type": "boolean",
+      "title": "Success"
+    },
+    "message": {
+      "type": "string",
+      "title": "Message"
+    },
+    "latency_ms": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Latency Ms"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Status"
+    },
+    "warning": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Warning"
+    },
+    "differing_keys": {
+      "anyOf": [
+        {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Differing Keys"
+    }
+  },
+  "type": "object",
+  "required": [
+    "success",
+    "message"
+  ],
+  "title": "TestConnectionResponse"
+}
+
+
TimelineEventCreate
+{
+  "properties": {
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "internal_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Internal Note"
+    }
+  },
+  "type": "object",
+  "required": [
+    "event_type",
+    "description"
+  ],
+  "title": "TimelineEventCreate"
+}
+
+
TimelineEventRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "actor_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Actor Id"
+    },
+    "actor_role": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Actor Role"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "internal_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Internal Note"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "event_type",
+    "actor_id",
+    "actor_role",
+    "description",
+    "internal_note",
+    "created_at"
+  ],
+  "title": "TimelineEventRead"
+}
+
+
TimelineView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "actor": {
+      "type": "string",
+      "title": "Actor"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "action",
+    "actor",
+    "note",
+    "created_at_unix_seconds"
+  ],
+  "title": "TimelineView"
+}
+
+
TitleCreate
+{
+  "properties": {
+    "title_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Title Id"
+    },
+    "title_number": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title Number"
+    },
+    "title_name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title Name"
+    },
+    "sort_order": {
+      "type": "integer",
+      "title": "Sort Order",
+      "default": 0
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title_number",
+    "title_name"
+  ],
+  "title": "TitleCreate",
+  "description": "Request body for creating a code title."
+}
+
+
TranscriptInput
+{
+  "properties": {
+    "source_label": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Label"
+    },
+    "transcript_text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Transcript Text"
+    },
+    "correction_of_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Correction Of Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_label",
+    "transcript_text"
+  ],
+  "title": "TranscriptInput"
+}
+
+
UserRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "email": {
+      "type": "string",
+      "format": "email",
+      "title": "Email"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active",
+      "default": true
+    },
+    "is_superuser": {
+      "type": "boolean",
+      "title": "Is Superuser",
+      "default": false
+    },
+    "is_verified": {
+      "type": "boolean",
+      "title": "Is Verified",
+      "default": false
+    },
+    "full_name": {
+      "type": "string",
+      "title": "Full Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "last_login": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Login"
+    },
+    "must_change_password": {
+      "type": "boolean",
+      "title": "Must Change Password",
+      "default": false
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "email",
+    "full_name",
+    "role",
+    "created_at",
+    "last_login"
+  ],
+  "title": "UserRead"
+}
+
+
UserRole
+{
+  "type": "string",
+  "enum": [
+    "admin",
+    "staff",
+    "reviewer",
+    "read_only",
+    "liaison",
+    "public"
+  ],
+  "title": "UserRole"
+}
+
+
UserSelfUpdate
+{
+  "properties": {
+    "password": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Password"
+    },
+    "email": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "email"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    },
+    "is_superuser": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Superuser"
+    },
+    "is_verified": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Verified"
+    },
+    "full_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Full Name"
+    }
+  },
+  "type": "object",
+  "title": "UserSelfUpdate",
+  "description": "Schema for user self-update via PATCH /users/me.\n\nExcludes role and department_id. Any payload containing those fields is\nrejected at parse time (HTTP 422). Role and department changes require\nadmin privileges via /admin/users/{id}."
+}
+
+
UserUpdateRequest
+{
+  "properties": {
+    "full_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Full Name"
+    },
+    "role": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Role"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "UserUpdateRequest"
+}
+
+
ValidationError
+{
+  "properties": {
+    "loc": {
+      "items": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "integer"
+          }
+        ]
+      },
+      "type": "array",
+      "title": "Location"
+    },
+    "msg": {
+      "type": "string",
+      "title": "Message"
+    },
+    "type": {
+      "type": "string",
+      "title": "Error Type"
+    },
+    "input": {
+      "title": "Input"
+    },
+    "ctx": {
+      "type": "object",
+      "title": "Context"
+    }
+  },
+  "type": "object",
+  "required": [
+    "loc",
+    "msg",
+    "type"
+  ],
+  "title": "ValidationError"
+}
+
+
Version
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence"
+  ],
+  "title": "Version"
+}
+
+
VoteCorrection
+{
+  "properties": {
+    "vote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Vote"
+    },
+    "reason": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Reason"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "vote",
+    "reason"
+  ],
+  "title": "VoteCorrection"
+}
+
+
VoteInput
+{
+  "properties": {
+    "voter_name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Voter Name"
+    },
+    "vote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Vote"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "voter_name",
+    "vote"
+  ],
+  "title": "VoteInput"
+}
+
+
_ParcelLookupIn
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "query"
+  ],
+  "title": "_ParcelLookupIn"
+}
+
+
townlight_inspections__workflow_models__SourceLink
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "const": "code",
+      "title": "Provider",
+      "default": "code"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "SourceLink"
+}
+
+
townlight_permitting__workflow_models__SourceLink
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "enum": [
+        "code",
+        "zoning"
+      ],
+      "title": "Provider"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "SourceLink"
+}
+
+
townlight_runtime__inspections_bridge__Search
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "const": "code",
+      "title": "Provider"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "query"
+  ],
+  "title": "Search"
+}
+
+
townlight_runtime__notice_bridge__Review
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence",
+    "note"
+  ],
+  "title": "Review"
+}
+
+
townlight_runtime__permitting_bridge__Import
+{
+  "properties": {
+    "bundle": {
+      "$ref": "#/components/schemas/RequirementBundle"
+    },
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "bundle"
+  ],
+  "title": "Import"
+}
+
+
townlight_runtime__permitting_bridge__Search
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "enum": [
+        "code",
+        "zoning"
+      ],
+      "title": "Provider"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "query"
+  ],
+  "title": "Search"
+}
+
+
townlight_runtime__planning_bridge__Import
+{
+  "properties": {
+    "bundle": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Bundle"
+    },
+    "expected_previous_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Previous Revision"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "bundle"
+  ],
+  "title": "Import"
+}
+
+
townlight_runtime__planning_bridge__Search
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Query"
+    },
+    "plan_type": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 40
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Plan Type"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "Search"
+}
+
+
townlight_runtime__zoning_bridge__Review
+{
+  "properties": {
+    "answer": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Answer",
+      "default": ""
+    },
+    "notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Notes",
+      "default": ""
+    },
+    "queue_status": {
+      "type": "string",
+      "enum": [
+        "open",
+        "in_review",
+        "resolved",
+        "closed"
+      ],
+      "title": "Queue Status",
+      "default": "resolved"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "Review"
+}
+
Townlight · AGPL-3.0-only · Source schema evidence only
\ No newline at end of file diff --git a/docs/beta-1/api/permitting-openapi.json b/docs/beta-1/api/permitting-openapi.json new file mode 100644 index 0000000..8a857fe --- /dev/null +++ b/docs/beta-1/api/permitting-openapi.json @@ -0,0 +1,11763 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "Townlight Records", + "description": "Prepared source schema for the actual native composition; installed acceptance remains pending. Exported without lifespan, migrations or database/network access.", + "version": "1.8.0.dev2" + }, + "paths": { + "/desktop/v1/permitting-sources/search": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Search Permitting Sources", + "operationId": "search_permitting_sources_desktop_v1_permitting_sources_search_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MeetingsSearch" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/permitting/requirements": { + "post": { + "tags": [ + "native-permitting" + ], + "summary": "Import Requirements", + "operationId": "import_requirements_desktop_v1_permitting_requirements_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/townlight_runtime__permitting_bridge__Import" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "get": { + "tags": [ + "native-permitting" + ], + "summary": "Requirements", + "operationId": "requirements_desktop_v1_permitting_requirements_get", + "parameters": [ + { + "name": "offset", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 100000, + "minimum": 0, + "default": 0, + "title": "Offset" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/permitting/requirements/{revision_id}": { + "get": { + "tags": [ + "native-permitting" + ], + "summary": "Requirement", + "operationId": "requirement_desktop_v1_permitting_requirements__revision_id__get", + "parameters": [ + { + "name": "revision_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Revision Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/permitting/cases": { + "get": { + "tags": [ + "native-permitting" + ], + "summary": "Cases", + "operationId": "cases_desktop_v1_permitting_cases_get", + "parameters": [ + { + "name": "offset", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 100000, + "minimum": 0, + "default": 0, + "title": "Offset" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "tags": [ + "native-permitting" + ], + "summary": "Create Case", + "operationId": "create_case_desktop_v1_permitting_cases_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IntakeInput" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/permitting/cases/{case_id}": { + "get": { + "tags": [ + "native-permitting" + ], + "summary": "Case", + "operationId": "case_desktop_v1_permitting_cases__case_id__get", + "parameters": [ + { + "name": "case_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Case Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/permitting/cases/{case_id}/revisions": { + "post": { + "tags": [ + "native-permitting" + ], + "summary": "Revise", + "operationId": "revise_desktop_v1_permitting_cases__case_id__revisions_post", + "parameters": [ + { + "name": "case_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Case Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IntakeInput" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/permitting/cases/{case_id}/history": { + "get": { + "tags": [ + "native-permitting" + ], + "summary": "History", + "operationId": "history_desktop_v1_permitting_cases__case_id__history_get", + "parameters": [ + { + "name": "case_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Case Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/permitting/cases/{case_id}/packets": { + "post": { + "tags": [ + "native-permitting" + ], + "summary": "Packet", + "operationId": "packet_desktop_v1_permitting_cases__case_id__packets_post", + "parameters": [ + { + "name": "case_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Case Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Packet" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/permitting/packets/{packet_id}": { + "get": { + "tags": [ + "native-permitting" + ], + "summary": "Document", + "operationId": "document_desktop_v1_permitting_packets__packet_id__get", + "parameters": [ + { + "name": "packet_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Packet Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/permitting/pathway": { + "post": { + "tags": [ + "native-permitting" + ], + "summary": "Pathway", + "description": "Cited likely permit pathway, attachments and timeline; informational only.\n\n``use_model_assistance`` does not exist here: the resident live-model\nassistance flag (F-07) stays excluded, so only the deterministic cited\npathway is reachable from the shared shell.", + "operationId": "pathway_desktop_v1_permitting_pathway_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Pathway" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/permitting/connections/search": { + "post": { + "tags": [ + "native-permitting" + ], + "summary": "Connections", + "operationId": "connections_desktop_v1_permitting_connections_search_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/townlight_runtime__permitting_bridge__Search" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "ActionItemInput": { + "properties": { + "description": { + "type": "string", + "minLength": 1, + "title": "Description" + }, + "assigned_to": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "source_motion_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Source Motion Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "description" + ], + "title": "ActionItemInput" + }, + "AdaPlan": { + "properties": { + "action": { + "type": "string", + "const": "ada-title-ii", + "title": "Action" + }, + "serviceArea": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Servicearea" + }, + "hasCoordinatorReview": { + "type": "boolean", + "title": "Hascoordinatorreview", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "serviceArea" + ], + "title": "AdaPlan" + }, + "AdminUserCreateRequest": { + "properties": { + "email": { + "type": "string", + "title": "Email" + }, + "password": { + "type": "string", + "title": "Password" + }, + "full_name": { + "type": "string", + "title": "Full Name", + "default": "" + }, + "role": { + "type": "string", + "title": "Role", + "default": "staff" + } + }, + "type": "object", + "required": [ + "email", + "password" + ], + "title": "AdminUserCreateRequest" + }, + "AdminUserCreateResponse": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "email": { + "type": "string", + "title": "Email" + }, + "full_name": { + "type": "string", + "title": "Full Name" + }, + "role": { + "type": "string", + "title": "Role" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + } + }, + "type": "object", + "required": [ + "id", + "email", + "full_name", + "role", + "is_active" + ], + "title": "AdminUserCreateResponse" + }, + "AgendaAssignment": { + "properties": { + "meeting_id": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "meeting_id" + ], + "title": "AgendaAssignment" + }, + "AgendaInput": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "department_name": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Department Name" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "department_name" + ], + "title": "AgendaInput" + }, + "AgendaReviewInput": { + "properties": { + "to_status": { + "type": "string", + "enum": [ + "DRAFTED", + "SUBMITTED", + "DEPT_APPROVED", + "LEGAL_REVIEWED", + "CLERK_ACCEPTED", + "ON_AGENDA", + "IN_PACKET", + "POSTED", + "HEARD", + "DISPOSED", + "ARCHIVED" + ], + "title": "To Status" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "to_status" + ], + "title": "AgendaReviewInput" + }, + "AmendmentInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "policy": { + "$ref": "#/components/schemas/PolicySelection" + }, + "proposal": { + "type": "string", + "maxLength": 20000, + "minLength": 1, + "title": "Proposal" + }, + "responsible_staff": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Responsible Staff" + }, + "status": { + "type": "string", + "enum": [ + "draft", + "review", + "adopted", + "withdrawn" + ], + "title": "Status", + "default": "draft" + }, + "review_note": { + "type": "string", + "maxLength": 5000, + "title": "Review Note", + "default": "" + }, + "adoption_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Adoption Revision" + }, + "note": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "policy", + "proposal", + "responsible_staff", + "note" + ], + "title": "AmendmentInput" + }, + "AnalysisObservation": { + "properties": { + "source": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "title": "Source" + }, + "filename": { + "type": "string", + "maxLength": 160, + "title": "Filename", + "default": "" + }, + "media_type": { + "type": "string", + "maxLength": 80, + "title": "Media Type", + "default": "" + }, + "text": { + "type": "string", + "maxLength": 4000, + "minLength": 1, + "title": "Text" + }, + "adapter": { + "type": "string", + "maxLength": 120, + "title": "Adapter", + "default": "" + }, + "citation_source_ids": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 30, + "title": "Citation Source Ids" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source", + "text" + ], + "title": "AnalysisObservation", + "description": "One draft observation, named with the adapter that actually produced it." + }, + "AnalysisRecord": { + "properties": { + "observations": { + "items": { + "$ref": "#/components/schemas/AnalysisObservation" + }, + "type": "array", + "maxItems": 30, + "title": "Observations" + }, + "cited_sections": { + "items": { + "$ref": "#/components/schemas/CitedSection" + }, + "type": "array", + "maxItems": 30, + "title": "Cited Sections" + }, + "unavailable": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 30, + "title": "Unavailable" + }, + "runtime": { + "additionalProperties": true, + "type": "object", + "title": "Runtime" + }, + "review_required": { + "type": "boolean", + "title": "Review Required", + "default": true + } + }, + "additionalProperties": false, + "type": "object", + "title": "AnalysisRecord", + "description": "The adapter output that accompanies a saved inspection draft." + }, + "ApprovalCommand": { + "properties": { + "action": { + "type": "string", + "const": "approve-records-response", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ApprovalPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "ApprovalCommand" + }, + "ApprovalPayload": { + "properties": { + "approvalNote": { + "type": "string", + "title": "Approvalnote", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "title": "ApprovalPayload" + }, + "ArchiveInput": { + "properties": { + "visibility": { + "type": "string", + "enum": [ + "public", + "closed_session" + ], + "title": "Visibility" + }, + "packet_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Packet Id" + }, + "minutes_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Minutes Id" + }, + "plain_language_summary": { + "type": "string", + "title": "Plain Language Summary", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "visibility" + ], + "title": "ArchiveInput" + }, + "ArtifactPlan": { + "properties": { + "artifact_id": { + "type": "string", + "title": "Artifact Id" + }, + "file_name": { + "type": "string", + "title": "File Name" + }, + "content": { + "type": "string", + "title": "Content" + }, + "sha256": { + "type": "string", + "title": "Sha256" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "artifact_id", + "file_name", + "content", + "sha256", + "created_at_unix_seconds" + ], + "title": "ArtifactPlan" + }, + "AssignCommand": { + "properties": { + "action": { + "type": "string", + "const": "assign-records-request", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/AssignmentPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "AssignCommand" + }, + "AssignmentPayload": { + "properties": { + "assignedTo": { + "type": "string", + "minLength": 1, + "title": "Assignedto" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "assignedTo" + ], + "title": "AssignmentPayload" + }, + "AttachDocument": { + "properties": { + "title": { + "type": "string", + "minLength": 1, + "title": "Title" + }, + "citation": { + "type": "string", + "title": "Citation", + "default": "" + }, + "file": { + "$ref": "#/components/schemas/ManagedFileReceipt" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "file" + ], + "title": "AttachDocument" + }, + "AttachReleaseCopy": { + "properties": { + "status": { + "type": "string", + "enum": [ + "release-ready copy", + "redacted copy" + ], + "title": "Status" + }, + "note": { + "type": "string", + "title": "Note", + "default": "" + }, + "added_by": { + "type": "string", + "title": "Added By", + "default": "" + }, + "file": { + "$ref": "#/components/schemas/ManagedFileReceipt" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "status", + "file" + ], + "title": "AttachReleaseCopy" + }, + "AuditChainVerification": { + "properties": { + "is_valid": { + "type": "boolean", + "title": "Is Valid" + }, + "entries_checked": { + "type": "integer", + "title": "Entries Checked" + }, + "error_message": { + "type": "string", + "title": "Error Message" + } + }, + "type": "object", + "required": [ + "is_valid", + "entries_checked", + "error_message" + ], + "title": "AuditChainVerification" + }, + "AuditLogRead": { + "properties": { + "id": { + "type": "integer", + "title": "Id" + }, + "prev_hash": { + "type": "string", + "title": "Prev Hash" + }, + "entry_hash": { + "type": "string", + "title": "Entry Hash" + }, + "timestamp": { + "type": "string", + "format": "date-time", + "title": "Timestamp" + }, + "user_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "User Id" + }, + "action": { + "type": "string", + "title": "Action" + }, + "resource_type": { + "type": "string", + "title": "Resource Type" + }, + "resource_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Resource Id" + }, + "details": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Details" + }, + "ai_generated": { + "type": "boolean", + "title": "Ai Generated" + } + }, + "type": "object", + "required": [ + "id", + "prev_hash", + "entry_hash", + "timestamp", + "user_id", + "action", + "resource_type", + "resource_id", + "details", + "ai_generated" + ], + "title": "AuditLogRead" + }, + "AuditView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "module_id": { + "type": "string", + "title": "Module Id" + }, + "action": { + "type": "string", + "title": "Action" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + }, + "previous_hash": { + "type": "string", + "title": "Previous Hash" + }, + "entry_hash": { + "type": "string", + "title": "Entry Hash" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "module_id", + "action", + "summary", + "created_at_unix_seconds", + "previous_hash", + "entry_hash" + ], + "title": "AuditView" + }, + "BearerResponse": { + "properties": { + "access_token": { + "type": "string", + "title": "Access Token" + }, + "token_type": { + "type": "string", + "title": "Token Type" + } + }, + "type": "object", + "required": [ + "access_token", + "token_type" + ], + "title": "BearerResponse" + }, + "Body_auth_jwt_login_auth_jwt_login_post": { + "properties": { + "grant_type": { + "anyOf": [ + { + "type": "string", + "pattern": "^password$" + }, + { + "type": "null" + } + ], + "title": "Grant Type" + }, + "username": { + "type": "string", + "title": "Username" + }, + "password": { + "type": "string", + "format": "password", + "title": "Password" + }, + "scope": { + "type": "string", + "title": "Scope", + "default": "" + }, + "client_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Client Id" + }, + "client_secret": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "format": "password", + "title": "Client Secret" + } + }, + "type": "object", + "required": [ + "username", + "password" + ], + "title": "Body_auth_jwt_login_auth_jwt_login_post" + }, + "Body_upload_file_datasources_upload_post": { + "properties": { + "file": { + "type": "string", + "contentMediaType": "application/octet-stream", + "title": "File" + } + }, + "type": "object", + "required": [ + "file" + ], + "title": "Body_upload_file_datasources_upload_post" + }, + "CalculateDeadlineCommand": { + "properties": { + "action": { + "type": "string", + "const": "calculate-records-deadline", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/CalculateDeadlinePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "CalculateDeadlineCommand" + }, + "CalculateDeadlinePayload": { + "properties": { + "deadlineReceivedDate": { + "type": "string", + "title": "Deadlinereceiveddate" + }, + "deadlineRuleName": { + "type": "string", + "minLength": 1, + "title": "Deadlinerulename" + }, + "deadlineDayCount": { + "type": "string", + "title": "Deadlinedaycount" + }, + "deadlineDayType": { + "type": "string", + "title": "Deadlinedaytype" + }, + "deadlineBasis": { + "type": "string", + "minLength": 1, + "title": "Deadlinebasis" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "deadlineReceivedDate", + "deadlineRuleName", + "deadlineDayCount", + "deadlineDayType", + "deadlineBasis" + ], + "title": "CalculateDeadlinePayload" + }, + "ChapterCreate": { + "properties": { + "chapter_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Chapter Id" + }, + "title_id": { + "type": "string", + "minLength": 1, + "title": "Title Id" + }, + "chapter_number": { + "type": "string", + "minLength": 1, + "title": "Chapter Number" + }, + "chapter_name": { + "type": "string", + "minLength": 1, + "title": "Chapter Name" + }, + "sort_order": { + "type": "integer", + "title": "Sort Order", + "default": 0 + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title_id", + "chapter_number", + "chapter_name" + ], + "title": "ChapterCreate", + "description": "Request body for creating a code chapter." + }, + "CitedSection": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "citation": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Citation" + }, + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "version": { + "type": "string", + "maxLength": 80, + "title": "Version", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "citation" + ], + "title": "CitedSection", + "description": "One resolved public Code section; never a caller-supplied quotation." + }, + "CityProfileCreate": { + "properties": { + "city_name": { + "type": "string", + "title": "City Name" + }, + "state": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State" + }, + "county": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "County" + }, + "population_band": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Population Band" + }, + "email_platform": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Email Platform" + }, + "has_dedicated_it": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Has Dedicated It" + }, + "monthly_request_volume": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Monthly Request Volume" + }, + "profile_data": { + "additionalProperties": true, + "type": "object", + "title": "Profile Data", + "default": {} + }, + "gap_map": { + "additionalProperties": true, + "type": "object", + "title": "Gap Map", + "default": {} + } + }, + "type": "object", + "required": [ + "city_name" + ], + "title": "CityProfileCreate" + }, + "CityProfileRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "city_name": { + "type": "string", + "title": "City Name" + }, + "state": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State" + }, + "county": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "County" + }, + "population_band": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Population Band" + }, + "email_platform": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Email Platform" + }, + "has_dedicated_it": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Has Dedicated It" + }, + "monthly_request_volume": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Monthly Request Volume" + }, + "onboarding_status": { + "type": "string", + "title": "Onboarding Status" + }, + "profile_data": { + "additionalProperties": true, + "type": "object", + "title": "Profile Data" + }, + "gap_map": { + "additionalProperties": true, + "type": "object", + "title": "Gap Map" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "city_name", + "state", + "county", + "population_band", + "email_platform", + "has_dedicated_it", + "monthly_request_volume", + "onboarding_status", + "profile_data", + "gap_map", + "created_at", + "updated_at" + ], + "title": "CityProfileRead" + }, + "CityProfileUpdate": { + "properties": { + "city_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "City Name" + }, + "state": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State" + }, + "county": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "County" + }, + "population_band": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Population Band" + }, + "email_platform": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Email Platform" + }, + "has_dedicated_it": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Has Dedicated It" + }, + "monthly_request_volume": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Monthly Request Volume" + }, + "onboarding_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Onboarding Status" + }, + "profile_data": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Profile Data" + }, + "gap_map": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Gap Map" + } + }, + "type": "object", + "title": "CityProfileUpdate" + }, + "ClarificationCommand": { + "properties": { + "action": { + "type": "string", + "const": "request-records-clarification", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ClarificationPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "ClarificationCommand" + }, + "ClarificationPayload": { + "properties": { + "clarificationNote": { + "type": "string", + "minLength": 1, + "title": "Clarificationnote" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "clarificationNote" + ], + "title": "ClarificationPayload" + }, + "Closeout": { + "properties": { + "decision_id": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Decision Id" + }, + "version_id": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Version Id" + }, + "source_id": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Source Id" + }, + "version_label": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Version Label" + }, + "body": { + "type": "string", + "maxLength": 1000000, + "minLength": 1, + "title": "Body" + }, + "effective_start": { + "type": "string", + "format": "date", + "title": "Effective Start" + }, + "effective_end": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective End" + }, + "is_current": { + "type": "boolean", + "title": "Is Current" + }, + "reconciliation_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reconciliation Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "decision_id", + "version_id", + "source_id", + "version_label", + "body", + "effective_start", + "is_current" + ], + "title": "Closeout" + }, + "CodeContext": { + "properties": { + "section_number": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Section Number" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "section_number" + ], + "title": "CodeContext" + }, + "CodeLink": { + "properties": { + "provider": { + "type": "string", + "const": "code", + "title": "Provider", + "default": "code" + }, + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "CodeLink" + }, + "CodeSearch": { + "properties": { + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "CodeSearch" + }, + "CodeSourceSelection": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "CodeSourceSelection" + }, + "CompleteArtifact": { + "properties": { + "export_path": { + "type": "string", + "minLength": 1, + "title": "Export Path" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "export_path" + ], + "title": "CompleteArtifact" + }, + "ConnectionSearch": { + "properties": { + "provider": { + "type": "string", + "enum": [ + "meetings", + "zoning" + ], + "title": "Provider" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "query" + ], + "title": "ConnectionSearch" + }, + "CoverageGapResponse": { + "properties": { + "jurisdictions_without_rules": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Jurisdictions Without Rules" + }, + "departments_without_staff": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array", + "title": "Departments Without Staff" + }, + "uncovered_categories": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Uncovered Categories" + }, + "total_gaps": { + "type": "integer", + "title": "Total Gaps" + } + }, + "type": "object", + "required": [ + "jurisdictions_without_rules", + "departments_without_staff", + "uncovered_categories", + "total_gaps" + ], + "title": "CoverageGapResponse" + }, + "DataSourceAdminRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "source_type": { + "$ref": "#/components/schemas/SourceType" + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "type": "boolean", + "title": "Schedule Enabled", + "default": true + }, + "next_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Next Sync At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "last_ingestion_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Ingestion At" + }, + "last_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Sync At" + }, + "last_sync_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Sync Status" + }, + "last_error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Error Message" + }, + "consecutive_failure_count": { + "type": "integer", + "title": "Consecutive Failure Count", + "default": 0 + }, + "sync_paused": { + "type": "boolean", + "title": "Sync Paused", + "default": false + }, + "health_status": { + "type": "string", + "title": "Health Status", + "default": "healthy" + }, + "active_failure_count": { + "type": "integer", + "title": "Active Failure Count", + "default": 0 + }, + "connector_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Connector Type" + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At" + }, + "connection_config": { + "additionalProperties": true, + "type": "object", + "title": "Connection Config" + } + }, + "type": "object", + "required": [ + "id", + "name", + "source_type", + "is_active", + "created_by", + "created_at", + "last_ingestion_at", + "connection_config" + ], + "title": "DataSourceAdminRead", + "description": "Full datasource shape including connection_config. Returned only by admin-gated endpoints." + }, + "DataSourceCreate": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "source_type": { + "$ref": "#/components/schemas/SourceType" + }, + "connection_config": { + "additionalProperties": true, + "type": "object", + "title": "Connection Config", + "default": {} + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "type": "boolean", + "title": "Schedule Enabled", + "default": true + } + }, + "type": "object", + "required": [ + "name", + "source_type" + ], + "title": "DataSourceCreate" + }, + "DataSourceRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "source_type": { + "$ref": "#/components/schemas/SourceType" + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "type": "boolean", + "title": "Schedule Enabled", + "default": true + }, + "next_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Next Sync At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "last_ingestion_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Ingestion At" + }, + "last_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Sync At" + }, + "last_sync_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Sync Status" + }, + "last_error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Error Message" + }, + "consecutive_failure_count": { + "type": "integer", + "title": "Consecutive Failure Count", + "default": 0 + }, + "sync_paused": { + "type": "boolean", + "title": "Sync Paused", + "default": false + }, + "health_status": { + "type": "string", + "title": "Health Status", + "default": "healthy" + }, + "active_failure_count": { + "type": "integer", + "title": "Active Failure Count", + "default": 0 + }, + "connector_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Connector Type" + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "name", + "source_type", + "is_active", + "created_by", + "created_at", + "last_ingestion_at" + ], + "title": "DataSourceRead", + "description": "Redacted datasource shape — safe for non-admin roles. connection_config omitted." + }, + "DataSourceUpdate": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "connection_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Connection Config" + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Schedule Enabled" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "DataSourceUpdate" + }, + "DeadlineCommand": { + "properties": { + "action": { + "type": "string", + "const": "set-records-deadline", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/DeadlinePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "DeadlineCommand" + }, + "DeadlinePayload": { + "properties": { + "deadline": { + "type": "string", + "title": "Deadline" + }, + "deadlineBasis": { + "type": "string", + "minLength": 1, + "title": "Deadlinebasis" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "deadline", + "deadlineBasis" + ], + "title": "DeadlinePayload" + }, + "Decision": { + "properties": { + "id": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Id" + }, + "outcome": { + "type": "string", + "enum": [ + "adopted", + "not_adopted", + "deferred", + "withdrawn" + ], + "title": "Outcome" + }, + "decided_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Decided At" + }, + "decision_text": { + "type": "string", + "maxLength": 1000000, + "minLength": 1, + "title": "Decision Text" + }, + "supporting_references": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Supporting References" + }, + "supersedes_decision_id": { + "anyOf": [ + { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$" + }, + { + "type": "null" + } + ], + "title": "Supersedes Decision Id" + }, + "reconciliation_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reconciliation Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "outcome", + "decision_text" + ], + "title": "Decision" + }, + "DepartmentCreate": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "code": { + "type": "string", + "title": "Code" + }, + "contact_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Contact Email" + } + }, + "type": "object", + "required": [ + "name", + "code" + ], + "title": "DepartmentCreate" + }, + "DepartmentRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "code": { + "type": "string", + "title": "Code" + }, + "contact_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Contact Email" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "name", + "code", + "contact_email", + "created_at" + ], + "title": "DepartmentRead" + }, + "DepartmentUpdate": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Code" + }, + "contact_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Contact Email" + } + }, + "type": "object", + "title": "DepartmentUpdate" + }, + "DisclosureTemplateCreate": { + "properties": { + "template_type": { + "type": "string", + "title": "Template Type" + }, + "state_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State Code" + }, + "content": { + "type": "string", + "title": "Content" + } + }, + "type": "object", + "required": [ + "template_type", + "content" + ], + "title": "DisclosureTemplateCreate" + }, + "DisclosureTemplateRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "template_type": { + "type": "string", + "title": "Template Type" + }, + "state_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State Code" + }, + "content": { + "type": "string", + "title": "Content" + }, + "version": { + "type": "integer", + "title": "Version" + }, + "updated_by": { + "type": "string", + "format": "uuid", + "title": "Updated By" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "template_type", + "state_code", + "content", + "version", + "updated_by", + "updated_at" + ], + "title": "DisclosureTemplateRead" + }, + "DisclosureTemplateRendered": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "template_type": { + "type": "string", + "title": "Template Type" + }, + "rendered_content": { + "type": "string", + "title": "Rendered Content" + }, + "has_unresolved_variables": { + "type": "boolean", + "title": "Has Unresolved Variables" + } + }, + "type": "object", + "required": [ + "id", + "template_type", + "rendered_content", + "has_unresolved_variables" + ], + "title": "DisclosureTemplateRendered" + }, + "DisclosureTemplateUpdate": { + "properties": { + "content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Content" + }, + "state_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State Code" + } + }, + "type": "object", + "title": "DisclosureTemplateUpdate" + }, + "DocumentChunkRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "chunk_index": { + "type": "integer", + "title": "Chunk Index" + }, + "content_text": { + "type": "string", + "title": "Content Text" + }, + "token_count": { + "type": "integer", + "title": "Token Count" + }, + "page_number": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Page Number" + } + }, + "type": "object", + "required": [ + "id", + "document_id", + "chunk_index", + "content_text", + "token_count", + "page_number" + ], + "title": "DocumentChunkRead" + }, + "DocumentRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "source_id": { + "type": "string", + "format": "uuid", + "title": "Source Id" + }, + "source_path": { + "type": "string", + "title": "Source Path" + }, + "filename": { + "type": "string", + "title": "Filename" + }, + "file_type": { + "type": "string", + "title": "File Type" + }, + "file_hash": { + "type": "string", + "title": "File Hash" + }, + "file_size": { + "type": "integer", + "title": "File Size" + }, + "ingestion_status": { + "$ref": "#/components/schemas/IngestionStatus" + }, + "ingestion_error": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Ingestion Error" + }, + "chunk_count": { + "type": "integer", + "title": "Chunk Count" + }, + "ingested_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Ingested At" + }, + "connector_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Connector Type" + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "source_id", + "source_path", + "filename", + "file_type", + "file_hash", + "file_size", + "ingestion_status", + "ingestion_error", + "chunk_count", + "ingested_at" + ], + "title": "DocumentRead" + }, + "DraftCommand": { + "properties": { + "action": { + "type": "string", + "const": "draft-records-response", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/DraftPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "DraftCommand" + }, + "DraftInput": { + "properties": { + "source_materials": { + "items": { + "$ref": "#/components/schemas/SourceInput" + }, + "type": "array", + "title": "Source Materials" + }, + "sentences": { + "items": { + "$ref": "#/components/schemas/SentenceInput" + }, + "type": "array", + "minItems": 1, + "title": "Sentences" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sentences" + ], + "title": "DraftInput" + }, + "DraftPayload": { + "properties": { + "responseDraft": { + "type": "string", + "minLength": 1, + "title": "Responsedraft" + }, + "citation": { + "type": "string", + "title": "Citation", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "responseDraft" + ], + "title": "DraftPayload" + }, + "ErrorModel": { + "properties": { + "detail": { + "anyOf": [ + { + "type": "string" + }, + { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + ], + "title": "Detail" + } + }, + "type": "object", + "required": [ + "detail" + ], + "title": "ErrorModel" + }, + "Evidence": { + "properties": { + "filename": { + "type": "string", + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$", + "title": "Filename" + }, + "description": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Description" + }, + "media_type": { + "type": "string", + "enum": [ + "text/plain", + "image/jpeg", + "image/png", + "image/webp", + "application/pdf", + "audio/webm", + "audio/ogg", + "audio/wav", + "audio/mpeg", + "audio/mp4" + ], + "title": "Media Type" + }, + "content_base64": { + "type": "string", + "maxLength": 14000000, + "minLength": 1, + "title": "Content Base64" + }, + "sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "filename", + "description", + "media_type", + "content_base64", + "sha256" + ], + "title": "Evidence" + }, + "EvidenceItem": { + "properties": { + "filename": { + "type": "string", + "maxLength": 151, + "minLength": 1, + "title": "Filename" + }, + "media_type": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Media Type" + }, + "description": { + "type": "string", + "maxLength": 2000, + "title": "Description", + "default": "" + }, + "content_base64": { + "type": "string", + "maxLength": 14000000, + "minLength": 1, + "title": "Content Base64" + }, + "sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "filename", + "media_type", + "content_base64", + "sha256" + ], + "title": "EvidenceItem" + }, + "EvidenceItems": { + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/EvidenceItem" + }, + "type": "array", + "maxItems": 10, + "minItems": 1, + "title": "Items" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "items" + ], + "title": "EvidenceItems" + }, + "ExemptionAccuracyReport": { + "properties": { + "category": { + "type": "string", + "title": "Category" + }, + "total_flags": { + "type": "integer", + "title": "Total Flags" + }, + "accepted": { + "type": "integer", + "title": "Accepted" + }, + "rejected": { + "type": "integer", + "title": "Rejected" + }, + "pending": { + "type": "integer", + "title": "Pending" + }, + "acceptance_rate": { + "type": "number", + "title": "Acceptance Rate" + } + }, + "type": "object", + "required": [ + "category", + "total_flags", + "accepted", + "rejected", + "pending", + "acceptance_rate" + ], + "title": "ExemptionAccuracyReport" + }, + "ExemptionDashboard": { + "properties": { + "total_flags": { + "type": "integer", + "title": "Total Flags" + }, + "by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "By Status" + }, + "by_category": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "By Category" + }, + "acceptance_rate": { + "type": "number", + "title": "Acceptance Rate" + }, + "total_rules": { + "type": "integer", + "title": "Total Rules" + }, + "active_rules": { + "type": "integer", + "title": "Active Rules" + } + }, + "type": "object", + "required": [ + "total_flags", + "by_status", + "by_category", + "acceptance_rate", + "total_rules", + "active_rules" + ], + "title": "ExemptionDashboard" + }, + "ExemptionDecisionCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-exemption-decision", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ExemptionDecisionPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "ExemptionDecisionCommand" + }, + "ExemptionDecisionPayload": { + "properties": { + "exemptionSource": { + "type": "string", + "minLength": 1, + "title": "Exemptionsource" + }, + "exemptionKind": { + "type": "string", + "minLength": 1, + "title": "Exemptionkind" + }, + "exemptionFinding": { + "type": "string", + "minLength": 1, + "title": "Exemptionfinding" + }, + "exemptionDecision": { + "type": "string", + "enum": [ + "release", + "redact", + "exempt" + ], + "title": "Exemptiondecision" + }, + "exemptionBasis": { + "type": "string", + "minLength": 1, + "title": "Exemptionbasis" + }, + "exemptionReviewer": { + "type": "string", + "title": "Exemptionreviewer", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "exemptionSource", + "exemptionKind", + "exemptionFinding", + "exemptionDecision", + "exemptionBasis" + ], + "title": "ExemptionDecisionPayload" + }, + "ExemptionDecisionView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "source": { + "type": "string", + "title": "Source" + }, + "kind": { + "type": "string", + "title": "Kind" + }, + "finding": { + "type": "string", + "title": "Finding" + }, + "decision": { + "type": "string", + "enum": [ + "release", + "redact", + "exempt" + ], + "title": "Decision" + }, + "basis": { + "type": "string", + "title": "Basis" + }, + "reviewer": { + "type": "string", + "title": "Reviewer" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "source", + "kind", + "finding", + "decision", + "basis", + "reviewer", + "created_at_unix_seconds" + ], + "title": "ExemptionDecisionView" + }, + "ExemptionFlagRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "chunk_id": { + "type": "string", + "format": "uuid", + "title": "Chunk Id" + }, + "rule_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Rule Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "category": { + "type": "string", + "title": "Category" + }, + "matched_text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Matched Text" + }, + "confidence": { + "type": "number", + "title": "Confidence" + }, + "status": { + "$ref": "#/components/schemas/FlagStatus" + }, + "reviewed_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Reviewed By" + }, + "reviewed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Reviewed At" + }, + "review_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Reason" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "chunk_id", + "rule_id", + "request_id", + "category", + "matched_text", + "confidence", + "status", + "reviewed_by", + "reviewed_at", + "review_reason", + "created_at" + ], + "title": "ExemptionFlagRead" + }, + "ExemptionFlagReview": { + "properties": { + "status": { + "$ref": "#/components/schemas/FlagStatus" + }, + "review_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Reason" + } + }, + "type": "object", + "required": [ + "status" + ], + "title": "ExemptionFlagReview" + }, + "ExemptionNoteCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-exemption-review", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ExemptionNotePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "ExemptionNoteCommand" + }, + "ExemptionNotePayload": { + "properties": { + "exemptionNote": { + "type": "string", + "minLength": 1, + "title": "Exemptionnote" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "exemptionNote" + ], + "title": "ExemptionNotePayload" + }, + "ExemptionRuleCreate": { + "properties": { + "state_code": { + "type": "string", + "title": "State Code" + }, + "category": { + "type": "string", + "title": "Category" + }, + "rule_type": { + "$ref": "#/components/schemas/RuleType" + }, + "rule_definition": { + "type": "string", + "title": "Rule Definition" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "enabled": { + "type": "boolean", + "title": "Enabled", + "default": true + } + }, + "type": "object", + "required": [ + "state_code", + "category", + "rule_type", + "rule_definition" + ], + "title": "ExemptionRuleCreate" + }, + "ExemptionRuleRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "state_code": { + "type": "string", + "title": "State Code" + }, + "category": { + "type": "string", + "title": "Category" + }, + "rule_type": { + "$ref": "#/components/schemas/RuleType" + }, + "rule_definition": { + "type": "string", + "title": "Rule Definition" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "enabled": { + "type": "boolean", + "title": "Enabled" + }, + "version": { + "type": "integer", + "title": "Version", + "default": 1 + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "state_code", + "category", + "rule_type", + "rule_definition", + "description", + "enabled", + "created_by", + "created_at" + ], + "title": "ExemptionRuleRead" + }, + "ExemptionRuleUpdate": { + "properties": { + "rule_definition": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Rule Definition" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "enabled": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Enabled" + } + }, + "type": "object", + "title": "ExemptionRuleUpdate" + }, + "ExportReceipt": { + "properties": { + "export_path": { + "type": "string", + "maxLength": 32768, + "minLength": 1, + "title": "Export Path" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "export_path" + ], + "title": "ExportReceipt" + }, + "FeeEstimateCommand": { + "properties": { + "action": { + "type": "string", + "const": "estimate-records-fee", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/FeeEstimatePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "FeeEstimateCommand" + }, + "FeeEstimatePayload": { + "properties": { + "feeEstimate": { + "type": "string", + "minLength": 1, + "title": "Feeestimate" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "feeEstimate" + ], + "title": "FeeEstimatePayload" + }, + "FeeEstimateRequest": { + "properties": { + "page_count": { + "type": "integer", + "title": "Page Count" + }, + "fee_schedule_id": { + "type": "string", + "format": "uuid", + "title": "Fee Schedule Id" + } + }, + "type": "object", + "required": [ + "page_count", + "fee_schedule_id" + ], + "title": "FeeEstimateRequest" + }, + "FeeEstimateResponse": { + "properties": { + "page_count": { + "type": "integer", + "title": "Page Count" + }, + "unit_price": { + "type": "number", + "title": "Unit Price" + }, + "total": { + "type": "number", + "title": "Total" + }, + "fee_type": { + "type": "string", + "title": "Fee Type" + }, + "description": { + "type": "string", + "title": "Description" + } + }, + "type": "object", + "required": [ + "page_count", + "unit_price", + "total", + "fee_type", + "description" + ], + "title": "FeeEstimateResponse" + }, + "FeeLineCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-fee-line", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/FeeLinePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "FeeLineCommand" + }, + "FeeLineItemCreate": { + "properties": { + "description": { + "type": "string", + "title": "Description" + }, + "quantity": { + "type": "integer", + "title": "Quantity", + "default": 1 + }, + "unit_price": { + "type": "number", + "title": "Unit Price" + }, + "fee_schedule_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Fee Schedule Id" + } + }, + "type": "object", + "required": [ + "description", + "unit_price" + ], + "title": "FeeLineItemCreate" + }, + "FeeLineItemRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "fee_schedule_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Fee Schedule Id" + }, + "description": { + "type": "string", + "title": "Description" + }, + "quantity": { + "type": "integer", + "title": "Quantity" + }, + "unit_price": { + "type": "number", + "title": "Unit Price" + }, + "total": { + "type": "number", + "title": "Total" + }, + "status": { + "type": "string", + "title": "Status" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "fee_schedule_id", + "description", + "quantity", + "unit_price", + "total", + "status", + "created_at" + ], + "title": "FeeLineItemRead" + }, + "FeeLinePayload": { + "properties": { + "feeLineDescription": { + "type": "string", + "minLength": 1, + "title": "Feelinedescription" + }, + "feeScheduleBasis": { + "type": "string", + "minLength": 1, + "title": "Feeschedulebasis" + }, + "feeLineAmount": { + "type": "string", + "title": "Feelineamount" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "feeLineDescription", + "feeScheduleBasis", + "feeLineAmount" + ], + "title": "FeeLinePayload" + }, + "FeeLineView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "description": { + "type": "string", + "title": "Description" + }, + "schedule_basis": { + "type": "string", + "title": "Schedule Basis" + }, + "amount_cents": { + "type": "integer", + "title": "Amount Cents" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "description", + "schedule_basis", + "amount_cents", + "created_at_unix_seconds" + ], + "title": "FeeLineView" + }, + "FeeScheduleCreate": { + "properties": { + "jurisdiction": { + "type": "string", + "title": "Jurisdiction" + }, + "fee_type": { + "type": "string", + "title": "Fee Type" + }, + "amount": { + "type": "number", + "title": "Amount" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "effective_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective Date" + } + }, + "type": "object", + "required": [ + "jurisdiction", + "fee_type", + "amount" + ], + "title": "FeeScheduleCreate" + }, + "FeeScheduleRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "jurisdiction": { + "type": "string", + "title": "Jurisdiction" + }, + "fee_type": { + "type": "string", + "title": "Fee Type" + }, + "amount": { + "type": "number", + "title": "Amount" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "effective_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective Date" + }, + "created_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "jurisdiction", + "fee_type", + "amount", + "description", + "effective_date", + "created_by", + "created_at" + ], + "title": "FeeScheduleRead" + }, + "FeeScheduleUpdate": { + "properties": { + "fee_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Fee Type" + }, + "amount": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Amount" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "effective_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective Date" + } + }, + "type": "object", + "title": "FeeScheduleUpdate" + }, + "FeeWaiverCommand": { + "properties": { + "action": { + "type": "string", + "const": "waive-records-fee", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/FeeWaiverPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "FeeWaiverCommand" + }, + "FeeWaiverCreateRequest": { + "properties": { + "waiver_type": { + "type": "string", + "title": "Waiver Type" + }, + "reason": { + "type": "string", + "title": "Reason" + } + }, + "type": "object", + "required": [ + "waiver_type", + "reason" + ], + "title": "FeeWaiverCreateRequest" + }, + "FeeWaiverPayload": { + "properties": { + "feeWaiverReason": { + "type": "string", + "minLength": 1, + "title": "Feewaiverreason" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "feeWaiverReason" + ], + "title": "FeeWaiverPayload" + }, + "FeeWaiverReadResponse": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "waiver_type": { + "type": "string", + "title": "Waiver Type" + }, + "reason": { + "type": "string", + "title": "Reason" + }, + "status": { + "type": "string", + "title": "Status" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + }, + "created_at": { + "type": "string", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "waiver_type", + "reason", + "status", + "created_at" + ], + "title": "FeeWaiverReadResponse" + }, + "FeeWaiverReviewRequest": { + "properties": { + "status": { + "type": "string", + "title": "Status" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + } + }, + "type": "object", + "required": [ + "status" + ], + "title": "FeeWaiverReviewRequest" + }, + "FinishCommand": { + "properties": { + "action": { + "type": "string", + "enum": [ + "fulfill-records-request", + "close-records-request" + ], + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/NativePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "FinishCommand" + }, + "FlagStatus": { + "type": "string", + "enum": [ + "flagged", + "reviewed", + "accepted", + "rejected" + ], + "title": "FlagStatus" + }, + "FormPlan": { + "properties": { + "action": { + "type": "string", + "const": "form-plan", + "title": "Action" + }, + "formName": { + "type": "string", + "maxLength": 500, + "title": "Formname", + "default": "" + }, + "fields": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 50, + "title": "Fields" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "FormPlan" + }, + "GeneratedDraft": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "model": { + "type": "string", + "minLength": 1, + "title": "Model" + }, + "previous_response_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Previous Response Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text", + "model", + "previous_response_sha256" + ], + "title": "GeneratedDraft" + }, + "HTTPValidationError": { + "properties": { + "detail": { + "items": { + "$ref": "#/components/schemas/ValidationError" + }, + "type": "array", + "title": "Detail" + } + }, + "type": "object", + "title": "HTTPValidationError" + }, + "Handoff": { + "properties": { + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "request_id" + ], + "title": "Handoff" + }, + "ImportBundleCreate": { + "properties": { + "job_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Job Id" + }, + "connector_type": { + "type": "string", + "minLength": 1, + "title": "Connector Type" + }, + "source": { + "$ref": "#/components/schemas/SourceCreate" + }, + "sources": { + "items": { + "$ref": "#/components/schemas/SourceCreate" + }, + "type": "array", + "title": "Sources" + }, + "titles": { + "items": { + "$ref": "#/components/schemas/TitleCreate" + }, + "type": "array", + "title": "Titles" + }, + "chapters": { + "items": { + "$ref": "#/components/schemas/ChapterCreate" + }, + "type": "array", + "title": "Chapters" + }, + "sections": { + "items": { + "$ref": "#/components/schemas/SectionCreate" + }, + "type": "array", + "title": "Sections" + }, + "versions": { + "items": { + "$ref": "#/components/schemas/SectionVersionCreate" + }, + "type": "array", + "title": "Versions" + }, + "provenance": { + "additionalProperties": true, + "type": "object", + "title": "Provenance" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "connector_type", + "source" + ], + "title": "ImportBundleCreate", + "description": "Request body for local fixture/file-drop import jobs." + }, + "InclusionStatus": { + "type": "string", + "enum": [ + "included", + "excluded", + "pending" + ], + "title": "InclusionStatus" + }, + "IngestionStats": { + "properties": { + "total_sources": { + "type": "integer", + "title": "Total Sources" + }, + "active_sources": { + "type": "integer", + "title": "Active Sources" + }, + "total_documents": { + "type": "integer", + "title": "Total Documents" + }, + "documents_by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Documents By Status" + }, + "total_chunks": { + "type": "integer", + "title": "Total Chunks" + } + }, + "type": "object", + "required": [ + "total_sources", + "active_sources", + "total_documents", + "documents_by_status", + "total_chunks" + ], + "title": "IngestionStats" + }, + "IngestionStatus": { + "type": "string", + "enum": [ + "pending", + "processing", + "completed", + "failed" + ], + "title": "IngestionStatus" + }, + "InitiativeInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "policy": { + "$ref": "#/components/schemas/PolicySelection" + }, + "responsible_staff": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Responsible Staff" + }, + "target": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "title": "Target" + }, + "unit": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Unit" + }, + "due_on": { + "type": "string", + "format": "date", + "title": "Due On" + }, + "status": { + "type": "string", + "enum": [ + "planned", + "active", + "completed", + "cancelled" + ], + "title": "Status", + "default": "planned" + }, + "milestones": { + "items": { + "$ref": "#/components/schemas/Milestone" + }, + "type": "array", + "maxItems": 100, + "title": "Milestones" + }, + "measurements": { + "items": { + "$ref": "#/components/schemas/Measurement" + }, + "type": "array", + "maxItems": 1000, + "title": "Measurements" + }, + "note": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "policy", + "responsible_staff", + "target", + "unit", + "due_on", + "note" + ], + "title": "InitiativeInput" + }, + "InspectionInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "property_reference": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Property Reference" + }, + "inspection_reference": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Inspection Reference" + }, + "dataset_kind": { + "type": "string", + "enum": [ + "municipal", + "fictional" + ], + "title": "Dataset Kind" + }, + "inspector_notes": { + "type": "string", + "maxLength": 10000, + "minLength": 1, + "title": "Inspector Notes" + }, + "photo_observations": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 30, + "title": "Photo Observations" + }, + "voice_notes": { + "type": "string", + "maxLength": 10000, + "title": "Voice Notes", + "default": "" + }, + "evidence": { + "items": { + "$ref": "#/components/schemas/Evidence" + }, + "type": "array", + "maxItems": 10, + "title": "Evidence" + }, + "linked_sources": { + "items": { + "$ref": "#/components/schemas/townlight_inspections__workflow_models__SourceLink" + }, + "type": "array", + "maxItems": 30, + "title": "Linked Sources" + }, + "assigned_to": { + "type": "string", + "maxLength": 255, + "title": "Assigned To", + "default": "" + }, + "staff_notes": { + "type": "string", + "maxLength": 10000, + "title": "Staff Notes", + "default": "" + }, + "notice_draft": { + "type": "string", + "maxLength": 10000, + "title": "Notice Draft", + "default": "" + }, + "review_state": { + "type": "string", + "enum": [ + "draft", + "follow_up", + "reviewed" + ], + "title": "Review State", + "default": "draft" + }, + "review_notes": { + "type": "string", + "maxLength": 4000, + "title": "Review Notes", + "default": "" + }, + "public_summary": { + "type": "string", + "maxLength": 10000, + "title": "Public Summary", + "default": "" + }, + "analysis": { + "anyOf": [ + { + "$ref": "#/components/schemas/AnalysisRecord" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "property_reference", + "inspection_reference", + "dataset_kind", + "inspector_notes" + ], + "title": "InspectionInput" + }, + "IntakeInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "project_name": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Project Name" + }, + "project_description": { + "type": "string", + "maxLength": 10000, + "minLength": 1, + "title": "Project Description" + }, + "location": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Location" + }, + "applicant_contact": { + "type": "string", + "maxLength": 2000, + "title": "Applicant Contact", + "default": "" + }, + "requirement_revision": { + "type": "string", + "format": "uuid", + "title": "Requirement Revision" + }, + "materials": { + "items": { + "$ref": "#/components/schemas/MaterialReview" + }, + "type": "array", + "maxItems": 100, + "minItems": 1, + "title": "Materials" + }, + "linked_sources": { + "items": { + "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink" + }, + "type": "array", + "maxItems": 30, + "title": "Linked Sources" + }, + "staff_notes": { + "type": "string", + "maxLength": 10000, + "title": "Staff Notes", + "default": "" + }, + "assigned_to": { + "type": "string", + "maxLength": 255, + "title": "Assigned To", + "default": "" + }, + "review_state": { + "type": "string", + "enum": [ + "draft", + "follow_up", + "reviewed" + ], + "title": "Review State", + "default": "draft" + }, + "review_notes": { + "type": "string", + "maxLength": 4000, + "title": "Review Notes", + "default": "" + }, + "public_summary": { + "type": "string", + "maxLength": 10000, + "title": "Public Summary", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "project_name", + "project_description", + "location", + "requirement_revision", + "materials" + ], + "title": "IntakeInput" + }, + "InterpretationNoteCreate": { + "properties": { + "note_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Note Id" + }, + "note_text": { + "type": "string", + "minLength": 1, + "title": "Note Text" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "note_text" + ], + "title": "InterpretationNoteCreate", + "description": "Request body for staff-only interpretation notes." + }, + "InterviewRequest": { + "properties": { + "last_answer": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Answer" + }, + "last_field": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Field" + }, + "skipped_fields": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Skipped Fields" + } + }, + "type": "object", + "title": "InterviewRequest" + }, + "InterviewResponse": { + "properties": { + "question": { + "type": "string", + "title": "Question" + }, + "target_field": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Target Field" + }, + "all_complete": { + "type": "boolean", + "title": "All Complete" + }, + "completed_fields": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Completed Fields" + }, + "onboarding_status": { + "type": "string", + "title": "Onboarding Status" + }, + "skipped_fields": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Skipped Fields" + } + }, + "type": "object", + "required": [ + "question", + "target_field", + "all_complete", + "completed_fields", + "onboarding_status", + "skipped_fields" + ], + "title": "InterviewResponse" + }, + "ManagedFileReceipt": { + "properties": { + "original_path": { + "type": "string", + "minLength": 1, + "title": "Original Path" + }, + "stored_path": { + "type": "string", + "minLength": 1, + "title": "Stored Path" + }, + "file_name": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "File Name" + }, + "sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Sha256" + }, + "size_bytes": { + "type": "integer", + "maximum": 2147483647.0, + "minimum": 0.0, + "title": "Size Bytes" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "original_path", + "stored_path", + "file_name", + "sha256", + "size_bytes" + ], + "title": "ManagedFileReceipt" + }, + "ManagedSource": { + "properties": { + "original_path": { + "type": "string", + "title": "Original Path" + }, + "stored_path": { + "type": "string", + "title": "Stored Path" + }, + "file_name": { + "type": "string", + "title": "File Name" + }, + "sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Sha256" + }, + "size_bytes": { + "type": "integer", + "minimum": 0.0, + "title": "Size Bytes" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "original_path", + "stored_path", + "file_name", + "sha256", + "size_bytes" + ], + "title": "ManagedSource" + }, + "Material": { + "properties": { + "material_id": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]{1,80}$", + "title": "Material Id" + }, + "description": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Description" + }, + "citation": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Citation" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "material_id", + "description", + "citation" + ], + "title": "Material" + }, + "MaterialReview": { + "properties": { + "material_id": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Material Id" + }, + "status": { + "type": "string", + "enum": [ + "not_reviewed", + "provided", + "missing", + "unclear" + ], + "title": "Status", + "default": "not_reviewed" + }, + "note": { + "type": "string", + "maxLength": 2000, + "title": "Note", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "material_id" + ], + "title": "MaterialReview" + }, + "Measurement": { + "properties": { + "recorded_on": { + "type": "string", + "format": "date", + "title": "Recorded On" + }, + "value": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "title": "Value" + }, + "evidence": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Evidence" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "recorded_on", + "value", + "evidence" + ], + "title": "Measurement" + }, + "MediaAnalysis": { + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/EvidenceItem" + }, + "type": "array", + "maxItems": 10, + "minItems": 1, + "title": "Items" + }, + "code_links": { + "items": { + "$ref": "#/components/schemas/CodeLink" + }, + "type": "array", + "maxItems": 30, + "title": "Code Links" + }, + "inspector_supplied_text": { + "type": "string", + "maxLength": 10000, + "title": "Inspector Supplied Text", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "items" + ], + "title": "MediaAnalysis" + }, + "MeetingInput": { + "properties": { + "title": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Title" + }, + "scheduled_start": { + "type": "string", + "format": "date-time", + "title": "Scheduled Start" + }, + "location": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Location" + }, + "meeting_type": { + "type": "string", + "enum": [ + "regular", + "special", + "emergency", + "closed_session", + "executive" + ], + "title": "Meeting Type", + "default": "regular" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "scheduled_start", + "location" + ], + "title": "MeetingInput" + }, + "MeetingLink": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + }, + "relation": { + "type": "string", + "enum": [ + "hearing", + "context", + "precedent" + ], + "title": "Relation" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256", + "relation" + ], + "title": "MeetingLink" + }, + "MeetingSearch": { + "properties": { + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "MeetingSearch" + }, + "MeetingStageInput": { + "properties": { + "to_status": { + "type": "string", + "enum": [ + "SCHEDULED", + "NOTICED", + "PACKET_POSTED", + "IN_PROGRESS", + "RECESSED", + "ADJOURNED", + "TRANSCRIPT_READY", + "MINUTES_DRAFTED", + "MINUTES_POSTED", + "MINUTES_ADOPTED", + "MINUTES_SIGNED", + "ARCHIVED", + "CANCELLED" + ], + "title": "To Status" + }, + "statutory_basis": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Statutory Basis" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "to_status" + ], + "title": "MeetingStageInput" + }, + "MeetingsSearch": { + "properties": { + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "MeetingsSearch" + }, + "MeetingsSourceSelection": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "MeetingsSourceSelection" + }, + "MessageCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-message", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/MessagePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "MessageCommand" + }, + "MessageCreate": { + "properties": { + "message_text": { + "type": "string", + "title": "Message Text" + }, + "is_internal": { + "type": "boolean", + "title": "Is Internal", + "default": false + } + }, + "type": "object", + "required": [ + "message_text" + ], + "title": "MessageCreate" + }, + "MessagePayload": { + "properties": { + "requestMessageBody": { + "type": "string", + "minLength": 1, + "title": "Requestmessagebody" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requestMessageBody" + ], + "title": "MessagePayload" + }, + "MessageRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "sender_type": { + "type": "string", + "title": "Sender Type" + }, + "sender_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Sender Id" + }, + "message_text": { + "type": "string", + "title": "Message Text" + }, + "is_internal": { + "type": "boolean", + "title": "Is Internal" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "sender_type", + "sender_id", + "message_text", + "is_internal", + "created_at" + ], + "title": "MessageRead" + }, + "MessageView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "author": { + "type": "string", + "title": "Author" + }, + "author_role": { + "type": "string", + "title": "Author Role" + }, + "body": { + "type": "string", + "title": "Body" + }, + "visibility": { + "type": "string", + "title": "Visibility" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "author", + "author_role", + "body", + "visibility", + "created_at_unix_seconds" + ], + "title": "MessageView" + }, + "Milestone": { + "properties": { + "title": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Title" + }, + "due_on": { + "type": "string", + "format": "date", + "title": "Due On" + }, + "completed_on": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Completed On" + }, + "evidence": { + "type": "string", + "maxLength": 2000, + "title": "Evidence", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "due_on" + ], + "title": "Milestone" + }, + "MinutesDecision": { + "properties": { + "action": { + "type": "string", + "enum": [ + "post", + "adopt", + "sign" + ], + "title": "Action" + }, + "note": { + "type": "string", + "title": "Note", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "MinutesDecision" + }, + "ModelRegistryCreate": { + "properties": { + "model_name": { + "type": "string", + "title": "Model Name" + }, + "model_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Version" + }, + "parameter_count": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parameter Count" + }, + "license": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License" + }, + "model_card_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Card Url" + }, + "is_active": { + "type": "boolean", + "title": "Is Active", + "default": false + }, + "context_window_size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Context Window Size" + }, + "supports_ner": { + "type": "boolean", + "title": "Supports Ner", + "default": false + }, + "supports_vision": { + "type": "boolean", + "title": "Supports Vision", + "default": false + } + }, + "type": "object", + "required": [ + "model_name" + ], + "title": "ModelRegistryCreate", + "description": "Schema for creating a new model_registry record (POST body)." + }, + "ModelRegistryRead": { + "properties": { + "id": { + "type": "integer", + "title": "Id" + }, + "model_name": { + "type": "string", + "title": "Model Name" + }, + "model_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Version" + }, + "parameter_count": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parameter Count" + }, + "license": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License" + }, + "model_card_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Card Url" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "added_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Added At" + }, + "context_window_size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Context Window Size" + }, + "supports_ner": { + "type": "boolean", + "title": "Supports Ner" + }, + "supports_vision": { + "type": "boolean", + "title": "Supports Vision" + } + }, + "type": "object", + "required": [ + "id", + "model_name", + "is_active", + "supports_ner", + "supports_vision" + ], + "title": "ModelRegistryRead", + "description": "Schema for returning a model_registry record (GET response).\n\n``from_attributes=True`` allows construction directly from an ORM instance." + }, + "ModelRegistryUpdate": { + "properties": { + "model_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Name" + }, + "model_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Version" + }, + "parameter_count": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parameter Count" + }, + "license": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License" + }, + "model_card_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Card Url" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + }, + "context_window_size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Context Window Size" + }, + "supports_ner": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Supports Ner" + }, + "supports_vision": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Supports Vision" + } + }, + "type": "object", + "title": "ModelRegistryUpdate", + "description": "Schema for partially updating a model_registry record (PATCH body).\n\nEvery field is optional so callers can send only the fields they want to\nchange." + }, + "MotionCorrection": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "reason": { + "type": "string", + "minLength": 1, + "title": "Reason" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text", + "reason" + ], + "title": "MotionCorrection" + }, + "MotionInput": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "seconded_by": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Seconded By" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text" + ], + "title": "MotionInput" + }, + "NativePayload": { + "properties": {}, + "additionalProperties": false, + "type": "object", + "title": "NativePayload" + }, + "NativeRequestRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "requester_name": { + "type": "string", + "title": "Requester Name" + }, + "requester_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Email" + }, + "requester_phone": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Phone" + }, + "requester_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Type" + }, + "date_received": { + "type": "string", + "format": "date-time", + "title": "Date Received" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "description": { + "type": "string", + "title": "Description" + }, + "status": { + "$ref": "#/components/schemas/RequestStatus" + }, + "assigned_to": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "created_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "response_draft": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Response Draft" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + }, + "estimated_fee": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Estimated Fee" + }, + "fee_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Fee Status" + }, + "fee_waiver_requested": { + "type": "boolean", + "title": "Fee Waiver Requested", + "default": false + }, + "priority": { + "type": "string", + "title": "Priority", + "default": "normal" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + }, + "closed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Closed At" + }, + "closure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Closure Reason" + }, + "desktop_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Desktop Id" + }, + "public_tracking_number": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Public Tracking Number" + }, + "submitted_via": { + "type": "string", + "title": "Submitted Via" + }, + "deadline_label": { + "type": "string", + "title": "Deadline Label" + }, + "deadline_basis": { + "type": "string", + "title": "Deadline Basis" + }, + "deadline_reviewed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Deadline Reviewed At" + } + }, + "type": "object", + "required": [ + "id", + "requester_name", + "requester_email", + "date_received", + "statutory_deadline", + "description", + "status", + "assigned_to", + "created_by", + "created_at", + "response_draft", + "review_notes", + "desktop_id", + "public_tracking_number", + "submitted_via", + "deadline_label", + "deadline_basis", + "deadline_reviewed_at" + ], + "title": "NativeRequestRead" + }, + "NoticeDocumentInput": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text" + ], + "title": "NoticeDocumentInput" + }, + "NoticeDraft": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "body": { + "type": "string", + "maxLength": 100000, + "minLength": 1, + "title": "Body" + }, + "notice_type": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Notice Type" + }, + "statutory_basis": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Statutory Basis" + }, + "event_date": { + "type": "string", + "format": "date", + "title": "Event Date" + }, + "lead_days": { + "type": "integer", + "maximum": 365.0, + "minimum": 0.0, + "title": "Lead Days" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "body", + "notice_type", + "statutory_basis", + "event_date", + "lead_days" + ], + "title": "NoticeDraft" + }, + "NoticeInput": { + "properties": { + "notice_type": { + "type": "string", + "enum": [ + "regular", + "special", + "emergency", + "closed_session", + "executive" + ], + "title": "Notice Type" + }, + "posted_at": { + "type": "string", + "format": "date-time", + "title": "Posted At" + }, + "minimum_notice_hours": { + "type": "integer", + "minimum": 0.0, + "title": "Minimum Notice Hours" + }, + "statutory_basis": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Statutory Basis" + }, + "approved_by": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Approved By" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "notice_type", + "posted_at", + "minimum_notice_hours" + ], + "title": "NoticeInput" + }, + "NoticeProofInput": { + "properties": { + "location": { + "type": "string", + "minLength": 1, + "title": "Location" + }, + "note": { + "type": "string", + "title": "Note", + "default": "" + }, + "document_delivery_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Document Delivery Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "location" + ], + "title": "NoticeProofInput" + }, + "NotificationLogRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "template_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Template Id" + }, + "recipient_email": { + "type": "string", + "title": "Recipient Email" + }, + "request_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Request Id" + }, + "channel": { + "type": "string", + "title": "Channel" + }, + "status": { + "type": "string", + "title": "Status" + }, + "sent_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Sent At" + }, + "error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Message" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "template_id", + "recipient_email", + "request_id", + "channel", + "status", + "sent_at", + "error_message", + "created_at" + ], + "title": "NotificationLogRead" + }, + "NotificationTemplateCreate": { + "properties": { + "event_type": { + "type": "string", + "title": "Event Type" + }, + "channel": { + "type": "string", + "title": "Channel", + "default": "email" + }, + "subject_template": { + "type": "string", + "title": "Subject Template" + }, + "body_template": { + "type": "string", + "title": "Body Template" + } + }, + "type": "object", + "required": [ + "event_type", + "subject_template", + "body_template" + ], + "title": "NotificationTemplateCreate" + }, + "NotificationTemplateRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "event_type": { + "type": "string", + "title": "Event Type" + }, + "channel": { + "type": "string", + "title": "Channel" + }, + "subject_template": { + "type": "string", + "title": "Subject Template" + }, + "body_template": { + "type": "string", + "title": "Body Template" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "event_type", + "channel", + "subject_template", + "body_template", + "is_active", + "created_at" + ], + "title": "NotificationTemplateRead" + }, + "NotificationTemplateUpdate": { + "properties": { + "subject_template": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Subject Template" + }, + "body_template": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Body Template" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "NotificationTemplateUpdate" + }, + "NotificationView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "notification_id": { + "type": "string", + "title": "Notification Id" + }, + "module_id": { + "type": "string", + "title": "Module Id" + }, + "record_id": { + "type": "string", + "title": "Record Id" + }, + "audience": { + "type": "string", + "title": "Audience" + }, + "channel": { + "type": "string", + "title": "Channel" + }, + "subject": { + "type": "string", + "title": "Subject" + }, + "body": { + "type": "string", + "title": "Body" + }, + "status": { + "type": "string", + "title": "Status" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + }, + "sent_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Sent At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "notification_id", + "module_id", + "record_id", + "audience", + "channel", + "subject", + "body", + "status", + "created_at_unix_seconds", + "sent_at_unix_seconds" + ], + "title": "NotificationView" + }, + "OllamaModelInfo": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Size" + }, + "details": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Details" + } + }, + "type": "object", + "required": [ + "name" + ], + "title": "OllamaModelInfo" + }, + "OllamaStatus": { + "properties": { + "status": { + "type": "string", + "title": "Status" + }, + "models": { + "items": { + "$ref": "#/components/schemas/OllamaModelInfo" + }, + "type": "array", + "title": "Models" + } + }, + "type": "object", + "required": [ + "status", + "models" + ], + "title": "OllamaStatus" + }, + "OperationalMetrics": { + "properties": { + "average_response_time_days": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Average Response Time Days" + }, + "median_response_time_days": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Median Response Time Days" + }, + "requests_by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Requests By Status" + }, + "requests_by_department": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Requests By Department" + }, + "deadline_compliance_rate": { + "type": "number", + "title": "Deadline Compliance Rate" + }, + "total_open": { + "type": "integer", + "title": "Total Open" + }, + "total_closed": { + "type": "integer", + "title": "Total Closed" + }, + "total_overdue": { + "type": "integer", + "title": "Total Overdue" + }, + "clarification_frequency": { + "type": "number", + "title": "Clarification Frequency" + }, + "top_request_topics": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Top Request Topics" + } + }, + "type": "object", + "required": [ + "average_response_time_days", + "median_response_time_days", + "requests_by_status", + "requests_by_department", + "deadline_compliance_rate", + "total_open", + "total_closed", + "total_overdue", + "clarification_frequency", + "top_request_topics" + ], + "title": "OperationalMetrics" + }, + "Outline": { + "properties": { + "title": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Title" + }, + "question_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "maxItems": 50, + "minItems": 1, + "title": "Question Ids" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "question_ids" + ], + "title": "Outline" + }, + "Packet": { + "properties": { + "expected_revision": { + "type": "string", + "format": "uuid", + "title": "Expected Revision" + }, + "visibility": { + "type": "string", + "enum": [ + "staff_only", + "records_copy" + ], + "title": "Visibility" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "expected_revision", + "visibility" + ], + "title": "Packet" + }, + "PacketInput": { + "properties": { + "agenda_item_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "title": "Agenda Item Ids" + }, + "source_files": { + "items": { + "$ref": "#/components/schemas/ManagedSource" + }, + "type": "array", + "title": "Source Files" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "agenda_item_ids" + ], + "title": "PacketInput" + }, + "Pathway": { + "properties": { + "project_type": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Project Type" + }, + "proposal": { + "type": "string", + "maxLength": 4000, + "title": "Proposal", + "default": "" + }, + "location_context": { + "type": "string", + "maxLength": 1000, + "title": "Location Context", + "default": "" + }, + "requirement_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Requirement Revision" + }, + "fee_link": { + "anyOf": [ + { + "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "project_type" + ], + "title": "Pathway" + }, + "PathwayStep": { + "properties": { + "step": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Step" + }, + "citation": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Citation" + }, + "typical_time": { + "type": "string", + "maxLength": 1000, + "title": "Typical Time", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "step", + "citation" + ], + "title": "PathwayStep" + }, + "PlainLanguageSummaryCreate": { + "properties": { + "summary_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Summary Id" + }, + "section_version_id": { + "type": "string", + "minLength": 1, + "title": "Section Version Id" + }, + "summary_text": { + "type": "string", + "minLength": 1, + "title": "Summary Text" + }, + "language_code": { + "type": "string", + "title": "Language Code", + "default": "en" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "section_version_id", + "summary_text" + ], + "title": "PlainLanguageSummaryCreate", + "description": "Request body for staff-drafted plain-language summaries." + }, + "PolicySelection": { + "properties": { + "plan_id": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Plan Id" + }, + "revision_id": { + "type": "string", + "maxLength": 36, + "minLength": 36, + "title": "Revision Id" + }, + "policy_id": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Policy Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "plan_id", + "revision_id", + "policy_id" + ], + "title": "PolicySelection" + }, + "PortalModeResponse": { + "properties": { + "mode": { + "type": "string", + "enum": [ + "public", + "private" + ], + "title": "Mode", + "description": "Active portal posture for this deployment. ``public`` = minimal resident surface (landing + authenticated records-request submission + resident registration) reachable without staff auth. ``private`` = staff-only; no public routes, no resident self-registration." + } + }, + "type": "object", + "required": [ + "mode" + ], + "title": "PortalModeResponse", + "description": "T5D — schema for ``GET /config/portal-mode``.\n\nExposed to the frontend on boot so it can branch routing without a\nuser-identity lookup. The payload is intentionally the single field\nbelow — no staff config, no user state, no schema version." + }, + "PrepareArtifact": { + "properties": { + "kind": { + "type": "string", + "enum": [ + "response", + "release-package" + ], + "title": "Kind" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "kind" + ], + "title": "PrepareArtifact" + }, + "Proof": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + }, + "filename": { + "type": "string", + "maxLength": 150, + "minLength": 1, + "title": "Filename" + }, + "content_base64": { + "type": "string", + "maxLength": 7000000, + "minLength": 1, + "title": "Content Base64" + }, + "location": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Location" + }, + "published_at": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Published At" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence", + "filename", + "content_base64", + "location", + "published_at" + ], + "title": "Proof" + }, + "Proposal": { + "properties": { + "id": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Id" + }, + "version_id": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Version Id" + }, + "meeting_id": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "ordinance_number": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Ordinance Number" + }, + "proposed_text": { + "type": "string", + "maxLength": 1000000, + "minLength": 1, + "title": "Proposed Text" + }, + "supersedes_id": { + "anyOf": [ + { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$" + }, + { + "type": "null" + } + ], + "title": "Supersedes Id" + }, + "reconciliation_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reconciliation Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "version_id", + "meeting_id", + "title", + "ordinance_number", + "proposed_text" + ], + "title": "Proposal" + }, + "PublicExplore": { + "properties": { + "goal": { + "type": "string", + "maxLength": 500, + "title": "Goal", + "default": "" + }, + "topic": { + "type": "string", + "maxLength": 160, + "title": "Topic", + "default": "" + }, + "neighborhood": { + "type": "string", + "maxLength": 255, + "title": "Neighborhood", + "default": "" + }, + "plan_type": { + "type": "string", + "maxLength": 120, + "title": "Plan Type", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "title": "PublicExplore" + }, + "PublicIntake": { + "properties": { + "requester": { + "type": "string", + "minLength": 1, + "title": "Requester" + }, + "requesterContact": { + "type": "string", + "minLength": 1, + "title": "Requestercontact" + }, + "summary": { + "type": "string", + "minLength": 1, + "title": "Summary" + }, + "deadline": { + "type": "string", + "title": "Deadline", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requester", + "requesterContact", + "summary" + ], + "title": "PublicIntake" + }, + "PublicLookup": { + "properties": { + "trackingNumber": { + "type": "string", + "minLength": 1, + "title": "Trackingnumber" + }, + "requesterContact": { + "type": "string", + "minLength": 1, + "title": "Requestercontact" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "trackingNumber", + "requesterContact" + ], + "title": "PublicLookup" + }, + "PublicMessage": { + "properties": { + "trackingNumber": { + "type": "string", + "minLength": 1, + "title": "Trackingnumber" + }, + "requesterContact": { + "type": "string", + "minLength": 1, + "title": "Requestercontact" + }, + "publicRequestMessage": { + "type": "string", + "minLength": 1, + "title": "Publicrequestmessage" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "trackingNumber", + "requesterContact", + "publicRequestMessage" + ], + "title": "PublicMessage" + }, + "PublicStatusView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "label": { + "type": "string", + "title": "Label" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "status": { + "type": "string", + "title": "Status" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "label", + "summary", + "status", + "created_at_unix_seconds" + ], + "title": "PublicStatusView" + }, + "PublicationView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "source_module": { + "type": "string", + "title": "Source Module" + }, + "source_record_id": { + "type": "string", + "title": "Source Record Id" + }, + "record_type": { + "type": "string", + "title": "Record Type" + }, + "public_payload": { + "type": "string", + "title": "Public Payload" + }, + "payload_hash": { + "type": "string", + "title": "Payload Hash" + }, + "published_at_unix_seconds": { + "type": "integer", + "title": "Published At Unix Seconds" + }, + "retracted_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Retracted At Unix Seconds" + }, + "retracted_by": { + "type": "string", + "title": "Retracted By", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "source_module", + "source_record_id", + "record_type", + "public_payload", + "payload_hash", + "published_at_unix_seconds" + ], + "title": "PublicationView" + }, + "PublishingPlan": { + "properties": { + "action": { + "type": "string", + "const": "publishing-workflow", + "title": "Action" + }, + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "hasReview": { + "type": "boolean", + "title": "Hasreview", + "default": false + }, + "hasPlainLanguage": { + "type": "boolean", + "title": "Hasplainlanguage", + "default": false + }, + "hasTranslationReview": { + "type": "boolean", + "title": "Hastranslationreview", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "PublishingPlan" + }, + "Question": { + "properties": { + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + }, + "question": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Question" + }, + "kind": { + "type": "string", + "enum": [ + "use", + "dimension" + ], + "title": "Kind" + }, + "key": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Key" + }, + "audience": { + "type": "string", + "enum": [ + "resident", + "staff" + ], + "title": "Audience", + "default": "resident" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "jurisdiction", + "query", + "question", + "kind", + "key" + ], + "title": "Question" + }, + "QuestionAnswerRequest": { + "properties": { + "question": { + "type": "string", + "minLength": 1, + "title": "Question" + }, + "section_number": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Section Number" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "question" + ], + "title": "QuestionAnswerRequest", + "description": "Request body for citation-grounded code Q&A." + }, + "RecordsDocumentView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "attachment_id": { + "type": "string", + "title": "Attachment Id" + }, + "title": { + "type": "string", + "title": "Title" + }, + "original_path": { + "type": "string", + "title": "Original Path" + }, + "stored_path": { + "type": "string", + "title": "Stored Path" + }, + "citation": { + "type": "string", + "title": "Citation" + }, + "sha256": { + "type": "string", + "title": "Sha256" + }, + "size_bytes": { + "type": "integer", + "title": "Size Bytes" + }, + "status": { + "type": "string", + "title": "Status" + }, + "added_by": { + "type": "string", + "title": "Added By" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + }, + "release_original_path": { + "type": "string", + "title": "Release Original Path", + "default": "" + }, + "release_stored_path": { + "type": "string", + "title": "Release Stored Path", + "default": "" + }, + "release_file_name": { + "type": "string", + "title": "Release File Name", + "default": "" + }, + "release_sha256": { + "type": "string", + "title": "Release Sha256", + "default": "" + }, + "release_size_bytes": { + "type": "integer", + "title": "Release Size Bytes", + "default": 0 + }, + "release_status": { + "type": "string", + "title": "Release Status", + "default": "" + }, + "release_note": { + "type": "string", + "title": "Release Note", + "default": "" + }, + "release_added_by": { + "type": "string", + "title": "Release Added By", + "default": "" + }, + "release_added_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Release Added At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "attachment_id", + "title", + "original_path", + "stored_path", + "citation", + "sha256", + "size_bytes", + "status", + "added_by", + "created_at_unix_seconds" + ], + "title": "RecordsDocumentView" + }, + "RecordsOperationRead": { + "properties": { + "action": { + "type": "string", + "title": "Action" + }, + "message": { + "type": "string", + "title": "Message" + }, + "request": { + "$ref": "#/components/schemas/RecordsView" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "message", + "request" + ], + "title": "RecordsOperationRead" + }, + "RecordsStateRead": { + "properties": { + "demo_fixture": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Demo Fixture" + }, + "records_requests": { + "items": { + "$ref": "#/components/schemas/RecordsView" + }, + "type": "array", + "title": "Records Requests" + }, + "notification_events": { + "items": { + "$ref": "#/components/schemas/NotificationView" + }, + "type": "array", + "title": "Notification Events" + }, + "publication_events": { + "items": { + "$ref": "#/components/schemas/PublicationView" + }, + "type": "array", + "title": "Publication Events" + }, + "audit_entries": { + "items": { + "$ref": "#/components/schemas/AuditView" + }, + "type": "array", + "title": "Audit Entries" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "records_requests" + ], + "title": "RecordsStateRead" + }, + "RecordsView": { + "properties": { + "request_id": { + "type": "string", + "title": "Request Id" + }, + "id": { + "type": "string", + "title": "Id" + }, + "public_tracking_number": { + "type": "string", + "title": "Public Tracking Number" + }, + "requester": { + "type": "string", + "title": "Requester" + }, + "requester_contact": { + "type": "string", + "title": "Requester Contact" + }, + "submitted_via": { + "type": "string", + "title": "Submitted Via" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "deadline": { + "type": "string", + "title": "Deadline" + }, + "deadline_basis": { + "type": "string", + "title": "Deadline Basis" + }, + "status": { + "type": "string", + "title": "Status" + }, + "assigned_to": { + "type": "string", + "title": "Assigned To" + }, + "clarification_notes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Clarification Notes" + }, + "search_notes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Search Notes" + }, + "search_sessions": { + "items": { + "$ref": "#/components/schemas/SearchReceiptView" + }, + "type": "array", + "title": "Search Sessions" + }, + "exemption_reviews": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Exemption Reviews" + }, + "exemption_decisions": { + "items": { + "$ref": "#/components/schemas/ExemptionDecisionView" + }, + "type": "array", + "title": "Exemption Decisions" + }, + "fee_estimate": { + "type": "string", + "title": "Fee Estimate" + }, + "fee_line_items": { + "items": { + "$ref": "#/components/schemas/FeeLineView" + }, + "type": "array", + "title": "Fee Line Items" + }, + "fee_waiver_reason": { + "type": "string", + "title": "Fee Waiver Reason" + }, + "citations": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Citations" + }, + "response_draft": { + "type": "string", + "title": "Response Draft" + }, + "approval_notes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Approval Notes" + }, + "exports": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Exports" + }, + "documents": { + "items": { + "$ref": "#/components/schemas/RecordsDocumentView" + }, + "type": "array", + "title": "Documents" + }, + "release_packages": { + "items": { + "$ref": "#/components/schemas/ReleasePackageView" + }, + "type": "array", + "title": "Release Packages" + }, + "timeline": { + "items": { + "$ref": "#/components/schemas/TimelineView" + }, + "type": "array", + "title": "Timeline" + }, + "public_status_events": { + "items": { + "$ref": "#/components/schemas/PublicStatusView" + }, + "type": "array", + "title": "Public Status Events" + }, + "messages": { + "items": { + "$ref": "#/components/schemas/MessageView" + }, + "type": "array", + "title": "Messages" + }, + "deadline_reviewed_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Deadline Reviewed At Unix Seconds" + }, + "approved_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Approved At Unix Seconds" + }, + "fulfilled_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Fulfilled At Unix Seconds" + }, + "closed_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Closed At Unix Seconds" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "request_id", + "id", + "public_tracking_number", + "requester", + "requester_contact", + "submitted_via", + "summary", + "deadline", + "deadline_basis", + "status", + "assigned_to", + "clarification_notes", + "search_notes", + "search_sessions", + "exemption_reviews", + "exemption_decisions", + "fee_estimate", + "fee_line_items", + "fee_waiver_reason", + "citations", + "response_draft", + "approval_notes", + "exports", + "timeline", + "public_status_events", + "messages", + "deadline_reviewed_at_unix_seconds", + "approved_at_unix_seconds", + "fulfilled_at_unix_seconds", + "closed_at_unix_seconds", + "created_at_unix_seconds" + ], + "title": "RecordsView" + }, + "ReleasePackageView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "export_path": { + "type": "string", + "title": "Export Path" + }, + "package_hash": { + "type": "string", + "title": "Package Hash" + }, + "document_count": { + "type": "integer", + "title": "Document Count" + }, + "release_artifact_count": { + "type": "integer", + "title": "Release Artifact Count" + }, + "search_session_count": { + "type": "integer", + "title": "Search Session Count" + }, + "release_count": { + "type": "integer", + "title": "Release Count" + }, + "redacted_count": { + "type": "integer", + "title": "Redacted Count" + }, + "exempt_count": { + "type": "integer", + "title": "Exempt Count" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "export_path", + "package_hash", + "document_count", + "release_artifact_count", + "search_session_count", + "release_count", + "redacted_count", + "exempt_count", + "created_at_unix_seconds" + ], + "title": "ReleasePackageView" + }, + "RepeatLookup": { + "properties": { + "property_reference": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Property Reference" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "property_reference" + ], + "title": "RepeatLookup" + }, + "RequestCreate": { + "properties": { + "requester_name": { + "type": "string", + "maxLength": 255, + "title": "Requester Name" + }, + "requester_email": { + "anyOf": [ + { + "type": "string", + "maxLength": 255 + }, + { + "type": "null" + } + ], + "title": "Requester Email" + }, + "requester_phone": { + "anyOf": [ + { + "type": "string", + "maxLength": 50 + }, + { + "type": "null" + } + ], + "title": "Requester Phone" + }, + "requester_type": { + "anyOf": [ + { + "type": "string", + "maxLength": 100 + }, + { + "type": "null" + } + ], + "title": "Requester Type" + }, + "description": { + "type": "string", + "maxLength": 10000, + "title": "Description" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "priority": { + "type": "string", + "title": "Priority", + "default": "normal" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string", + "pattern": "^(narrow|moderate|broad)$" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + } + }, + "type": "object", + "required": [ + "requester_name", + "description" + ], + "title": "RequestCreate" + }, + "RequestDocumentAdd": { + "properties": { + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "relevance_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Relevance Note" + } + }, + "type": "object", + "required": [ + "document_id" + ], + "title": "RequestDocumentAdd" + }, + "RequestDocumentRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "relevance_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Relevance Note" + }, + "exemption_flags": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Exemption Flags" + }, + "inclusion_status": { + "$ref": "#/components/schemas/InclusionStatus" + }, + "attached_at": { + "type": "string", + "format": "date-time", + "title": "Attached At" + }, + "attached_by": { + "type": "string", + "format": "uuid", + "title": "Attached By" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "document_id", + "relevance_note", + "exemption_flags", + "inclusion_status", + "attached_at", + "attached_by" + ], + "title": "RequestDocumentRead" + }, + "RequestRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "requester_name": { + "type": "string", + "title": "Requester Name" + }, + "requester_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Email" + }, + "requester_phone": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Phone" + }, + "requester_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Type" + }, + "date_received": { + "type": "string", + "format": "date-time", + "title": "Date Received" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "description": { + "type": "string", + "title": "Description" + }, + "status": { + "$ref": "#/components/schemas/RequestStatus" + }, + "assigned_to": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "created_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "response_draft": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Response Draft" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + }, + "estimated_fee": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Estimated Fee" + }, + "fee_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Fee Status" + }, + "fee_waiver_requested": { + "type": "boolean", + "title": "Fee Waiver Requested", + "default": false + }, + "priority": { + "type": "string", + "title": "Priority", + "default": "normal" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + }, + "closed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Closed At" + }, + "closure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Closure Reason" + } + }, + "type": "object", + "required": [ + "id", + "requester_name", + "requester_email", + "date_received", + "statutory_deadline", + "description", + "status", + "assigned_to", + "created_by", + "created_at", + "response_draft", + "review_notes" + ], + "title": "RequestRead" + }, + "RequestStats": { + "properties": { + "total_requests": { + "type": "integer", + "title": "Total Requests" + }, + "by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "By Status" + }, + "approaching_deadline": { + "type": "integer", + "title": "Approaching Deadline" + }, + "overdue": { + "type": "integer", + "title": "Overdue" + } + }, + "type": "object", + "required": [ + "total_requests", + "by_status", + "approaching_deadline", + "overdue" + ], + "title": "RequestStats" + }, + "RequestStatus": { + "type": "string", + "enum": [ + "received", + "clarification_needed", + "assigned", + "searching", + "in_review", + "ready_for_release", + "drafted", + "approved", + "fulfilled", + "closed" + ], + "title": "RequestStatus" + }, + "RequestUpdate": { + "properties": { + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "status": { + "anyOf": [ + { + "$ref": "#/components/schemas/RequestStatus" + }, + { + "type": "null" + } + ] + }, + "assigned_to": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "response_draft": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Response Draft" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + } + }, + "type": "object", + "title": "RequestUpdate" + }, + "RequirementBundle": { + "properties": { + "requirement_id": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]{1,100}$", + "title": "Requirement Id" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "project_type": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Project Type" + }, + "source_reference": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Source Reference" + }, + "source_date": { + "type": "string", + "format": "date", + "title": "Source Date" + }, + "effective_on": { + "type": "string", + "format": "date", + "title": "Effective On" + }, + "dataset_kind": { + "type": "string", + "enum": [ + "municipal", + "fictional" + ], + "title": "Dataset Kind" + }, + "filename": { + "type": "string", + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$", + "title": "Filename" + }, + "content_base64": { + "type": "string", + "maxLength": 14000000, + "minLength": 1, + "title": "Content Base64" + }, + "sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Sha256" + }, + "materials": { + "items": { + "$ref": "#/components/schemas/Material" + }, + "type": "array", + "maxItems": 100, + "minItems": 1, + "title": "Materials" + }, + "pathway": { + "items": { + "$ref": "#/components/schemas/PathwayStep" + }, + "type": "array", + "maxItems": 100, + "title": "Pathway" + }, + "fee_link": { + "anyOf": [ + { + "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink" + }, + { + "type": "null" + } + ] + }, + "staff_note": { + "type": "string", + "maxLength": 4000, + "title": "Staff Note", + "default": "" + }, + "change_note": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Change Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requirement_id", + "title", + "jurisdiction", + "project_type", + "source_reference", + "source_date", + "effective_on", + "dataset_kind", + "filename", + "content_base64", + "sha256", + "materials", + "change_note" + ], + "title": "RequirementBundle" + }, + "ResponseLetterCreate": { + "properties": { + "template_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Template Id" + } + }, + "type": "object", + "title": "ResponseLetterCreate" + }, + "ResponseLetterRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "template_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Template Id" + }, + "generated_content": { + "type": "string", + "title": "Generated Content" + }, + "edited_content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Edited Content" + }, + "status": { + "type": "string", + "title": "Status" + }, + "generated_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Generated By" + }, + "approved_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Approved By" + }, + "sent_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Sent At" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "template_id", + "generated_content", + "edited_content", + "status", + "generated_by", + "approved_by", + "sent_at", + "created_at" + ], + "title": "ResponseLetterRead" + }, + "ResponseLetterUpdate": { + "properties": { + "edited_content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Edited Content" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + } + }, + "type": "object", + "title": "ResponseLetterUpdate" + }, + "ReviewInput": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "body": { + "type": "string", + "maxLength": 5000, + "title": "Body", + "default": "" + }, + "hasAltText": { + "type": "boolean", + "title": "Hasalttext", + "default": false + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "en" + } + }, + "additionalProperties": false, + "type": "object", + "title": "ReviewInput" + }, + "Revision": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + }, + "document": { + "$ref": "#/components/schemas/NoticeDraft" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence", + "document" + ], + "title": "Revision" + }, + "RewriteInput": { + "properties": { + "action": { + "type": "string", + "enum": [ + "plain-language", + "language-variant" + ], + "title": "Action" + }, + "text": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Text" + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "text" + ], + "title": "RewriteInput" + }, + "RewriteResult": { + "properties": { + "action": { + "type": "string", + "enum": [ + "plain-language", + "language-variant" + ], + "title": "Action" + }, + "text": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Text" + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "" + }, + "outcome": { + "type": "string", + "enum": [ + "generated", + "unavailable" + ], + "title": "Outcome" + }, + "generated": { + "anyOf": [ + { + "type": "string", + "maxLength": 100000 + }, + { + "type": "null" + } + ], + "title": "Generated" + }, + "model": { + "anyOf": [ + { + "type": "string", + "maxLength": 200 + }, + { + "type": "null" + } + ], + "title": "Model" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "text", + "outcome" + ], + "title": "RewriteResult" + }, + "Rule": { + "properties": { + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "zone_code": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Zone Code" + }, + "key": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Key" + }, + "section_number": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Section Number" + }, + "kind": { + "type": "string", + "enum": [ + "use", + "dimension" + ], + "title": "Kind" + }, + "value": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Value" + }, + "overlay_code": { + "anyOf": [ + { + "type": "string", + "maxLength": 255 + }, + { + "type": "null" + } + ], + "title": "Overlay Code" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "jurisdiction", + "zone_code", + "key", + "section_number", + "kind", + "value" + ], + "title": "Rule" + }, + "RuleTestMatch": { + "properties": { + "matched_text": { + "type": "string", + "title": "Matched Text" + }, + "start": { + "type": "integer", + "title": "Start" + }, + "end": { + "type": "integer", + "title": "End" + } + }, + "type": "object", + "required": [ + "matched_text", + "start", + "end" + ], + "title": "RuleTestMatch" + }, + "RuleTestRequest": { + "properties": { + "sample_text": { + "type": "string", + "title": "Sample Text" + } + }, + "type": "object", + "required": [ + "sample_text" + ], + "title": "RuleTestRequest" + }, + "RuleTestResponse": { + "properties": { + "rule_id": { + "type": "string", + "format": "uuid", + "title": "Rule Id" + }, + "rule_type": { + "type": "string", + "title": "Rule Type" + }, + "matched": { + "type": "boolean", + "title": "Matched" + }, + "matches": { + "items": { + "$ref": "#/components/schemas/RuleTestMatch" + }, + "type": "array", + "title": "Matches" + } + }, + "type": "object", + "required": [ + "rule_id", + "rule_type", + "matched", + "matches" + ], + "title": "RuleTestResponse" + }, + "RuleType": { + "type": "string", + "enum": [ + "regex", + "keyword", + "llm_prompt" + ], + "title": "RuleType" + }, + "SaveReview": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "body": { + "type": "string", + "maxLength": 5000, + "title": "Body", + "default": "" + }, + "hasAltText": { + "type": "boolean", + "title": "Hasalttext", + "default": false + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "en" + }, + "ai_analysis": { + "anyOf": [ + { + "type": "string", + "maxLength": 100000 + }, + { + "type": "null" + } + ], + "title": "Ai Analysis" + }, + "ai_analysis_model": { + "anyOf": [ + { + "type": "string", + "maxLength": 200 + }, + { + "type": "null" + } + ], + "title": "Ai Analysis Model" + }, + "ai_outcome": { + "type": "string", + "enum": [ + "generated", + "unavailable", + "failed" + ], + "title": "Ai Outcome" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "ai_outcome" + ], + "title": "SaveReview" + }, + "SearchFilterOptions": { + "properties": { + "file_types": { + "items": { + "type": "string" + }, + "type": "array", + "title": "File Types" + }, + "source_names": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Source Names" + }, + "departments": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array", + "title": "Departments", + "default": [] + }, + "date_range": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Date Range" + } + }, + "type": "object", + "required": [ + "file_types", + "source_names" + ], + "title": "SearchFilterOptions" + }, + "SearchInput": { + "properties": { + "query": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "SearchInput" + }, + "SearchNoteCommand": { + "properties": { + "action": { + "type": "string", + "const": "record-records-search", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/SearchNotePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "SearchNoteCommand" + }, + "SearchNotePayload": { + "properties": { + "sourceNote": { + "type": "string", + "minLength": 1, + "title": "Sourcenote" + }, + "citation": { + "type": "string", + "title": "Citation", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sourceNote" + ], + "title": "SearchNotePayload" + }, + "SearchReceiptCommand": { + "properties": { + "action": { + "type": "string", + "const": "record-records-search-session", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/SearchReceiptPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "SearchReceiptCommand" + }, + "SearchReceiptPayload": { + "properties": { + "searchQuery": { + "type": "string", + "minLength": 1, + "title": "Searchquery" + }, + "searchLocations": { + "type": "string", + "minLength": 1, + "title": "Searchlocations" + }, + "searchResultTitle": { + "type": "string", + "minLength": 1, + "title": "Searchresulttitle" + }, + "searchResultCitation": { + "type": "string", + "minLength": 1, + "title": "Searchresultcitation" + }, + "searchResultSummary": { + "type": "string", + "minLength": 1, + "title": "Searchresultsummary" + }, + "searchResultStatus": { + "type": "string", + "title": "Searchresultstatus", + "default": "" + }, + "searchReviewer": { + "type": "string", + "title": "Searchreviewer", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "searchQuery", + "searchLocations", + "searchResultTitle", + "searchResultCitation", + "searchResultSummary" + ], + "title": "SearchReceiptPayload" + }, + "SearchReceiptView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "query": { + "type": "string", + "title": "Query" + }, + "locations": { + "type": "string", + "title": "Locations" + }, + "reviewer": { + "type": "string", + "title": "Reviewer" + }, + "results": { + "items": { + "$ref": "#/components/schemas/SearchResultView" + }, + "type": "array", + "title": "Results" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "query", + "locations", + "reviewer", + "results", + "created_at_unix_seconds" + ], + "title": "SearchReceiptView" + }, + "SearchRequest": { + "properties": { + "query": { + "type": "string", + "title": "Query" + }, + "session_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Session Id" + }, + "filters": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Filters" + }, + "limit": { + "type": "integer", + "maximum": 50.0, + "title": "Limit", + "default": 10 + }, + "synthesize": { + "type": "boolean", + "title": "Synthesize", + "default": false + } + }, + "type": "object", + "required": [ + "query" + ], + "title": "SearchRequest" + }, + "SearchResponse": { + "properties": { + "query_id": { + "type": "string", + "format": "uuid", + "title": "Query Id" + }, + "session_id": { + "type": "string", + "format": "uuid", + "title": "Session Id" + }, + "query_text": { + "type": "string", + "title": "Query Text" + }, + "results": { + "items": { + "$ref": "#/components/schemas/SearchResultItem" + }, + "type": "array", + "title": "Results" + }, + "results_count": { + "type": "integer", + "title": "Results Count" + }, + "synthesized_answer": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Synthesized Answer" + }, + "ai_generated": { + "type": "boolean", + "title": "Ai Generated", + "default": false + } + }, + "type": "object", + "required": [ + "query_id", + "session_id", + "query_text", + "results", + "results_count" + ], + "title": "SearchResponse" + }, + "SearchResultItem": { + "properties": { + "chunk_id": { + "type": "string", + "format": "uuid", + "title": "Chunk Id" + }, + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "filename": { + "type": "string", + "title": "Filename" + }, + "file_type": { + "type": "string", + "title": "File Type" + }, + "source_path": { + "type": "string", + "title": "Source Path" + }, + "page_number": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Page Number" + }, + "content_text": { + "type": "string", + "title": "Content Text" + }, + "similarity_score": { + "type": "number", + "title": "Similarity Score" + }, + "rank": { + "type": "integer", + "title": "Rank" + } + }, + "type": "object", + "required": [ + "chunk_id", + "document_id", + "filename", + "file_type", + "source_path", + "page_number", + "content_text", + "similarity_score", + "rank" + ], + "title": "SearchResultItem" + }, + "SearchResultView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "title": { + "type": "string", + "title": "Title" + }, + "citation": { + "type": "string", + "title": "Citation" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "status": { + "type": "string", + "title": "Status" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "title", + "citation", + "summary", + "status" + ], + "title": "SearchResultView" + }, + "SearchSessionRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "user_id": { + "type": "string", + "format": "uuid", + "title": "User Id" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "queries": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array", + "title": "Queries", + "default": [] + } + }, + "type": "object", + "required": [ + "id", + "user_id", + "created_at" + ], + "title": "SearchSessionRead" + }, + "SectionCreate": { + "properties": { + "section_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Section Id" + }, + "chapter_id": { + "type": "string", + "minLength": 1, + "title": "Chapter Id" + }, + "section_number": { + "type": "string", + "minLength": 1, + "title": "Section Number" + }, + "section_heading": { + "type": "string", + "minLength": 1, + "title": "Section Heading" + }, + "parent_section_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parent Section Id" + }, + "sort_order": { + "type": "integer", + "title": "Sort Order", + "default": 0 + }, + "administrative_regulation_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Administrative Regulation Refs" + }, + "resolution_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Resolution Refs" + }, + "policy_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Policy Refs" + }, + "approved_summary_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Approved Summary Refs" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "chapter_id", + "section_number", + "section_heading" + ], + "title": "SectionCreate", + "description": "Request body for creating a code section or subsection." + }, + "SectionVersionCreate": { + "properties": { + "version_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Version Id" + }, + "section_id": { + "type": "string", + "minLength": 1, + "title": "Section Id" + }, + "source_id": { + "type": "string", + "minLength": 1, + "title": "Source Id" + }, + "version_label": { + "type": "string", + "minLength": 1, + "title": "Version Label" + }, + "body": { + "type": "string", + "minLength": 1, + "title": "Body" + }, + "effective_start": { + "type": "string", + "format": "date", + "title": "Effective Start" + }, + "effective_end": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective End" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + }, + "is_current": { + "type": "boolean", + "title": "Is Current", + "default": false + }, + "adoption_event_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Adoption Event Id" + }, + "amendment_event_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Amendment Event Id" + }, + "amendment_summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Amendment Summary" + }, + "prior_version_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Prior Version Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "section_id", + "source_id", + "version_label", + "body", + "effective_start" + ], + "title": "SectionVersionCreate", + "description": "Request body for adding an immutable section version." + }, + "Selection": { + "properties": { + "recording_id": { + "type": "string", + "format": "uuid", + "title": "Recording Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "recording_id", + "expected_sha256" + ], + "title": "Selection" + }, + "SentenceInput": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "citations": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Citations" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text" + ], + "title": "SentenceInput" + }, + "ServiceAccountCreate": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole", + "default": "read_only" + } + }, + "type": "object", + "required": [ + "name" + ], + "title": "ServiceAccountCreate" + }, + "ServiceAccountCreated": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "api_key": { + "type": "string", + "title": "Api Key" + } + }, + "type": "object", + "required": [ + "id", + "name", + "role", + "created_by", + "created_at", + "is_active", + "api_key" + ], + "title": "ServiceAccountCreated", + "description": "Returned only on creation — includes the plaintext API key (shown once)." + }, + "ServiceAccountRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + } + }, + "type": "object", + "required": [ + "id", + "name", + "role", + "created_by", + "created_at", + "is_active" + ], + "title": "ServiceAccountRead" + }, + "ServiceAccountUpdate": { + "properties": { + "role": { + "anyOf": [ + { + "$ref": "#/components/schemas/UserRole" + }, + { + "type": "null" + } + ] + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "ServiceAccountUpdate" + }, + "Snapshot": { + "properties": { + "expected_revision": { + "type": "string", + "format": "uuid", + "title": "Expected Revision" + }, + "visibility": { + "type": "string", + "enum": [ + "staff_only", + "public" + ], + "title": "Visibility" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "expected_revision", + "visibility" + ], + "title": "Snapshot" + }, + "SourceCreate": { + "properties": { + "source_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Id" + }, + "name": { + "type": "string", + "minLength": 1, + "title": "Name" + }, + "publisher": { + "type": "string", + "minLength": 1, + "title": "Publisher" + }, + "source_type": { + "type": "string", + "minLength": 1, + "title": "Source Type" + }, + "source_category": { + "type": "string", + "minLength": 1, + "title": "Source Category" + }, + "source_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Url" + }, + "file_reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "File Reference" + }, + "retrieved_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Retrieved At" + }, + "retrieval_method": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Retrieval Method" + }, + "checksum": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Checksum" + }, + "source_owner": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Owner" + }, + "is_official": { + "type": "boolean", + "title": "Is Official", + "default": true + }, + "official_status_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Official Status Note" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + }, + "staff_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Staff Notes" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "name", + "publisher", + "source_type", + "source_category" + ], + "title": "SourceCreate", + "description": "Request body for registering an official or explicitly labeled source." + }, + "SourceInput": { + "properties": { + "source_id": { + "type": "string", + "minLength": 1, + "title": "Source Id" + }, + "label": { + "type": "string", + "minLength": 1, + "title": "Label" + }, + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "label", + "text" + ], + "title": "SourceInput" + }, + "SourceSnapshot": { + "properties": { + "visibility": { + "type": "string", + "enum": [ + "public", + "staff_only" + ], + "title": "Visibility" + }, + "meeting_event_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "maxItems": 50, + "title": "Meeting Event Ids" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "visibility" + ], + "title": "SourceSnapshot" + }, + "SourceType": { + "type": "string", + "enum": [ + "manual_drop", + "file_system", + "rest_api", + "odbc" + ], + "title": "SourceType" + }, + "StaffRecordsIntake": { + "properties": { + "requester": { + "type": "string", + "minLength": 1, + "title": "Requester" + }, + "summary": { + "type": "string", + "minLength": 1, + "title": "Summary" + }, + "deadline": { + "type": "string", + "title": "Deadline" + }, + "deadlineBasis": { + "type": "string", + "title": "Deadlinebasis", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requester", + "summary", + "deadline" + ], + "title": "StaffRecordsIntake", + "description": "Existing native create-records-request input; no caller-supplied actor." + }, + "StandardsExplanation": { + "properties": { + "question": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Question" + }, + "process_section": { + "type": "string", + "maxLength": 255, + "title": "Process Section", + "default": "" + }, + "zone_code": { + "type": "string", + "maxLength": 40, + "title": "Zone Code", + "default": "" + }, + "rule_types": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 10, + "title": "Rule Types" + }, + "observed": { + "additionalProperties": { + "type": "string" + }, + "type": "object", + "title": "Observed" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "question" + ], + "title": "StandardsExplanation" + }, + "SyncFailureRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "source_id": { + "type": "string", + "format": "uuid", + "title": "Source Id" + }, + "source_path": { + "type": "string", + "title": "Source Path" + }, + "error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Message" + }, + "error_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Class" + }, + "http_status_code": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Http Status Code" + }, + "retry_count": { + "type": "integer", + "title": "Retry Count" + }, + "status": { + "type": "string", + "title": "Status" + }, + "first_failed_at": { + "type": "string", + "format": "date-time", + "title": "First Failed At" + }, + "last_retried_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Retried At" + }, + "dismissed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Dismissed At" + }, + "dismissed_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Dismissed By" + } + }, + "type": "object", + "required": [ + "id", + "source_id", + "source_path", + "error_message", + "error_class", + "http_status_code", + "retry_count", + "status", + "first_failed_at", + "last_retried_at", + "dismissed_at", + "dismissed_by" + ], + "title": "SyncFailureRead" + }, + "SyncRunLogRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "source_id": { + "type": "string", + "format": "uuid", + "title": "Source Id" + }, + "started_at": { + "type": "string", + "format": "date-time", + "title": "Started At" + }, + "finished_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Finished At" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + }, + "records_attempted": { + "type": "integer", + "title": "Records Attempted" + }, + "records_succeeded": { + "type": "integer", + "title": "Records Succeeded" + }, + "records_failed": { + "type": "integer", + "title": "Records Failed" + }, + "error_summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Summary" + } + }, + "type": "object", + "required": [ + "id", + "source_id", + "started_at", + "finished_at", + "status", + "records_attempted", + "records_succeeded", + "records_failed", + "error_summary" + ], + "title": "SyncRunLogRead" + }, + "SystemStatus": { + "properties": { + "version": { + "type": "string", + "title": "Version" + }, + "database": { + "type": "string", + "title": "Database" + }, + "ollama": { + "type": "string", + "title": "Ollama" + }, + "redis": { + "type": "string", + "title": "Redis" + }, + "user_count": { + "type": "integer", + "title": "User Count" + }, + "audit_log_count": { + "type": "integer", + "title": "Audit Log Count" + }, + "suite_session": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Suite Session" + } + }, + "type": "object", + "required": [ + "version", + "database", + "ollama", + "redis", + "user_count", + "audit_log_count" + ], + "title": "SystemStatus" + }, + "TaggedPlan": { + "properties": { + "action": { + "type": "string", + "const": "tagged-pdf", + "title": "Action" + }, + "headingLevels": { + "items": { + "type": "integer", + "maximum": 4294967295.0, + "minimum": 0.0 + }, + "type": "array", + "maxItems": 50, + "title": "Headinglevels" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "TaggedPlan" + }, + "TestConnectionRequest": { + "properties": { + "source_type": { + "type": "string", + "title": "Source Type" + }, + "host": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Host" + }, + "port": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Port" + }, + "path": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Path" + }, + "username": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Username" + }, + "password": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Password" + }, + "rest_api_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Rest Api Config" + }, + "odbc_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Odbc Config" + } + }, + "type": "object", + "required": [ + "source_type" + ], + "title": "TestConnectionRequest", + "description": "Dedicated schema for test-connection. NOT the create schema.\n\nSecurity: credentials in this request body are never persisted, never\nwritten to audit logs, and never returned in the response." + }, + "TestConnectionResponse": { + "properties": { + "success": { + "type": "boolean", + "title": "Success" + }, + "message": { + "type": "string", + "title": "Message" + }, + "latency_ms": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Latency Ms" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + }, + "warning": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Warning" + }, + "differing_keys": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Differing Keys" + } + }, + "type": "object", + "required": [ + "success", + "message" + ], + "title": "TestConnectionResponse" + }, + "TimelineEventCreate": { + "properties": { + "event_type": { + "type": "string", + "title": "Event Type" + }, + "description": { + "type": "string", + "title": "Description" + }, + "internal_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Internal Note" + } + }, + "type": "object", + "required": [ + "event_type", + "description" + ], + "title": "TimelineEventCreate" + }, + "TimelineEventRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "event_type": { + "type": "string", + "title": "Event Type" + }, + "actor_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Actor Id" + }, + "actor_role": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Actor Role" + }, + "description": { + "type": "string", + "title": "Description" + }, + "internal_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Internal Note" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "event_type", + "actor_id", + "actor_role", + "description", + "internal_note", + "created_at" + ], + "title": "TimelineEventRead" + }, + "TimelineView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "action": { + "type": "string", + "title": "Action" + }, + "actor": { + "type": "string", + "title": "Actor" + }, + "note": { + "type": "string", + "title": "Note" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "action", + "actor", + "note", + "created_at_unix_seconds" + ], + "title": "TimelineView" + }, + "TitleCreate": { + "properties": { + "title_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Title Id" + }, + "title_number": { + "type": "string", + "minLength": 1, + "title": "Title Number" + }, + "title_name": { + "type": "string", + "minLength": 1, + "title": "Title Name" + }, + "sort_order": { + "type": "integer", + "title": "Sort Order", + "default": 0 + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title_number", + "title_name" + ], + "title": "TitleCreate", + "description": "Request body for creating a code title." + }, + "TranscriptInput": { + "properties": { + "source_label": { + "type": "string", + "minLength": 1, + "title": "Source Label" + }, + "transcript_text": { + "type": "string", + "minLength": 1, + "title": "Transcript Text" + }, + "correction_of_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Correction Of Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_label", + "transcript_text" + ], + "title": "TranscriptInput" + }, + "UserRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "email": { + "type": "string", + "format": "email", + "title": "Email" + }, + "is_active": { + "type": "boolean", + "title": "Is Active", + "default": true + }, + "is_superuser": { + "type": "boolean", + "title": "Is Superuser", + "default": false + }, + "is_verified": { + "type": "boolean", + "title": "Is Verified", + "default": false + }, + "full_name": { + "type": "string", + "title": "Full Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "last_login": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Login" + }, + "must_change_password": { + "type": "boolean", + "title": "Must Change Password", + "default": false + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + } + }, + "type": "object", + "required": [ + "id", + "email", + "full_name", + "role", + "created_at", + "last_login" + ], + "title": "UserRead" + }, + "UserRole": { + "type": "string", + "enum": [ + "admin", + "staff", + "reviewer", + "read_only", + "liaison", + "public" + ], + "title": "UserRole" + }, + "UserSelfUpdate": { + "properties": { + "password": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Password" + }, + "email": { + "anyOf": [ + { + "type": "string", + "format": "email" + }, + { + "type": "null" + } + ], + "title": "Email" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + }, + "is_superuser": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Superuser" + }, + "is_verified": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Verified" + }, + "full_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Full Name" + } + }, + "type": "object", + "title": "UserSelfUpdate", + "description": "Schema for user self-update via PATCH /users/me.\n\nExcludes role and department_id. Any payload containing those fields is\nrejected at parse time (HTTP 422). Role and department changes require\nadmin privileges via /admin/users/{id}." + }, + "UserUpdateRequest": { + "properties": { + "full_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Full Name" + }, + "role": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Role" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "UserUpdateRequest" + }, + "ValidationError": { + "properties": { + "loc": { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "integer" + } + ] + }, + "type": "array", + "title": "Location" + }, + "msg": { + "type": "string", + "title": "Message" + }, + "type": { + "type": "string", + "title": "Error Type" + }, + "input": { + "title": "Input" + }, + "ctx": { + "type": "object", + "title": "Context" + } + }, + "type": "object", + "required": [ + "loc", + "msg", + "type" + ], + "title": "ValidationError" + }, + "Version": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence" + ], + "title": "Version" + }, + "VoteCorrection": { + "properties": { + "vote": { + "type": "string", + "minLength": 1, + "title": "Vote" + }, + "reason": { + "type": "string", + "minLength": 1, + "title": "Reason" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "vote", + "reason" + ], + "title": "VoteCorrection" + }, + "VoteInput": { + "properties": { + "voter_name": { + "type": "string", + "minLength": 1, + "title": "Voter Name" + }, + "vote": { + "type": "string", + "minLength": 1, + "title": "Vote" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "voter_name", + "vote" + ], + "title": "VoteInput" + }, + "_ParcelLookupIn": { + "properties": { + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "jurisdiction", + "query" + ], + "title": "_ParcelLookupIn" + }, + "townlight_inspections__workflow_models__SourceLink": { + "properties": { + "provider": { + "type": "string", + "const": "code", + "title": "Provider", + "default": "code" + }, + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "SourceLink" + }, + "townlight_permitting__workflow_models__SourceLink": { + "properties": { + "provider": { + "type": "string", + "enum": [ + "code", + "zoning" + ], + "title": "Provider" + }, + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "source_id", + "expected_sha256" + ], + "title": "SourceLink" + }, + "townlight_runtime__inspections_bridge__Search": { + "properties": { + "provider": { + "type": "string", + "const": "code", + "title": "Provider" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "query" + ], + "title": "Search" + }, + "townlight_runtime__notice_bridge__Review": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + }, + "note": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence", + "note" + ], + "title": "Review" + }, + "townlight_runtime__permitting_bridge__Import": { + "properties": { + "bundle": { + "$ref": "#/components/schemas/RequirementBundle" + }, + "expected_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "bundle" + ], + "title": "Import" + }, + "townlight_runtime__permitting_bridge__Search": { + "properties": { + "provider": { + "type": "string", + "enum": [ + "code", + "zoning" + ], + "title": "Provider" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "query" + ], + "title": "Search" + }, + "townlight_runtime__planning_bridge__Import": { + "properties": { + "bundle": { + "additionalProperties": true, + "type": "object", + "title": "Bundle" + }, + "expected_previous_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Expected Previous Revision" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "bundle" + ], + "title": "Import" + }, + "townlight_runtime__planning_bridge__Search": { + "properties": { + "query": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Query" + }, + "plan_type": { + "anyOf": [ + { + "type": "string", + "maxLength": 40 + }, + { + "type": "null" + } + ], + "title": "Plan Type" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "Search" + }, + "townlight_runtime__zoning_bridge__Review": { + "properties": { + "answer": { + "type": "string", + "maxLength": 10000, + "title": "Answer", + "default": "" + }, + "notes": { + "type": "string", + "maxLength": 10000, + "title": "Notes", + "default": "" + }, + "queue_status": { + "type": "string", + "enum": [ + "open", + "in_review", + "resolved", + "closed" + ], + "title": "Queue Status", + "default": "resolved" + } + }, + "additionalProperties": false, + "type": "object", + "title": "Review" + } + }, + "securitySchemes": { + "OAuth2PasswordBearer": { + "type": "oauth2", + "flows": { + "password": { + "scopes": {}, + "tokenUrl": "auth/jwt/login" + } + } + } + } + }, + "x-townlight-component": { + "view": "permitting", + "identity": "Townlight Permitting 0.3.0+dev.2", + "evidence": "source-schema-only" + } +} diff --git a/docs/beta-1/api/permitting.html b/docs/beta-1/api/permitting.html new file mode 100644 index 0000000..9b8dc83 --- /dev/null +++ b/docs/beta-1/api/permitting.html @@ -0,0 +1,12243 @@ +Townlight Permitting API reference
Townlight

Townlight Permitting API reference

+

Prepared source candidate, November 2, 2026. New signed Windows installed acceptance and publication remain pending.

+

Townlight Permitting 0.3.0+dev.2. The HTTP host is Townlight Records 1.8.0.dev2. Component package versions and the host API version are separate identities.

+

Generated from the actual native inspections-preview composition without application lifespan, migrations or database/network access. It describes route and validation contracts; it does not establish endpoint behavior, individual authorization or installed acceptance. Standalone product applications have separate deployment boundaries.

+

Machine-readable OpenAPI schema · Operating manual and limits

+

HTTP operations

+
POST /desktop/v1/permitting-sources/search +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Search Permitting Sources",
+  "operationId": "search_permitting_sources_desktop_v1_permitting_sources_search_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MeetingsSearch"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/permitting/cases +
{
+  "tags": [
+    "native-permitting"
+  ],
+  "summary": "Cases",
+  "operationId": "cases_desktop_v1_permitting_cases_get",
+  "parameters": [
+    {
+      "name": "offset",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 100000,
+        "minimum": 0,
+        "default": 0,
+        "title": "Offset"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/permitting/cases +
{
+  "tags": [
+    "native-permitting"
+  ],
+  "summary": "Create Case",
+  "operationId": "create_case_desktop_v1_permitting_cases_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/IntakeInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/permitting/cases/{case_id} +
{
+  "tags": [
+    "native-permitting"
+  ],
+  "summary": "Case",
+  "operationId": "case_desktop_v1_permitting_cases__case_id__get",
+  "parameters": [
+    {
+      "name": "case_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Case Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/permitting/cases/{case_id}/history +
{
+  "tags": [
+    "native-permitting"
+  ],
+  "summary": "History",
+  "operationId": "history_desktop_v1_permitting_cases__case_id__history_get",
+  "parameters": [
+    {
+      "name": "case_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Case Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/permitting/cases/{case_id}/packets +
{
+  "tags": [
+    "native-permitting"
+  ],
+  "summary": "Packet",
+  "operationId": "packet_desktop_v1_permitting_cases__case_id__packets_post",
+  "parameters": [
+    {
+      "name": "case_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Case Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/Packet"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/permitting/cases/{case_id}/revisions +
{
+  "tags": [
+    "native-permitting"
+  ],
+  "summary": "Revise",
+  "operationId": "revise_desktop_v1_permitting_cases__case_id__revisions_post",
+  "parameters": [
+    {
+      "name": "case_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Case Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/IntakeInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/permitting/connections/search +
{
+  "tags": [
+    "native-permitting"
+  ],
+  "summary": "Connections",
+  "operationId": "connections_desktop_v1_permitting_connections_search_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/townlight_runtime__permitting_bridge__Search"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/permitting/packets/{packet_id} +
{
+  "tags": [
+    "native-permitting"
+  ],
+  "summary": "Document",
+  "operationId": "document_desktop_v1_permitting_packets__packet_id__get",
+  "parameters": [
+    {
+      "name": "packet_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Packet Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/permitting/pathway +
{
+  "tags": [
+    "native-permitting"
+  ],
+  "summary": "Pathway",
+  "description": "Cited likely permit pathway, attachments and timeline; informational only.\n\n``use_model_assistance`` does not exist here: the resident live-model\nassistance flag (F-07) stays excluded, so only the deterministic cited\npathway is reachable from the shared shell.",
+  "operationId": "pathway_desktop_v1_permitting_pathway_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/Pathway"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/permitting/requirements +
{
+  "tags": [
+    "native-permitting"
+  ],
+  "summary": "Import Requirements",
+  "operationId": "import_requirements_desktop_v1_permitting_requirements_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/townlight_runtime__permitting_bridge__Import"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/permitting/requirements +
{
+  "tags": [
+    "native-permitting"
+  ],
+  "summary": "Requirements",
+  "operationId": "requirements_desktop_v1_permitting_requirements_get",
+  "parameters": [
+    {
+      "name": "offset",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 100000,
+        "minimum": 0,
+        "default": 0,
+        "title": "Offset"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/permitting/requirements/{revision_id} +
{
+  "tags": [
+    "native-permitting"
+  ],
+  "summary": "Requirement",
+  "operationId": "requirement_desktop_v1_permitting_requirements__revision_id__get",
+  "parameters": [
+    {
+      "name": "revision_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Revision Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+

Request and response data dictionary

+

Each schema includes the actual required fields, types, constraints and descriptions. References resolve against the machine-readable document.

+
ActionItemInput
+{
+  "properties": {
+    "description": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Description"
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "source_motion_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Motion Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "description"
+  ],
+  "title": "ActionItemInput"
+}
+
+
AdaPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "ada-title-ii",
+      "title": "Action"
+    },
+    "serviceArea": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Servicearea"
+    },
+    "hasCoordinatorReview": {
+      "type": "boolean",
+      "title": "Hascoordinatorreview",
+      "default": false
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "serviceArea"
+  ],
+  "title": "AdaPlan"
+}
+
+
AdminUserCreateRequest
+{
+  "properties": {
+    "email": {
+      "type": "string",
+      "title": "Email"
+    },
+    "password": {
+      "type": "string",
+      "title": "Password"
+    },
+    "full_name": {
+      "type": "string",
+      "title": "Full Name",
+      "default": ""
+    },
+    "role": {
+      "type": "string",
+      "title": "Role",
+      "default": "staff"
+    }
+  },
+  "type": "object",
+  "required": [
+    "email",
+    "password"
+  ],
+  "title": "AdminUserCreateRequest"
+}
+
+
AdminUserCreateResponse
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "email": {
+      "type": "string",
+      "title": "Email"
+    },
+    "full_name": {
+      "type": "string",
+      "title": "Full Name"
+    },
+    "role": {
+      "type": "string",
+      "title": "Role"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "email",
+    "full_name",
+    "role",
+    "is_active"
+  ],
+  "title": "AdminUserCreateResponse"
+}
+
+
AgendaAssignment
+{
+  "properties": {
+    "meeting_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Meeting Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "meeting_id"
+  ],
+  "title": "AgendaAssignment"
+}
+
+
AgendaInput
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "department_name": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Department Name"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "department_name"
+  ],
+  "title": "AgendaInput"
+}
+
+
AgendaReviewInput
+{
+  "properties": {
+    "to_status": {
+      "type": "string",
+      "enum": [
+        "DRAFTED",
+        "SUBMITTED",
+        "DEPT_APPROVED",
+        "LEGAL_REVIEWED",
+        "CLERK_ACCEPTED",
+        "ON_AGENDA",
+        "IN_PACKET",
+        "POSTED",
+        "HEARD",
+        "DISPOSED",
+        "ARCHIVED"
+      ],
+      "title": "To Status"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "to_status"
+  ],
+  "title": "AgendaReviewInput"
+}
+
+
AmendmentInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "policy": {
+      "$ref": "#/components/schemas/PolicySelection"
+    },
+    "proposal": {
+      "type": "string",
+      "maxLength": 20000,
+      "minLength": 1,
+      "title": "Proposal"
+    },
+    "responsible_staff": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Responsible Staff"
+    },
+    "status": {
+      "type": "string",
+      "enum": [
+        "draft",
+        "review",
+        "adopted",
+        "withdrawn"
+      ],
+      "title": "Status",
+      "default": "draft"
+    },
+    "review_note": {
+      "type": "string",
+      "maxLength": 5000,
+      "title": "Review Note",
+      "default": ""
+    },
+    "adoption_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Adoption Revision"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "policy",
+    "proposal",
+    "responsible_staff",
+    "note"
+  ],
+  "title": "AmendmentInput"
+}
+
+
AnalysisObservation
+{
+  "properties": {
+    "source": {
+      "type": "string",
+      "maxLength": 64,
+      "minLength": 1,
+      "title": "Source"
+    },
+    "filename": {
+      "type": "string",
+      "maxLength": 160,
+      "title": "Filename",
+      "default": ""
+    },
+    "media_type": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Media Type",
+      "default": ""
+    },
+    "text": {
+      "type": "string",
+      "maxLength": 4000,
+      "minLength": 1,
+      "title": "Text"
+    },
+    "adapter": {
+      "type": "string",
+      "maxLength": 120,
+      "title": "Adapter",
+      "default": ""
+    },
+    "citation_source_ids": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Citation Source Ids"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source",
+    "text"
+  ],
+  "title": "AnalysisObservation",
+  "description": "One draft observation, named with the adapter that actually produced it."
+}
+
+
AnalysisRecord
+{
+  "properties": {
+    "observations": {
+      "items": {
+        "$ref": "#/components/schemas/AnalysisObservation"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Observations"
+    },
+    "cited_sections": {
+      "items": {
+        "$ref": "#/components/schemas/CitedSection"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Cited Sections"
+    },
+    "unavailable": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Unavailable"
+    },
+    "runtime": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Runtime"
+    },
+    "review_required": {
+      "type": "boolean",
+      "title": "Review Required",
+      "default": true
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "AnalysisRecord",
+  "description": "The adapter output that accompanies a saved inspection draft."
+}
+
+
ApprovalCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "approve-records-response",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ApprovalPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "ApprovalCommand"
+}
+
+
ApprovalPayload
+{
+  "properties": {
+    "approvalNote": {
+      "type": "string",
+      "title": "Approvalnote",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "ApprovalPayload"
+}
+
+
ArchiveInput
+{
+  "properties": {
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "public",
+        "closed_session"
+      ],
+      "title": "Visibility"
+    },
+    "packet_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Packet Id"
+    },
+    "minutes_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Minutes Id"
+    },
+    "plain_language_summary": {
+      "type": "string",
+      "title": "Plain Language Summary",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "visibility"
+  ],
+  "title": "ArchiveInput"
+}
+
+
ArtifactPlan
+{
+  "properties": {
+    "artifact_id": {
+      "type": "string",
+      "title": "Artifact Id"
+    },
+    "file_name": {
+      "type": "string",
+      "title": "File Name"
+    },
+    "content": {
+      "type": "string",
+      "title": "Content"
+    },
+    "sha256": {
+      "type": "string",
+      "title": "Sha256"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "artifact_id",
+    "file_name",
+    "content",
+    "sha256",
+    "created_at_unix_seconds"
+  ],
+  "title": "ArtifactPlan"
+}
+
+
AssignCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "assign-records-request",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/AssignmentPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "AssignCommand"
+}
+
+
AssignmentPayload
+{
+  "properties": {
+    "assignedTo": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Assignedto"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "assignedTo"
+  ],
+  "title": "AssignmentPayload"
+}
+
+
AttachDocument
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation",
+      "default": ""
+    },
+    "file": {
+      "$ref": "#/components/schemas/ManagedFileReceipt"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "file"
+  ],
+  "title": "AttachDocument"
+}
+
+
AttachReleaseCopy
+{
+  "properties": {
+    "status": {
+      "type": "string",
+      "enum": [
+        "release-ready copy",
+        "redacted copy"
+      ],
+      "title": "Status"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note",
+      "default": ""
+    },
+    "added_by": {
+      "type": "string",
+      "title": "Added By",
+      "default": ""
+    },
+    "file": {
+      "$ref": "#/components/schemas/ManagedFileReceipt"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "status",
+    "file"
+  ],
+  "title": "AttachReleaseCopy"
+}
+
+
AuditChainVerification
+{
+  "properties": {
+    "is_valid": {
+      "type": "boolean",
+      "title": "Is Valid"
+    },
+    "entries_checked": {
+      "type": "integer",
+      "title": "Entries Checked"
+    },
+    "error_message": {
+      "type": "string",
+      "title": "Error Message"
+    }
+  },
+  "type": "object",
+  "required": [
+    "is_valid",
+    "entries_checked",
+    "error_message"
+  ],
+  "title": "AuditChainVerification"
+}
+
+
AuditLogRead
+{
+  "properties": {
+    "id": {
+      "type": "integer",
+      "title": "Id"
+    },
+    "prev_hash": {
+      "type": "string",
+      "title": "Prev Hash"
+    },
+    "entry_hash": {
+      "type": "string",
+      "title": "Entry Hash"
+    },
+    "timestamp": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Timestamp"
+    },
+    "user_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "User Id"
+    },
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "resource_type": {
+      "type": "string",
+      "title": "Resource Type"
+    },
+    "resource_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Resource Id"
+    },
+    "details": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Details"
+    },
+    "ai_generated": {
+      "type": "boolean",
+      "title": "Ai Generated"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "prev_hash",
+    "entry_hash",
+    "timestamp",
+    "user_id",
+    "action",
+    "resource_type",
+    "resource_id",
+    "details",
+    "ai_generated"
+  ],
+  "title": "AuditLogRead"
+}
+
+
AuditView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "module_id": {
+      "type": "string",
+      "title": "Module Id"
+    },
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    },
+    "previous_hash": {
+      "type": "string",
+      "title": "Previous Hash"
+    },
+    "entry_hash": {
+      "type": "string",
+      "title": "Entry Hash"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "module_id",
+    "action",
+    "summary",
+    "created_at_unix_seconds",
+    "previous_hash",
+    "entry_hash"
+  ],
+  "title": "AuditView"
+}
+
+
BearerResponse
+{
+  "properties": {
+    "access_token": {
+      "type": "string",
+      "title": "Access Token"
+    },
+    "token_type": {
+      "type": "string",
+      "title": "Token Type"
+    }
+  },
+  "type": "object",
+  "required": [
+    "access_token",
+    "token_type"
+  ],
+  "title": "BearerResponse"
+}
+
+
Body_auth_jwt_login_auth_jwt_login_post
+{
+  "properties": {
+    "grant_type": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^password$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Grant Type"
+    },
+    "username": {
+      "type": "string",
+      "title": "Username"
+    },
+    "password": {
+      "type": "string",
+      "format": "password",
+      "title": "Password"
+    },
+    "scope": {
+      "type": "string",
+      "title": "Scope",
+      "default": ""
+    },
+    "client_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Client Id"
+    },
+    "client_secret": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "format": "password",
+      "title": "Client Secret"
+    }
+  },
+  "type": "object",
+  "required": [
+    "username",
+    "password"
+  ],
+  "title": "Body_auth_jwt_login_auth_jwt_login_post"
+}
+
+
Body_upload_file_datasources_upload_post
+{
+  "properties": {
+    "file": {
+      "type": "string",
+      "contentMediaType": "application/octet-stream",
+      "title": "File"
+    }
+  },
+  "type": "object",
+  "required": [
+    "file"
+  ],
+  "title": "Body_upload_file_datasources_upload_post"
+}
+
+
CalculateDeadlineCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "calculate-records-deadline",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/CalculateDeadlinePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "CalculateDeadlineCommand"
+}
+
+
CalculateDeadlinePayload
+{
+  "properties": {
+    "deadlineReceivedDate": {
+      "type": "string",
+      "title": "Deadlinereceiveddate"
+    },
+    "deadlineRuleName": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Deadlinerulename"
+    },
+    "deadlineDayCount": {
+      "type": "string",
+      "title": "Deadlinedaycount"
+    },
+    "deadlineDayType": {
+      "type": "string",
+      "title": "Deadlinedaytype"
+    },
+    "deadlineBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Deadlinebasis"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "deadlineReceivedDate",
+    "deadlineRuleName",
+    "deadlineDayCount",
+    "deadlineDayType",
+    "deadlineBasis"
+  ],
+  "title": "CalculateDeadlinePayload"
+}
+
+
ChapterCreate
+{
+  "properties": {
+    "chapter_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Chapter Id"
+    },
+    "title_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title Id"
+    },
+    "chapter_number": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Chapter Number"
+    },
+    "chapter_name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Chapter Name"
+    },
+    "sort_order": {
+      "type": "integer",
+      "title": "Sort Order",
+      "default": 0
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title_id",
+    "chapter_number",
+    "chapter_name"
+  ],
+  "title": "ChapterCreate",
+  "description": "Request body for creating a code chapter."
+}
+
+
CitedSection
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "citation": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Citation"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "version": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Version",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "citation"
+  ],
+  "title": "CitedSection",
+  "description": "One resolved public Code section; never a caller-supplied quotation."
+}
+
+
CityProfileCreate
+{
+  "properties": {
+    "city_name": {
+      "type": "string",
+      "title": "City Name"
+    },
+    "state": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State"
+    },
+    "county": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "County"
+    },
+    "population_band": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Population Band"
+    },
+    "email_platform": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email Platform"
+    },
+    "has_dedicated_it": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Has Dedicated It"
+    },
+    "monthly_request_volume": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Monthly Request Volume"
+    },
+    "profile_data": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Profile Data",
+      "default": {}
+    },
+    "gap_map": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Gap Map",
+      "default": {}
+    }
+  },
+  "type": "object",
+  "required": [
+    "city_name"
+  ],
+  "title": "CityProfileCreate"
+}
+
+
CityProfileRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "city_name": {
+      "type": "string",
+      "title": "City Name"
+    },
+    "state": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State"
+    },
+    "county": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "County"
+    },
+    "population_band": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Population Band"
+    },
+    "email_platform": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email Platform"
+    },
+    "has_dedicated_it": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Has Dedicated It"
+    },
+    "monthly_request_volume": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Monthly Request Volume"
+    },
+    "onboarding_status": {
+      "type": "string",
+      "title": "Onboarding Status"
+    },
+    "profile_data": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Profile Data"
+    },
+    "gap_map": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Gap Map"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "updated_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "city_name",
+    "state",
+    "county",
+    "population_band",
+    "email_platform",
+    "has_dedicated_it",
+    "monthly_request_volume",
+    "onboarding_status",
+    "profile_data",
+    "gap_map",
+    "created_at",
+    "updated_at"
+  ],
+  "title": "CityProfileRead"
+}
+
+
CityProfileUpdate
+{
+  "properties": {
+    "city_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "City Name"
+    },
+    "state": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State"
+    },
+    "county": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "County"
+    },
+    "population_band": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Population Band"
+    },
+    "email_platform": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email Platform"
+    },
+    "has_dedicated_it": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Has Dedicated It"
+    },
+    "monthly_request_volume": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Monthly Request Volume"
+    },
+    "onboarding_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Onboarding Status"
+    },
+    "profile_data": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Profile Data"
+    },
+    "gap_map": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Gap Map"
+    }
+  },
+  "type": "object",
+  "title": "CityProfileUpdate"
+}
+
+
ClarificationCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "request-records-clarification",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ClarificationPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "ClarificationCommand"
+}
+
+
ClarificationPayload
+{
+  "properties": {
+    "clarificationNote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Clarificationnote"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "clarificationNote"
+  ],
+  "title": "ClarificationPayload"
+}
+
+
Closeout
+{
+  "properties": {
+    "decision_id": {
+      "type": "string",
+      "pattern": "^[A-Za-z0-9_-]{1,64}$",
+      "title": "Decision Id"
+    },
+    "version_id": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Version Id"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "version_label": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Version Label"
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 1000000,
+      "minLength": 1,
+      "title": "Body"
+    },
+    "effective_start": {
+      "type": "string",
+      "format": "date",
+      "title": "Effective Start"
+    },
+    "effective_end": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective End"
+    },
+    "is_current": {
+      "type": "boolean",
+      "title": "Is Current"
+    },
+    "reconciliation_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reconciliation Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "decision_id",
+    "version_id",
+    "source_id",
+    "version_label",
+    "body",
+    "effective_start",
+    "is_current"
+  ],
+  "title": "Closeout"
+}
+
+
CodeContext
+{
+  "properties": {
+    "section_number": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Section Number"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "section_number"
+  ],
+  "title": "CodeContext"
+}
+
+
CodeLink
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "const": "code",
+      "title": "Provider",
+      "default": "code"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "CodeLink"
+}
+
+
CodeSearch
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "CodeSearch"
+}
+
+
CodeSourceSelection
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 200,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "CodeSourceSelection"
+}
+
+
CompleteArtifact
+{
+  "properties": {
+    "export_path": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Export Path"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "export_path"
+  ],
+  "title": "CompleteArtifact"
+}
+
+
ConnectionSearch
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "enum": [
+        "meetings",
+        "zoning"
+      ],
+      "title": "Provider"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "query"
+  ],
+  "title": "ConnectionSearch"
+}
+
+
CoverageGapResponse
+{
+  "properties": {
+    "jurisdictions_without_rules": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Jurisdictions Without Rules"
+    },
+    "departments_without_staff": {
+      "items": {
+        "additionalProperties": true,
+        "type": "object"
+      },
+      "type": "array",
+      "title": "Departments Without Staff"
+    },
+    "uncovered_categories": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Uncovered Categories"
+    },
+    "total_gaps": {
+      "type": "integer",
+      "title": "Total Gaps"
+    }
+  },
+  "type": "object",
+  "required": [
+    "jurisdictions_without_rules",
+    "departments_without_staff",
+    "uncovered_categories",
+    "total_gaps"
+  ],
+  "title": "CoverageGapResponse"
+}
+
+
DataSourceAdminRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "source_type": {
+      "$ref": "#/components/schemas/SourceType"
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "type": "boolean",
+      "title": "Schedule Enabled",
+      "default": true
+    },
+    "next_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Next Sync At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "last_ingestion_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Ingestion At"
+    },
+    "last_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync At"
+    },
+    "last_sync_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync Status"
+    },
+    "last_error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Error Message"
+    },
+    "consecutive_failure_count": {
+      "type": "integer",
+      "title": "Consecutive Failure Count",
+      "default": 0
+    },
+    "sync_paused": {
+      "type": "boolean",
+      "title": "Sync Paused",
+      "default": false
+    },
+    "health_status": {
+      "type": "string",
+      "title": "Health Status",
+      "default": "healthy"
+    },
+    "active_failure_count": {
+      "type": "integer",
+      "title": "Active Failure Count",
+      "default": 0
+    },
+    "connector_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connector Type"
+    },
+    "updated_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Updated At"
+    },
+    "connection_config": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Connection Config"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "source_type",
+    "is_active",
+    "created_by",
+    "created_at",
+    "last_ingestion_at",
+    "connection_config"
+  ],
+  "title": "DataSourceAdminRead",
+  "description": "Full datasource shape including connection_config. Returned only by admin-gated endpoints."
+}
+
+
DataSourceCreate
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "source_type": {
+      "$ref": "#/components/schemas/SourceType"
+    },
+    "connection_config": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Connection Config",
+      "default": {}
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "type": "boolean",
+      "title": "Schedule Enabled",
+      "default": true
+    }
+  },
+  "type": "object",
+  "required": [
+    "name",
+    "source_type"
+  ],
+  "title": "DataSourceCreate"
+}
+
+
DataSourceRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "source_type": {
+      "$ref": "#/components/schemas/SourceType"
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "type": "boolean",
+      "title": "Schedule Enabled",
+      "default": true
+    },
+    "next_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Next Sync At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "last_ingestion_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Ingestion At"
+    },
+    "last_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync At"
+    },
+    "last_sync_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync Status"
+    },
+    "last_error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Error Message"
+    },
+    "consecutive_failure_count": {
+      "type": "integer",
+      "title": "Consecutive Failure Count",
+      "default": 0
+    },
+    "sync_paused": {
+      "type": "boolean",
+      "title": "Sync Paused",
+      "default": false
+    },
+    "health_status": {
+      "type": "string",
+      "title": "Health Status",
+      "default": "healthy"
+    },
+    "active_failure_count": {
+      "type": "integer",
+      "title": "Active Failure Count",
+      "default": 0
+    },
+    "connector_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connector Type"
+    },
+    "updated_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "source_type",
+    "is_active",
+    "created_by",
+    "created_at",
+    "last_ingestion_at"
+  ],
+  "title": "DataSourceRead",
+  "description": "Redacted datasource shape — safe for non-admin roles. connection_config omitted."
+}
+
+
DataSourceUpdate
+{
+  "properties": {
+    "name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Name"
+    },
+    "connection_config": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connection Config"
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Schedule Enabled"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "DataSourceUpdate"
+}
+
+
DeadlineCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "set-records-deadline",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/DeadlinePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "DeadlineCommand"
+}
+
+
DeadlinePayload
+{
+  "properties": {
+    "deadline": {
+      "type": "string",
+      "title": "Deadline"
+    },
+    "deadlineBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Deadlinebasis"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "deadline",
+    "deadlineBasis"
+  ],
+  "title": "DeadlinePayload"
+}
+
+
Decision
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "pattern": "^[A-Za-z0-9_-]{1,64}$",
+      "title": "Id"
+    },
+    "outcome": {
+      "type": "string",
+      "enum": [
+        "adopted",
+        "not_adopted",
+        "deferred",
+        "withdrawn"
+      ],
+      "title": "Outcome"
+    },
+    "decided_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Decided At"
+    },
+    "decision_text": {
+      "type": "string",
+      "maxLength": 1000000,
+      "minLength": 1,
+      "title": "Decision Text"
+    },
+    "supporting_references": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Supporting References"
+    },
+    "supersedes_decision_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^[A-Za-z0-9_-]{1,64}$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supersedes Decision Id"
+    },
+    "reconciliation_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reconciliation Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "outcome",
+    "decision_text"
+  ],
+  "title": "Decision"
+}
+
+
DepartmentCreate
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "code": {
+      "type": "string",
+      "title": "Code"
+    },
+    "contact_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Contact Email"
+    }
+  },
+  "type": "object",
+  "required": [
+    "name",
+    "code"
+  ],
+  "title": "DepartmentCreate"
+}
+
+
DepartmentRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "code": {
+      "type": "string",
+      "title": "Code"
+    },
+    "contact_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Contact Email"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "code",
+    "contact_email",
+    "created_at"
+  ],
+  "title": "DepartmentRead"
+}
+
+
DepartmentUpdate
+{
+  "properties": {
+    "name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Name"
+    },
+    "code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Code"
+    },
+    "contact_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Contact Email"
+    }
+  },
+  "type": "object",
+  "title": "DepartmentUpdate"
+}
+
+
DisclosureTemplateCreate
+{
+  "properties": {
+    "template_type": {
+      "type": "string",
+      "title": "Template Type"
+    },
+    "state_code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State Code"
+    },
+    "content": {
+      "type": "string",
+      "title": "Content"
+    }
+  },
+  "type": "object",
+  "required": [
+    "template_type",
+    "content"
+  ],
+  "title": "DisclosureTemplateCreate"
+}
+
+
DisclosureTemplateRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "template_type": {
+      "type": "string",
+      "title": "Template Type"
+    },
+    "state_code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State Code"
+    },
+    "content": {
+      "type": "string",
+      "title": "Content"
+    },
+    "version": {
+      "type": "integer",
+      "title": "Version"
+    },
+    "updated_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Updated By"
+    },
+    "updated_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "template_type",
+    "state_code",
+    "content",
+    "version",
+    "updated_by",
+    "updated_at"
+  ],
+  "title": "DisclosureTemplateRead"
+}
+
+
DisclosureTemplateRendered
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "template_type": {
+      "type": "string",
+      "title": "Template Type"
+    },
+    "rendered_content": {
+      "type": "string",
+      "title": "Rendered Content"
+    },
+    "has_unresolved_variables": {
+      "type": "boolean",
+      "title": "Has Unresolved Variables"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "template_type",
+    "rendered_content",
+    "has_unresolved_variables"
+  ],
+  "title": "DisclosureTemplateRendered"
+}
+
+
DisclosureTemplateUpdate
+{
+  "properties": {
+    "content": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Content"
+    },
+    "state_code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State Code"
+    }
+  },
+  "type": "object",
+  "title": "DisclosureTemplateUpdate"
+}
+
+
DocumentChunkRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "chunk_index": {
+      "type": "integer",
+      "title": "Chunk Index"
+    },
+    "content_text": {
+      "type": "string",
+      "title": "Content Text"
+    },
+    "token_count": {
+      "type": "integer",
+      "title": "Token Count"
+    },
+    "page_number": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Page Number"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "document_id",
+    "chunk_index",
+    "content_text",
+    "token_count",
+    "page_number"
+  ],
+  "title": "DocumentChunkRead"
+}
+
+
DocumentRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "source_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Source Id"
+    },
+    "source_path": {
+      "type": "string",
+      "title": "Source Path"
+    },
+    "filename": {
+      "type": "string",
+      "title": "Filename"
+    },
+    "file_type": {
+      "type": "string",
+      "title": "File Type"
+    },
+    "file_hash": {
+      "type": "string",
+      "title": "File Hash"
+    },
+    "file_size": {
+      "type": "integer",
+      "title": "File Size"
+    },
+    "ingestion_status": {
+      "$ref": "#/components/schemas/IngestionStatus"
+    },
+    "ingestion_error": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ingestion Error"
+    },
+    "chunk_count": {
+      "type": "integer",
+      "title": "Chunk Count"
+    },
+    "ingested_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ingested At"
+    },
+    "connector_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connector Type"
+    },
+    "updated_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "source_id",
+    "source_path",
+    "filename",
+    "file_type",
+    "file_hash",
+    "file_size",
+    "ingestion_status",
+    "ingestion_error",
+    "chunk_count",
+    "ingested_at"
+  ],
+  "title": "DocumentRead"
+}
+
+
DraftCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "draft-records-response",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/DraftPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "DraftCommand"
+}
+
+
DraftInput
+{
+  "properties": {
+    "source_materials": {
+      "items": {
+        "$ref": "#/components/schemas/SourceInput"
+      },
+      "type": "array",
+      "title": "Source Materials"
+    },
+    "sentences": {
+      "items": {
+        "$ref": "#/components/schemas/SentenceInput"
+      },
+      "type": "array",
+      "minItems": 1,
+      "title": "Sentences"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sentences"
+  ],
+  "title": "DraftInput"
+}
+
+
DraftPayload
+{
+  "properties": {
+    "responseDraft": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Responsedraft"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "responseDraft"
+  ],
+  "title": "DraftPayload"
+}
+
+
ErrorModel
+{
+  "properties": {
+    "detail": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "additionalProperties": {
+            "type": "string"
+          },
+          "type": "object"
+        }
+      ],
+      "title": "Detail"
+    }
+  },
+  "type": "object",
+  "required": [
+    "detail"
+  ],
+  "title": "ErrorModel"
+}
+
+
Evidence
+{
+  "properties": {
+    "filename": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$",
+      "title": "Filename"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Description"
+    },
+    "media_type": {
+      "type": "string",
+      "enum": [
+        "text/plain",
+        "image/jpeg",
+        "image/png",
+        "image/webp",
+        "application/pdf",
+        "audio/webm",
+        "audio/ogg",
+        "audio/wav",
+        "audio/mpeg",
+        "audio/mp4"
+      ],
+      "title": "Media Type"
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 14000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "filename",
+    "description",
+    "media_type",
+    "content_base64",
+    "sha256"
+  ],
+  "title": "Evidence"
+}
+
+
EvidenceItem
+{
+  "properties": {
+    "filename": {
+      "type": "string",
+      "maxLength": 151,
+      "minLength": 1,
+      "title": "Filename"
+    },
+    "media_type": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Media Type"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Description",
+      "default": ""
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 14000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "filename",
+    "media_type",
+    "content_base64",
+    "sha256"
+  ],
+  "title": "EvidenceItem"
+}
+
+
EvidenceItems
+{
+  "properties": {
+    "items": {
+      "items": {
+        "$ref": "#/components/schemas/EvidenceItem"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "minItems": 1,
+      "title": "Items"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "items"
+  ],
+  "title": "EvidenceItems"
+}
+
+
ExemptionAccuracyReport
+{
+  "properties": {
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "total_flags": {
+      "type": "integer",
+      "title": "Total Flags"
+    },
+    "accepted": {
+      "type": "integer",
+      "title": "Accepted"
+    },
+    "rejected": {
+      "type": "integer",
+      "title": "Rejected"
+    },
+    "pending": {
+      "type": "integer",
+      "title": "Pending"
+    },
+    "acceptance_rate": {
+      "type": "number",
+      "title": "Acceptance Rate"
+    }
+  },
+  "type": "object",
+  "required": [
+    "category",
+    "total_flags",
+    "accepted",
+    "rejected",
+    "pending",
+    "acceptance_rate"
+  ],
+  "title": "ExemptionAccuracyReport"
+}
+
+
ExemptionDashboard
+{
+  "properties": {
+    "total_flags": {
+      "type": "integer",
+      "title": "Total Flags"
+    },
+    "by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "By Status"
+    },
+    "by_category": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "By Category"
+    },
+    "acceptance_rate": {
+      "type": "number",
+      "title": "Acceptance Rate"
+    },
+    "total_rules": {
+      "type": "integer",
+      "title": "Total Rules"
+    },
+    "active_rules": {
+      "type": "integer",
+      "title": "Active Rules"
+    }
+  },
+  "type": "object",
+  "required": [
+    "total_flags",
+    "by_status",
+    "by_category",
+    "acceptance_rate",
+    "total_rules",
+    "active_rules"
+  ],
+  "title": "ExemptionDashboard"
+}
+
+
ExemptionDecisionCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-exemption-decision",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ExemptionDecisionPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "ExemptionDecisionCommand"
+}
+
+
ExemptionDecisionPayload
+{
+  "properties": {
+    "exemptionSource": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionsource"
+    },
+    "exemptionKind": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionkind"
+    },
+    "exemptionFinding": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionfinding"
+    },
+    "exemptionDecision": {
+      "type": "string",
+      "enum": [
+        "release",
+        "redact",
+        "exempt"
+      ],
+      "title": "Exemptiondecision"
+    },
+    "exemptionBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionbasis"
+    },
+    "exemptionReviewer": {
+      "type": "string",
+      "title": "Exemptionreviewer",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "exemptionSource",
+    "exemptionKind",
+    "exemptionFinding",
+    "exemptionDecision",
+    "exemptionBasis"
+  ],
+  "title": "ExemptionDecisionPayload"
+}
+
+
ExemptionDecisionView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "source": {
+      "type": "string",
+      "title": "Source"
+    },
+    "kind": {
+      "type": "string",
+      "title": "Kind"
+    },
+    "finding": {
+      "type": "string",
+      "title": "Finding"
+    },
+    "decision": {
+      "type": "string",
+      "enum": [
+        "release",
+        "redact",
+        "exempt"
+      ],
+      "title": "Decision"
+    },
+    "basis": {
+      "type": "string",
+      "title": "Basis"
+    },
+    "reviewer": {
+      "type": "string",
+      "title": "Reviewer"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "source",
+    "kind",
+    "finding",
+    "decision",
+    "basis",
+    "reviewer",
+    "created_at_unix_seconds"
+  ],
+  "title": "ExemptionDecisionView"
+}
+
+
ExemptionFlagRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "chunk_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Chunk Id"
+    },
+    "rule_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Rule Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "matched_text": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Matched Text"
+    },
+    "confidence": {
+      "type": "number",
+      "title": "Confidence"
+    },
+    "status": {
+      "$ref": "#/components/schemas/FlagStatus"
+    },
+    "reviewed_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reviewed By"
+    },
+    "reviewed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reviewed At"
+    },
+    "review_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Reason"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "chunk_id",
+    "rule_id",
+    "request_id",
+    "category",
+    "matched_text",
+    "confidence",
+    "status",
+    "reviewed_by",
+    "reviewed_at",
+    "review_reason",
+    "created_at"
+  ],
+  "title": "ExemptionFlagRead"
+}
+
+
ExemptionFlagReview
+{
+  "properties": {
+    "status": {
+      "$ref": "#/components/schemas/FlagStatus"
+    },
+    "review_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Reason"
+    }
+  },
+  "type": "object",
+  "required": [
+    "status"
+  ],
+  "title": "ExemptionFlagReview"
+}
+
+
ExemptionNoteCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-exemption-review",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ExemptionNotePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "ExemptionNoteCommand"
+}
+
+
ExemptionNotePayload
+{
+  "properties": {
+    "exemptionNote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionnote"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "exemptionNote"
+  ],
+  "title": "ExemptionNotePayload"
+}
+
+
ExemptionRuleCreate
+{
+  "properties": {
+    "state_code": {
+      "type": "string",
+      "title": "State Code"
+    },
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "rule_type": {
+      "$ref": "#/components/schemas/RuleType"
+    },
+    "rule_definition": {
+      "type": "string",
+      "title": "Rule Definition"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "enabled": {
+      "type": "boolean",
+      "title": "Enabled",
+      "default": true
+    }
+  },
+  "type": "object",
+  "required": [
+    "state_code",
+    "category",
+    "rule_type",
+    "rule_definition"
+  ],
+  "title": "ExemptionRuleCreate"
+}
+
+
ExemptionRuleRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "state_code": {
+      "type": "string",
+      "title": "State Code"
+    },
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "rule_type": {
+      "$ref": "#/components/schemas/RuleType"
+    },
+    "rule_definition": {
+      "type": "string",
+      "title": "Rule Definition"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "enabled": {
+      "type": "boolean",
+      "title": "Enabled"
+    },
+    "version": {
+      "type": "integer",
+      "title": "Version",
+      "default": 1
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "state_code",
+    "category",
+    "rule_type",
+    "rule_definition",
+    "description",
+    "enabled",
+    "created_by",
+    "created_at"
+  ],
+  "title": "ExemptionRuleRead"
+}
+
+
ExemptionRuleUpdate
+{
+  "properties": {
+    "rule_definition": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Rule Definition"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "enabled": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Enabled"
+    }
+  },
+  "type": "object",
+  "title": "ExemptionRuleUpdate"
+}
+
+
ExportReceipt
+{
+  "properties": {
+    "export_path": {
+      "type": "string",
+      "maxLength": 32768,
+      "minLength": 1,
+      "title": "Export Path"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "export_path"
+  ],
+  "title": "ExportReceipt"
+}
+
+
FeeEstimateCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "estimate-records-fee",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/FeeEstimatePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "FeeEstimateCommand"
+}
+
+
FeeEstimatePayload
+{
+  "properties": {
+    "feeEstimate": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feeestimate"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "feeEstimate"
+  ],
+  "title": "FeeEstimatePayload"
+}
+
+
FeeEstimateRequest
+{
+  "properties": {
+    "page_count": {
+      "type": "integer",
+      "title": "Page Count"
+    },
+    "fee_schedule_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Fee Schedule Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "page_count",
+    "fee_schedule_id"
+  ],
+  "title": "FeeEstimateRequest"
+}
+
+
FeeEstimateResponse
+{
+  "properties": {
+    "page_count": {
+      "type": "integer",
+      "title": "Page Count"
+    },
+    "unit_price": {
+      "type": "number",
+      "title": "Unit Price"
+    },
+    "total": {
+      "type": "number",
+      "title": "Total"
+    },
+    "fee_type": {
+      "type": "string",
+      "title": "Fee Type"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    }
+  },
+  "type": "object",
+  "required": [
+    "page_count",
+    "unit_price",
+    "total",
+    "fee_type",
+    "description"
+  ],
+  "title": "FeeEstimateResponse"
+}
+
+
FeeLineCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-fee-line",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/FeeLinePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "FeeLineCommand"
+}
+
+
FeeLineItemCreate
+{
+  "properties": {
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "quantity": {
+      "type": "integer",
+      "title": "Quantity",
+      "default": 1
+    },
+    "unit_price": {
+      "type": "number",
+      "title": "Unit Price"
+    },
+    "fee_schedule_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Schedule Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "description",
+    "unit_price"
+  ],
+  "title": "FeeLineItemCreate"
+}
+
+
FeeLineItemRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "fee_schedule_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Schedule Id"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "quantity": {
+      "type": "integer",
+      "title": "Quantity"
+    },
+    "unit_price": {
+      "type": "number",
+      "title": "Unit Price"
+    },
+    "total": {
+      "type": "number",
+      "title": "Total"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "fee_schedule_id",
+    "description",
+    "quantity",
+    "unit_price",
+    "total",
+    "status",
+    "created_at"
+  ],
+  "title": "FeeLineItemRead"
+}
+
+
FeeLinePayload
+{
+  "properties": {
+    "feeLineDescription": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feelinedescription"
+    },
+    "feeScheduleBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feeschedulebasis"
+    },
+    "feeLineAmount": {
+      "type": "string",
+      "title": "Feelineamount"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "feeLineDescription",
+    "feeScheduleBasis",
+    "feeLineAmount"
+  ],
+  "title": "FeeLinePayload"
+}
+
+
FeeLineView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "schedule_basis": {
+      "type": "string",
+      "title": "Schedule Basis"
+    },
+    "amount_cents": {
+      "type": "integer",
+      "title": "Amount Cents"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "description",
+    "schedule_basis",
+    "amount_cents",
+    "created_at_unix_seconds"
+  ],
+  "title": "FeeLineView"
+}
+
+
FeeScheduleCreate
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "title": "Jurisdiction"
+    },
+    "fee_type": {
+      "type": "string",
+      "title": "Fee Type"
+    },
+    "amount": {
+      "type": "number",
+      "title": "Amount"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "effective_date": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective Date"
+    }
+  },
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "fee_type",
+    "amount"
+  ],
+  "title": "FeeScheduleCreate"
+}
+
+
FeeScheduleRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "jurisdiction": {
+      "type": "string",
+      "title": "Jurisdiction"
+    },
+    "fee_type": {
+      "type": "string",
+      "title": "Fee Type"
+    },
+    "amount": {
+      "type": "number",
+      "title": "Amount"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "effective_date": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective Date"
+    },
+    "created_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "jurisdiction",
+    "fee_type",
+    "amount",
+    "description",
+    "effective_date",
+    "created_by",
+    "created_at"
+  ],
+  "title": "FeeScheduleRead"
+}
+
+
FeeScheduleUpdate
+{
+  "properties": {
+    "fee_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Type"
+    },
+    "amount": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Amount"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "effective_date": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective Date"
+    }
+  },
+  "type": "object",
+  "title": "FeeScheduleUpdate"
+}
+
+
FeeWaiverCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "waive-records-fee",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/FeeWaiverPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "FeeWaiverCommand"
+}
+
+
FeeWaiverCreateRequest
+{
+  "properties": {
+    "waiver_type": {
+      "type": "string",
+      "title": "Waiver Type"
+    },
+    "reason": {
+      "type": "string",
+      "title": "Reason"
+    }
+  },
+  "type": "object",
+  "required": [
+    "waiver_type",
+    "reason"
+  ],
+  "title": "FeeWaiverCreateRequest"
+}
+
+
FeeWaiverPayload
+{
+  "properties": {
+    "feeWaiverReason": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feewaiverreason"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "feeWaiverReason"
+  ],
+  "title": "FeeWaiverPayload"
+}
+
+
FeeWaiverReadResponse
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "waiver_type": {
+      "type": "string",
+      "title": "Waiver Type"
+    },
+    "reason": {
+      "type": "string",
+      "title": "Reason"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    },
+    "created_at": {
+      "type": "string",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "waiver_type",
+    "reason",
+    "status",
+    "created_at"
+  ],
+  "title": "FeeWaiverReadResponse"
+}
+
+
FeeWaiverReviewRequest
+{
+  "properties": {
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    }
+  },
+  "type": "object",
+  "required": [
+    "status"
+  ],
+  "title": "FeeWaiverReviewRequest"
+}
+
+
FinishCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "fulfill-records-request",
+        "close-records-request"
+      ],
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/NativePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "FinishCommand"
+}
+
+
FlagStatus
+{
+  "type": "string",
+  "enum": [
+    "flagged",
+    "reviewed",
+    "accepted",
+    "rejected"
+  ],
+  "title": "FlagStatus"
+}
+
+
FormPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "form-plan",
+      "title": "Action"
+    },
+    "formName": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Formname",
+      "default": ""
+    },
+    "fields": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 50,
+      "title": "Fields"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "FormPlan"
+}
+
+
GeneratedDraft
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "model": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Model"
+    },
+    "previous_response_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Previous Response Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text",
+    "model",
+    "previous_response_sha256"
+  ],
+  "title": "GeneratedDraft"
+}
+
+
HTTPValidationError
+{
+  "properties": {
+    "detail": {
+      "items": {
+        "$ref": "#/components/schemas/ValidationError"
+      },
+      "type": "array",
+      "title": "Detail"
+    }
+  },
+  "type": "object",
+  "title": "HTTPValidationError"
+}
+
+
Handoff
+{
+  "properties": {
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "request_id"
+  ],
+  "title": "Handoff"
+}
+
+
ImportBundleCreate
+{
+  "properties": {
+    "job_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Job Id"
+    },
+    "connector_type": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Connector Type"
+    },
+    "source": {
+      "$ref": "#/components/schemas/SourceCreate"
+    },
+    "sources": {
+      "items": {
+        "$ref": "#/components/schemas/SourceCreate"
+      },
+      "type": "array",
+      "title": "Sources"
+    },
+    "titles": {
+      "items": {
+        "$ref": "#/components/schemas/TitleCreate"
+      },
+      "type": "array",
+      "title": "Titles"
+    },
+    "chapters": {
+      "items": {
+        "$ref": "#/components/schemas/ChapterCreate"
+      },
+      "type": "array",
+      "title": "Chapters"
+    },
+    "sections": {
+      "items": {
+        "$ref": "#/components/schemas/SectionCreate"
+      },
+      "type": "array",
+      "title": "Sections"
+    },
+    "versions": {
+      "items": {
+        "$ref": "#/components/schemas/SectionVersionCreate"
+      },
+      "type": "array",
+      "title": "Versions"
+    },
+    "provenance": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Provenance"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "connector_type",
+    "source"
+  ],
+  "title": "ImportBundleCreate",
+  "description": "Request body for local fixture/file-drop import jobs."
+}
+
+
InclusionStatus
+{
+  "type": "string",
+  "enum": [
+    "included",
+    "excluded",
+    "pending"
+  ],
+  "title": "InclusionStatus"
+}
+
+
IngestionStats
+{
+  "properties": {
+    "total_sources": {
+      "type": "integer",
+      "title": "Total Sources"
+    },
+    "active_sources": {
+      "type": "integer",
+      "title": "Active Sources"
+    },
+    "total_documents": {
+      "type": "integer",
+      "title": "Total Documents"
+    },
+    "documents_by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "Documents By Status"
+    },
+    "total_chunks": {
+      "type": "integer",
+      "title": "Total Chunks"
+    }
+  },
+  "type": "object",
+  "required": [
+    "total_sources",
+    "active_sources",
+    "total_documents",
+    "documents_by_status",
+    "total_chunks"
+  ],
+  "title": "IngestionStats"
+}
+
+
IngestionStatus
+{
+  "type": "string",
+  "enum": [
+    "pending",
+    "processing",
+    "completed",
+    "failed"
+  ],
+  "title": "IngestionStatus"
+}
+
+
InitiativeInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "policy": {
+      "$ref": "#/components/schemas/PolicySelection"
+    },
+    "responsible_staff": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Responsible Staff"
+    },
+    "target": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "string"
+        }
+      ],
+      "title": "Target"
+    },
+    "unit": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Unit"
+    },
+    "due_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Due On"
+    },
+    "status": {
+      "type": "string",
+      "enum": [
+        "planned",
+        "active",
+        "completed",
+        "cancelled"
+      ],
+      "title": "Status",
+      "default": "planned"
+    },
+    "milestones": {
+      "items": {
+        "$ref": "#/components/schemas/Milestone"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "title": "Milestones"
+    },
+    "measurements": {
+      "items": {
+        "$ref": "#/components/schemas/Measurement"
+      },
+      "type": "array",
+      "maxItems": 1000,
+      "title": "Measurements"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "policy",
+    "responsible_staff",
+    "target",
+    "unit",
+    "due_on",
+    "note"
+  ],
+  "title": "InitiativeInput"
+}
+
+
InspectionInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "property_reference": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Property Reference"
+    },
+    "inspection_reference": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Inspection Reference"
+    },
+    "dataset_kind": {
+      "type": "string",
+      "enum": [
+        "municipal",
+        "fictional"
+      ],
+      "title": "Dataset Kind"
+    },
+    "inspector_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "minLength": 1,
+      "title": "Inspector Notes"
+    },
+    "photo_observations": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Photo Observations"
+    },
+    "voice_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Voice Notes",
+      "default": ""
+    },
+    "evidence": {
+      "items": {
+        "$ref": "#/components/schemas/Evidence"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "title": "Evidence"
+    },
+    "linked_sources": {
+      "items": {
+        "$ref": "#/components/schemas/townlight_inspections__workflow_models__SourceLink"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Linked Sources"
+    },
+    "assigned_to": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Assigned To",
+      "default": ""
+    },
+    "staff_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Staff Notes",
+      "default": ""
+    },
+    "notice_draft": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Notice Draft",
+      "default": ""
+    },
+    "review_state": {
+      "type": "string",
+      "enum": [
+        "draft",
+        "follow_up",
+        "reviewed"
+      ],
+      "title": "Review State",
+      "default": "draft"
+    },
+    "review_notes": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Review Notes",
+      "default": ""
+    },
+    "public_summary": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Public Summary",
+      "default": ""
+    },
+    "analysis": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/AnalysisRecord"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "property_reference",
+    "inspection_reference",
+    "dataset_kind",
+    "inspector_notes"
+  ],
+  "title": "InspectionInput"
+}
+
+
IntakeInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "project_name": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Project Name"
+    },
+    "project_description": {
+      "type": "string",
+      "maxLength": 10000,
+      "minLength": 1,
+      "title": "Project Description"
+    },
+    "location": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Location"
+    },
+    "applicant_contact": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Applicant Contact",
+      "default": ""
+    },
+    "requirement_revision": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Requirement Revision"
+    },
+    "materials": {
+      "items": {
+        "$ref": "#/components/schemas/MaterialReview"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "minItems": 1,
+      "title": "Materials"
+    },
+    "linked_sources": {
+      "items": {
+        "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Linked Sources"
+    },
+    "staff_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Staff Notes",
+      "default": ""
+    },
+    "assigned_to": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Assigned To",
+      "default": ""
+    },
+    "review_state": {
+      "type": "string",
+      "enum": [
+        "draft",
+        "follow_up",
+        "reviewed"
+      ],
+      "title": "Review State",
+      "default": "draft"
+    },
+    "review_notes": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Review Notes",
+      "default": ""
+    },
+    "public_summary": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Public Summary",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "project_name",
+    "project_description",
+    "location",
+    "requirement_revision",
+    "materials"
+  ],
+  "title": "IntakeInput"
+}
+
+
InterpretationNoteCreate
+{
+  "properties": {
+    "note_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Note Id"
+    },
+    "note_text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Note Text"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "note_text"
+  ],
+  "title": "InterpretationNoteCreate",
+  "description": "Request body for staff-only interpretation notes."
+}
+
+
InterviewRequest
+{
+  "properties": {
+    "last_answer": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Answer"
+    },
+    "last_field": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Field"
+    },
+    "skipped_fields": {
+      "anyOf": [
+        {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Skipped Fields"
+    }
+  },
+  "type": "object",
+  "title": "InterviewRequest"
+}
+
+
InterviewResponse
+{
+  "properties": {
+    "question": {
+      "type": "string",
+      "title": "Question"
+    },
+    "target_field": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Target Field"
+    },
+    "all_complete": {
+      "type": "boolean",
+      "title": "All Complete"
+    },
+    "completed_fields": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Completed Fields"
+    },
+    "onboarding_status": {
+      "type": "string",
+      "title": "Onboarding Status"
+    },
+    "skipped_fields": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Skipped Fields"
+    }
+  },
+  "type": "object",
+  "required": [
+    "question",
+    "target_field",
+    "all_complete",
+    "completed_fields",
+    "onboarding_status",
+    "skipped_fields"
+  ],
+  "title": "InterviewResponse"
+}
+
+
ManagedFileReceipt
+{
+  "properties": {
+    "original_path": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Original Path"
+    },
+    "stored_path": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Stored Path"
+    },
+    "file_name": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "File Name"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Sha256"
+    },
+    "size_bytes": {
+      "type": "integer",
+      "maximum": 2147483647.0,
+      "minimum": 0.0,
+      "title": "Size Bytes"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "original_path",
+    "stored_path",
+    "file_name",
+    "sha256",
+    "size_bytes"
+  ],
+  "title": "ManagedFileReceipt"
+}
+
+
ManagedSource
+{
+  "properties": {
+    "original_path": {
+      "type": "string",
+      "title": "Original Path"
+    },
+    "stored_path": {
+      "type": "string",
+      "title": "Stored Path"
+    },
+    "file_name": {
+      "type": "string",
+      "title": "File Name"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Sha256"
+    },
+    "size_bytes": {
+      "type": "integer",
+      "minimum": 0.0,
+      "title": "Size Bytes"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "original_path",
+    "stored_path",
+    "file_name",
+    "sha256",
+    "size_bytes"
+  ],
+  "title": "ManagedSource"
+}
+
+
Material
+{
+  "properties": {
+    "material_id": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9_-]{1,80}$",
+      "title": "Material Id"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Description"
+    },
+    "citation": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Citation"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "material_id",
+    "description",
+    "citation"
+  ],
+  "title": "Material"
+}
+
+
MaterialReview
+{
+  "properties": {
+    "material_id": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Material Id"
+    },
+    "status": {
+      "type": "string",
+      "enum": [
+        "not_reviewed",
+        "provided",
+        "missing",
+        "unclear"
+      ],
+      "title": "Status",
+      "default": "not_reviewed"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Note",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "material_id"
+  ],
+  "title": "MaterialReview"
+}
+
+
Measurement
+{
+  "properties": {
+    "recorded_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Recorded On"
+    },
+    "value": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "string"
+        }
+      ],
+      "title": "Value"
+    },
+    "evidence": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Evidence"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "recorded_on",
+    "value",
+    "evidence"
+  ],
+  "title": "Measurement"
+}
+
+
MediaAnalysis
+{
+  "properties": {
+    "items": {
+      "items": {
+        "$ref": "#/components/schemas/EvidenceItem"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "minItems": 1,
+      "title": "Items"
+    },
+    "code_links": {
+      "items": {
+        "$ref": "#/components/schemas/CodeLink"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Code Links"
+    },
+    "inspector_supplied_text": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Inspector Supplied Text",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "items"
+  ],
+  "title": "MediaAnalysis"
+}
+
+
MeetingInput
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "scheduled_start": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Scheduled Start"
+    },
+    "location": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Location"
+    },
+    "meeting_type": {
+      "type": "string",
+      "enum": [
+        "regular",
+        "special",
+        "emergency",
+        "closed_session",
+        "executive"
+      ],
+      "title": "Meeting Type",
+      "default": "regular"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "scheduled_start",
+    "location"
+  ],
+  "title": "MeetingInput"
+}
+
+
MeetingLink
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 200,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    },
+    "relation": {
+      "type": "string",
+      "enum": [
+        "hearing",
+        "context",
+        "precedent"
+      ],
+      "title": "Relation"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256",
+    "relation"
+  ],
+  "title": "MeetingLink"
+}
+
+
MeetingSearch
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "MeetingSearch"
+}
+
+
MeetingStageInput
+{
+  "properties": {
+    "to_status": {
+      "type": "string",
+      "enum": [
+        "SCHEDULED",
+        "NOTICED",
+        "PACKET_POSTED",
+        "IN_PROGRESS",
+        "RECESSED",
+        "ADJOURNED",
+        "TRANSCRIPT_READY",
+        "MINUTES_DRAFTED",
+        "MINUTES_POSTED",
+        "MINUTES_ADOPTED",
+        "MINUTES_SIGNED",
+        "ARCHIVED",
+        "CANCELLED"
+      ],
+      "title": "To Status"
+    },
+    "statutory_basis": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Basis"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "to_status"
+  ],
+  "title": "MeetingStageInput"
+}
+
+
MeetingsSearch
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "MeetingsSearch"
+}
+
+
MeetingsSourceSelection
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 200,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "MeetingsSourceSelection"
+}
+
+
MessageCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-message",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/MessagePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "MessageCommand"
+}
+
+
MessageCreate
+{
+  "properties": {
+    "message_text": {
+      "type": "string",
+      "title": "Message Text"
+    },
+    "is_internal": {
+      "type": "boolean",
+      "title": "Is Internal",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "message_text"
+  ],
+  "title": "MessageCreate"
+}
+
+
MessagePayload
+{
+  "properties": {
+    "requestMessageBody": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestmessagebody"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requestMessageBody"
+  ],
+  "title": "MessagePayload"
+}
+
+
MessageRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "sender_type": {
+      "type": "string",
+      "title": "Sender Type"
+    },
+    "sender_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sender Id"
+    },
+    "message_text": {
+      "type": "string",
+      "title": "Message Text"
+    },
+    "is_internal": {
+      "type": "boolean",
+      "title": "Is Internal"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "sender_type",
+    "sender_id",
+    "message_text",
+    "is_internal",
+    "created_at"
+  ],
+  "title": "MessageRead"
+}
+
+
MessageView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "author": {
+      "type": "string",
+      "title": "Author"
+    },
+    "author_role": {
+      "type": "string",
+      "title": "Author Role"
+    },
+    "body": {
+      "type": "string",
+      "title": "Body"
+    },
+    "visibility": {
+      "type": "string",
+      "title": "Visibility"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "author",
+    "author_role",
+    "body",
+    "visibility",
+    "created_at_unix_seconds"
+  ],
+  "title": "MessageView"
+}
+
+
Milestone
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "due_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Due On"
+    },
+    "completed_on": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Completed On"
+    },
+    "evidence": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Evidence",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "due_on"
+  ],
+  "title": "Milestone"
+}
+
+
MinutesDecision
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "post",
+        "adopt",
+        "sign"
+      ],
+      "title": "Action"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "MinutesDecision"
+}
+
+
ModelRegistryCreate
+{
+  "properties": {
+    "model_name": {
+      "type": "string",
+      "title": "Model Name"
+    },
+    "model_version": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Version"
+    },
+    "parameter_count": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parameter Count"
+    },
+    "license": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "License"
+    },
+    "model_card_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Card Url"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active",
+      "default": false
+    },
+    "context_window_size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Context Window Size"
+    },
+    "supports_ner": {
+      "type": "boolean",
+      "title": "Supports Ner",
+      "default": false
+    },
+    "supports_vision": {
+      "type": "boolean",
+      "title": "Supports Vision",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "model_name"
+  ],
+  "title": "ModelRegistryCreate",
+  "description": "Schema for creating a new model_registry record (POST body)."
+}
+
+
ModelRegistryRead
+{
+  "properties": {
+    "id": {
+      "type": "integer",
+      "title": "Id"
+    },
+    "model_name": {
+      "type": "string",
+      "title": "Model Name"
+    },
+    "model_version": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Version"
+    },
+    "parameter_count": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parameter Count"
+    },
+    "license": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "License"
+    },
+    "model_card_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Card Url"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "added_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Added At"
+    },
+    "context_window_size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Context Window Size"
+    },
+    "supports_ner": {
+      "type": "boolean",
+      "title": "Supports Ner"
+    },
+    "supports_vision": {
+      "type": "boolean",
+      "title": "Supports Vision"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "model_name",
+    "is_active",
+    "supports_ner",
+    "supports_vision"
+  ],
+  "title": "ModelRegistryRead",
+  "description": "Schema for returning a model_registry record (GET response).\n\n``from_attributes=True`` allows construction directly from an ORM instance."
+}
+
+
ModelRegistryUpdate
+{
+  "properties": {
+    "model_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Name"
+    },
+    "model_version": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Version"
+    },
+    "parameter_count": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parameter Count"
+    },
+    "license": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "License"
+    },
+    "model_card_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Card Url"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    },
+    "context_window_size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Context Window Size"
+    },
+    "supports_ner": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supports Ner"
+    },
+    "supports_vision": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supports Vision"
+    }
+  },
+  "type": "object",
+  "title": "ModelRegistryUpdate",
+  "description": "Schema for partially updating a model_registry record (PATCH body).\n\nEvery field is optional so callers can send only the fields they want to\nchange."
+}
+
+
MotionCorrection
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "reason": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Reason"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text",
+    "reason"
+  ],
+  "title": "MotionCorrection"
+}
+
+
MotionInput
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "seconded_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "minLength": 1
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Seconded By"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text"
+  ],
+  "title": "MotionInput"
+}
+
+
NativePayload
+{
+  "properties": {},
+  "additionalProperties": false,
+  "type": "object",
+  "title": "NativePayload"
+}
+
+
NativeRequestRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "requester_name": {
+      "type": "string",
+      "title": "Requester Name"
+    },
+    "requester_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Email"
+    },
+    "requester_phone": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Phone"
+    },
+    "requester_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Type"
+    },
+    "date_received": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Date Received"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "status": {
+      "$ref": "#/components/schemas/RequestStatus"
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "created_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "response_draft": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Response Draft"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    },
+    "estimated_fee": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Estimated Fee"
+    },
+    "fee_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Status"
+    },
+    "fee_waiver_requested": {
+      "type": "boolean",
+      "title": "Fee Waiver Requested",
+      "default": false
+    },
+    "priority": {
+      "type": "string",
+      "title": "Priority",
+      "default": "normal"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    },
+    "closed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closed At"
+    },
+    "closure_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closure Reason"
+    },
+    "desktop_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Desktop Id"
+    },
+    "public_tracking_number": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Public Tracking Number"
+    },
+    "submitted_via": {
+      "type": "string",
+      "title": "Submitted Via"
+    },
+    "deadline_label": {
+      "type": "string",
+      "title": "Deadline Label"
+    },
+    "deadline_basis": {
+      "type": "string",
+      "title": "Deadline Basis"
+    },
+    "deadline_reviewed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Deadline Reviewed At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "requester_name",
+    "requester_email",
+    "date_received",
+    "statutory_deadline",
+    "description",
+    "status",
+    "assigned_to",
+    "created_by",
+    "created_at",
+    "response_draft",
+    "review_notes",
+    "desktop_id",
+    "public_tracking_number",
+    "submitted_via",
+    "deadline_label",
+    "deadline_basis",
+    "deadline_reviewed_at"
+  ],
+  "title": "NativeRequestRead"
+}
+
+
NoticeDocumentInput
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text"
+  ],
+  "title": "NoticeDocumentInput"
+}
+
+
NoticeDraft
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 100000,
+      "minLength": 1,
+      "title": "Body"
+    },
+    "notice_type": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Notice Type"
+    },
+    "statutory_basis": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Statutory Basis"
+    },
+    "event_date": {
+      "type": "string",
+      "format": "date",
+      "title": "Event Date"
+    },
+    "lead_days": {
+      "type": "integer",
+      "maximum": 365.0,
+      "minimum": 0.0,
+      "title": "Lead Days"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "body",
+    "notice_type",
+    "statutory_basis",
+    "event_date",
+    "lead_days"
+  ],
+  "title": "NoticeDraft"
+}
+
+
NoticeInput
+{
+  "properties": {
+    "notice_type": {
+      "type": "string",
+      "enum": [
+        "regular",
+        "special",
+        "emergency",
+        "closed_session",
+        "executive"
+      ],
+      "title": "Notice Type"
+    },
+    "posted_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Posted At"
+    },
+    "minimum_notice_hours": {
+      "type": "integer",
+      "minimum": 0.0,
+      "title": "Minimum Notice Hours"
+    },
+    "statutory_basis": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Basis"
+    },
+    "approved_by": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Approved By"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "notice_type",
+    "posted_at",
+    "minimum_notice_hours"
+  ],
+  "title": "NoticeInput"
+}
+
+
NoticeProofInput
+{
+  "properties": {
+    "location": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Location"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note",
+      "default": ""
+    },
+    "document_delivery_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Document Delivery Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "location"
+  ],
+  "title": "NoticeProofInput"
+}
+
+
NotificationLogRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "template_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Template Id"
+    },
+    "recipient_email": {
+      "type": "string",
+      "title": "Recipient Email"
+    },
+    "request_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Request Id"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "sent_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sent At"
+    },
+    "error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Message"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "template_id",
+    "recipient_email",
+    "request_id",
+    "channel",
+    "status",
+    "sent_at",
+    "error_message",
+    "created_at"
+  ],
+  "title": "NotificationLogRead"
+}
+
+
NotificationTemplateCreate
+{
+  "properties": {
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel",
+      "default": "email"
+    },
+    "subject_template": {
+      "type": "string",
+      "title": "Subject Template"
+    },
+    "body_template": {
+      "type": "string",
+      "title": "Body Template"
+    }
+  },
+  "type": "object",
+  "required": [
+    "event_type",
+    "subject_template",
+    "body_template"
+  ],
+  "title": "NotificationTemplateCreate"
+}
+
+
NotificationTemplateRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel"
+    },
+    "subject_template": {
+      "type": "string",
+      "title": "Subject Template"
+    },
+    "body_template": {
+      "type": "string",
+      "title": "Body Template"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "event_type",
+    "channel",
+    "subject_template",
+    "body_template",
+    "is_active",
+    "created_at"
+  ],
+  "title": "NotificationTemplateRead"
+}
+
+
NotificationTemplateUpdate
+{
+  "properties": {
+    "subject_template": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Subject Template"
+    },
+    "body_template": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Body Template"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "NotificationTemplateUpdate"
+}
+
+
NotificationView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "notification_id": {
+      "type": "string",
+      "title": "Notification Id"
+    },
+    "module_id": {
+      "type": "string",
+      "title": "Module Id"
+    },
+    "record_id": {
+      "type": "string",
+      "title": "Record Id"
+    },
+    "audience": {
+      "type": "string",
+      "title": "Audience"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel"
+    },
+    "subject": {
+      "type": "string",
+      "title": "Subject"
+    },
+    "body": {
+      "type": "string",
+      "title": "Body"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    },
+    "sent_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sent At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "notification_id",
+    "module_id",
+    "record_id",
+    "audience",
+    "channel",
+    "subject",
+    "body",
+    "status",
+    "created_at_unix_seconds",
+    "sent_at_unix_seconds"
+  ],
+  "title": "NotificationView"
+}
+
+
OllamaModelInfo
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Size"
+    },
+    "details": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Details"
+    }
+  },
+  "type": "object",
+  "required": [
+    "name"
+  ],
+  "title": "OllamaModelInfo"
+}
+
+
OllamaStatus
+{
+  "properties": {
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "models": {
+      "items": {
+        "$ref": "#/components/schemas/OllamaModelInfo"
+      },
+      "type": "array",
+      "title": "Models"
+    }
+  },
+  "type": "object",
+  "required": [
+    "status",
+    "models"
+  ],
+  "title": "OllamaStatus"
+}
+
+
OperationalMetrics
+{
+  "properties": {
+    "average_response_time_days": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Average Response Time Days"
+    },
+    "median_response_time_days": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Median Response Time Days"
+    },
+    "requests_by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "Requests By Status"
+    },
+    "requests_by_department": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "Requests By Department"
+    },
+    "deadline_compliance_rate": {
+      "type": "number",
+      "title": "Deadline Compliance Rate"
+    },
+    "total_open": {
+      "type": "integer",
+      "title": "Total Open"
+    },
+    "total_closed": {
+      "type": "integer",
+      "title": "Total Closed"
+    },
+    "total_overdue": {
+      "type": "integer",
+      "title": "Total Overdue"
+    },
+    "clarification_frequency": {
+      "type": "number",
+      "title": "Clarification Frequency"
+    },
+    "top_request_topics": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Top Request Topics"
+    }
+  },
+  "type": "object",
+  "required": [
+    "average_response_time_days",
+    "median_response_time_days",
+    "requests_by_status",
+    "requests_by_department",
+    "deadline_compliance_rate",
+    "total_open",
+    "total_closed",
+    "total_overdue",
+    "clarification_frequency",
+    "top_request_topics"
+  ],
+  "title": "OperationalMetrics"
+}
+
+
Outline
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "question_ids": {
+      "items": {
+        "type": "string",
+        "format": "uuid"
+      },
+      "type": "array",
+      "maxItems": 50,
+      "minItems": 1,
+      "title": "Question Ids"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "question_ids"
+  ],
+  "title": "Outline"
+}
+
+
Packet
+{
+  "properties": {
+    "expected_revision": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Expected Revision"
+    },
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "staff_only",
+        "records_copy"
+      ],
+      "title": "Visibility"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "expected_revision",
+    "visibility"
+  ],
+  "title": "Packet"
+}
+
+
PacketInput
+{
+  "properties": {
+    "agenda_item_ids": {
+      "items": {
+        "type": "string",
+        "format": "uuid"
+      },
+      "type": "array",
+      "title": "Agenda Item Ids"
+    },
+    "source_files": {
+      "items": {
+        "$ref": "#/components/schemas/ManagedSource"
+      },
+      "type": "array",
+      "title": "Source Files"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "agenda_item_ids"
+  ],
+  "title": "PacketInput"
+}
+
+
Pathway
+{
+  "properties": {
+    "project_type": {
+      "type": "string",
+      "maxLength": 120,
+      "minLength": 1,
+      "title": "Project Type"
+    },
+    "proposal": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Proposal",
+      "default": ""
+    },
+    "location_context": {
+      "type": "string",
+      "maxLength": 1000,
+      "title": "Location Context",
+      "default": ""
+    },
+    "requirement_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requirement Revision"
+    },
+    "fee_link": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "project_type"
+  ],
+  "title": "Pathway"
+}
+
+
PathwayStep
+{
+  "properties": {
+    "step": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Step"
+    },
+    "citation": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Citation"
+    },
+    "typical_time": {
+      "type": "string",
+      "maxLength": 1000,
+      "title": "Typical Time",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "step",
+    "citation"
+  ],
+  "title": "PathwayStep"
+}
+
+
PlainLanguageSummaryCreate
+{
+  "properties": {
+    "summary_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Summary Id"
+    },
+    "section_version_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Version Id"
+    },
+    "summary_text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Summary Text"
+    },
+    "language_code": {
+      "type": "string",
+      "title": "Language Code",
+      "default": "en"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "section_version_id",
+    "summary_text"
+  ],
+  "title": "PlainLanguageSummaryCreate",
+  "description": "Request body for staff-drafted plain-language summaries."
+}
+
+
PolicySelection
+{
+  "properties": {
+    "plan_id": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Plan Id"
+    },
+    "revision_id": {
+      "type": "string",
+      "maxLength": 36,
+      "minLength": 36,
+      "title": "Revision Id"
+    },
+    "policy_id": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Policy Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "plan_id",
+    "revision_id",
+    "policy_id"
+  ],
+  "title": "PolicySelection"
+}
+
+
PortalModeResponse
+{
+  "properties": {
+    "mode": {
+      "type": "string",
+      "enum": [
+        "public",
+        "private"
+      ],
+      "title": "Mode",
+      "description": "Active portal posture for this deployment. ``public`` = minimal resident surface (landing + authenticated records-request submission + resident registration) reachable without staff auth. ``private`` = staff-only; no public routes, no resident self-registration."
+    }
+  },
+  "type": "object",
+  "required": [
+    "mode"
+  ],
+  "title": "PortalModeResponse",
+  "description": "T5D — schema for ``GET /config/portal-mode``.\n\nExposed to the frontend on boot so it can branch routing without a\nuser-identity lookup. The payload is intentionally the single field\nbelow — no staff config, no user state, no schema version."
+}
+
+
PrepareArtifact
+{
+  "properties": {
+    "kind": {
+      "type": "string",
+      "enum": [
+        "response",
+        "release-package"
+      ],
+      "title": "Kind"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "kind"
+  ],
+  "title": "PrepareArtifact"
+}
+
+
Proof
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    },
+    "filename": {
+      "type": "string",
+      "maxLength": 150,
+      "minLength": 1,
+      "title": "Filename"
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 7000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "location": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Location"
+    },
+    "published_at": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Published At"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence",
+    "filename",
+    "content_base64",
+    "location",
+    "published_at"
+  ],
+  "title": "Proof"
+}
+
+
Proposal
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "pattern": "^[A-Za-z0-9_-]{1,64}$",
+      "title": "Id"
+    },
+    "version_id": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Version Id"
+    },
+    "meeting_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Meeting Id"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "ordinance_number": {
+      "type": "string",
+      "maxLength": 120,
+      "minLength": 1,
+      "title": "Ordinance Number"
+    },
+    "proposed_text": {
+      "type": "string",
+      "maxLength": 1000000,
+      "minLength": 1,
+      "title": "Proposed Text"
+    },
+    "supersedes_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^[A-Za-z0-9_-]{1,64}$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supersedes Id"
+    },
+    "reconciliation_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reconciliation Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "version_id",
+    "meeting_id",
+    "title",
+    "ordinance_number",
+    "proposed_text"
+  ],
+  "title": "Proposal"
+}
+
+
PublicExplore
+{
+  "properties": {
+    "goal": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Goal",
+      "default": ""
+    },
+    "topic": {
+      "type": "string",
+      "maxLength": 160,
+      "title": "Topic",
+      "default": ""
+    },
+    "neighborhood": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Neighborhood",
+      "default": ""
+    },
+    "plan_type": {
+      "type": "string",
+      "maxLength": 120,
+      "title": "Plan Type",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "PublicExplore"
+}
+
+
PublicIntake
+{
+  "properties": {
+    "requester": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requester"
+    },
+    "requesterContact": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestercontact"
+    },
+    "summary": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Summary"
+    },
+    "deadline": {
+      "type": "string",
+      "title": "Deadline",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requester",
+    "requesterContact",
+    "summary"
+  ],
+  "title": "PublicIntake"
+}
+
+
PublicLookup
+{
+  "properties": {
+    "trackingNumber": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Trackingnumber"
+    },
+    "requesterContact": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestercontact"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "trackingNumber",
+    "requesterContact"
+  ],
+  "title": "PublicLookup"
+}
+
+
PublicMessage
+{
+  "properties": {
+    "trackingNumber": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Trackingnumber"
+    },
+    "requesterContact": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestercontact"
+    },
+    "publicRequestMessage": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Publicrequestmessage"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "trackingNumber",
+    "requesterContact",
+    "publicRequestMessage"
+  ],
+  "title": "PublicMessage"
+}
+
+
PublicStatusView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "label": {
+      "type": "string",
+      "title": "Label"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "label",
+    "summary",
+    "status",
+    "created_at_unix_seconds"
+  ],
+  "title": "PublicStatusView"
+}
+
+
PublicationView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "source_module": {
+      "type": "string",
+      "title": "Source Module"
+    },
+    "source_record_id": {
+      "type": "string",
+      "title": "Source Record Id"
+    },
+    "record_type": {
+      "type": "string",
+      "title": "Record Type"
+    },
+    "public_payload": {
+      "type": "string",
+      "title": "Public Payload"
+    },
+    "payload_hash": {
+      "type": "string",
+      "title": "Payload Hash"
+    },
+    "published_at_unix_seconds": {
+      "type": "integer",
+      "title": "Published At Unix Seconds"
+    },
+    "retracted_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Retracted At Unix Seconds"
+    },
+    "retracted_by": {
+      "type": "string",
+      "title": "Retracted By",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "source_module",
+    "source_record_id",
+    "record_type",
+    "public_payload",
+    "payload_hash",
+    "published_at_unix_seconds"
+  ],
+  "title": "PublicationView"
+}
+
+
PublishingPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "publishing-workflow",
+      "title": "Action"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "hasReview": {
+      "type": "boolean",
+      "title": "Hasreview",
+      "default": false
+    },
+    "hasPlainLanguage": {
+      "type": "boolean",
+      "title": "Hasplainlanguage",
+      "default": false
+    },
+    "hasTranslationReview": {
+      "type": "boolean",
+      "title": "Hastranslationreview",
+      "default": false
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "PublishingPlan"
+}
+
+
Question
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    },
+    "question": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Question"
+    },
+    "kind": {
+      "type": "string",
+      "enum": [
+        "use",
+        "dimension"
+      ],
+      "title": "Kind"
+    },
+    "key": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Key"
+    },
+    "audience": {
+      "type": "string",
+      "enum": [
+        "resident",
+        "staff"
+      ],
+      "title": "Audience",
+      "default": "resident"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "query",
+    "question",
+    "kind",
+    "key"
+  ],
+  "title": "Question"
+}
+
+
QuestionAnswerRequest
+{
+  "properties": {
+    "question": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Question"
+    },
+    "section_number": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Section Number"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "question"
+  ],
+  "title": "QuestionAnswerRequest",
+  "description": "Request body for citation-grounded code Q&A."
+}
+
+
RecordsDocumentView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "attachment_id": {
+      "type": "string",
+      "title": "Attachment Id"
+    },
+    "title": {
+      "type": "string",
+      "title": "Title"
+    },
+    "original_path": {
+      "type": "string",
+      "title": "Original Path"
+    },
+    "stored_path": {
+      "type": "string",
+      "title": "Stored Path"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation"
+    },
+    "sha256": {
+      "type": "string",
+      "title": "Sha256"
+    },
+    "size_bytes": {
+      "type": "integer",
+      "title": "Size Bytes"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "added_by": {
+      "type": "string",
+      "title": "Added By"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    },
+    "release_original_path": {
+      "type": "string",
+      "title": "Release Original Path",
+      "default": ""
+    },
+    "release_stored_path": {
+      "type": "string",
+      "title": "Release Stored Path",
+      "default": ""
+    },
+    "release_file_name": {
+      "type": "string",
+      "title": "Release File Name",
+      "default": ""
+    },
+    "release_sha256": {
+      "type": "string",
+      "title": "Release Sha256",
+      "default": ""
+    },
+    "release_size_bytes": {
+      "type": "integer",
+      "title": "Release Size Bytes",
+      "default": 0
+    },
+    "release_status": {
+      "type": "string",
+      "title": "Release Status",
+      "default": ""
+    },
+    "release_note": {
+      "type": "string",
+      "title": "Release Note",
+      "default": ""
+    },
+    "release_added_by": {
+      "type": "string",
+      "title": "Release Added By",
+      "default": ""
+    },
+    "release_added_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Release Added At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "attachment_id",
+    "title",
+    "original_path",
+    "stored_path",
+    "citation",
+    "sha256",
+    "size_bytes",
+    "status",
+    "added_by",
+    "created_at_unix_seconds"
+  ],
+  "title": "RecordsDocumentView"
+}
+
+
RecordsOperationRead
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "message": {
+      "type": "string",
+      "title": "Message"
+    },
+    "request": {
+      "$ref": "#/components/schemas/RecordsView"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "message",
+    "request"
+  ],
+  "title": "RecordsOperationRead"
+}
+
+
RecordsStateRead
+{
+  "properties": {
+    "demo_fixture": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Demo Fixture"
+    },
+    "records_requests": {
+      "items": {
+        "$ref": "#/components/schemas/RecordsView"
+      },
+      "type": "array",
+      "title": "Records Requests"
+    },
+    "notification_events": {
+      "items": {
+        "$ref": "#/components/schemas/NotificationView"
+      },
+      "type": "array",
+      "title": "Notification Events"
+    },
+    "publication_events": {
+      "items": {
+        "$ref": "#/components/schemas/PublicationView"
+      },
+      "type": "array",
+      "title": "Publication Events"
+    },
+    "audit_entries": {
+      "items": {
+        "$ref": "#/components/schemas/AuditView"
+      },
+      "type": "array",
+      "title": "Audit Entries"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "records_requests"
+  ],
+  "title": "RecordsStateRead"
+}
+
+
RecordsView
+{
+  "properties": {
+    "request_id": {
+      "type": "string",
+      "title": "Request Id"
+    },
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "public_tracking_number": {
+      "type": "string",
+      "title": "Public Tracking Number"
+    },
+    "requester": {
+      "type": "string",
+      "title": "Requester"
+    },
+    "requester_contact": {
+      "type": "string",
+      "title": "Requester Contact"
+    },
+    "submitted_via": {
+      "type": "string",
+      "title": "Submitted Via"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "deadline": {
+      "type": "string",
+      "title": "Deadline"
+    },
+    "deadline_basis": {
+      "type": "string",
+      "title": "Deadline Basis"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "assigned_to": {
+      "type": "string",
+      "title": "Assigned To"
+    },
+    "clarification_notes": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Clarification Notes"
+    },
+    "search_notes": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Search Notes"
+    },
+    "search_sessions": {
+      "items": {
+        "$ref": "#/components/schemas/SearchReceiptView"
+      },
+      "type": "array",
+      "title": "Search Sessions"
+    },
+    "exemption_reviews": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Exemption Reviews"
+    },
+    "exemption_decisions": {
+      "items": {
+        "$ref": "#/components/schemas/ExemptionDecisionView"
+      },
+      "type": "array",
+      "title": "Exemption Decisions"
+    },
+    "fee_estimate": {
+      "type": "string",
+      "title": "Fee Estimate"
+    },
+    "fee_line_items": {
+      "items": {
+        "$ref": "#/components/schemas/FeeLineView"
+      },
+      "type": "array",
+      "title": "Fee Line Items"
+    },
+    "fee_waiver_reason": {
+      "type": "string",
+      "title": "Fee Waiver Reason"
+    },
+    "citations": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Citations"
+    },
+    "response_draft": {
+      "type": "string",
+      "title": "Response Draft"
+    },
+    "approval_notes": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Approval Notes"
+    },
+    "exports": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Exports"
+    },
+    "documents": {
+      "items": {
+        "$ref": "#/components/schemas/RecordsDocumentView"
+      },
+      "type": "array",
+      "title": "Documents"
+    },
+    "release_packages": {
+      "items": {
+        "$ref": "#/components/schemas/ReleasePackageView"
+      },
+      "type": "array",
+      "title": "Release Packages"
+    },
+    "timeline": {
+      "items": {
+        "$ref": "#/components/schemas/TimelineView"
+      },
+      "type": "array",
+      "title": "Timeline"
+    },
+    "public_status_events": {
+      "items": {
+        "$ref": "#/components/schemas/PublicStatusView"
+      },
+      "type": "array",
+      "title": "Public Status Events"
+    },
+    "messages": {
+      "items": {
+        "$ref": "#/components/schemas/MessageView"
+      },
+      "type": "array",
+      "title": "Messages"
+    },
+    "deadline_reviewed_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Deadline Reviewed At Unix Seconds"
+    },
+    "approved_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Approved At Unix Seconds"
+    },
+    "fulfilled_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fulfilled At Unix Seconds"
+    },
+    "closed_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closed At Unix Seconds"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "request_id",
+    "id",
+    "public_tracking_number",
+    "requester",
+    "requester_contact",
+    "submitted_via",
+    "summary",
+    "deadline",
+    "deadline_basis",
+    "status",
+    "assigned_to",
+    "clarification_notes",
+    "search_notes",
+    "search_sessions",
+    "exemption_reviews",
+    "exemption_decisions",
+    "fee_estimate",
+    "fee_line_items",
+    "fee_waiver_reason",
+    "citations",
+    "response_draft",
+    "approval_notes",
+    "exports",
+    "timeline",
+    "public_status_events",
+    "messages",
+    "deadline_reviewed_at_unix_seconds",
+    "approved_at_unix_seconds",
+    "fulfilled_at_unix_seconds",
+    "closed_at_unix_seconds",
+    "created_at_unix_seconds"
+  ],
+  "title": "RecordsView"
+}
+
+
ReleasePackageView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "export_path": {
+      "type": "string",
+      "title": "Export Path"
+    },
+    "package_hash": {
+      "type": "string",
+      "title": "Package Hash"
+    },
+    "document_count": {
+      "type": "integer",
+      "title": "Document Count"
+    },
+    "release_artifact_count": {
+      "type": "integer",
+      "title": "Release Artifact Count"
+    },
+    "search_session_count": {
+      "type": "integer",
+      "title": "Search Session Count"
+    },
+    "release_count": {
+      "type": "integer",
+      "title": "Release Count"
+    },
+    "redacted_count": {
+      "type": "integer",
+      "title": "Redacted Count"
+    },
+    "exempt_count": {
+      "type": "integer",
+      "title": "Exempt Count"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "export_path",
+    "package_hash",
+    "document_count",
+    "release_artifact_count",
+    "search_session_count",
+    "release_count",
+    "redacted_count",
+    "exempt_count",
+    "created_at_unix_seconds"
+  ],
+  "title": "ReleasePackageView"
+}
+
+
RepeatLookup
+{
+  "properties": {
+    "property_reference": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Property Reference"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "property_reference"
+  ],
+  "title": "RepeatLookup"
+}
+
+
RequestCreate
+{
+  "properties": {
+    "requester_name": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Requester Name"
+    },
+    "requester_email": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 255
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Email"
+    },
+    "requester_phone": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 50
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Phone"
+    },
+    "requester_type": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 100
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Type"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Description"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "priority": {
+      "type": "string",
+      "title": "Priority",
+      "default": "normal"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^(narrow|moderate|broad)$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "requester_name",
+    "description"
+  ],
+  "title": "RequestCreate"
+}
+
+
RequestDocumentAdd
+{
+  "properties": {
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "relevance_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Relevance Note"
+    }
+  },
+  "type": "object",
+  "required": [
+    "document_id"
+  ],
+  "title": "RequestDocumentAdd"
+}
+
+
RequestDocumentRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "relevance_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Relevance Note"
+    },
+    "exemption_flags": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Exemption Flags"
+    },
+    "inclusion_status": {
+      "$ref": "#/components/schemas/InclusionStatus"
+    },
+    "attached_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Attached At"
+    },
+    "attached_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Attached By"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "document_id",
+    "relevance_note",
+    "exemption_flags",
+    "inclusion_status",
+    "attached_at",
+    "attached_by"
+  ],
+  "title": "RequestDocumentRead"
+}
+
+
RequestRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "requester_name": {
+      "type": "string",
+      "title": "Requester Name"
+    },
+    "requester_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Email"
+    },
+    "requester_phone": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Phone"
+    },
+    "requester_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Type"
+    },
+    "date_received": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Date Received"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "status": {
+      "$ref": "#/components/schemas/RequestStatus"
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "created_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "response_draft": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Response Draft"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    },
+    "estimated_fee": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Estimated Fee"
+    },
+    "fee_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Status"
+    },
+    "fee_waiver_requested": {
+      "type": "boolean",
+      "title": "Fee Waiver Requested",
+      "default": false
+    },
+    "priority": {
+      "type": "string",
+      "title": "Priority",
+      "default": "normal"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    },
+    "closed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closed At"
+    },
+    "closure_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closure Reason"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "requester_name",
+    "requester_email",
+    "date_received",
+    "statutory_deadline",
+    "description",
+    "status",
+    "assigned_to",
+    "created_by",
+    "created_at",
+    "response_draft",
+    "review_notes"
+  ],
+  "title": "RequestRead"
+}
+
+
RequestStats
+{
+  "properties": {
+    "total_requests": {
+      "type": "integer",
+      "title": "Total Requests"
+    },
+    "by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "By Status"
+    },
+    "approaching_deadline": {
+      "type": "integer",
+      "title": "Approaching Deadline"
+    },
+    "overdue": {
+      "type": "integer",
+      "title": "Overdue"
+    }
+  },
+  "type": "object",
+  "required": [
+    "total_requests",
+    "by_status",
+    "approaching_deadline",
+    "overdue"
+  ],
+  "title": "RequestStats"
+}
+
+
RequestStatus
+{
+  "type": "string",
+  "enum": [
+    "received",
+    "clarification_needed",
+    "assigned",
+    "searching",
+    "in_review",
+    "ready_for_release",
+    "drafted",
+    "approved",
+    "fulfilled",
+    "closed"
+  ],
+  "title": "RequestStatus"
+}
+
+
RequestUpdate
+{
+  "properties": {
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/RequestStatus"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "response_draft": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Response Draft"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    }
+  },
+  "type": "object",
+  "title": "RequestUpdate"
+}
+
+
RequirementBundle
+{
+  "properties": {
+    "requirement_id": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9_-]{1,100}$",
+      "title": "Requirement Id"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "project_type": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Project Type"
+    },
+    "source_reference": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Source Reference"
+    },
+    "source_date": {
+      "type": "string",
+      "format": "date",
+      "title": "Source Date"
+    },
+    "effective_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Effective On"
+    },
+    "dataset_kind": {
+      "type": "string",
+      "enum": [
+        "municipal",
+        "fictional"
+      ],
+      "title": "Dataset Kind"
+    },
+    "filename": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$",
+      "title": "Filename"
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 14000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Sha256"
+    },
+    "materials": {
+      "items": {
+        "$ref": "#/components/schemas/Material"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "minItems": 1,
+      "title": "Materials"
+    },
+    "pathway": {
+      "items": {
+        "$ref": "#/components/schemas/PathwayStep"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "title": "Pathway"
+    },
+    "fee_link": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    },
+    "staff_note": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Staff Note",
+      "default": ""
+    },
+    "change_note": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Change Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requirement_id",
+    "title",
+    "jurisdiction",
+    "project_type",
+    "source_reference",
+    "source_date",
+    "effective_on",
+    "dataset_kind",
+    "filename",
+    "content_base64",
+    "sha256",
+    "materials",
+    "change_note"
+  ],
+  "title": "RequirementBundle"
+}
+
+
ResponseLetterCreate
+{
+  "properties": {
+    "template_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Template Id"
+    }
+  },
+  "type": "object",
+  "title": "ResponseLetterCreate"
+}
+
+
ResponseLetterRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "template_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Template Id"
+    },
+    "generated_content": {
+      "type": "string",
+      "title": "Generated Content"
+    },
+    "edited_content": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Edited Content"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "generated_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Generated By"
+    },
+    "approved_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Approved By"
+    },
+    "sent_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sent At"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "template_id",
+    "generated_content",
+    "edited_content",
+    "status",
+    "generated_by",
+    "approved_by",
+    "sent_at",
+    "created_at"
+  ],
+  "title": "ResponseLetterRead"
+}
+
+
ResponseLetterUpdate
+{
+  "properties": {
+    "edited_content": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Edited Content"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Status"
+    }
+  },
+  "type": "object",
+  "title": "ResponseLetterUpdate"
+}
+
+
ReviewInput
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 5000,
+      "title": "Body",
+      "default": ""
+    },
+    "hasAltText": {
+      "type": "boolean",
+      "title": "Hasalttext",
+      "default": false
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": "en"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "ReviewInput"
+}
+
+
Revision
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    },
+    "document": {
+      "$ref": "#/components/schemas/NoticeDraft"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence",
+    "document"
+  ],
+  "title": "Revision"
+}
+
+
RewriteInput
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "plain-language",
+        "language-variant"
+      ],
+      "title": "Action"
+    },
+    "text": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Text"
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "text"
+  ],
+  "title": "RewriteInput"
+}
+
+
RewriteResult
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "plain-language",
+        "language-variant"
+      ],
+      "title": "Action"
+    },
+    "text": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Text"
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": ""
+    },
+    "outcome": {
+      "type": "string",
+      "enum": [
+        "generated",
+        "unavailable"
+      ],
+      "title": "Outcome"
+    },
+    "generated": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 100000
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Generated"
+    },
+    "model": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 200
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "text",
+    "outcome"
+  ],
+  "title": "RewriteResult"
+}
+
+
Rule
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "zone_code": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Zone Code"
+    },
+    "key": {
+      "type": "string",
+      "maxLength": 120,
+      "minLength": 1,
+      "title": "Key"
+    },
+    "section_number": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Section Number"
+    },
+    "kind": {
+      "type": "string",
+      "enum": [
+        "use",
+        "dimension"
+      ],
+      "title": "Kind"
+    },
+    "value": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Value"
+    },
+    "overlay_code": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 255
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Overlay Code"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "zone_code",
+    "key",
+    "section_number",
+    "kind",
+    "value"
+  ],
+  "title": "Rule"
+}
+
+
RuleTestMatch
+{
+  "properties": {
+    "matched_text": {
+      "type": "string",
+      "title": "Matched Text"
+    },
+    "start": {
+      "type": "integer",
+      "title": "Start"
+    },
+    "end": {
+      "type": "integer",
+      "title": "End"
+    }
+  },
+  "type": "object",
+  "required": [
+    "matched_text",
+    "start",
+    "end"
+  ],
+  "title": "RuleTestMatch"
+}
+
+
RuleTestRequest
+{
+  "properties": {
+    "sample_text": {
+      "type": "string",
+      "title": "Sample Text"
+    }
+  },
+  "type": "object",
+  "required": [
+    "sample_text"
+  ],
+  "title": "RuleTestRequest"
+}
+
+
RuleTestResponse
+{
+  "properties": {
+    "rule_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Rule Id"
+    },
+    "rule_type": {
+      "type": "string",
+      "title": "Rule Type"
+    },
+    "matched": {
+      "type": "boolean",
+      "title": "Matched"
+    },
+    "matches": {
+      "items": {
+        "$ref": "#/components/schemas/RuleTestMatch"
+      },
+      "type": "array",
+      "title": "Matches"
+    }
+  },
+  "type": "object",
+  "required": [
+    "rule_id",
+    "rule_type",
+    "matched",
+    "matches"
+  ],
+  "title": "RuleTestResponse"
+}
+
+
RuleType
+{
+  "type": "string",
+  "enum": [
+    "regex",
+    "keyword",
+    "llm_prompt"
+  ],
+  "title": "RuleType"
+}
+
+
SaveReview
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 5000,
+      "title": "Body",
+      "default": ""
+    },
+    "hasAltText": {
+      "type": "boolean",
+      "title": "Hasalttext",
+      "default": false
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": "en"
+    },
+    "ai_analysis": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 100000
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ai Analysis"
+    },
+    "ai_analysis_model": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 200
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ai Analysis Model"
+    },
+    "ai_outcome": {
+      "type": "string",
+      "enum": [
+        "generated",
+        "unavailable",
+        "failed"
+      ],
+      "title": "Ai Outcome"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "ai_outcome"
+  ],
+  "title": "SaveReview"
+}
+
+
SearchFilterOptions
+{
+  "properties": {
+    "file_types": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "File Types"
+    },
+    "source_names": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Source Names"
+    },
+    "departments": {
+      "items": {
+        "additionalProperties": true,
+        "type": "object"
+      },
+      "type": "array",
+      "title": "Departments",
+      "default": []
+    },
+    "date_range": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Date Range"
+    }
+  },
+  "type": "object",
+  "required": [
+    "file_types",
+    "source_names"
+  ],
+  "title": "SearchFilterOptions"
+}
+
+
SearchInput
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "SearchInput"
+}
+
+
SearchNoteCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "record-records-search",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/SearchNotePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "SearchNoteCommand"
+}
+
+
SearchNotePayload
+{
+  "properties": {
+    "sourceNote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Sourcenote"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sourceNote"
+  ],
+  "title": "SearchNotePayload"
+}
+
+
SearchReceiptCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "record-records-search-session",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/SearchReceiptPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "SearchReceiptCommand"
+}
+
+
SearchReceiptPayload
+{
+  "properties": {
+    "searchQuery": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchquery"
+    },
+    "searchLocations": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchlocations"
+    },
+    "searchResultTitle": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchresulttitle"
+    },
+    "searchResultCitation": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchresultcitation"
+    },
+    "searchResultSummary": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchresultsummary"
+    },
+    "searchResultStatus": {
+      "type": "string",
+      "title": "Searchresultstatus",
+      "default": ""
+    },
+    "searchReviewer": {
+      "type": "string",
+      "title": "Searchreviewer",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "searchQuery",
+    "searchLocations",
+    "searchResultTitle",
+    "searchResultCitation",
+    "searchResultSummary"
+  ],
+  "title": "SearchReceiptPayload"
+}
+
+
SearchReceiptView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "query": {
+      "type": "string",
+      "title": "Query"
+    },
+    "locations": {
+      "type": "string",
+      "title": "Locations"
+    },
+    "reviewer": {
+      "type": "string",
+      "title": "Reviewer"
+    },
+    "results": {
+      "items": {
+        "$ref": "#/components/schemas/SearchResultView"
+      },
+      "type": "array",
+      "title": "Results"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "query",
+    "locations",
+    "reviewer",
+    "results",
+    "created_at_unix_seconds"
+  ],
+  "title": "SearchReceiptView"
+}
+
+
SearchRequest
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "title": "Query"
+    },
+    "session_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Session Id"
+    },
+    "filters": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Filters"
+    },
+    "limit": {
+      "type": "integer",
+      "maximum": 50.0,
+      "title": "Limit",
+      "default": 10
+    },
+    "synthesize": {
+      "type": "boolean",
+      "title": "Synthesize",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "SearchRequest"
+}
+
+
SearchResponse
+{
+  "properties": {
+    "query_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Query Id"
+    },
+    "session_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Session Id"
+    },
+    "query_text": {
+      "type": "string",
+      "title": "Query Text"
+    },
+    "results": {
+      "items": {
+        "$ref": "#/components/schemas/SearchResultItem"
+      },
+      "type": "array",
+      "title": "Results"
+    },
+    "results_count": {
+      "type": "integer",
+      "title": "Results Count"
+    },
+    "synthesized_answer": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Synthesized Answer"
+    },
+    "ai_generated": {
+      "type": "boolean",
+      "title": "Ai Generated",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "query_id",
+    "session_id",
+    "query_text",
+    "results",
+    "results_count"
+  ],
+  "title": "SearchResponse"
+}
+
+
SearchResultItem
+{
+  "properties": {
+    "chunk_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Chunk Id"
+    },
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "filename": {
+      "type": "string",
+      "title": "Filename"
+    },
+    "file_type": {
+      "type": "string",
+      "title": "File Type"
+    },
+    "source_path": {
+      "type": "string",
+      "title": "Source Path"
+    },
+    "page_number": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Page Number"
+    },
+    "content_text": {
+      "type": "string",
+      "title": "Content Text"
+    },
+    "similarity_score": {
+      "type": "number",
+      "title": "Similarity Score"
+    },
+    "rank": {
+      "type": "integer",
+      "title": "Rank"
+    }
+  },
+  "type": "object",
+  "required": [
+    "chunk_id",
+    "document_id",
+    "filename",
+    "file_type",
+    "source_path",
+    "page_number",
+    "content_text",
+    "similarity_score",
+    "rank"
+  ],
+  "title": "SearchResultItem"
+}
+
+
SearchResultView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "title": {
+      "type": "string",
+      "title": "Title"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "title",
+    "citation",
+    "summary",
+    "status"
+  ],
+  "title": "SearchResultView"
+}
+
+
SearchSessionRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "user_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "User Id"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "queries": {
+      "items": {
+        "additionalProperties": true,
+        "type": "object"
+      },
+      "type": "array",
+      "title": "Queries",
+      "default": []
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "user_id",
+    "created_at"
+  ],
+  "title": "SearchSessionRead"
+}
+
+
SectionCreate
+{
+  "properties": {
+    "section_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Section Id"
+    },
+    "chapter_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Chapter Id"
+    },
+    "section_number": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Number"
+    },
+    "section_heading": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Heading"
+    },
+    "parent_section_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parent Section Id"
+    },
+    "sort_order": {
+      "type": "integer",
+      "title": "Sort Order",
+      "default": 0
+    },
+    "administrative_regulation_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Administrative Regulation Refs"
+    },
+    "resolution_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Resolution Refs"
+    },
+    "policy_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Policy Refs"
+    },
+    "approved_summary_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Approved Summary Refs"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "chapter_id",
+    "section_number",
+    "section_heading"
+  ],
+  "title": "SectionCreate",
+  "description": "Request body for creating a code section or subsection."
+}
+
+
SectionVersionCreate
+{
+  "properties": {
+    "version_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Version Id"
+    },
+    "section_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Id"
+    },
+    "source_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "version_label": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Version Label"
+    },
+    "body": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Body"
+    },
+    "effective_start": {
+      "type": "string",
+      "format": "date",
+      "title": "Effective Start"
+    },
+    "effective_end": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective End"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    },
+    "is_current": {
+      "type": "boolean",
+      "title": "Is Current",
+      "default": false
+    },
+    "adoption_event_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Adoption Event Id"
+    },
+    "amendment_event_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Amendment Event Id"
+    },
+    "amendment_summary": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Amendment Summary"
+    },
+    "prior_version_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Prior Version Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "section_id",
+    "source_id",
+    "version_label",
+    "body",
+    "effective_start"
+  ],
+  "title": "SectionVersionCreate",
+  "description": "Request body for adding an immutable section version."
+}
+
+
Selection
+{
+  "properties": {
+    "recording_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Recording Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "recording_id",
+    "expected_sha256"
+  ],
+  "title": "Selection"
+}
+
+
SentenceInput
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "citations": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Citations"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text"
+  ],
+  "title": "SentenceInput"
+}
+
+
ServiceAccountCreate
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole",
+      "default": "read_only"
+    }
+  },
+  "type": "object",
+  "required": [
+    "name"
+  ],
+  "title": "ServiceAccountCreate"
+}
+
+
ServiceAccountCreated
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "api_key": {
+      "type": "string",
+      "title": "Api Key"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "role",
+    "created_by",
+    "created_at",
+    "is_active",
+    "api_key"
+  ],
+  "title": "ServiceAccountCreated",
+  "description": "Returned only on creation — includes the plaintext API key (shown once)."
+}
+
+
ServiceAccountRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "role",
+    "created_by",
+    "created_at",
+    "is_active"
+  ],
+  "title": "ServiceAccountRead"
+}
+
+
ServiceAccountUpdate
+{
+  "properties": {
+    "role": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/UserRole"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "ServiceAccountUpdate"
+}
+
+
Snapshot
+{
+  "properties": {
+    "expected_revision": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Expected Revision"
+    },
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "staff_only",
+        "public"
+      ],
+      "title": "Visibility"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "expected_revision",
+    "visibility"
+  ],
+  "title": "Snapshot"
+}
+
+
SourceCreate
+{
+  "properties": {
+    "source_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Id"
+    },
+    "name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Name"
+    },
+    "publisher": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Publisher"
+    },
+    "source_type": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Type"
+    },
+    "source_category": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Category"
+    },
+    "source_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Url"
+    },
+    "file_reference": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "File Reference"
+    },
+    "retrieved_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Retrieved At"
+    },
+    "retrieval_method": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Retrieval Method"
+    },
+    "checksum": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Checksum"
+    },
+    "source_owner": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Owner"
+    },
+    "is_official": {
+      "type": "boolean",
+      "title": "Is Official",
+      "default": true
+    },
+    "official_status_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Official Status Note"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    },
+    "staff_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Staff Notes"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "name",
+    "publisher",
+    "source_type",
+    "source_category"
+  ],
+  "title": "SourceCreate",
+  "description": "Request body for registering an official or explicitly labeled source."
+}
+
+
SourceInput
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "label": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Label"
+    },
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "label",
+    "text"
+  ],
+  "title": "SourceInput"
+}
+
+
SourceSnapshot
+{
+  "properties": {
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "public",
+        "staff_only"
+      ],
+      "title": "Visibility"
+    },
+    "meeting_event_ids": {
+      "items": {
+        "type": "string",
+        "format": "uuid"
+      },
+      "type": "array",
+      "maxItems": 50,
+      "title": "Meeting Event Ids"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "visibility"
+  ],
+  "title": "SourceSnapshot"
+}
+
+
SourceType
+{
+  "type": "string",
+  "enum": [
+    "manual_drop",
+    "file_system",
+    "rest_api",
+    "odbc"
+  ],
+  "title": "SourceType"
+}
+
+
StaffRecordsIntake
+{
+  "properties": {
+    "requester": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requester"
+    },
+    "summary": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Summary"
+    },
+    "deadline": {
+      "type": "string",
+      "title": "Deadline"
+    },
+    "deadlineBasis": {
+      "type": "string",
+      "title": "Deadlinebasis",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requester",
+    "summary",
+    "deadline"
+  ],
+  "title": "StaffRecordsIntake",
+  "description": "Existing native create-records-request input; no caller-supplied actor."
+}
+
+
StandardsExplanation
+{
+  "properties": {
+    "question": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Question"
+    },
+    "process_section": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Process Section",
+      "default": ""
+    },
+    "zone_code": {
+      "type": "string",
+      "maxLength": 40,
+      "title": "Zone Code",
+      "default": ""
+    },
+    "rule_types": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "title": "Rule Types"
+    },
+    "observed": {
+      "additionalProperties": {
+        "type": "string"
+      },
+      "type": "object",
+      "title": "Observed"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "question"
+  ],
+  "title": "StandardsExplanation"
+}
+
+
SyncFailureRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "source_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Source Id"
+    },
+    "source_path": {
+      "type": "string",
+      "title": "Source Path"
+    },
+    "error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Message"
+    },
+    "error_class": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Class"
+    },
+    "http_status_code": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Http Status Code"
+    },
+    "retry_count": {
+      "type": "integer",
+      "title": "Retry Count"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "first_failed_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "First Failed At"
+    },
+    "last_retried_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Retried At"
+    },
+    "dismissed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Dismissed At"
+    },
+    "dismissed_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Dismissed By"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "source_id",
+    "source_path",
+    "error_message",
+    "error_class",
+    "http_status_code",
+    "retry_count",
+    "status",
+    "first_failed_at",
+    "last_retried_at",
+    "dismissed_at",
+    "dismissed_by"
+  ],
+  "title": "SyncFailureRead"
+}
+
+
SyncRunLogRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "source_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Source Id"
+    },
+    "started_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Started At"
+    },
+    "finished_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Finished At"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Status"
+    },
+    "records_attempted": {
+      "type": "integer",
+      "title": "Records Attempted"
+    },
+    "records_succeeded": {
+      "type": "integer",
+      "title": "Records Succeeded"
+    },
+    "records_failed": {
+      "type": "integer",
+      "title": "Records Failed"
+    },
+    "error_summary": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Summary"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "source_id",
+    "started_at",
+    "finished_at",
+    "status",
+    "records_attempted",
+    "records_succeeded",
+    "records_failed",
+    "error_summary"
+  ],
+  "title": "SyncRunLogRead"
+}
+
+
SystemStatus
+{
+  "properties": {
+    "version": {
+      "type": "string",
+      "title": "Version"
+    },
+    "database": {
+      "type": "string",
+      "title": "Database"
+    },
+    "ollama": {
+      "type": "string",
+      "title": "Ollama"
+    },
+    "redis": {
+      "type": "string",
+      "title": "Redis"
+    },
+    "user_count": {
+      "type": "integer",
+      "title": "User Count"
+    },
+    "audit_log_count": {
+      "type": "integer",
+      "title": "Audit Log Count"
+    },
+    "suite_session": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Suite Session"
+    }
+  },
+  "type": "object",
+  "required": [
+    "version",
+    "database",
+    "ollama",
+    "redis",
+    "user_count",
+    "audit_log_count"
+  ],
+  "title": "SystemStatus"
+}
+
+
TaggedPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "tagged-pdf",
+      "title": "Action"
+    },
+    "headingLevels": {
+      "items": {
+        "type": "integer",
+        "maximum": 4294967295.0,
+        "minimum": 0.0
+      },
+      "type": "array",
+      "maxItems": 50,
+      "title": "Headinglevels"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "TaggedPlan"
+}
+
+
TestConnectionRequest
+{
+  "properties": {
+    "source_type": {
+      "type": "string",
+      "title": "Source Type"
+    },
+    "host": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Host"
+    },
+    "port": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Port"
+    },
+    "path": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Path"
+    },
+    "username": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Username"
+    },
+    "password": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Password"
+    },
+    "rest_api_config": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Rest Api Config"
+    },
+    "odbc_config": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Odbc Config"
+    }
+  },
+  "type": "object",
+  "required": [
+    "source_type"
+  ],
+  "title": "TestConnectionRequest",
+  "description": "Dedicated schema for test-connection. NOT the create schema.\n\nSecurity: credentials in this request body are never persisted, never\nwritten to audit logs, and never returned in the response."
+}
+
+
TestConnectionResponse
+{
+  "properties": {
+    "success": {
+      "type": "boolean",
+      "title": "Success"
+    },
+    "message": {
+      "type": "string",
+      "title": "Message"
+    },
+    "latency_ms": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Latency Ms"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Status"
+    },
+    "warning": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Warning"
+    },
+    "differing_keys": {
+      "anyOf": [
+        {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Differing Keys"
+    }
+  },
+  "type": "object",
+  "required": [
+    "success",
+    "message"
+  ],
+  "title": "TestConnectionResponse"
+}
+
+
TimelineEventCreate
+{
+  "properties": {
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "internal_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Internal Note"
+    }
+  },
+  "type": "object",
+  "required": [
+    "event_type",
+    "description"
+  ],
+  "title": "TimelineEventCreate"
+}
+
+
TimelineEventRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "actor_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Actor Id"
+    },
+    "actor_role": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Actor Role"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "internal_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Internal Note"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "event_type",
+    "actor_id",
+    "actor_role",
+    "description",
+    "internal_note",
+    "created_at"
+  ],
+  "title": "TimelineEventRead"
+}
+
+
TimelineView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "actor": {
+      "type": "string",
+      "title": "Actor"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "action",
+    "actor",
+    "note",
+    "created_at_unix_seconds"
+  ],
+  "title": "TimelineView"
+}
+
+
TitleCreate
+{
+  "properties": {
+    "title_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Title Id"
+    },
+    "title_number": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title Number"
+    },
+    "title_name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title Name"
+    },
+    "sort_order": {
+      "type": "integer",
+      "title": "Sort Order",
+      "default": 0
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title_number",
+    "title_name"
+  ],
+  "title": "TitleCreate",
+  "description": "Request body for creating a code title."
+}
+
+
TranscriptInput
+{
+  "properties": {
+    "source_label": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Label"
+    },
+    "transcript_text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Transcript Text"
+    },
+    "correction_of_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Correction Of Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_label",
+    "transcript_text"
+  ],
+  "title": "TranscriptInput"
+}
+
+
UserRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "email": {
+      "type": "string",
+      "format": "email",
+      "title": "Email"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active",
+      "default": true
+    },
+    "is_superuser": {
+      "type": "boolean",
+      "title": "Is Superuser",
+      "default": false
+    },
+    "is_verified": {
+      "type": "boolean",
+      "title": "Is Verified",
+      "default": false
+    },
+    "full_name": {
+      "type": "string",
+      "title": "Full Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "last_login": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Login"
+    },
+    "must_change_password": {
+      "type": "boolean",
+      "title": "Must Change Password",
+      "default": false
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "email",
+    "full_name",
+    "role",
+    "created_at",
+    "last_login"
+  ],
+  "title": "UserRead"
+}
+
+
UserRole
+{
+  "type": "string",
+  "enum": [
+    "admin",
+    "staff",
+    "reviewer",
+    "read_only",
+    "liaison",
+    "public"
+  ],
+  "title": "UserRole"
+}
+
+
UserSelfUpdate
+{
+  "properties": {
+    "password": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Password"
+    },
+    "email": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "email"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    },
+    "is_superuser": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Superuser"
+    },
+    "is_verified": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Verified"
+    },
+    "full_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Full Name"
+    }
+  },
+  "type": "object",
+  "title": "UserSelfUpdate",
+  "description": "Schema for user self-update via PATCH /users/me.\n\nExcludes role and department_id. Any payload containing those fields is\nrejected at parse time (HTTP 422). Role and department changes require\nadmin privileges via /admin/users/{id}."
+}
+
+
UserUpdateRequest
+{
+  "properties": {
+    "full_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Full Name"
+    },
+    "role": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Role"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "UserUpdateRequest"
+}
+
+
ValidationError
+{
+  "properties": {
+    "loc": {
+      "items": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "integer"
+          }
+        ]
+      },
+      "type": "array",
+      "title": "Location"
+    },
+    "msg": {
+      "type": "string",
+      "title": "Message"
+    },
+    "type": {
+      "type": "string",
+      "title": "Error Type"
+    },
+    "input": {
+      "title": "Input"
+    },
+    "ctx": {
+      "type": "object",
+      "title": "Context"
+    }
+  },
+  "type": "object",
+  "required": [
+    "loc",
+    "msg",
+    "type"
+  ],
+  "title": "ValidationError"
+}
+
+
Version
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence"
+  ],
+  "title": "Version"
+}
+
+
VoteCorrection
+{
+  "properties": {
+    "vote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Vote"
+    },
+    "reason": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Reason"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "vote",
+    "reason"
+  ],
+  "title": "VoteCorrection"
+}
+
+
VoteInput
+{
+  "properties": {
+    "voter_name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Voter Name"
+    },
+    "vote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Vote"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "voter_name",
+    "vote"
+  ],
+  "title": "VoteInput"
+}
+
+
_ParcelLookupIn
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "query"
+  ],
+  "title": "_ParcelLookupIn"
+}
+
+
townlight_inspections__workflow_models__SourceLink
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "const": "code",
+      "title": "Provider",
+      "default": "code"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "SourceLink"
+}
+
+
townlight_permitting__workflow_models__SourceLink
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "enum": [
+        "code",
+        "zoning"
+      ],
+      "title": "Provider"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "SourceLink"
+}
+
+
townlight_runtime__inspections_bridge__Search
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "const": "code",
+      "title": "Provider"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "query"
+  ],
+  "title": "Search"
+}
+
+
townlight_runtime__notice_bridge__Review
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence",
+    "note"
+  ],
+  "title": "Review"
+}
+
+
townlight_runtime__permitting_bridge__Import
+{
+  "properties": {
+    "bundle": {
+      "$ref": "#/components/schemas/RequirementBundle"
+    },
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "bundle"
+  ],
+  "title": "Import"
+}
+
+
townlight_runtime__permitting_bridge__Search
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "enum": [
+        "code",
+        "zoning"
+      ],
+      "title": "Provider"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "query"
+  ],
+  "title": "Search"
+}
+
+
townlight_runtime__planning_bridge__Import
+{
+  "properties": {
+    "bundle": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Bundle"
+    },
+    "expected_previous_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Previous Revision"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "bundle"
+  ],
+  "title": "Import"
+}
+
+
townlight_runtime__planning_bridge__Search
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Query"
+    },
+    "plan_type": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 40
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Plan Type"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "Search"
+}
+
+
townlight_runtime__zoning_bridge__Review
+{
+  "properties": {
+    "answer": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Answer",
+      "default": ""
+    },
+    "notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Notes",
+      "default": ""
+    },
+    "queue_status": {
+      "type": "string",
+      "enum": [
+        "open",
+        "in_review",
+        "resolved",
+        "closed"
+      ],
+      "title": "Queue Status",
+      "default": "resolved"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "Review"
+}
+
Townlight · AGPL-3.0-only · Source schema evidence only
\ No newline at end of file diff --git a/docs/beta-1/api/planning-openapi.json b/docs/beta-1/api/planning-openapi.json new file mode 100644 index 0000000..952930b --- /dev/null +++ b/docs/beta-1/api/planning-openapi.json @@ -0,0 +1,12613 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "Townlight Records", + "description": "Prepared source schema for the actual native composition; installed acceptance remains pending. Exported without lifespan, migrations or database/network access.", + "version": "1.8.0.dev2" + }, + "paths": { + "/desktop/v1/planning-sources/search": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Search Planning Sources", + "operationId": "search_planning_sources_desktop_v1_planning_sources_search_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MeetingsSearch" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/imports/preview": { + "post": { + "tags": [ + "native-planning" + ], + "summary": "Preview Import", + "operationId": "preview_import_desktop_v1_planning_imports_preview_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/townlight_runtime__planning_bridge__Import" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/imports": { + "post": { + "tags": [ + "native-planning" + ], + "summary": "Import Source", + "operationId": "import_source_desktop_v1_planning_imports_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/townlight_runtime__planning_bridge__Import" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/sources": { + "get": { + "tags": [ + "native-planning" + ], + "summary": "Source List", + "operationId": "source_list_desktop_v1_planning_sources_get", + "parameters": [ + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 100, + "minimum": 1, + "default": 50, + "title": "Limit" + } + }, + { + "name": "offset", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 100000, + "minimum": 0, + "default": 0, + "title": "Offset" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/sources/{plan_id}/history": { + "get": { + "tags": [ + "native-planning" + ], + "summary": "Source History", + "operationId": "source_history_desktop_v1_planning_sources__plan_id__history_get", + "parameters": [ + { + "name": "plan_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Plan Id" + } + }, + { + "name": "offset", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 100000, + "minimum": 0, + "default": 0, + "title": "Offset" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/revisions/{revision_id}": { + "get": { + "tags": [ + "native-planning" + ], + "summary": "Revision", + "operationId": "revision_desktop_v1_planning_revisions__revision_id__get", + "parameters": [ + { + "name": "revision_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Revision Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/revisions/{revision_id}/documents/{document_id}": { + "get": { + "tags": [ + "native-planning" + ], + "summary": "Staff Original", + "operationId": "staff_original_desktop_v1_planning_revisions__revision_id__documents__document_id__get", + "parameters": [ + { + "name": "revision_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Revision Id" + } + }, + { + "name": "document_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Document Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/policies/search": { + "post": { + "tags": [ + "native-planning" + ], + "summary": "Policies", + "operationId": "policies_desktop_v1_planning_policies_search_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/townlight_runtime__planning_bridge__Search" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/analyses": { + "get": { + "tags": [ + "native-planning" + ], + "summary": "Analyses", + "operationId": "analyses_desktop_v1_planning_analyses_get", + "parameters": [ + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 100, + "minimum": 1, + "default": 50, + "title": "Limit" + } + }, + { + "name": "offset", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 100000, + "minimum": 0, + "default": 0, + "title": "Offset" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "tags": [ + "native-planning" + ], + "summary": "Create Analysis", + "operationId": "create_analysis_desktop_v1_planning_analyses_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": true, + "title": "Body" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/analyses/{analysis_id}/revisions": { + "post": { + "tags": [ + "native-planning" + ], + "summary": "Revise Analysis", + "operationId": "revise_analysis_desktop_v1_planning_analyses__analysis_id__revisions_post", + "parameters": [ + { + "name": "analysis_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Analysis Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": true, + "title": "Body" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/analyses/{analysis_id}": { + "get": { + "tags": [ + "native-planning" + ], + "summary": "Analysis", + "operationId": "analysis_desktop_v1_planning_analyses__analysis_id__get", + "parameters": [ + { + "name": "analysis_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Analysis Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/analyses/{analysis_id}/history": { + "get": { + "tags": [ + "native-planning" + ], + "summary": "Analysis History", + "operationId": "analysis_history_desktop_v1_planning_analyses__analysis_id__history_get", + "parameters": [ + { + "name": "analysis_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Analysis Id" + } + }, + { + "name": "offset", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 100000, + "minimum": 0, + "default": 0, + "title": "Offset" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/analyses/{analysis_id}/snapshot-preview": { + "post": { + "tags": [ + "native-planning" + ], + "summary": "Preview Snapshot", + "operationId": "preview_snapshot_desktop_v1_planning_analyses__analysis_id__snapshot_preview_post", + "parameters": [ + { + "name": "analysis_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Analysis Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Snapshot" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/analyses/{analysis_id}/snapshots": { + "post": { + "tags": [ + "native-planning" + ], + "summary": "Snapshot", + "operationId": "snapshot_desktop_v1_planning_analyses__analysis_id__snapshots_post", + "parameters": [ + { + "name": "analysis_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Analysis Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Snapshot" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/snapshots": { + "get": { + "tags": [ + "native-planning" + ], + "summary": "Snapshots", + "operationId": "snapshots_desktop_v1_planning_snapshots_get", + "parameters": [ + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 100, + "minimum": 1, + "default": 50, + "title": "Limit" + } + }, + { + "name": "offset", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 100000, + "minimum": 0, + "default": 0, + "title": "Offset" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/snapshots/{snapshot_id}": { + "get": { + "tags": [ + "native-planning" + ], + "summary": "Document", + "operationId": "document_desktop_v1_planning_snapshots__snapshot_id__get", + "parameters": [ + { + "name": "snapshot_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Snapshot Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/snapshots/{snapshot_id}/access-advice": { + "post": { + "tags": [ + "native-planning" + ], + "summary": "Access Advice", + "operationId": "access_advice_desktop_v1_planning_snapshots__snapshot_id__access_advice_post", + "parameters": [ + { + "name": "snapshot_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Snapshot Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/connections/search": { + "post": { + "tags": [ + "native-planning" + ], + "summary": "Connections", + "operationId": "connections_desktop_v1_planning_connections_search_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConnectionSearch" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/progress/targets": { + "get": { + "tags": [ + "native-planning" + ], + "summary": "Municipal Progress", + "operationId": "municipal_progress_desktop_v1_planning_progress_targets_get", + "parameters": [ + { + "name": "offset", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 100000, + "minimum": 0, + "default": 0, + "title": "Offset" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/amendments/history": { + "get": { + "tags": [ + "native-planning" + ], + "summary": "Municipal Amendments", + "operationId": "municipal_amendments_desktop_v1_planning_amendments_history_get", + "parameters": [ + { + "name": "offset", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 100000, + "minimum": 0, + "default": 0, + "title": "Offset" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/municipal-work/{item_id}/history": { + "get": { + "tags": [ + "native-planning" + ], + "summary": "Municipal History", + "operationId": "municipal_history_desktop_v1_planning_municipal_work__item_id__history_get", + "parameters": [ + { + "name": "item_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Item Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/initiatives": { + "post": { + "tags": [ + "native-planning" + ], + "summary": "Create Initiative", + "operationId": "create_initiative_desktop_v1_planning_initiatives_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InitiativeInput" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/initiatives/{item_id}/revisions": { + "post": { + "tags": [ + "native-planning" + ], + "summary": "Update Initiative", + "operationId": "update_initiative_desktop_v1_planning_initiatives__item_id__revisions_post", + "parameters": [ + { + "name": "item_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Item Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InitiativeInput" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/amendments": { + "post": { + "tags": [ + "native-planning" + ], + "summary": "Create Amendment", + "operationId": "create_amendment_desktop_v1_planning_amendments_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AmendmentInput" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/amendments/{item_id}/revisions": { + "post": { + "tags": [ + "native-planning" + ], + "summary": "Update Amendment", + "operationId": "update_amendment_desktop_v1_planning_amendments__item_id__revisions_post", + "parameters": [ + { + "name": "item_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Item Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AmendmentInput" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "ActionItemInput": { + "properties": { + "description": { + "type": "string", + "minLength": 1, + "title": "Description" + }, + "assigned_to": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "source_motion_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Source Motion Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "description" + ], + "title": "ActionItemInput" + }, + "AdaPlan": { + "properties": { + "action": { + "type": "string", + "const": "ada-title-ii", + "title": "Action" + }, + "serviceArea": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Servicearea" + }, + "hasCoordinatorReview": { + "type": "boolean", + "title": "Hascoordinatorreview", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "serviceArea" + ], + "title": "AdaPlan" + }, + "AdminUserCreateRequest": { + "properties": { + "email": { + "type": "string", + "title": "Email" + }, + "password": { + "type": "string", + "title": "Password" + }, + "full_name": { + "type": "string", + "title": "Full Name", + "default": "" + }, + "role": { + "type": "string", + "title": "Role", + "default": "staff" + } + }, + "type": "object", + "required": [ + "email", + "password" + ], + "title": "AdminUserCreateRequest" + }, + "AdminUserCreateResponse": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "email": { + "type": "string", + "title": "Email" + }, + "full_name": { + "type": "string", + "title": "Full Name" + }, + "role": { + "type": "string", + "title": "Role" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + } + }, + "type": "object", + "required": [ + "id", + "email", + "full_name", + "role", + "is_active" + ], + "title": "AdminUserCreateResponse" + }, + "AgendaAssignment": { + "properties": { + "meeting_id": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "meeting_id" + ], + "title": "AgendaAssignment" + }, + "AgendaInput": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "department_name": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Department Name" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "department_name" + ], + "title": "AgendaInput" + }, + "AgendaReviewInput": { + "properties": { + "to_status": { + "type": "string", + "enum": [ + "DRAFTED", + "SUBMITTED", + "DEPT_APPROVED", + "LEGAL_REVIEWED", + "CLERK_ACCEPTED", + "ON_AGENDA", + "IN_PACKET", + "POSTED", + "HEARD", + "DISPOSED", + "ARCHIVED" + ], + "title": "To Status" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "to_status" + ], + "title": "AgendaReviewInput" + }, + "AmendmentInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "policy": { + "$ref": "#/components/schemas/PolicySelection" + }, + "proposal": { + "type": "string", + "maxLength": 20000, + "minLength": 1, + "title": "Proposal" + }, + "responsible_staff": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Responsible Staff" + }, + "status": { + "type": "string", + "enum": [ + "draft", + "review", + "adopted", + "withdrawn" + ], + "title": "Status", + "default": "draft" + }, + "review_note": { + "type": "string", + "maxLength": 5000, + "title": "Review Note", + "default": "" + }, + "adoption_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Adoption Revision" + }, + "note": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "policy", + "proposal", + "responsible_staff", + "note" + ], + "title": "AmendmentInput" + }, + "AnalysisObservation": { + "properties": { + "source": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "title": "Source" + }, + "filename": { + "type": "string", + "maxLength": 160, + "title": "Filename", + "default": "" + }, + "media_type": { + "type": "string", + "maxLength": 80, + "title": "Media Type", + "default": "" + }, + "text": { + "type": "string", + "maxLength": 4000, + "minLength": 1, + "title": "Text" + }, + "adapter": { + "type": "string", + "maxLength": 120, + "title": "Adapter", + "default": "" + }, + "citation_source_ids": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 30, + "title": "Citation Source Ids" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source", + "text" + ], + "title": "AnalysisObservation", + "description": "One draft observation, named with the adapter that actually produced it." + }, + "AnalysisRecord": { + "properties": { + "observations": { + "items": { + "$ref": "#/components/schemas/AnalysisObservation" + }, + "type": "array", + "maxItems": 30, + "title": "Observations" + }, + "cited_sections": { + "items": { + "$ref": "#/components/schemas/CitedSection" + }, + "type": "array", + "maxItems": 30, + "title": "Cited Sections" + }, + "unavailable": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 30, + "title": "Unavailable" + }, + "runtime": { + "additionalProperties": true, + "type": "object", + "title": "Runtime" + }, + "review_required": { + "type": "boolean", + "title": "Review Required", + "default": true + } + }, + "additionalProperties": false, + "type": "object", + "title": "AnalysisRecord", + "description": "The adapter output that accompanies a saved inspection draft." + }, + "ApprovalCommand": { + "properties": { + "action": { + "type": "string", + "const": "approve-records-response", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ApprovalPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "ApprovalCommand" + }, + "ApprovalPayload": { + "properties": { + "approvalNote": { + "type": "string", + "title": "Approvalnote", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "title": "ApprovalPayload" + }, + "ArchiveInput": { + "properties": { + "visibility": { + "type": "string", + "enum": [ + "public", + "closed_session" + ], + "title": "Visibility" + }, + "packet_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Packet Id" + }, + "minutes_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Minutes Id" + }, + "plain_language_summary": { + "type": "string", + "title": "Plain Language Summary", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "visibility" + ], + "title": "ArchiveInput" + }, + "ArtifactPlan": { + "properties": { + "artifact_id": { + "type": "string", + "title": "Artifact Id" + }, + "file_name": { + "type": "string", + "title": "File Name" + }, + "content": { + "type": "string", + "title": "Content" + }, + "sha256": { + "type": "string", + "title": "Sha256" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "artifact_id", + "file_name", + "content", + "sha256", + "created_at_unix_seconds" + ], + "title": "ArtifactPlan" + }, + "AssignCommand": { + "properties": { + "action": { + "type": "string", + "const": "assign-records-request", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/AssignmentPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "AssignCommand" + }, + "AssignmentPayload": { + "properties": { + "assignedTo": { + "type": "string", + "minLength": 1, + "title": "Assignedto" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "assignedTo" + ], + "title": "AssignmentPayload" + }, + "AttachDocument": { + "properties": { + "title": { + "type": "string", + "minLength": 1, + "title": "Title" + }, + "citation": { + "type": "string", + "title": "Citation", + "default": "" + }, + "file": { + "$ref": "#/components/schemas/ManagedFileReceipt" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "file" + ], + "title": "AttachDocument" + }, + "AttachReleaseCopy": { + "properties": { + "status": { + "type": "string", + "enum": [ + "release-ready copy", + "redacted copy" + ], + "title": "Status" + }, + "note": { + "type": "string", + "title": "Note", + "default": "" + }, + "added_by": { + "type": "string", + "title": "Added By", + "default": "" + }, + "file": { + "$ref": "#/components/schemas/ManagedFileReceipt" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "status", + "file" + ], + "title": "AttachReleaseCopy" + }, + "AuditChainVerification": { + "properties": { + "is_valid": { + "type": "boolean", + "title": "Is Valid" + }, + "entries_checked": { + "type": "integer", + "title": "Entries Checked" + }, + "error_message": { + "type": "string", + "title": "Error Message" + } + }, + "type": "object", + "required": [ + "is_valid", + "entries_checked", + "error_message" + ], + "title": "AuditChainVerification" + }, + "AuditLogRead": { + "properties": { + "id": { + "type": "integer", + "title": "Id" + }, + "prev_hash": { + "type": "string", + "title": "Prev Hash" + }, + "entry_hash": { + "type": "string", + "title": "Entry Hash" + }, + "timestamp": { + "type": "string", + "format": "date-time", + "title": "Timestamp" + }, + "user_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "User Id" + }, + "action": { + "type": "string", + "title": "Action" + }, + "resource_type": { + "type": "string", + "title": "Resource Type" + }, + "resource_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Resource Id" + }, + "details": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Details" + }, + "ai_generated": { + "type": "boolean", + "title": "Ai Generated" + } + }, + "type": "object", + "required": [ + "id", + "prev_hash", + "entry_hash", + "timestamp", + "user_id", + "action", + "resource_type", + "resource_id", + "details", + "ai_generated" + ], + "title": "AuditLogRead" + }, + "AuditView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "module_id": { + "type": "string", + "title": "Module Id" + }, + "action": { + "type": "string", + "title": "Action" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + }, + "previous_hash": { + "type": "string", + "title": "Previous Hash" + }, + "entry_hash": { + "type": "string", + "title": "Entry Hash" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "module_id", + "action", + "summary", + "created_at_unix_seconds", + "previous_hash", + "entry_hash" + ], + "title": "AuditView" + }, + "BearerResponse": { + "properties": { + "access_token": { + "type": "string", + "title": "Access Token" + }, + "token_type": { + "type": "string", + "title": "Token Type" + } + }, + "type": "object", + "required": [ + "access_token", + "token_type" + ], + "title": "BearerResponse" + }, + "Body_auth_jwt_login_auth_jwt_login_post": { + "properties": { + "grant_type": { + "anyOf": [ + { + "type": "string", + "pattern": "^password$" + }, + { + "type": "null" + } + ], + "title": "Grant Type" + }, + "username": { + "type": "string", + "title": "Username" + }, + "password": { + "type": "string", + "format": "password", + "title": "Password" + }, + "scope": { + "type": "string", + "title": "Scope", + "default": "" + }, + "client_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Client Id" + }, + "client_secret": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "format": "password", + "title": "Client Secret" + } + }, + "type": "object", + "required": [ + "username", + "password" + ], + "title": "Body_auth_jwt_login_auth_jwt_login_post" + }, + "Body_upload_file_datasources_upload_post": { + "properties": { + "file": { + "type": "string", + "contentMediaType": "application/octet-stream", + "title": "File" + } + }, + "type": "object", + "required": [ + "file" + ], + "title": "Body_upload_file_datasources_upload_post" + }, + "CalculateDeadlineCommand": { + "properties": { + "action": { + "type": "string", + "const": "calculate-records-deadline", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/CalculateDeadlinePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "CalculateDeadlineCommand" + }, + "CalculateDeadlinePayload": { + "properties": { + "deadlineReceivedDate": { + "type": "string", + "title": "Deadlinereceiveddate" + }, + "deadlineRuleName": { + "type": "string", + "minLength": 1, + "title": "Deadlinerulename" + }, + "deadlineDayCount": { + "type": "string", + "title": "Deadlinedaycount" + }, + "deadlineDayType": { + "type": "string", + "title": "Deadlinedaytype" + }, + "deadlineBasis": { + "type": "string", + "minLength": 1, + "title": "Deadlinebasis" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "deadlineReceivedDate", + "deadlineRuleName", + "deadlineDayCount", + "deadlineDayType", + "deadlineBasis" + ], + "title": "CalculateDeadlinePayload" + }, + "ChapterCreate": { + "properties": { + "chapter_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Chapter Id" + }, + "title_id": { + "type": "string", + "minLength": 1, + "title": "Title Id" + }, + "chapter_number": { + "type": "string", + "minLength": 1, + "title": "Chapter Number" + }, + "chapter_name": { + "type": "string", + "minLength": 1, + "title": "Chapter Name" + }, + "sort_order": { + "type": "integer", + "title": "Sort Order", + "default": 0 + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title_id", + "chapter_number", + "chapter_name" + ], + "title": "ChapterCreate", + "description": "Request body for creating a code chapter." + }, + "CitedSection": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "citation": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Citation" + }, + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "version": { + "type": "string", + "maxLength": 80, + "title": "Version", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "citation" + ], + "title": "CitedSection", + "description": "One resolved public Code section; never a caller-supplied quotation." + }, + "CityProfileCreate": { + "properties": { + "city_name": { + "type": "string", + "title": "City Name" + }, + "state": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State" + }, + "county": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "County" + }, + "population_band": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Population Band" + }, + "email_platform": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Email Platform" + }, + "has_dedicated_it": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Has Dedicated It" + }, + "monthly_request_volume": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Monthly Request Volume" + }, + "profile_data": { + "additionalProperties": true, + "type": "object", + "title": "Profile Data", + "default": {} + }, + "gap_map": { + "additionalProperties": true, + "type": "object", + "title": "Gap Map", + "default": {} + } + }, + "type": "object", + "required": [ + "city_name" + ], + "title": "CityProfileCreate" + }, + "CityProfileRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "city_name": { + "type": "string", + "title": "City Name" + }, + "state": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State" + }, + "county": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "County" + }, + "population_band": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Population Band" + }, + "email_platform": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Email Platform" + }, + "has_dedicated_it": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Has Dedicated It" + }, + "monthly_request_volume": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Monthly Request Volume" + }, + "onboarding_status": { + "type": "string", + "title": "Onboarding Status" + }, + "profile_data": { + "additionalProperties": true, + "type": "object", + "title": "Profile Data" + }, + "gap_map": { + "additionalProperties": true, + "type": "object", + "title": "Gap Map" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "city_name", + "state", + "county", + "population_band", + "email_platform", + "has_dedicated_it", + "monthly_request_volume", + "onboarding_status", + "profile_data", + "gap_map", + "created_at", + "updated_at" + ], + "title": "CityProfileRead" + }, + "CityProfileUpdate": { + "properties": { + "city_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "City Name" + }, + "state": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State" + }, + "county": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "County" + }, + "population_band": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Population Band" + }, + "email_platform": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Email Platform" + }, + "has_dedicated_it": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Has Dedicated It" + }, + "monthly_request_volume": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Monthly Request Volume" + }, + "onboarding_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Onboarding Status" + }, + "profile_data": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Profile Data" + }, + "gap_map": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Gap Map" + } + }, + "type": "object", + "title": "CityProfileUpdate" + }, + "ClarificationCommand": { + "properties": { + "action": { + "type": "string", + "const": "request-records-clarification", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ClarificationPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "ClarificationCommand" + }, + "ClarificationPayload": { + "properties": { + "clarificationNote": { + "type": "string", + "minLength": 1, + "title": "Clarificationnote" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "clarificationNote" + ], + "title": "ClarificationPayload" + }, + "Closeout": { + "properties": { + "decision_id": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Decision Id" + }, + "version_id": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Version Id" + }, + "source_id": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Source Id" + }, + "version_label": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Version Label" + }, + "body": { + "type": "string", + "maxLength": 1000000, + "minLength": 1, + "title": "Body" + }, + "effective_start": { + "type": "string", + "format": "date", + "title": "Effective Start" + }, + "effective_end": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective End" + }, + "is_current": { + "type": "boolean", + "title": "Is Current" + }, + "reconciliation_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reconciliation Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "decision_id", + "version_id", + "source_id", + "version_label", + "body", + "effective_start", + "is_current" + ], + "title": "Closeout" + }, + "CodeContext": { + "properties": { + "section_number": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Section Number" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "section_number" + ], + "title": "CodeContext" + }, + "CodeLink": { + "properties": { + "provider": { + "type": "string", + "const": "code", + "title": "Provider", + "default": "code" + }, + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "CodeLink" + }, + "CodeSearch": { + "properties": { + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "CodeSearch" + }, + "CodeSourceSelection": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "CodeSourceSelection" + }, + "CompleteArtifact": { + "properties": { + "export_path": { + "type": "string", + "minLength": 1, + "title": "Export Path" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "export_path" + ], + "title": "CompleteArtifact" + }, + "ConnectionSearch": { + "properties": { + "provider": { + "type": "string", + "enum": [ + "meetings", + "zoning" + ], + "title": "Provider" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "query" + ], + "title": "ConnectionSearch" + }, + "CoverageGapResponse": { + "properties": { + "jurisdictions_without_rules": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Jurisdictions Without Rules" + }, + "departments_without_staff": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array", + "title": "Departments Without Staff" + }, + "uncovered_categories": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Uncovered Categories" + }, + "total_gaps": { + "type": "integer", + "title": "Total Gaps" + } + }, + "type": "object", + "required": [ + "jurisdictions_without_rules", + "departments_without_staff", + "uncovered_categories", + "total_gaps" + ], + "title": "CoverageGapResponse" + }, + "DataSourceAdminRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "source_type": { + "$ref": "#/components/schemas/SourceType" + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "type": "boolean", + "title": "Schedule Enabled", + "default": true + }, + "next_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Next Sync At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "last_ingestion_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Ingestion At" + }, + "last_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Sync At" + }, + "last_sync_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Sync Status" + }, + "last_error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Error Message" + }, + "consecutive_failure_count": { + "type": "integer", + "title": "Consecutive Failure Count", + "default": 0 + }, + "sync_paused": { + "type": "boolean", + "title": "Sync Paused", + "default": false + }, + "health_status": { + "type": "string", + "title": "Health Status", + "default": "healthy" + }, + "active_failure_count": { + "type": "integer", + "title": "Active Failure Count", + "default": 0 + }, + "connector_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Connector Type" + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At" + }, + "connection_config": { + "additionalProperties": true, + "type": "object", + "title": "Connection Config" + } + }, + "type": "object", + "required": [ + "id", + "name", + "source_type", + "is_active", + "created_by", + "created_at", + "last_ingestion_at", + "connection_config" + ], + "title": "DataSourceAdminRead", + "description": "Full datasource shape including connection_config. Returned only by admin-gated endpoints." + }, + "DataSourceCreate": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "source_type": { + "$ref": "#/components/schemas/SourceType" + }, + "connection_config": { + "additionalProperties": true, + "type": "object", + "title": "Connection Config", + "default": {} + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "type": "boolean", + "title": "Schedule Enabled", + "default": true + } + }, + "type": "object", + "required": [ + "name", + "source_type" + ], + "title": "DataSourceCreate" + }, + "DataSourceRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "source_type": { + "$ref": "#/components/schemas/SourceType" + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "type": "boolean", + "title": "Schedule Enabled", + "default": true + }, + "next_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Next Sync At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "last_ingestion_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Ingestion At" + }, + "last_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Sync At" + }, + "last_sync_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Sync Status" + }, + "last_error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Error Message" + }, + "consecutive_failure_count": { + "type": "integer", + "title": "Consecutive Failure Count", + "default": 0 + }, + "sync_paused": { + "type": "boolean", + "title": "Sync Paused", + "default": false + }, + "health_status": { + "type": "string", + "title": "Health Status", + "default": "healthy" + }, + "active_failure_count": { + "type": "integer", + "title": "Active Failure Count", + "default": 0 + }, + "connector_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Connector Type" + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "name", + "source_type", + "is_active", + "created_by", + "created_at", + "last_ingestion_at" + ], + "title": "DataSourceRead", + "description": "Redacted datasource shape — safe for non-admin roles. connection_config omitted." + }, + "DataSourceUpdate": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "connection_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Connection Config" + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Schedule Enabled" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "DataSourceUpdate" + }, + "DeadlineCommand": { + "properties": { + "action": { + "type": "string", + "const": "set-records-deadline", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/DeadlinePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "DeadlineCommand" + }, + "DeadlinePayload": { + "properties": { + "deadline": { + "type": "string", + "title": "Deadline" + }, + "deadlineBasis": { + "type": "string", + "minLength": 1, + "title": "Deadlinebasis" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "deadline", + "deadlineBasis" + ], + "title": "DeadlinePayload" + }, + "Decision": { + "properties": { + "id": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Id" + }, + "outcome": { + "type": "string", + "enum": [ + "adopted", + "not_adopted", + "deferred", + "withdrawn" + ], + "title": "Outcome" + }, + "decided_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Decided At" + }, + "decision_text": { + "type": "string", + "maxLength": 1000000, + "minLength": 1, + "title": "Decision Text" + }, + "supporting_references": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Supporting References" + }, + "supersedes_decision_id": { + "anyOf": [ + { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$" + }, + { + "type": "null" + } + ], + "title": "Supersedes Decision Id" + }, + "reconciliation_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reconciliation Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "outcome", + "decision_text" + ], + "title": "Decision" + }, + "DepartmentCreate": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "code": { + "type": "string", + "title": "Code" + }, + "contact_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Contact Email" + } + }, + "type": "object", + "required": [ + "name", + "code" + ], + "title": "DepartmentCreate" + }, + "DepartmentRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "code": { + "type": "string", + "title": "Code" + }, + "contact_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Contact Email" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "name", + "code", + "contact_email", + "created_at" + ], + "title": "DepartmentRead" + }, + "DepartmentUpdate": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Code" + }, + "contact_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Contact Email" + } + }, + "type": "object", + "title": "DepartmentUpdate" + }, + "DisclosureTemplateCreate": { + "properties": { + "template_type": { + "type": "string", + "title": "Template Type" + }, + "state_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State Code" + }, + "content": { + "type": "string", + "title": "Content" + } + }, + "type": "object", + "required": [ + "template_type", + "content" + ], + "title": "DisclosureTemplateCreate" + }, + "DisclosureTemplateRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "template_type": { + "type": "string", + "title": "Template Type" + }, + "state_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State Code" + }, + "content": { + "type": "string", + "title": "Content" + }, + "version": { + "type": "integer", + "title": "Version" + }, + "updated_by": { + "type": "string", + "format": "uuid", + "title": "Updated By" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "template_type", + "state_code", + "content", + "version", + "updated_by", + "updated_at" + ], + "title": "DisclosureTemplateRead" + }, + "DisclosureTemplateRendered": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "template_type": { + "type": "string", + "title": "Template Type" + }, + "rendered_content": { + "type": "string", + "title": "Rendered Content" + }, + "has_unresolved_variables": { + "type": "boolean", + "title": "Has Unresolved Variables" + } + }, + "type": "object", + "required": [ + "id", + "template_type", + "rendered_content", + "has_unresolved_variables" + ], + "title": "DisclosureTemplateRendered" + }, + "DisclosureTemplateUpdate": { + "properties": { + "content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Content" + }, + "state_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State Code" + } + }, + "type": "object", + "title": "DisclosureTemplateUpdate" + }, + "DocumentChunkRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "chunk_index": { + "type": "integer", + "title": "Chunk Index" + }, + "content_text": { + "type": "string", + "title": "Content Text" + }, + "token_count": { + "type": "integer", + "title": "Token Count" + }, + "page_number": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Page Number" + } + }, + "type": "object", + "required": [ + "id", + "document_id", + "chunk_index", + "content_text", + "token_count", + "page_number" + ], + "title": "DocumentChunkRead" + }, + "DocumentRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "source_id": { + "type": "string", + "format": "uuid", + "title": "Source Id" + }, + "source_path": { + "type": "string", + "title": "Source Path" + }, + "filename": { + "type": "string", + "title": "Filename" + }, + "file_type": { + "type": "string", + "title": "File Type" + }, + "file_hash": { + "type": "string", + "title": "File Hash" + }, + "file_size": { + "type": "integer", + "title": "File Size" + }, + "ingestion_status": { + "$ref": "#/components/schemas/IngestionStatus" + }, + "ingestion_error": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Ingestion Error" + }, + "chunk_count": { + "type": "integer", + "title": "Chunk Count" + }, + "ingested_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Ingested At" + }, + "connector_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Connector Type" + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "source_id", + "source_path", + "filename", + "file_type", + "file_hash", + "file_size", + "ingestion_status", + "ingestion_error", + "chunk_count", + "ingested_at" + ], + "title": "DocumentRead" + }, + "DraftCommand": { + "properties": { + "action": { + "type": "string", + "const": "draft-records-response", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/DraftPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "DraftCommand" + }, + "DraftInput": { + "properties": { + "source_materials": { + "items": { + "$ref": "#/components/schemas/SourceInput" + }, + "type": "array", + "title": "Source Materials" + }, + "sentences": { + "items": { + "$ref": "#/components/schemas/SentenceInput" + }, + "type": "array", + "minItems": 1, + "title": "Sentences" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sentences" + ], + "title": "DraftInput" + }, + "DraftPayload": { + "properties": { + "responseDraft": { + "type": "string", + "minLength": 1, + "title": "Responsedraft" + }, + "citation": { + "type": "string", + "title": "Citation", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "responseDraft" + ], + "title": "DraftPayload" + }, + "ErrorModel": { + "properties": { + "detail": { + "anyOf": [ + { + "type": "string" + }, + { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + ], + "title": "Detail" + } + }, + "type": "object", + "required": [ + "detail" + ], + "title": "ErrorModel" + }, + "Evidence": { + "properties": { + "filename": { + "type": "string", + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$", + "title": "Filename" + }, + "description": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Description" + }, + "media_type": { + "type": "string", + "enum": [ + "text/plain", + "image/jpeg", + "image/png", + "image/webp", + "application/pdf", + "audio/webm", + "audio/ogg", + "audio/wav", + "audio/mpeg", + "audio/mp4" + ], + "title": "Media Type" + }, + "content_base64": { + "type": "string", + "maxLength": 14000000, + "minLength": 1, + "title": "Content Base64" + }, + "sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "filename", + "description", + "media_type", + "content_base64", + "sha256" + ], + "title": "Evidence" + }, + "EvidenceItem": { + "properties": { + "filename": { + "type": "string", + "maxLength": 151, + "minLength": 1, + "title": "Filename" + }, + "media_type": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Media Type" + }, + "description": { + "type": "string", + "maxLength": 2000, + "title": "Description", + "default": "" + }, + "content_base64": { + "type": "string", + "maxLength": 14000000, + "minLength": 1, + "title": "Content Base64" + }, + "sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "filename", + "media_type", + "content_base64", + "sha256" + ], + "title": "EvidenceItem" + }, + "EvidenceItems": { + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/EvidenceItem" + }, + "type": "array", + "maxItems": 10, + "minItems": 1, + "title": "Items" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "items" + ], + "title": "EvidenceItems" + }, + "ExemptionAccuracyReport": { + "properties": { + "category": { + "type": "string", + "title": "Category" + }, + "total_flags": { + "type": "integer", + "title": "Total Flags" + }, + "accepted": { + "type": "integer", + "title": "Accepted" + }, + "rejected": { + "type": "integer", + "title": "Rejected" + }, + "pending": { + "type": "integer", + "title": "Pending" + }, + "acceptance_rate": { + "type": "number", + "title": "Acceptance Rate" + } + }, + "type": "object", + "required": [ + "category", + "total_flags", + "accepted", + "rejected", + "pending", + "acceptance_rate" + ], + "title": "ExemptionAccuracyReport" + }, + "ExemptionDashboard": { + "properties": { + "total_flags": { + "type": "integer", + "title": "Total Flags" + }, + "by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "By Status" + }, + "by_category": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "By Category" + }, + "acceptance_rate": { + "type": "number", + "title": "Acceptance Rate" + }, + "total_rules": { + "type": "integer", + "title": "Total Rules" + }, + "active_rules": { + "type": "integer", + "title": "Active Rules" + } + }, + "type": "object", + "required": [ + "total_flags", + "by_status", + "by_category", + "acceptance_rate", + "total_rules", + "active_rules" + ], + "title": "ExemptionDashboard" + }, + "ExemptionDecisionCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-exemption-decision", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ExemptionDecisionPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "ExemptionDecisionCommand" + }, + "ExemptionDecisionPayload": { + "properties": { + "exemptionSource": { + "type": "string", + "minLength": 1, + "title": "Exemptionsource" + }, + "exemptionKind": { + "type": "string", + "minLength": 1, + "title": "Exemptionkind" + }, + "exemptionFinding": { + "type": "string", + "minLength": 1, + "title": "Exemptionfinding" + }, + "exemptionDecision": { + "type": "string", + "enum": [ + "release", + "redact", + "exempt" + ], + "title": "Exemptiondecision" + }, + "exemptionBasis": { + "type": "string", + "minLength": 1, + "title": "Exemptionbasis" + }, + "exemptionReviewer": { + "type": "string", + "title": "Exemptionreviewer", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "exemptionSource", + "exemptionKind", + "exemptionFinding", + "exemptionDecision", + "exemptionBasis" + ], + "title": "ExemptionDecisionPayload" + }, + "ExemptionDecisionView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "source": { + "type": "string", + "title": "Source" + }, + "kind": { + "type": "string", + "title": "Kind" + }, + "finding": { + "type": "string", + "title": "Finding" + }, + "decision": { + "type": "string", + "enum": [ + "release", + "redact", + "exempt" + ], + "title": "Decision" + }, + "basis": { + "type": "string", + "title": "Basis" + }, + "reviewer": { + "type": "string", + "title": "Reviewer" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "source", + "kind", + "finding", + "decision", + "basis", + "reviewer", + "created_at_unix_seconds" + ], + "title": "ExemptionDecisionView" + }, + "ExemptionFlagRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "chunk_id": { + "type": "string", + "format": "uuid", + "title": "Chunk Id" + }, + "rule_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Rule Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "category": { + "type": "string", + "title": "Category" + }, + "matched_text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Matched Text" + }, + "confidence": { + "type": "number", + "title": "Confidence" + }, + "status": { + "$ref": "#/components/schemas/FlagStatus" + }, + "reviewed_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Reviewed By" + }, + "reviewed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Reviewed At" + }, + "review_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Reason" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "chunk_id", + "rule_id", + "request_id", + "category", + "matched_text", + "confidence", + "status", + "reviewed_by", + "reviewed_at", + "review_reason", + "created_at" + ], + "title": "ExemptionFlagRead" + }, + "ExemptionFlagReview": { + "properties": { + "status": { + "$ref": "#/components/schemas/FlagStatus" + }, + "review_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Reason" + } + }, + "type": "object", + "required": [ + "status" + ], + "title": "ExemptionFlagReview" + }, + "ExemptionNoteCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-exemption-review", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ExemptionNotePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "ExemptionNoteCommand" + }, + "ExemptionNotePayload": { + "properties": { + "exemptionNote": { + "type": "string", + "minLength": 1, + "title": "Exemptionnote" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "exemptionNote" + ], + "title": "ExemptionNotePayload" + }, + "ExemptionRuleCreate": { + "properties": { + "state_code": { + "type": "string", + "title": "State Code" + }, + "category": { + "type": "string", + "title": "Category" + }, + "rule_type": { + "$ref": "#/components/schemas/RuleType" + }, + "rule_definition": { + "type": "string", + "title": "Rule Definition" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "enabled": { + "type": "boolean", + "title": "Enabled", + "default": true + } + }, + "type": "object", + "required": [ + "state_code", + "category", + "rule_type", + "rule_definition" + ], + "title": "ExemptionRuleCreate" + }, + "ExemptionRuleRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "state_code": { + "type": "string", + "title": "State Code" + }, + "category": { + "type": "string", + "title": "Category" + }, + "rule_type": { + "$ref": "#/components/schemas/RuleType" + }, + "rule_definition": { + "type": "string", + "title": "Rule Definition" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "enabled": { + "type": "boolean", + "title": "Enabled" + }, + "version": { + "type": "integer", + "title": "Version", + "default": 1 + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "state_code", + "category", + "rule_type", + "rule_definition", + "description", + "enabled", + "created_by", + "created_at" + ], + "title": "ExemptionRuleRead" + }, + "ExemptionRuleUpdate": { + "properties": { + "rule_definition": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Rule Definition" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "enabled": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Enabled" + } + }, + "type": "object", + "title": "ExemptionRuleUpdate" + }, + "ExportReceipt": { + "properties": { + "export_path": { + "type": "string", + "maxLength": 32768, + "minLength": 1, + "title": "Export Path" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "export_path" + ], + "title": "ExportReceipt" + }, + "FeeEstimateCommand": { + "properties": { + "action": { + "type": "string", + "const": "estimate-records-fee", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/FeeEstimatePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "FeeEstimateCommand" + }, + "FeeEstimatePayload": { + "properties": { + "feeEstimate": { + "type": "string", + "minLength": 1, + "title": "Feeestimate" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "feeEstimate" + ], + "title": "FeeEstimatePayload" + }, + "FeeEstimateRequest": { + "properties": { + "page_count": { + "type": "integer", + "title": "Page Count" + }, + "fee_schedule_id": { + "type": "string", + "format": "uuid", + "title": "Fee Schedule Id" + } + }, + "type": "object", + "required": [ + "page_count", + "fee_schedule_id" + ], + "title": "FeeEstimateRequest" + }, + "FeeEstimateResponse": { + "properties": { + "page_count": { + "type": "integer", + "title": "Page Count" + }, + "unit_price": { + "type": "number", + "title": "Unit Price" + }, + "total": { + "type": "number", + "title": "Total" + }, + "fee_type": { + "type": "string", + "title": "Fee Type" + }, + "description": { + "type": "string", + "title": "Description" + } + }, + "type": "object", + "required": [ + "page_count", + "unit_price", + "total", + "fee_type", + "description" + ], + "title": "FeeEstimateResponse" + }, + "FeeLineCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-fee-line", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/FeeLinePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "FeeLineCommand" + }, + "FeeLineItemCreate": { + "properties": { + "description": { + "type": "string", + "title": "Description" + }, + "quantity": { + "type": "integer", + "title": "Quantity", + "default": 1 + }, + "unit_price": { + "type": "number", + "title": "Unit Price" + }, + "fee_schedule_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Fee Schedule Id" + } + }, + "type": "object", + "required": [ + "description", + "unit_price" + ], + "title": "FeeLineItemCreate" + }, + "FeeLineItemRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "fee_schedule_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Fee Schedule Id" + }, + "description": { + "type": "string", + "title": "Description" + }, + "quantity": { + "type": "integer", + "title": "Quantity" + }, + "unit_price": { + "type": "number", + "title": "Unit Price" + }, + "total": { + "type": "number", + "title": "Total" + }, + "status": { + "type": "string", + "title": "Status" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "fee_schedule_id", + "description", + "quantity", + "unit_price", + "total", + "status", + "created_at" + ], + "title": "FeeLineItemRead" + }, + "FeeLinePayload": { + "properties": { + "feeLineDescription": { + "type": "string", + "minLength": 1, + "title": "Feelinedescription" + }, + "feeScheduleBasis": { + "type": "string", + "minLength": 1, + "title": "Feeschedulebasis" + }, + "feeLineAmount": { + "type": "string", + "title": "Feelineamount" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "feeLineDescription", + "feeScheduleBasis", + "feeLineAmount" + ], + "title": "FeeLinePayload" + }, + "FeeLineView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "description": { + "type": "string", + "title": "Description" + }, + "schedule_basis": { + "type": "string", + "title": "Schedule Basis" + }, + "amount_cents": { + "type": "integer", + "title": "Amount Cents" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "description", + "schedule_basis", + "amount_cents", + "created_at_unix_seconds" + ], + "title": "FeeLineView" + }, + "FeeScheduleCreate": { + "properties": { + "jurisdiction": { + "type": "string", + "title": "Jurisdiction" + }, + "fee_type": { + "type": "string", + "title": "Fee Type" + }, + "amount": { + "type": "number", + "title": "Amount" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "effective_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective Date" + } + }, + "type": "object", + "required": [ + "jurisdiction", + "fee_type", + "amount" + ], + "title": "FeeScheduleCreate" + }, + "FeeScheduleRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "jurisdiction": { + "type": "string", + "title": "Jurisdiction" + }, + "fee_type": { + "type": "string", + "title": "Fee Type" + }, + "amount": { + "type": "number", + "title": "Amount" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "effective_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective Date" + }, + "created_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "jurisdiction", + "fee_type", + "amount", + "description", + "effective_date", + "created_by", + "created_at" + ], + "title": "FeeScheduleRead" + }, + "FeeScheduleUpdate": { + "properties": { + "fee_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Fee Type" + }, + "amount": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Amount" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "effective_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective Date" + } + }, + "type": "object", + "title": "FeeScheduleUpdate" + }, + "FeeWaiverCommand": { + "properties": { + "action": { + "type": "string", + "const": "waive-records-fee", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/FeeWaiverPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "FeeWaiverCommand" + }, + "FeeWaiverCreateRequest": { + "properties": { + "waiver_type": { + "type": "string", + "title": "Waiver Type" + }, + "reason": { + "type": "string", + "title": "Reason" + } + }, + "type": "object", + "required": [ + "waiver_type", + "reason" + ], + "title": "FeeWaiverCreateRequest" + }, + "FeeWaiverPayload": { + "properties": { + "feeWaiverReason": { + "type": "string", + "minLength": 1, + "title": "Feewaiverreason" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "feeWaiverReason" + ], + "title": "FeeWaiverPayload" + }, + "FeeWaiverReadResponse": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "waiver_type": { + "type": "string", + "title": "Waiver Type" + }, + "reason": { + "type": "string", + "title": "Reason" + }, + "status": { + "type": "string", + "title": "Status" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + }, + "created_at": { + "type": "string", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "waiver_type", + "reason", + "status", + "created_at" + ], + "title": "FeeWaiverReadResponse" + }, + "FeeWaiverReviewRequest": { + "properties": { + "status": { + "type": "string", + "title": "Status" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + } + }, + "type": "object", + "required": [ + "status" + ], + "title": "FeeWaiverReviewRequest" + }, + "FinishCommand": { + "properties": { + "action": { + "type": "string", + "enum": [ + "fulfill-records-request", + "close-records-request" + ], + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/NativePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "FinishCommand" + }, + "FlagStatus": { + "type": "string", + "enum": [ + "flagged", + "reviewed", + "accepted", + "rejected" + ], + "title": "FlagStatus" + }, + "FormPlan": { + "properties": { + "action": { + "type": "string", + "const": "form-plan", + "title": "Action" + }, + "formName": { + "type": "string", + "maxLength": 500, + "title": "Formname", + "default": "" + }, + "fields": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 50, + "title": "Fields" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "FormPlan" + }, + "GeneratedDraft": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "model": { + "type": "string", + "minLength": 1, + "title": "Model" + }, + "previous_response_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Previous Response Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text", + "model", + "previous_response_sha256" + ], + "title": "GeneratedDraft" + }, + "HTTPValidationError": { + "properties": { + "detail": { + "items": { + "$ref": "#/components/schemas/ValidationError" + }, + "type": "array", + "title": "Detail" + } + }, + "type": "object", + "title": "HTTPValidationError" + }, + "Handoff": { + "properties": { + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "request_id" + ], + "title": "Handoff" + }, + "ImportBundleCreate": { + "properties": { + "job_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Job Id" + }, + "connector_type": { + "type": "string", + "minLength": 1, + "title": "Connector Type" + }, + "source": { + "$ref": "#/components/schemas/SourceCreate" + }, + "sources": { + "items": { + "$ref": "#/components/schemas/SourceCreate" + }, + "type": "array", + "title": "Sources" + }, + "titles": { + "items": { + "$ref": "#/components/schemas/TitleCreate" + }, + "type": "array", + "title": "Titles" + }, + "chapters": { + "items": { + "$ref": "#/components/schemas/ChapterCreate" + }, + "type": "array", + "title": "Chapters" + }, + "sections": { + "items": { + "$ref": "#/components/schemas/SectionCreate" + }, + "type": "array", + "title": "Sections" + }, + "versions": { + "items": { + "$ref": "#/components/schemas/SectionVersionCreate" + }, + "type": "array", + "title": "Versions" + }, + "provenance": { + "additionalProperties": true, + "type": "object", + "title": "Provenance" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "connector_type", + "source" + ], + "title": "ImportBundleCreate", + "description": "Request body for local fixture/file-drop import jobs." + }, + "InclusionStatus": { + "type": "string", + "enum": [ + "included", + "excluded", + "pending" + ], + "title": "InclusionStatus" + }, + "IngestionStats": { + "properties": { + "total_sources": { + "type": "integer", + "title": "Total Sources" + }, + "active_sources": { + "type": "integer", + "title": "Active Sources" + }, + "total_documents": { + "type": "integer", + "title": "Total Documents" + }, + "documents_by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Documents By Status" + }, + "total_chunks": { + "type": "integer", + "title": "Total Chunks" + } + }, + "type": "object", + "required": [ + "total_sources", + "active_sources", + "total_documents", + "documents_by_status", + "total_chunks" + ], + "title": "IngestionStats" + }, + "IngestionStatus": { + "type": "string", + "enum": [ + "pending", + "processing", + "completed", + "failed" + ], + "title": "IngestionStatus" + }, + "InitiativeInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "policy": { + "$ref": "#/components/schemas/PolicySelection" + }, + "responsible_staff": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Responsible Staff" + }, + "target": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "title": "Target" + }, + "unit": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Unit" + }, + "due_on": { + "type": "string", + "format": "date", + "title": "Due On" + }, + "status": { + "type": "string", + "enum": [ + "planned", + "active", + "completed", + "cancelled" + ], + "title": "Status", + "default": "planned" + }, + "milestones": { + "items": { + "$ref": "#/components/schemas/Milestone" + }, + "type": "array", + "maxItems": 100, + "title": "Milestones" + }, + "measurements": { + "items": { + "$ref": "#/components/schemas/Measurement" + }, + "type": "array", + "maxItems": 1000, + "title": "Measurements" + }, + "note": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "policy", + "responsible_staff", + "target", + "unit", + "due_on", + "note" + ], + "title": "InitiativeInput" + }, + "InspectionInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "property_reference": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Property Reference" + }, + "inspection_reference": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Inspection Reference" + }, + "dataset_kind": { + "type": "string", + "enum": [ + "municipal", + "fictional" + ], + "title": "Dataset Kind" + }, + "inspector_notes": { + "type": "string", + "maxLength": 10000, + "minLength": 1, + "title": "Inspector Notes" + }, + "photo_observations": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 30, + "title": "Photo Observations" + }, + "voice_notes": { + "type": "string", + "maxLength": 10000, + "title": "Voice Notes", + "default": "" + }, + "evidence": { + "items": { + "$ref": "#/components/schemas/Evidence" + }, + "type": "array", + "maxItems": 10, + "title": "Evidence" + }, + "linked_sources": { + "items": { + "$ref": "#/components/schemas/townlight_inspections__workflow_models__SourceLink" + }, + "type": "array", + "maxItems": 30, + "title": "Linked Sources" + }, + "assigned_to": { + "type": "string", + "maxLength": 255, + "title": "Assigned To", + "default": "" + }, + "staff_notes": { + "type": "string", + "maxLength": 10000, + "title": "Staff Notes", + "default": "" + }, + "notice_draft": { + "type": "string", + "maxLength": 10000, + "title": "Notice Draft", + "default": "" + }, + "review_state": { + "type": "string", + "enum": [ + "draft", + "follow_up", + "reviewed" + ], + "title": "Review State", + "default": "draft" + }, + "review_notes": { + "type": "string", + "maxLength": 4000, + "title": "Review Notes", + "default": "" + }, + "public_summary": { + "type": "string", + "maxLength": 10000, + "title": "Public Summary", + "default": "" + }, + "analysis": { + "anyOf": [ + { + "$ref": "#/components/schemas/AnalysisRecord" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "property_reference", + "inspection_reference", + "dataset_kind", + "inspector_notes" + ], + "title": "InspectionInput" + }, + "IntakeInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "project_name": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Project Name" + }, + "project_description": { + "type": "string", + "maxLength": 10000, + "minLength": 1, + "title": "Project Description" + }, + "location": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Location" + }, + "applicant_contact": { + "type": "string", + "maxLength": 2000, + "title": "Applicant Contact", + "default": "" + }, + "requirement_revision": { + "type": "string", + "format": "uuid", + "title": "Requirement Revision" + }, + "materials": { + "items": { + "$ref": "#/components/schemas/MaterialReview" + }, + "type": "array", + "maxItems": 100, + "minItems": 1, + "title": "Materials" + }, + "linked_sources": { + "items": { + "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink" + }, + "type": "array", + "maxItems": 30, + "title": "Linked Sources" + }, + "staff_notes": { + "type": "string", + "maxLength": 10000, + "title": "Staff Notes", + "default": "" + }, + "assigned_to": { + "type": "string", + "maxLength": 255, + "title": "Assigned To", + "default": "" + }, + "review_state": { + "type": "string", + "enum": [ + "draft", + "follow_up", + "reviewed" + ], + "title": "Review State", + "default": "draft" + }, + "review_notes": { + "type": "string", + "maxLength": 4000, + "title": "Review Notes", + "default": "" + }, + "public_summary": { + "type": "string", + "maxLength": 10000, + "title": "Public Summary", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "project_name", + "project_description", + "location", + "requirement_revision", + "materials" + ], + "title": "IntakeInput" + }, + "InterpretationNoteCreate": { + "properties": { + "note_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Note Id" + }, + "note_text": { + "type": "string", + "minLength": 1, + "title": "Note Text" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "note_text" + ], + "title": "InterpretationNoteCreate", + "description": "Request body for staff-only interpretation notes." + }, + "InterviewRequest": { + "properties": { + "last_answer": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Answer" + }, + "last_field": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Field" + }, + "skipped_fields": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Skipped Fields" + } + }, + "type": "object", + "title": "InterviewRequest" + }, + "InterviewResponse": { + "properties": { + "question": { + "type": "string", + "title": "Question" + }, + "target_field": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Target Field" + }, + "all_complete": { + "type": "boolean", + "title": "All Complete" + }, + "completed_fields": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Completed Fields" + }, + "onboarding_status": { + "type": "string", + "title": "Onboarding Status" + }, + "skipped_fields": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Skipped Fields" + } + }, + "type": "object", + "required": [ + "question", + "target_field", + "all_complete", + "completed_fields", + "onboarding_status", + "skipped_fields" + ], + "title": "InterviewResponse" + }, + "ManagedFileReceipt": { + "properties": { + "original_path": { + "type": "string", + "minLength": 1, + "title": "Original Path" + }, + "stored_path": { + "type": "string", + "minLength": 1, + "title": "Stored Path" + }, + "file_name": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "File Name" + }, + "sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Sha256" + }, + "size_bytes": { + "type": "integer", + "maximum": 2147483647.0, + "minimum": 0.0, + "title": "Size Bytes" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "original_path", + "stored_path", + "file_name", + "sha256", + "size_bytes" + ], + "title": "ManagedFileReceipt" + }, + "ManagedSource": { + "properties": { + "original_path": { + "type": "string", + "title": "Original Path" + }, + "stored_path": { + "type": "string", + "title": "Stored Path" + }, + "file_name": { + "type": "string", + "title": "File Name" + }, + "sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Sha256" + }, + "size_bytes": { + "type": "integer", + "minimum": 0.0, + "title": "Size Bytes" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "original_path", + "stored_path", + "file_name", + "sha256", + "size_bytes" + ], + "title": "ManagedSource" + }, + "Material": { + "properties": { + "material_id": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]{1,80}$", + "title": "Material Id" + }, + "description": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Description" + }, + "citation": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Citation" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "material_id", + "description", + "citation" + ], + "title": "Material" + }, + "MaterialReview": { + "properties": { + "material_id": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Material Id" + }, + "status": { + "type": "string", + "enum": [ + "not_reviewed", + "provided", + "missing", + "unclear" + ], + "title": "Status", + "default": "not_reviewed" + }, + "note": { + "type": "string", + "maxLength": 2000, + "title": "Note", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "material_id" + ], + "title": "MaterialReview" + }, + "Measurement": { + "properties": { + "recorded_on": { + "type": "string", + "format": "date", + "title": "Recorded On" + }, + "value": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "title": "Value" + }, + "evidence": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Evidence" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "recorded_on", + "value", + "evidence" + ], + "title": "Measurement" + }, + "MediaAnalysis": { + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/EvidenceItem" + }, + "type": "array", + "maxItems": 10, + "minItems": 1, + "title": "Items" + }, + "code_links": { + "items": { + "$ref": "#/components/schemas/CodeLink" + }, + "type": "array", + "maxItems": 30, + "title": "Code Links" + }, + "inspector_supplied_text": { + "type": "string", + "maxLength": 10000, + "title": "Inspector Supplied Text", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "items" + ], + "title": "MediaAnalysis" + }, + "MeetingInput": { + "properties": { + "title": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Title" + }, + "scheduled_start": { + "type": "string", + "format": "date-time", + "title": "Scheduled Start" + }, + "location": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Location" + }, + "meeting_type": { + "type": "string", + "enum": [ + "regular", + "special", + "emergency", + "closed_session", + "executive" + ], + "title": "Meeting Type", + "default": "regular" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "scheduled_start", + "location" + ], + "title": "MeetingInput" + }, + "MeetingLink": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + }, + "relation": { + "type": "string", + "enum": [ + "hearing", + "context", + "precedent" + ], + "title": "Relation" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256", + "relation" + ], + "title": "MeetingLink" + }, + "MeetingSearch": { + "properties": { + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "MeetingSearch" + }, + "MeetingStageInput": { + "properties": { + "to_status": { + "type": "string", + "enum": [ + "SCHEDULED", + "NOTICED", + "PACKET_POSTED", + "IN_PROGRESS", + "RECESSED", + "ADJOURNED", + "TRANSCRIPT_READY", + "MINUTES_DRAFTED", + "MINUTES_POSTED", + "MINUTES_ADOPTED", + "MINUTES_SIGNED", + "ARCHIVED", + "CANCELLED" + ], + "title": "To Status" + }, + "statutory_basis": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Statutory Basis" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "to_status" + ], + "title": "MeetingStageInput" + }, + "MeetingsSearch": { + "properties": { + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "MeetingsSearch" + }, + "MeetingsSourceSelection": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "MeetingsSourceSelection" + }, + "MessageCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-message", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/MessagePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "MessageCommand" + }, + "MessageCreate": { + "properties": { + "message_text": { + "type": "string", + "title": "Message Text" + }, + "is_internal": { + "type": "boolean", + "title": "Is Internal", + "default": false + } + }, + "type": "object", + "required": [ + "message_text" + ], + "title": "MessageCreate" + }, + "MessagePayload": { + "properties": { + "requestMessageBody": { + "type": "string", + "minLength": 1, + "title": "Requestmessagebody" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requestMessageBody" + ], + "title": "MessagePayload" + }, + "MessageRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "sender_type": { + "type": "string", + "title": "Sender Type" + }, + "sender_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Sender Id" + }, + "message_text": { + "type": "string", + "title": "Message Text" + }, + "is_internal": { + "type": "boolean", + "title": "Is Internal" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "sender_type", + "sender_id", + "message_text", + "is_internal", + "created_at" + ], + "title": "MessageRead" + }, + "MessageView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "author": { + "type": "string", + "title": "Author" + }, + "author_role": { + "type": "string", + "title": "Author Role" + }, + "body": { + "type": "string", + "title": "Body" + }, + "visibility": { + "type": "string", + "title": "Visibility" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "author", + "author_role", + "body", + "visibility", + "created_at_unix_seconds" + ], + "title": "MessageView" + }, + "Milestone": { + "properties": { + "title": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Title" + }, + "due_on": { + "type": "string", + "format": "date", + "title": "Due On" + }, + "completed_on": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Completed On" + }, + "evidence": { + "type": "string", + "maxLength": 2000, + "title": "Evidence", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "due_on" + ], + "title": "Milestone" + }, + "MinutesDecision": { + "properties": { + "action": { + "type": "string", + "enum": [ + "post", + "adopt", + "sign" + ], + "title": "Action" + }, + "note": { + "type": "string", + "title": "Note", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "MinutesDecision" + }, + "ModelRegistryCreate": { + "properties": { + "model_name": { + "type": "string", + "title": "Model Name" + }, + "model_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Version" + }, + "parameter_count": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parameter Count" + }, + "license": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License" + }, + "model_card_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Card Url" + }, + "is_active": { + "type": "boolean", + "title": "Is Active", + "default": false + }, + "context_window_size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Context Window Size" + }, + "supports_ner": { + "type": "boolean", + "title": "Supports Ner", + "default": false + }, + "supports_vision": { + "type": "boolean", + "title": "Supports Vision", + "default": false + } + }, + "type": "object", + "required": [ + "model_name" + ], + "title": "ModelRegistryCreate", + "description": "Schema for creating a new model_registry record (POST body)." + }, + "ModelRegistryRead": { + "properties": { + "id": { + "type": "integer", + "title": "Id" + }, + "model_name": { + "type": "string", + "title": "Model Name" + }, + "model_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Version" + }, + "parameter_count": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parameter Count" + }, + "license": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License" + }, + "model_card_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Card Url" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "added_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Added At" + }, + "context_window_size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Context Window Size" + }, + "supports_ner": { + "type": "boolean", + "title": "Supports Ner" + }, + "supports_vision": { + "type": "boolean", + "title": "Supports Vision" + } + }, + "type": "object", + "required": [ + "id", + "model_name", + "is_active", + "supports_ner", + "supports_vision" + ], + "title": "ModelRegistryRead", + "description": "Schema for returning a model_registry record (GET response).\n\n``from_attributes=True`` allows construction directly from an ORM instance." + }, + "ModelRegistryUpdate": { + "properties": { + "model_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Name" + }, + "model_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Version" + }, + "parameter_count": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parameter Count" + }, + "license": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License" + }, + "model_card_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Card Url" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + }, + "context_window_size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Context Window Size" + }, + "supports_ner": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Supports Ner" + }, + "supports_vision": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Supports Vision" + } + }, + "type": "object", + "title": "ModelRegistryUpdate", + "description": "Schema for partially updating a model_registry record (PATCH body).\n\nEvery field is optional so callers can send only the fields they want to\nchange." + }, + "MotionCorrection": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "reason": { + "type": "string", + "minLength": 1, + "title": "Reason" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text", + "reason" + ], + "title": "MotionCorrection" + }, + "MotionInput": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "seconded_by": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Seconded By" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text" + ], + "title": "MotionInput" + }, + "NativePayload": { + "properties": {}, + "additionalProperties": false, + "type": "object", + "title": "NativePayload" + }, + "NativeRequestRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "requester_name": { + "type": "string", + "title": "Requester Name" + }, + "requester_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Email" + }, + "requester_phone": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Phone" + }, + "requester_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Type" + }, + "date_received": { + "type": "string", + "format": "date-time", + "title": "Date Received" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "description": { + "type": "string", + "title": "Description" + }, + "status": { + "$ref": "#/components/schemas/RequestStatus" + }, + "assigned_to": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "created_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "response_draft": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Response Draft" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + }, + "estimated_fee": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Estimated Fee" + }, + "fee_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Fee Status" + }, + "fee_waiver_requested": { + "type": "boolean", + "title": "Fee Waiver Requested", + "default": false + }, + "priority": { + "type": "string", + "title": "Priority", + "default": "normal" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + }, + "closed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Closed At" + }, + "closure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Closure Reason" + }, + "desktop_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Desktop Id" + }, + "public_tracking_number": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Public Tracking Number" + }, + "submitted_via": { + "type": "string", + "title": "Submitted Via" + }, + "deadline_label": { + "type": "string", + "title": "Deadline Label" + }, + "deadline_basis": { + "type": "string", + "title": "Deadline Basis" + }, + "deadline_reviewed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Deadline Reviewed At" + } + }, + "type": "object", + "required": [ + "id", + "requester_name", + "requester_email", + "date_received", + "statutory_deadline", + "description", + "status", + "assigned_to", + "created_by", + "created_at", + "response_draft", + "review_notes", + "desktop_id", + "public_tracking_number", + "submitted_via", + "deadline_label", + "deadline_basis", + "deadline_reviewed_at" + ], + "title": "NativeRequestRead" + }, + "NoticeDocumentInput": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text" + ], + "title": "NoticeDocumentInput" + }, + "NoticeDraft": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "body": { + "type": "string", + "maxLength": 100000, + "minLength": 1, + "title": "Body" + }, + "notice_type": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Notice Type" + }, + "statutory_basis": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Statutory Basis" + }, + "event_date": { + "type": "string", + "format": "date", + "title": "Event Date" + }, + "lead_days": { + "type": "integer", + "maximum": 365.0, + "minimum": 0.0, + "title": "Lead Days" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "body", + "notice_type", + "statutory_basis", + "event_date", + "lead_days" + ], + "title": "NoticeDraft" + }, + "NoticeInput": { + "properties": { + "notice_type": { + "type": "string", + "enum": [ + "regular", + "special", + "emergency", + "closed_session", + "executive" + ], + "title": "Notice Type" + }, + "posted_at": { + "type": "string", + "format": "date-time", + "title": "Posted At" + }, + "minimum_notice_hours": { + "type": "integer", + "minimum": 0.0, + "title": "Minimum Notice Hours" + }, + "statutory_basis": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Statutory Basis" + }, + "approved_by": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Approved By" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "notice_type", + "posted_at", + "minimum_notice_hours" + ], + "title": "NoticeInput" + }, + "NoticeProofInput": { + "properties": { + "location": { + "type": "string", + "minLength": 1, + "title": "Location" + }, + "note": { + "type": "string", + "title": "Note", + "default": "" + }, + "document_delivery_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Document Delivery Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "location" + ], + "title": "NoticeProofInput" + }, + "NotificationLogRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "template_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Template Id" + }, + "recipient_email": { + "type": "string", + "title": "Recipient Email" + }, + "request_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Request Id" + }, + "channel": { + "type": "string", + "title": "Channel" + }, + "status": { + "type": "string", + "title": "Status" + }, + "sent_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Sent At" + }, + "error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Message" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "template_id", + "recipient_email", + "request_id", + "channel", + "status", + "sent_at", + "error_message", + "created_at" + ], + "title": "NotificationLogRead" + }, + "NotificationTemplateCreate": { + "properties": { + "event_type": { + "type": "string", + "title": "Event Type" + }, + "channel": { + "type": "string", + "title": "Channel", + "default": "email" + }, + "subject_template": { + "type": "string", + "title": "Subject Template" + }, + "body_template": { + "type": "string", + "title": "Body Template" + } + }, + "type": "object", + "required": [ + "event_type", + "subject_template", + "body_template" + ], + "title": "NotificationTemplateCreate" + }, + "NotificationTemplateRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "event_type": { + "type": "string", + "title": "Event Type" + }, + "channel": { + "type": "string", + "title": "Channel" + }, + "subject_template": { + "type": "string", + "title": "Subject Template" + }, + "body_template": { + "type": "string", + "title": "Body Template" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "event_type", + "channel", + "subject_template", + "body_template", + "is_active", + "created_at" + ], + "title": "NotificationTemplateRead" + }, + "NotificationTemplateUpdate": { + "properties": { + "subject_template": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Subject Template" + }, + "body_template": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Body Template" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "NotificationTemplateUpdate" + }, + "NotificationView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "notification_id": { + "type": "string", + "title": "Notification Id" + }, + "module_id": { + "type": "string", + "title": "Module Id" + }, + "record_id": { + "type": "string", + "title": "Record Id" + }, + "audience": { + "type": "string", + "title": "Audience" + }, + "channel": { + "type": "string", + "title": "Channel" + }, + "subject": { + "type": "string", + "title": "Subject" + }, + "body": { + "type": "string", + "title": "Body" + }, + "status": { + "type": "string", + "title": "Status" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + }, + "sent_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Sent At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "notification_id", + "module_id", + "record_id", + "audience", + "channel", + "subject", + "body", + "status", + "created_at_unix_seconds", + "sent_at_unix_seconds" + ], + "title": "NotificationView" + }, + "OllamaModelInfo": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Size" + }, + "details": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Details" + } + }, + "type": "object", + "required": [ + "name" + ], + "title": "OllamaModelInfo" + }, + "OllamaStatus": { + "properties": { + "status": { + "type": "string", + "title": "Status" + }, + "models": { + "items": { + "$ref": "#/components/schemas/OllamaModelInfo" + }, + "type": "array", + "title": "Models" + } + }, + "type": "object", + "required": [ + "status", + "models" + ], + "title": "OllamaStatus" + }, + "OperationalMetrics": { + "properties": { + "average_response_time_days": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Average Response Time Days" + }, + "median_response_time_days": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Median Response Time Days" + }, + "requests_by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Requests By Status" + }, + "requests_by_department": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Requests By Department" + }, + "deadline_compliance_rate": { + "type": "number", + "title": "Deadline Compliance Rate" + }, + "total_open": { + "type": "integer", + "title": "Total Open" + }, + "total_closed": { + "type": "integer", + "title": "Total Closed" + }, + "total_overdue": { + "type": "integer", + "title": "Total Overdue" + }, + "clarification_frequency": { + "type": "number", + "title": "Clarification Frequency" + }, + "top_request_topics": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Top Request Topics" + } + }, + "type": "object", + "required": [ + "average_response_time_days", + "median_response_time_days", + "requests_by_status", + "requests_by_department", + "deadline_compliance_rate", + "total_open", + "total_closed", + "total_overdue", + "clarification_frequency", + "top_request_topics" + ], + "title": "OperationalMetrics" + }, + "Outline": { + "properties": { + "title": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Title" + }, + "question_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "maxItems": 50, + "minItems": 1, + "title": "Question Ids" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "question_ids" + ], + "title": "Outline" + }, + "Packet": { + "properties": { + "expected_revision": { + "type": "string", + "format": "uuid", + "title": "Expected Revision" + }, + "visibility": { + "type": "string", + "enum": [ + "staff_only", + "records_copy" + ], + "title": "Visibility" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "expected_revision", + "visibility" + ], + "title": "Packet" + }, + "PacketInput": { + "properties": { + "agenda_item_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "title": "Agenda Item Ids" + }, + "source_files": { + "items": { + "$ref": "#/components/schemas/ManagedSource" + }, + "type": "array", + "title": "Source Files" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "agenda_item_ids" + ], + "title": "PacketInput" + }, + "Pathway": { + "properties": { + "project_type": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Project Type" + }, + "proposal": { + "type": "string", + "maxLength": 4000, + "title": "Proposal", + "default": "" + }, + "location_context": { + "type": "string", + "maxLength": 1000, + "title": "Location Context", + "default": "" + }, + "requirement_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Requirement Revision" + }, + "fee_link": { + "anyOf": [ + { + "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "project_type" + ], + "title": "Pathway" + }, + "PathwayStep": { + "properties": { + "step": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Step" + }, + "citation": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Citation" + }, + "typical_time": { + "type": "string", + "maxLength": 1000, + "title": "Typical Time", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "step", + "citation" + ], + "title": "PathwayStep" + }, + "PlainLanguageSummaryCreate": { + "properties": { + "summary_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Summary Id" + }, + "section_version_id": { + "type": "string", + "minLength": 1, + "title": "Section Version Id" + }, + "summary_text": { + "type": "string", + "minLength": 1, + "title": "Summary Text" + }, + "language_code": { + "type": "string", + "title": "Language Code", + "default": "en" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "section_version_id", + "summary_text" + ], + "title": "PlainLanguageSummaryCreate", + "description": "Request body for staff-drafted plain-language summaries." + }, + "PolicySelection": { + "properties": { + "plan_id": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Plan Id" + }, + "revision_id": { + "type": "string", + "maxLength": 36, + "minLength": 36, + "title": "Revision Id" + }, + "policy_id": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Policy Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "plan_id", + "revision_id", + "policy_id" + ], + "title": "PolicySelection" + }, + "PortalModeResponse": { + "properties": { + "mode": { + "type": "string", + "enum": [ + "public", + "private" + ], + "title": "Mode", + "description": "Active portal posture for this deployment. ``public`` = minimal resident surface (landing + authenticated records-request submission + resident registration) reachable without staff auth. ``private`` = staff-only; no public routes, no resident self-registration." + } + }, + "type": "object", + "required": [ + "mode" + ], + "title": "PortalModeResponse", + "description": "T5D — schema for ``GET /config/portal-mode``.\n\nExposed to the frontend on boot so it can branch routing without a\nuser-identity lookup. The payload is intentionally the single field\nbelow — no staff config, no user state, no schema version." + }, + "PrepareArtifact": { + "properties": { + "kind": { + "type": "string", + "enum": [ + "response", + "release-package" + ], + "title": "Kind" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "kind" + ], + "title": "PrepareArtifact" + }, + "Proof": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + }, + "filename": { + "type": "string", + "maxLength": 150, + "minLength": 1, + "title": "Filename" + }, + "content_base64": { + "type": "string", + "maxLength": 7000000, + "minLength": 1, + "title": "Content Base64" + }, + "location": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Location" + }, + "published_at": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Published At" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence", + "filename", + "content_base64", + "location", + "published_at" + ], + "title": "Proof" + }, + "Proposal": { + "properties": { + "id": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Id" + }, + "version_id": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Version Id" + }, + "meeting_id": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "ordinance_number": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Ordinance Number" + }, + "proposed_text": { + "type": "string", + "maxLength": 1000000, + "minLength": 1, + "title": "Proposed Text" + }, + "supersedes_id": { + "anyOf": [ + { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$" + }, + { + "type": "null" + } + ], + "title": "Supersedes Id" + }, + "reconciliation_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reconciliation Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "version_id", + "meeting_id", + "title", + "ordinance_number", + "proposed_text" + ], + "title": "Proposal" + }, + "PublicExplore": { + "properties": { + "goal": { + "type": "string", + "maxLength": 500, + "title": "Goal", + "default": "" + }, + "topic": { + "type": "string", + "maxLength": 160, + "title": "Topic", + "default": "" + }, + "neighborhood": { + "type": "string", + "maxLength": 255, + "title": "Neighborhood", + "default": "" + }, + "plan_type": { + "type": "string", + "maxLength": 120, + "title": "Plan Type", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "title": "PublicExplore" + }, + "PublicIntake": { + "properties": { + "requester": { + "type": "string", + "minLength": 1, + "title": "Requester" + }, + "requesterContact": { + "type": "string", + "minLength": 1, + "title": "Requestercontact" + }, + "summary": { + "type": "string", + "minLength": 1, + "title": "Summary" + }, + "deadline": { + "type": "string", + "title": "Deadline", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requester", + "requesterContact", + "summary" + ], + "title": "PublicIntake" + }, + "PublicLookup": { + "properties": { + "trackingNumber": { + "type": "string", + "minLength": 1, + "title": "Trackingnumber" + }, + "requesterContact": { + "type": "string", + "minLength": 1, + "title": "Requestercontact" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "trackingNumber", + "requesterContact" + ], + "title": "PublicLookup" + }, + "PublicMessage": { + "properties": { + "trackingNumber": { + "type": "string", + "minLength": 1, + "title": "Trackingnumber" + }, + "requesterContact": { + "type": "string", + "minLength": 1, + "title": "Requestercontact" + }, + "publicRequestMessage": { + "type": "string", + "minLength": 1, + "title": "Publicrequestmessage" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "trackingNumber", + "requesterContact", + "publicRequestMessage" + ], + "title": "PublicMessage" + }, + "PublicStatusView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "label": { + "type": "string", + "title": "Label" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "status": { + "type": "string", + "title": "Status" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "label", + "summary", + "status", + "created_at_unix_seconds" + ], + "title": "PublicStatusView" + }, + "PublicationView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "source_module": { + "type": "string", + "title": "Source Module" + }, + "source_record_id": { + "type": "string", + "title": "Source Record Id" + }, + "record_type": { + "type": "string", + "title": "Record Type" + }, + "public_payload": { + "type": "string", + "title": "Public Payload" + }, + "payload_hash": { + "type": "string", + "title": "Payload Hash" + }, + "published_at_unix_seconds": { + "type": "integer", + "title": "Published At Unix Seconds" + }, + "retracted_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Retracted At Unix Seconds" + }, + "retracted_by": { + "type": "string", + "title": "Retracted By", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "source_module", + "source_record_id", + "record_type", + "public_payload", + "payload_hash", + "published_at_unix_seconds" + ], + "title": "PublicationView" + }, + "PublishingPlan": { + "properties": { + "action": { + "type": "string", + "const": "publishing-workflow", + "title": "Action" + }, + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "hasReview": { + "type": "boolean", + "title": "Hasreview", + "default": false + }, + "hasPlainLanguage": { + "type": "boolean", + "title": "Hasplainlanguage", + "default": false + }, + "hasTranslationReview": { + "type": "boolean", + "title": "Hastranslationreview", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "PublishingPlan" + }, + "Question": { + "properties": { + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + }, + "question": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Question" + }, + "kind": { + "type": "string", + "enum": [ + "use", + "dimension" + ], + "title": "Kind" + }, + "key": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Key" + }, + "audience": { + "type": "string", + "enum": [ + "resident", + "staff" + ], + "title": "Audience", + "default": "resident" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "jurisdiction", + "query", + "question", + "kind", + "key" + ], + "title": "Question" + }, + "QuestionAnswerRequest": { + "properties": { + "question": { + "type": "string", + "minLength": 1, + "title": "Question" + }, + "section_number": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Section Number" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "question" + ], + "title": "QuestionAnswerRequest", + "description": "Request body for citation-grounded code Q&A." + }, + "RecordsDocumentView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "attachment_id": { + "type": "string", + "title": "Attachment Id" + }, + "title": { + "type": "string", + "title": "Title" + }, + "original_path": { + "type": "string", + "title": "Original Path" + }, + "stored_path": { + "type": "string", + "title": "Stored Path" + }, + "citation": { + "type": "string", + "title": "Citation" + }, + "sha256": { + "type": "string", + "title": "Sha256" + }, + "size_bytes": { + "type": "integer", + "title": "Size Bytes" + }, + "status": { + "type": "string", + "title": "Status" + }, + "added_by": { + "type": "string", + "title": "Added By" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + }, + "release_original_path": { + "type": "string", + "title": "Release Original Path", + "default": "" + }, + "release_stored_path": { + "type": "string", + "title": "Release Stored Path", + "default": "" + }, + "release_file_name": { + "type": "string", + "title": "Release File Name", + "default": "" + }, + "release_sha256": { + "type": "string", + "title": "Release Sha256", + "default": "" + }, + "release_size_bytes": { + "type": "integer", + "title": "Release Size Bytes", + "default": 0 + }, + "release_status": { + "type": "string", + "title": "Release Status", + "default": "" + }, + "release_note": { + "type": "string", + "title": "Release Note", + "default": "" + }, + "release_added_by": { + "type": "string", + "title": "Release Added By", + "default": "" + }, + "release_added_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Release Added At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "attachment_id", + "title", + "original_path", + "stored_path", + "citation", + "sha256", + "size_bytes", + "status", + "added_by", + "created_at_unix_seconds" + ], + "title": "RecordsDocumentView" + }, + "RecordsOperationRead": { + "properties": { + "action": { + "type": "string", + "title": "Action" + }, + "message": { + "type": "string", + "title": "Message" + }, + "request": { + "$ref": "#/components/schemas/RecordsView" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "message", + "request" + ], + "title": "RecordsOperationRead" + }, + "RecordsStateRead": { + "properties": { + "demo_fixture": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Demo Fixture" + }, + "records_requests": { + "items": { + "$ref": "#/components/schemas/RecordsView" + }, + "type": "array", + "title": "Records Requests" + }, + "notification_events": { + "items": { + "$ref": "#/components/schemas/NotificationView" + }, + "type": "array", + "title": "Notification Events" + }, + "publication_events": { + "items": { + "$ref": "#/components/schemas/PublicationView" + }, + "type": "array", + "title": "Publication Events" + }, + "audit_entries": { + "items": { + "$ref": "#/components/schemas/AuditView" + }, + "type": "array", + "title": "Audit Entries" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "records_requests" + ], + "title": "RecordsStateRead" + }, + "RecordsView": { + "properties": { + "request_id": { + "type": "string", + "title": "Request Id" + }, + "id": { + "type": "string", + "title": "Id" + }, + "public_tracking_number": { + "type": "string", + "title": "Public Tracking Number" + }, + "requester": { + "type": "string", + "title": "Requester" + }, + "requester_contact": { + "type": "string", + "title": "Requester Contact" + }, + "submitted_via": { + "type": "string", + "title": "Submitted Via" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "deadline": { + "type": "string", + "title": "Deadline" + }, + "deadline_basis": { + "type": "string", + "title": "Deadline Basis" + }, + "status": { + "type": "string", + "title": "Status" + }, + "assigned_to": { + "type": "string", + "title": "Assigned To" + }, + "clarification_notes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Clarification Notes" + }, + "search_notes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Search Notes" + }, + "search_sessions": { + "items": { + "$ref": "#/components/schemas/SearchReceiptView" + }, + "type": "array", + "title": "Search Sessions" + }, + "exemption_reviews": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Exemption Reviews" + }, + "exemption_decisions": { + "items": { + "$ref": "#/components/schemas/ExemptionDecisionView" + }, + "type": "array", + "title": "Exemption Decisions" + }, + "fee_estimate": { + "type": "string", + "title": "Fee Estimate" + }, + "fee_line_items": { + "items": { + "$ref": "#/components/schemas/FeeLineView" + }, + "type": "array", + "title": "Fee Line Items" + }, + "fee_waiver_reason": { + "type": "string", + "title": "Fee Waiver Reason" + }, + "citations": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Citations" + }, + "response_draft": { + "type": "string", + "title": "Response Draft" + }, + "approval_notes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Approval Notes" + }, + "exports": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Exports" + }, + "documents": { + "items": { + "$ref": "#/components/schemas/RecordsDocumentView" + }, + "type": "array", + "title": "Documents" + }, + "release_packages": { + "items": { + "$ref": "#/components/schemas/ReleasePackageView" + }, + "type": "array", + "title": "Release Packages" + }, + "timeline": { + "items": { + "$ref": "#/components/schemas/TimelineView" + }, + "type": "array", + "title": "Timeline" + }, + "public_status_events": { + "items": { + "$ref": "#/components/schemas/PublicStatusView" + }, + "type": "array", + "title": "Public Status Events" + }, + "messages": { + "items": { + "$ref": "#/components/schemas/MessageView" + }, + "type": "array", + "title": "Messages" + }, + "deadline_reviewed_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Deadline Reviewed At Unix Seconds" + }, + "approved_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Approved At Unix Seconds" + }, + "fulfilled_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Fulfilled At Unix Seconds" + }, + "closed_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Closed At Unix Seconds" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "request_id", + "id", + "public_tracking_number", + "requester", + "requester_contact", + "submitted_via", + "summary", + "deadline", + "deadline_basis", + "status", + "assigned_to", + "clarification_notes", + "search_notes", + "search_sessions", + "exemption_reviews", + "exemption_decisions", + "fee_estimate", + "fee_line_items", + "fee_waiver_reason", + "citations", + "response_draft", + "approval_notes", + "exports", + "timeline", + "public_status_events", + "messages", + "deadline_reviewed_at_unix_seconds", + "approved_at_unix_seconds", + "fulfilled_at_unix_seconds", + "closed_at_unix_seconds", + "created_at_unix_seconds" + ], + "title": "RecordsView" + }, + "ReleasePackageView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "export_path": { + "type": "string", + "title": "Export Path" + }, + "package_hash": { + "type": "string", + "title": "Package Hash" + }, + "document_count": { + "type": "integer", + "title": "Document Count" + }, + "release_artifact_count": { + "type": "integer", + "title": "Release Artifact Count" + }, + "search_session_count": { + "type": "integer", + "title": "Search Session Count" + }, + "release_count": { + "type": "integer", + "title": "Release Count" + }, + "redacted_count": { + "type": "integer", + "title": "Redacted Count" + }, + "exempt_count": { + "type": "integer", + "title": "Exempt Count" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "export_path", + "package_hash", + "document_count", + "release_artifact_count", + "search_session_count", + "release_count", + "redacted_count", + "exempt_count", + "created_at_unix_seconds" + ], + "title": "ReleasePackageView" + }, + "RepeatLookup": { + "properties": { + "property_reference": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Property Reference" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "property_reference" + ], + "title": "RepeatLookup" + }, + "RequestCreate": { + "properties": { + "requester_name": { + "type": "string", + "maxLength": 255, + "title": "Requester Name" + }, + "requester_email": { + "anyOf": [ + { + "type": "string", + "maxLength": 255 + }, + { + "type": "null" + } + ], + "title": "Requester Email" + }, + "requester_phone": { + "anyOf": [ + { + "type": "string", + "maxLength": 50 + }, + { + "type": "null" + } + ], + "title": "Requester Phone" + }, + "requester_type": { + "anyOf": [ + { + "type": "string", + "maxLength": 100 + }, + { + "type": "null" + } + ], + "title": "Requester Type" + }, + "description": { + "type": "string", + "maxLength": 10000, + "title": "Description" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "priority": { + "type": "string", + "title": "Priority", + "default": "normal" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string", + "pattern": "^(narrow|moderate|broad)$" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + } + }, + "type": "object", + "required": [ + "requester_name", + "description" + ], + "title": "RequestCreate" + }, + "RequestDocumentAdd": { + "properties": { + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "relevance_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Relevance Note" + } + }, + "type": "object", + "required": [ + "document_id" + ], + "title": "RequestDocumentAdd" + }, + "RequestDocumentRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "relevance_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Relevance Note" + }, + "exemption_flags": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Exemption Flags" + }, + "inclusion_status": { + "$ref": "#/components/schemas/InclusionStatus" + }, + "attached_at": { + "type": "string", + "format": "date-time", + "title": "Attached At" + }, + "attached_by": { + "type": "string", + "format": "uuid", + "title": "Attached By" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "document_id", + "relevance_note", + "exemption_flags", + "inclusion_status", + "attached_at", + "attached_by" + ], + "title": "RequestDocumentRead" + }, + "RequestRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "requester_name": { + "type": "string", + "title": "Requester Name" + }, + "requester_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Email" + }, + "requester_phone": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Phone" + }, + "requester_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Type" + }, + "date_received": { + "type": "string", + "format": "date-time", + "title": "Date Received" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "description": { + "type": "string", + "title": "Description" + }, + "status": { + "$ref": "#/components/schemas/RequestStatus" + }, + "assigned_to": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "created_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "response_draft": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Response Draft" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + }, + "estimated_fee": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Estimated Fee" + }, + "fee_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Fee Status" + }, + "fee_waiver_requested": { + "type": "boolean", + "title": "Fee Waiver Requested", + "default": false + }, + "priority": { + "type": "string", + "title": "Priority", + "default": "normal" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + }, + "closed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Closed At" + }, + "closure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Closure Reason" + } + }, + "type": "object", + "required": [ + "id", + "requester_name", + "requester_email", + "date_received", + "statutory_deadline", + "description", + "status", + "assigned_to", + "created_by", + "created_at", + "response_draft", + "review_notes" + ], + "title": "RequestRead" + }, + "RequestStats": { + "properties": { + "total_requests": { + "type": "integer", + "title": "Total Requests" + }, + "by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "By Status" + }, + "approaching_deadline": { + "type": "integer", + "title": "Approaching Deadline" + }, + "overdue": { + "type": "integer", + "title": "Overdue" + } + }, + "type": "object", + "required": [ + "total_requests", + "by_status", + "approaching_deadline", + "overdue" + ], + "title": "RequestStats" + }, + "RequestStatus": { + "type": "string", + "enum": [ + "received", + "clarification_needed", + "assigned", + "searching", + "in_review", + "ready_for_release", + "drafted", + "approved", + "fulfilled", + "closed" + ], + "title": "RequestStatus" + }, + "RequestUpdate": { + "properties": { + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "status": { + "anyOf": [ + { + "$ref": "#/components/schemas/RequestStatus" + }, + { + "type": "null" + } + ] + }, + "assigned_to": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "response_draft": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Response Draft" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + } + }, + "type": "object", + "title": "RequestUpdate" + }, + "RequirementBundle": { + "properties": { + "requirement_id": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]{1,100}$", + "title": "Requirement Id" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "project_type": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Project Type" + }, + "source_reference": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Source Reference" + }, + "source_date": { + "type": "string", + "format": "date", + "title": "Source Date" + }, + "effective_on": { + "type": "string", + "format": "date", + "title": "Effective On" + }, + "dataset_kind": { + "type": "string", + "enum": [ + "municipal", + "fictional" + ], + "title": "Dataset Kind" + }, + "filename": { + "type": "string", + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$", + "title": "Filename" + }, + "content_base64": { + "type": "string", + "maxLength": 14000000, + "minLength": 1, + "title": "Content Base64" + }, + "sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Sha256" + }, + "materials": { + "items": { + "$ref": "#/components/schemas/Material" + }, + "type": "array", + "maxItems": 100, + "minItems": 1, + "title": "Materials" + }, + "pathway": { + "items": { + "$ref": "#/components/schemas/PathwayStep" + }, + "type": "array", + "maxItems": 100, + "title": "Pathway" + }, + "fee_link": { + "anyOf": [ + { + "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink" + }, + { + "type": "null" + } + ] + }, + "staff_note": { + "type": "string", + "maxLength": 4000, + "title": "Staff Note", + "default": "" + }, + "change_note": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Change Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requirement_id", + "title", + "jurisdiction", + "project_type", + "source_reference", + "source_date", + "effective_on", + "dataset_kind", + "filename", + "content_base64", + "sha256", + "materials", + "change_note" + ], + "title": "RequirementBundle" + }, + "ResponseLetterCreate": { + "properties": { + "template_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Template Id" + } + }, + "type": "object", + "title": "ResponseLetterCreate" + }, + "ResponseLetterRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "template_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Template Id" + }, + "generated_content": { + "type": "string", + "title": "Generated Content" + }, + "edited_content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Edited Content" + }, + "status": { + "type": "string", + "title": "Status" + }, + "generated_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Generated By" + }, + "approved_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Approved By" + }, + "sent_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Sent At" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "template_id", + "generated_content", + "edited_content", + "status", + "generated_by", + "approved_by", + "sent_at", + "created_at" + ], + "title": "ResponseLetterRead" + }, + "ResponseLetterUpdate": { + "properties": { + "edited_content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Edited Content" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + } + }, + "type": "object", + "title": "ResponseLetterUpdate" + }, + "ReviewInput": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "body": { + "type": "string", + "maxLength": 5000, + "title": "Body", + "default": "" + }, + "hasAltText": { + "type": "boolean", + "title": "Hasalttext", + "default": false + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "en" + } + }, + "additionalProperties": false, + "type": "object", + "title": "ReviewInput" + }, + "Revision": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + }, + "document": { + "$ref": "#/components/schemas/NoticeDraft" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence", + "document" + ], + "title": "Revision" + }, + "RewriteInput": { + "properties": { + "action": { + "type": "string", + "enum": [ + "plain-language", + "language-variant" + ], + "title": "Action" + }, + "text": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Text" + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "text" + ], + "title": "RewriteInput" + }, + "RewriteResult": { + "properties": { + "action": { + "type": "string", + "enum": [ + "plain-language", + "language-variant" + ], + "title": "Action" + }, + "text": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Text" + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "" + }, + "outcome": { + "type": "string", + "enum": [ + "generated", + "unavailable" + ], + "title": "Outcome" + }, + "generated": { + "anyOf": [ + { + "type": "string", + "maxLength": 100000 + }, + { + "type": "null" + } + ], + "title": "Generated" + }, + "model": { + "anyOf": [ + { + "type": "string", + "maxLength": 200 + }, + { + "type": "null" + } + ], + "title": "Model" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "text", + "outcome" + ], + "title": "RewriteResult" + }, + "Rule": { + "properties": { + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "zone_code": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Zone Code" + }, + "key": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Key" + }, + "section_number": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Section Number" + }, + "kind": { + "type": "string", + "enum": [ + "use", + "dimension" + ], + "title": "Kind" + }, + "value": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Value" + }, + "overlay_code": { + "anyOf": [ + { + "type": "string", + "maxLength": 255 + }, + { + "type": "null" + } + ], + "title": "Overlay Code" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "jurisdiction", + "zone_code", + "key", + "section_number", + "kind", + "value" + ], + "title": "Rule" + }, + "RuleTestMatch": { + "properties": { + "matched_text": { + "type": "string", + "title": "Matched Text" + }, + "start": { + "type": "integer", + "title": "Start" + }, + "end": { + "type": "integer", + "title": "End" + } + }, + "type": "object", + "required": [ + "matched_text", + "start", + "end" + ], + "title": "RuleTestMatch" + }, + "RuleTestRequest": { + "properties": { + "sample_text": { + "type": "string", + "title": "Sample Text" + } + }, + "type": "object", + "required": [ + "sample_text" + ], + "title": "RuleTestRequest" + }, + "RuleTestResponse": { + "properties": { + "rule_id": { + "type": "string", + "format": "uuid", + "title": "Rule Id" + }, + "rule_type": { + "type": "string", + "title": "Rule Type" + }, + "matched": { + "type": "boolean", + "title": "Matched" + }, + "matches": { + "items": { + "$ref": "#/components/schemas/RuleTestMatch" + }, + "type": "array", + "title": "Matches" + } + }, + "type": "object", + "required": [ + "rule_id", + "rule_type", + "matched", + "matches" + ], + "title": "RuleTestResponse" + }, + "RuleType": { + "type": "string", + "enum": [ + "regex", + "keyword", + "llm_prompt" + ], + "title": "RuleType" + }, + "SaveReview": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "body": { + "type": "string", + "maxLength": 5000, + "title": "Body", + "default": "" + }, + "hasAltText": { + "type": "boolean", + "title": "Hasalttext", + "default": false + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "en" + }, + "ai_analysis": { + "anyOf": [ + { + "type": "string", + "maxLength": 100000 + }, + { + "type": "null" + } + ], + "title": "Ai Analysis" + }, + "ai_analysis_model": { + "anyOf": [ + { + "type": "string", + "maxLength": 200 + }, + { + "type": "null" + } + ], + "title": "Ai Analysis Model" + }, + "ai_outcome": { + "type": "string", + "enum": [ + "generated", + "unavailable", + "failed" + ], + "title": "Ai Outcome" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "ai_outcome" + ], + "title": "SaveReview" + }, + "SearchFilterOptions": { + "properties": { + "file_types": { + "items": { + "type": "string" + }, + "type": "array", + "title": "File Types" + }, + "source_names": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Source Names" + }, + "departments": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array", + "title": "Departments", + "default": [] + }, + "date_range": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Date Range" + } + }, + "type": "object", + "required": [ + "file_types", + "source_names" + ], + "title": "SearchFilterOptions" + }, + "SearchInput": { + "properties": { + "query": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "SearchInput" + }, + "SearchNoteCommand": { + "properties": { + "action": { + "type": "string", + "const": "record-records-search", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/SearchNotePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "SearchNoteCommand" + }, + "SearchNotePayload": { + "properties": { + "sourceNote": { + "type": "string", + "minLength": 1, + "title": "Sourcenote" + }, + "citation": { + "type": "string", + "title": "Citation", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sourceNote" + ], + "title": "SearchNotePayload" + }, + "SearchReceiptCommand": { + "properties": { + "action": { + "type": "string", + "const": "record-records-search-session", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/SearchReceiptPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "SearchReceiptCommand" + }, + "SearchReceiptPayload": { + "properties": { + "searchQuery": { + "type": "string", + "minLength": 1, + "title": "Searchquery" + }, + "searchLocations": { + "type": "string", + "minLength": 1, + "title": "Searchlocations" + }, + "searchResultTitle": { + "type": "string", + "minLength": 1, + "title": "Searchresulttitle" + }, + "searchResultCitation": { + "type": "string", + "minLength": 1, + "title": "Searchresultcitation" + }, + "searchResultSummary": { + "type": "string", + "minLength": 1, + "title": "Searchresultsummary" + }, + "searchResultStatus": { + "type": "string", + "title": "Searchresultstatus", + "default": "" + }, + "searchReviewer": { + "type": "string", + "title": "Searchreviewer", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "searchQuery", + "searchLocations", + "searchResultTitle", + "searchResultCitation", + "searchResultSummary" + ], + "title": "SearchReceiptPayload" + }, + "SearchReceiptView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "query": { + "type": "string", + "title": "Query" + }, + "locations": { + "type": "string", + "title": "Locations" + }, + "reviewer": { + "type": "string", + "title": "Reviewer" + }, + "results": { + "items": { + "$ref": "#/components/schemas/SearchResultView" + }, + "type": "array", + "title": "Results" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "query", + "locations", + "reviewer", + "results", + "created_at_unix_seconds" + ], + "title": "SearchReceiptView" + }, + "SearchRequest": { + "properties": { + "query": { + "type": "string", + "title": "Query" + }, + "session_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Session Id" + }, + "filters": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Filters" + }, + "limit": { + "type": "integer", + "maximum": 50.0, + "title": "Limit", + "default": 10 + }, + "synthesize": { + "type": "boolean", + "title": "Synthesize", + "default": false + } + }, + "type": "object", + "required": [ + "query" + ], + "title": "SearchRequest" + }, + "SearchResponse": { + "properties": { + "query_id": { + "type": "string", + "format": "uuid", + "title": "Query Id" + }, + "session_id": { + "type": "string", + "format": "uuid", + "title": "Session Id" + }, + "query_text": { + "type": "string", + "title": "Query Text" + }, + "results": { + "items": { + "$ref": "#/components/schemas/SearchResultItem" + }, + "type": "array", + "title": "Results" + }, + "results_count": { + "type": "integer", + "title": "Results Count" + }, + "synthesized_answer": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Synthesized Answer" + }, + "ai_generated": { + "type": "boolean", + "title": "Ai Generated", + "default": false + } + }, + "type": "object", + "required": [ + "query_id", + "session_id", + "query_text", + "results", + "results_count" + ], + "title": "SearchResponse" + }, + "SearchResultItem": { + "properties": { + "chunk_id": { + "type": "string", + "format": "uuid", + "title": "Chunk Id" + }, + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "filename": { + "type": "string", + "title": "Filename" + }, + "file_type": { + "type": "string", + "title": "File Type" + }, + "source_path": { + "type": "string", + "title": "Source Path" + }, + "page_number": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Page Number" + }, + "content_text": { + "type": "string", + "title": "Content Text" + }, + "similarity_score": { + "type": "number", + "title": "Similarity Score" + }, + "rank": { + "type": "integer", + "title": "Rank" + } + }, + "type": "object", + "required": [ + "chunk_id", + "document_id", + "filename", + "file_type", + "source_path", + "page_number", + "content_text", + "similarity_score", + "rank" + ], + "title": "SearchResultItem" + }, + "SearchResultView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "title": { + "type": "string", + "title": "Title" + }, + "citation": { + "type": "string", + "title": "Citation" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "status": { + "type": "string", + "title": "Status" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "title", + "citation", + "summary", + "status" + ], + "title": "SearchResultView" + }, + "SearchSessionRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "user_id": { + "type": "string", + "format": "uuid", + "title": "User Id" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "queries": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array", + "title": "Queries", + "default": [] + } + }, + "type": "object", + "required": [ + "id", + "user_id", + "created_at" + ], + "title": "SearchSessionRead" + }, + "SectionCreate": { + "properties": { + "section_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Section Id" + }, + "chapter_id": { + "type": "string", + "minLength": 1, + "title": "Chapter Id" + }, + "section_number": { + "type": "string", + "minLength": 1, + "title": "Section Number" + }, + "section_heading": { + "type": "string", + "minLength": 1, + "title": "Section Heading" + }, + "parent_section_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parent Section Id" + }, + "sort_order": { + "type": "integer", + "title": "Sort Order", + "default": 0 + }, + "administrative_regulation_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Administrative Regulation Refs" + }, + "resolution_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Resolution Refs" + }, + "policy_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Policy Refs" + }, + "approved_summary_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Approved Summary Refs" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "chapter_id", + "section_number", + "section_heading" + ], + "title": "SectionCreate", + "description": "Request body for creating a code section or subsection." + }, + "SectionVersionCreate": { + "properties": { + "version_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Version Id" + }, + "section_id": { + "type": "string", + "minLength": 1, + "title": "Section Id" + }, + "source_id": { + "type": "string", + "minLength": 1, + "title": "Source Id" + }, + "version_label": { + "type": "string", + "minLength": 1, + "title": "Version Label" + }, + "body": { + "type": "string", + "minLength": 1, + "title": "Body" + }, + "effective_start": { + "type": "string", + "format": "date", + "title": "Effective Start" + }, + "effective_end": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective End" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + }, + "is_current": { + "type": "boolean", + "title": "Is Current", + "default": false + }, + "adoption_event_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Adoption Event Id" + }, + "amendment_event_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Amendment Event Id" + }, + "amendment_summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Amendment Summary" + }, + "prior_version_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Prior Version Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "section_id", + "source_id", + "version_label", + "body", + "effective_start" + ], + "title": "SectionVersionCreate", + "description": "Request body for adding an immutable section version." + }, + "Selection": { + "properties": { + "recording_id": { + "type": "string", + "format": "uuid", + "title": "Recording Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "recording_id", + "expected_sha256" + ], + "title": "Selection" + }, + "SentenceInput": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "citations": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Citations" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text" + ], + "title": "SentenceInput" + }, + "ServiceAccountCreate": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole", + "default": "read_only" + } + }, + "type": "object", + "required": [ + "name" + ], + "title": "ServiceAccountCreate" + }, + "ServiceAccountCreated": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "api_key": { + "type": "string", + "title": "Api Key" + } + }, + "type": "object", + "required": [ + "id", + "name", + "role", + "created_by", + "created_at", + "is_active", + "api_key" + ], + "title": "ServiceAccountCreated", + "description": "Returned only on creation — includes the plaintext API key (shown once)." + }, + "ServiceAccountRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + } + }, + "type": "object", + "required": [ + "id", + "name", + "role", + "created_by", + "created_at", + "is_active" + ], + "title": "ServiceAccountRead" + }, + "ServiceAccountUpdate": { + "properties": { + "role": { + "anyOf": [ + { + "$ref": "#/components/schemas/UserRole" + }, + { + "type": "null" + } + ] + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "ServiceAccountUpdate" + }, + "Snapshot": { + "properties": { + "expected_revision": { + "type": "string", + "format": "uuid", + "title": "Expected Revision" + }, + "visibility": { + "type": "string", + "enum": [ + "staff_only", + "public" + ], + "title": "Visibility" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "expected_revision", + "visibility" + ], + "title": "Snapshot" + }, + "SourceCreate": { + "properties": { + "source_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Id" + }, + "name": { + "type": "string", + "minLength": 1, + "title": "Name" + }, + "publisher": { + "type": "string", + "minLength": 1, + "title": "Publisher" + }, + "source_type": { + "type": "string", + "minLength": 1, + "title": "Source Type" + }, + "source_category": { + "type": "string", + "minLength": 1, + "title": "Source Category" + }, + "source_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Url" + }, + "file_reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "File Reference" + }, + "retrieved_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Retrieved At" + }, + "retrieval_method": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Retrieval Method" + }, + "checksum": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Checksum" + }, + "source_owner": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Owner" + }, + "is_official": { + "type": "boolean", + "title": "Is Official", + "default": true + }, + "official_status_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Official Status Note" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + }, + "staff_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Staff Notes" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "name", + "publisher", + "source_type", + "source_category" + ], + "title": "SourceCreate", + "description": "Request body for registering an official or explicitly labeled source." + }, + "SourceInput": { + "properties": { + "source_id": { + "type": "string", + "minLength": 1, + "title": "Source Id" + }, + "label": { + "type": "string", + "minLength": 1, + "title": "Label" + }, + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "label", + "text" + ], + "title": "SourceInput" + }, + "SourceSnapshot": { + "properties": { + "visibility": { + "type": "string", + "enum": [ + "public", + "staff_only" + ], + "title": "Visibility" + }, + "meeting_event_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "maxItems": 50, + "title": "Meeting Event Ids" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "visibility" + ], + "title": "SourceSnapshot" + }, + "SourceType": { + "type": "string", + "enum": [ + "manual_drop", + "file_system", + "rest_api", + "odbc" + ], + "title": "SourceType" + }, + "StaffRecordsIntake": { + "properties": { + "requester": { + "type": "string", + "minLength": 1, + "title": "Requester" + }, + "summary": { + "type": "string", + "minLength": 1, + "title": "Summary" + }, + "deadline": { + "type": "string", + "title": "Deadline" + }, + "deadlineBasis": { + "type": "string", + "title": "Deadlinebasis", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requester", + "summary", + "deadline" + ], + "title": "StaffRecordsIntake", + "description": "Existing native create-records-request input; no caller-supplied actor." + }, + "StandardsExplanation": { + "properties": { + "question": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Question" + }, + "process_section": { + "type": "string", + "maxLength": 255, + "title": "Process Section", + "default": "" + }, + "zone_code": { + "type": "string", + "maxLength": 40, + "title": "Zone Code", + "default": "" + }, + "rule_types": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 10, + "title": "Rule Types" + }, + "observed": { + "additionalProperties": { + "type": "string" + }, + "type": "object", + "title": "Observed" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "question" + ], + "title": "StandardsExplanation" + }, + "SyncFailureRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "source_id": { + "type": "string", + "format": "uuid", + "title": "Source Id" + }, + "source_path": { + "type": "string", + "title": "Source Path" + }, + "error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Message" + }, + "error_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Class" + }, + "http_status_code": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Http Status Code" + }, + "retry_count": { + "type": "integer", + "title": "Retry Count" + }, + "status": { + "type": "string", + "title": "Status" + }, + "first_failed_at": { + "type": "string", + "format": "date-time", + "title": "First Failed At" + }, + "last_retried_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Retried At" + }, + "dismissed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Dismissed At" + }, + "dismissed_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Dismissed By" + } + }, + "type": "object", + "required": [ + "id", + "source_id", + "source_path", + "error_message", + "error_class", + "http_status_code", + "retry_count", + "status", + "first_failed_at", + "last_retried_at", + "dismissed_at", + "dismissed_by" + ], + "title": "SyncFailureRead" + }, + "SyncRunLogRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "source_id": { + "type": "string", + "format": "uuid", + "title": "Source Id" + }, + "started_at": { + "type": "string", + "format": "date-time", + "title": "Started At" + }, + "finished_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Finished At" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + }, + "records_attempted": { + "type": "integer", + "title": "Records Attempted" + }, + "records_succeeded": { + "type": "integer", + "title": "Records Succeeded" + }, + "records_failed": { + "type": "integer", + "title": "Records Failed" + }, + "error_summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Summary" + } + }, + "type": "object", + "required": [ + "id", + "source_id", + "started_at", + "finished_at", + "status", + "records_attempted", + "records_succeeded", + "records_failed", + "error_summary" + ], + "title": "SyncRunLogRead" + }, + "SystemStatus": { + "properties": { + "version": { + "type": "string", + "title": "Version" + }, + "database": { + "type": "string", + "title": "Database" + }, + "ollama": { + "type": "string", + "title": "Ollama" + }, + "redis": { + "type": "string", + "title": "Redis" + }, + "user_count": { + "type": "integer", + "title": "User Count" + }, + "audit_log_count": { + "type": "integer", + "title": "Audit Log Count" + }, + "suite_session": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Suite Session" + } + }, + "type": "object", + "required": [ + "version", + "database", + "ollama", + "redis", + "user_count", + "audit_log_count" + ], + "title": "SystemStatus" + }, + "TaggedPlan": { + "properties": { + "action": { + "type": "string", + "const": "tagged-pdf", + "title": "Action" + }, + "headingLevels": { + "items": { + "type": "integer", + "maximum": 4294967295.0, + "minimum": 0.0 + }, + "type": "array", + "maxItems": 50, + "title": "Headinglevels" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "TaggedPlan" + }, + "TestConnectionRequest": { + "properties": { + "source_type": { + "type": "string", + "title": "Source Type" + }, + "host": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Host" + }, + "port": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Port" + }, + "path": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Path" + }, + "username": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Username" + }, + "password": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Password" + }, + "rest_api_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Rest Api Config" + }, + "odbc_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Odbc Config" + } + }, + "type": "object", + "required": [ + "source_type" + ], + "title": "TestConnectionRequest", + "description": "Dedicated schema for test-connection. NOT the create schema.\n\nSecurity: credentials in this request body are never persisted, never\nwritten to audit logs, and never returned in the response." + }, + "TestConnectionResponse": { + "properties": { + "success": { + "type": "boolean", + "title": "Success" + }, + "message": { + "type": "string", + "title": "Message" + }, + "latency_ms": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Latency Ms" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + }, + "warning": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Warning" + }, + "differing_keys": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Differing Keys" + } + }, + "type": "object", + "required": [ + "success", + "message" + ], + "title": "TestConnectionResponse" + }, + "TimelineEventCreate": { + "properties": { + "event_type": { + "type": "string", + "title": "Event Type" + }, + "description": { + "type": "string", + "title": "Description" + }, + "internal_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Internal Note" + } + }, + "type": "object", + "required": [ + "event_type", + "description" + ], + "title": "TimelineEventCreate" + }, + "TimelineEventRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "event_type": { + "type": "string", + "title": "Event Type" + }, + "actor_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Actor Id" + }, + "actor_role": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Actor Role" + }, + "description": { + "type": "string", + "title": "Description" + }, + "internal_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Internal Note" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "event_type", + "actor_id", + "actor_role", + "description", + "internal_note", + "created_at" + ], + "title": "TimelineEventRead" + }, + "TimelineView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "action": { + "type": "string", + "title": "Action" + }, + "actor": { + "type": "string", + "title": "Actor" + }, + "note": { + "type": "string", + "title": "Note" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "action", + "actor", + "note", + "created_at_unix_seconds" + ], + "title": "TimelineView" + }, + "TitleCreate": { + "properties": { + "title_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Title Id" + }, + "title_number": { + "type": "string", + "minLength": 1, + "title": "Title Number" + }, + "title_name": { + "type": "string", + "minLength": 1, + "title": "Title Name" + }, + "sort_order": { + "type": "integer", + "title": "Sort Order", + "default": 0 + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title_number", + "title_name" + ], + "title": "TitleCreate", + "description": "Request body for creating a code title." + }, + "TranscriptInput": { + "properties": { + "source_label": { + "type": "string", + "minLength": 1, + "title": "Source Label" + }, + "transcript_text": { + "type": "string", + "minLength": 1, + "title": "Transcript Text" + }, + "correction_of_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Correction Of Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_label", + "transcript_text" + ], + "title": "TranscriptInput" + }, + "UserRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "email": { + "type": "string", + "format": "email", + "title": "Email" + }, + "is_active": { + "type": "boolean", + "title": "Is Active", + "default": true + }, + "is_superuser": { + "type": "boolean", + "title": "Is Superuser", + "default": false + }, + "is_verified": { + "type": "boolean", + "title": "Is Verified", + "default": false + }, + "full_name": { + "type": "string", + "title": "Full Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "last_login": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Login" + }, + "must_change_password": { + "type": "boolean", + "title": "Must Change Password", + "default": false + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + } + }, + "type": "object", + "required": [ + "id", + "email", + "full_name", + "role", + "created_at", + "last_login" + ], + "title": "UserRead" + }, + "UserRole": { + "type": "string", + "enum": [ + "admin", + "staff", + "reviewer", + "read_only", + "liaison", + "public" + ], + "title": "UserRole" + }, + "UserSelfUpdate": { + "properties": { + "password": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Password" + }, + "email": { + "anyOf": [ + { + "type": "string", + "format": "email" + }, + { + "type": "null" + } + ], + "title": "Email" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + }, + "is_superuser": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Superuser" + }, + "is_verified": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Verified" + }, + "full_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Full Name" + } + }, + "type": "object", + "title": "UserSelfUpdate", + "description": "Schema for user self-update via PATCH /users/me.\n\nExcludes role and department_id. Any payload containing those fields is\nrejected at parse time (HTTP 422). Role and department changes require\nadmin privileges via /admin/users/{id}." + }, + "UserUpdateRequest": { + "properties": { + "full_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Full Name" + }, + "role": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Role" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "UserUpdateRequest" + }, + "ValidationError": { + "properties": { + "loc": { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "integer" + } + ] + }, + "type": "array", + "title": "Location" + }, + "msg": { + "type": "string", + "title": "Message" + }, + "type": { + "type": "string", + "title": "Error Type" + }, + "input": { + "title": "Input" + }, + "ctx": { + "type": "object", + "title": "Context" + } + }, + "type": "object", + "required": [ + "loc", + "msg", + "type" + ], + "title": "ValidationError" + }, + "Version": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence" + ], + "title": "Version" + }, + "VoteCorrection": { + "properties": { + "vote": { + "type": "string", + "minLength": 1, + "title": "Vote" + }, + "reason": { + "type": "string", + "minLength": 1, + "title": "Reason" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "vote", + "reason" + ], + "title": "VoteCorrection" + }, + "VoteInput": { + "properties": { + "voter_name": { + "type": "string", + "minLength": 1, + "title": "Voter Name" + }, + "vote": { + "type": "string", + "minLength": 1, + "title": "Vote" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "voter_name", + "vote" + ], + "title": "VoteInput" + }, + "_ParcelLookupIn": { + "properties": { + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "jurisdiction", + "query" + ], + "title": "_ParcelLookupIn" + }, + "townlight_inspections__workflow_models__SourceLink": { + "properties": { + "provider": { + "type": "string", + "const": "code", + "title": "Provider", + "default": "code" + }, + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "SourceLink" + }, + "townlight_permitting__workflow_models__SourceLink": { + "properties": { + "provider": { + "type": "string", + "enum": [ + "code", + "zoning" + ], + "title": "Provider" + }, + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "source_id", + "expected_sha256" + ], + "title": "SourceLink" + }, + "townlight_runtime__inspections_bridge__Search": { + "properties": { + "provider": { + "type": "string", + "const": "code", + "title": "Provider" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "query" + ], + "title": "Search" + }, + "townlight_runtime__notice_bridge__Review": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + }, + "note": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence", + "note" + ], + "title": "Review" + }, + "townlight_runtime__permitting_bridge__Import": { + "properties": { + "bundle": { + "$ref": "#/components/schemas/RequirementBundle" + }, + "expected_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "bundle" + ], + "title": "Import" + }, + "townlight_runtime__permitting_bridge__Search": { + "properties": { + "provider": { + "type": "string", + "enum": [ + "code", + "zoning" + ], + "title": "Provider" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "query" + ], + "title": "Search" + }, + "townlight_runtime__planning_bridge__Import": { + "properties": { + "bundle": { + "additionalProperties": true, + "type": "object", + "title": "Bundle" + }, + "expected_previous_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Expected Previous Revision" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "bundle" + ], + "title": "Import" + }, + "townlight_runtime__planning_bridge__Search": { + "properties": { + "query": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Query" + }, + "plan_type": { + "anyOf": [ + { + "type": "string", + "maxLength": 40 + }, + { + "type": "null" + } + ], + "title": "Plan Type" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "Search" + }, + "townlight_runtime__zoning_bridge__Review": { + "properties": { + "answer": { + "type": "string", + "maxLength": 10000, + "title": "Answer", + "default": "" + }, + "notes": { + "type": "string", + "maxLength": 10000, + "title": "Notes", + "default": "" + }, + "queue_status": { + "type": "string", + "enum": [ + "open", + "in_review", + "resolved", + "closed" + ], + "title": "Queue Status", + "default": "resolved" + } + }, + "additionalProperties": false, + "type": "object", + "title": "Review" + } + }, + "securitySchemes": { + "OAuth2PasswordBearer": { + "type": "oauth2", + "flows": { + "password": { + "scopes": {}, + "tokenUrl": "auth/jwt/login" + } + } + } + } + }, + "x-townlight-component": { + "view": "planning", + "identity": "Townlight Planning 0.4.0.dev2", + "evidence": "source-schema-only" + } +} diff --git a/docs/beta-1/api/planning.html b/docs/beta-1/api/planning.html new file mode 100644 index 0000000..39ab819 --- /dev/null +++ b/docs/beta-1/api/planning.html @@ -0,0 +1,13078 @@ +Townlight Planning API reference
Townlight

Townlight Planning API reference

+

Prepared source candidate, November 2, 2026. New signed Windows installed acceptance and publication remain pending.

+

Townlight Planning 0.4.0.dev2. The HTTP host is Townlight Records 1.8.0.dev2. Component package versions and the host API version are separate identities.

+

Generated from the actual native inspections-preview composition without application lifespan, migrations or database/network access. It describes route and validation contracts; it does not establish endpoint behavior, individual authorization or installed acceptance. Standalone product applications have separate deployment boundaries.

+

Machine-readable OpenAPI schema · Operating manual and limits

+

HTTP operations

+
POST /desktop/v1/planning-sources/search +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Search Planning Sources",
+  "operationId": "search_planning_sources_desktop_v1_planning_sources_search_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MeetingsSearch"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/planning/amendments +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Create Amendment",
+  "operationId": "create_amendment_desktop_v1_planning_amendments_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/AmendmentInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/planning/amendments/history +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Municipal Amendments",
+  "operationId": "municipal_amendments_desktop_v1_planning_amendments_history_get",
+  "parameters": [
+    {
+      "name": "offset",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 100000,
+        "minimum": 0,
+        "default": 0,
+        "title": "Offset"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/planning/amendments/{item_id}/revisions +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Update Amendment",
+  "operationId": "update_amendment_desktop_v1_planning_amendments__item_id__revisions_post",
+  "parameters": [
+    {
+      "name": "item_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Item Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/AmendmentInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/planning/analyses +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Analyses",
+  "operationId": "analyses_desktop_v1_planning_analyses_get",
+  "parameters": [
+    {
+      "name": "limit",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 100,
+        "minimum": 1,
+        "default": 50,
+        "title": "Limit"
+      }
+    },
+    {
+      "name": "offset",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 100000,
+        "minimum": 0,
+        "default": 0,
+        "title": "Offset"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/planning/analyses +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Create Analysis",
+  "operationId": "create_analysis_desktop_v1_planning_analyses_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "type": "object",
+          "additionalProperties": true,
+          "title": "Body"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/planning/analyses/{analysis_id} +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Analysis",
+  "operationId": "analysis_desktop_v1_planning_analyses__analysis_id__get",
+  "parameters": [
+    {
+      "name": "analysis_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Analysis Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/planning/analyses/{analysis_id}/history +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Analysis History",
+  "operationId": "analysis_history_desktop_v1_planning_analyses__analysis_id__history_get",
+  "parameters": [
+    {
+      "name": "analysis_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Analysis Id"
+      }
+    },
+    {
+      "name": "offset",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 100000,
+        "minimum": 0,
+        "default": 0,
+        "title": "Offset"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/planning/analyses/{analysis_id}/revisions +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Revise Analysis",
+  "operationId": "revise_analysis_desktop_v1_planning_analyses__analysis_id__revisions_post",
+  "parameters": [
+    {
+      "name": "analysis_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Analysis Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "type": "object",
+          "additionalProperties": true,
+          "title": "Body"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/planning/analyses/{analysis_id}/snapshot-preview +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Preview Snapshot",
+  "operationId": "preview_snapshot_desktop_v1_planning_analyses__analysis_id__snapshot_preview_post",
+  "parameters": [
+    {
+      "name": "analysis_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Analysis Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/Snapshot"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/planning/analyses/{analysis_id}/snapshots +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Snapshot",
+  "operationId": "snapshot_desktop_v1_planning_analyses__analysis_id__snapshots_post",
+  "parameters": [
+    {
+      "name": "analysis_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Analysis Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/Snapshot"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/planning/connections/search +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Connections",
+  "operationId": "connections_desktop_v1_planning_connections_search_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/ConnectionSearch"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/planning/imports +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Import Source",
+  "operationId": "import_source_desktop_v1_planning_imports_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/townlight_runtime__planning_bridge__Import"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/planning/imports/preview +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Preview Import",
+  "operationId": "preview_import_desktop_v1_planning_imports_preview_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/townlight_runtime__planning_bridge__Import"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/planning/initiatives +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Create Initiative",
+  "operationId": "create_initiative_desktop_v1_planning_initiatives_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/InitiativeInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/planning/initiatives/{item_id}/revisions +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Update Initiative",
+  "operationId": "update_initiative_desktop_v1_planning_initiatives__item_id__revisions_post",
+  "parameters": [
+    {
+      "name": "item_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Item Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/InitiativeInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/planning/municipal-work/{item_id}/history +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Municipal History",
+  "operationId": "municipal_history_desktop_v1_planning_municipal_work__item_id__history_get",
+  "parameters": [
+    {
+      "name": "item_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Item Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/planning/policies/search +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Policies",
+  "operationId": "policies_desktop_v1_planning_policies_search_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/townlight_runtime__planning_bridge__Search"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/planning/progress/targets +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Municipal Progress",
+  "operationId": "municipal_progress_desktop_v1_planning_progress_targets_get",
+  "parameters": [
+    {
+      "name": "offset",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 100000,
+        "minimum": 0,
+        "default": 0,
+        "title": "Offset"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/planning/revisions/{revision_id} +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Revision",
+  "operationId": "revision_desktop_v1_planning_revisions__revision_id__get",
+  "parameters": [
+    {
+      "name": "revision_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Revision Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/planning/revisions/{revision_id}/documents/{document_id} +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Staff Original",
+  "operationId": "staff_original_desktop_v1_planning_revisions__revision_id__documents__document_id__get",
+  "parameters": [
+    {
+      "name": "revision_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Revision Id"
+      }
+    },
+    {
+      "name": "document_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Document Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/planning/snapshots +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Snapshots",
+  "operationId": "snapshots_desktop_v1_planning_snapshots_get",
+  "parameters": [
+    {
+      "name": "limit",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 100,
+        "minimum": 1,
+        "default": 50,
+        "title": "Limit"
+      }
+    },
+    {
+      "name": "offset",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 100000,
+        "minimum": 0,
+        "default": 0,
+        "title": "Offset"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/planning/snapshots/{snapshot_id} +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Document",
+  "operationId": "document_desktop_v1_planning_snapshots__snapshot_id__get",
+  "parameters": [
+    {
+      "name": "snapshot_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Snapshot Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/planning/snapshots/{snapshot_id}/access-advice +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Access Advice",
+  "operationId": "access_advice_desktop_v1_planning_snapshots__snapshot_id__access_advice_post",
+  "parameters": [
+    {
+      "name": "snapshot_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Snapshot Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/planning/sources +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Source List",
+  "operationId": "source_list_desktop_v1_planning_sources_get",
+  "parameters": [
+    {
+      "name": "limit",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 100,
+        "minimum": 1,
+        "default": 50,
+        "title": "Limit"
+      }
+    },
+    {
+      "name": "offset",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 100000,
+        "minimum": 0,
+        "default": 0,
+        "title": "Offset"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/planning/sources/{plan_id}/history +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Source History",
+  "operationId": "source_history_desktop_v1_planning_sources__plan_id__history_get",
+  "parameters": [
+    {
+      "name": "plan_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Plan Id"
+      }
+    },
+    {
+      "name": "offset",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 100000,
+        "minimum": 0,
+        "default": 0,
+        "title": "Offset"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+

Request and response data dictionary

+

Each schema includes the actual required fields, types, constraints and descriptions. References resolve against the machine-readable document.

+
ActionItemInput
+{
+  "properties": {
+    "description": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Description"
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "source_motion_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Motion Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "description"
+  ],
+  "title": "ActionItemInput"
+}
+
+
AdaPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "ada-title-ii",
+      "title": "Action"
+    },
+    "serviceArea": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Servicearea"
+    },
+    "hasCoordinatorReview": {
+      "type": "boolean",
+      "title": "Hascoordinatorreview",
+      "default": false
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "serviceArea"
+  ],
+  "title": "AdaPlan"
+}
+
+
AdminUserCreateRequest
+{
+  "properties": {
+    "email": {
+      "type": "string",
+      "title": "Email"
+    },
+    "password": {
+      "type": "string",
+      "title": "Password"
+    },
+    "full_name": {
+      "type": "string",
+      "title": "Full Name",
+      "default": ""
+    },
+    "role": {
+      "type": "string",
+      "title": "Role",
+      "default": "staff"
+    }
+  },
+  "type": "object",
+  "required": [
+    "email",
+    "password"
+  ],
+  "title": "AdminUserCreateRequest"
+}
+
+
AdminUserCreateResponse
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "email": {
+      "type": "string",
+      "title": "Email"
+    },
+    "full_name": {
+      "type": "string",
+      "title": "Full Name"
+    },
+    "role": {
+      "type": "string",
+      "title": "Role"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "email",
+    "full_name",
+    "role",
+    "is_active"
+  ],
+  "title": "AdminUserCreateResponse"
+}
+
+
AgendaAssignment
+{
+  "properties": {
+    "meeting_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Meeting Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "meeting_id"
+  ],
+  "title": "AgendaAssignment"
+}
+
+
AgendaInput
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "department_name": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Department Name"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "department_name"
+  ],
+  "title": "AgendaInput"
+}
+
+
AgendaReviewInput
+{
+  "properties": {
+    "to_status": {
+      "type": "string",
+      "enum": [
+        "DRAFTED",
+        "SUBMITTED",
+        "DEPT_APPROVED",
+        "LEGAL_REVIEWED",
+        "CLERK_ACCEPTED",
+        "ON_AGENDA",
+        "IN_PACKET",
+        "POSTED",
+        "HEARD",
+        "DISPOSED",
+        "ARCHIVED"
+      ],
+      "title": "To Status"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "to_status"
+  ],
+  "title": "AgendaReviewInput"
+}
+
+
AmendmentInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "policy": {
+      "$ref": "#/components/schemas/PolicySelection"
+    },
+    "proposal": {
+      "type": "string",
+      "maxLength": 20000,
+      "minLength": 1,
+      "title": "Proposal"
+    },
+    "responsible_staff": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Responsible Staff"
+    },
+    "status": {
+      "type": "string",
+      "enum": [
+        "draft",
+        "review",
+        "adopted",
+        "withdrawn"
+      ],
+      "title": "Status",
+      "default": "draft"
+    },
+    "review_note": {
+      "type": "string",
+      "maxLength": 5000,
+      "title": "Review Note",
+      "default": ""
+    },
+    "adoption_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Adoption Revision"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "policy",
+    "proposal",
+    "responsible_staff",
+    "note"
+  ],
+  "title": "AmendmentInput"
+}
+
+
AnalysisObservation
+{
+  "properties": {
+    "source": {
+      "type": "string",
+      "maxLength": 64,
+      "minLength": 1,
+      "title": "Source"
+    },
+    "filename": {
+      "type": "string",
+      "maxLength": 160,
+      "title": "Filename",
+      "default": ""
+    },
+    "media_type": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Media Type",
+      "default": ""
+    },
+    "text": {
+      "type": "string",
+      "maxLength": 4000,
+      "minLength": 1,
+      "title": "Text"
+    },
+    "adapter": {
+      "type": "string",
+      "maxLength": 120,
+      "title": "Adapter",
+      "default": ""
+    },
+    "citation_source_ids": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Citation Source Ids"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source",
+    "text"
+  ],
+  "title": "AnalysisObservation",
+  "description": "One draft observation, named with the adapter that actually produced it."
+}
+
+
AnalysisRecord
+{
+  "properties": {
+    "observations": {
+      "items": {
+        "$ref": "#/components/schemas/AnalysisObservation"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Observations"
+    },
+    "cited_sections": {
+      "items": {
+        "$ref": "#/components/schemas/CitedSection"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Cited Sections"
+    },
+    "unavailable": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Unavailable"
+    },
+    "runtime": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Runtime"
+    },
+    "review_required": {
+      "type": "boolean",
+      "title": "Review Required",
+      "default": true
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "AnalysisRecord",
+  "description": "The adapter output that accompanies a saved inspection draft."
+}
+
+
ApprovalCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "approve-records-response",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ApprovalPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "ApprovalCommand"
+}
+
+
ApprovalPayload
+{
+  "properties": {
+    "approvalNote": {
+      "type": "string",
+      "title": "Approvalnote",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "ApprovalPayload"
+}
+
+
ArchiveInput
+{
+  "properties": {
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "public",
+        "closed_session"
+      ],
+      "title": "Visibility"
+    },
+    "packet_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Packet Id"
+    },
+    "minutes_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Minutes Id"
+    },
+    "plain_language_summary": {
+      "type": "string",
+      "title": "Plain Language Summary",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "visibility"
+  ],
+  "title": "ArchiveInput"
+}
+
+
ArtifactPlan
+{
+  "properties": {
+    "artifact_id": {
+      "type": "string",
+      "title": "Artifact Id"
+    },
+    "file_name": {
+      "type": "string",
+      "title": "File Name"
+    },
+    "content": {
+      "type": "string",
+      "title": "Content"
+    },
+    "sha256": {
+      "type": "string",
+      "title": "Sha256"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "artifact_id",
+    "file_name",
+    "content",
+    "sha256",
+    "created_at_unix_seconds"
+  ],
+  "title": "ArtifactPlan"
+}
+
+
AssignCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "assign-records-request",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/AssignmentPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "AssignCommand"
+}
+
+
AssignmentPayload
+{
+  "properties": {
+    "assignedTo": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Assignedto"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "assignedTo"
+  ],
+  "title": "AssignmentPayload"
+}
+
+
AttachDocument
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation",
+      "default": ""
+    },
+    "file": {
+      "$ref": "#/components/schemas/ManagedFileReceipt"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "file"
+  ],
+  "title": "AttachDocument"
+}
+
+
AttachReleaseCopy
+{
+  "properties": {
+    "status": {
+      "type": "string",
+      "enum": [
+        "release-ready copy",
+        "redacted copy"
+      ],
+      "title": "Status"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note",
+      "default": ""
+    },
+    "added_by": {
+      "type": "string",
+      "title": "Added By",
+      "default": ""
+    },
+    "file": {
+      "$ref": "#/components/schemas/ManagedFileReceipt"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "status",
+    "file"
+  ],
+  "title": "AttachReleaseCopy"
+}
+
+
AuditChainVerification
+{
+  "properties": {
+    "is_valid": {
+      "type": "boolean",
+      "title": "Is Valid"
+    },
+    "entries_checked": {
+      "type": "integer",
+      "title": "Entries Checked"
+    },
+    "error_message": {
+      "type": "string",
+      "title": "Error Message"
+    }
+  },
+  "type": "object",
+  "required": [
+    "is_valid",
+    "entries_checked",
+    "error_message"
+  ],
+  "title": "AuditChainVerification"
+}
+
+
AuditLogRead
+{
+  "properties": {
+    "id": {
+      "type": "integer",
+      "title": "Id"
+    },
+    "prev_hash": {
+      "type": "string",
+      "title": "Prev Hash"
+    },
+    "entry_hash": {
+      "type": "string",
+      "title": "Entry Hash"
+    },
+    "timestamp": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Timestamp"
+    },
+    "user_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "User Id"
+    },
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "resource_type": {
+      "type": "string",
+      "title": "Resource Type"
+    },
+    "resource_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Resource Id"
+    },
+    "details": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Details"
+    },
+    "ai_generated": {
+      "type": "boolean",
+      "title": "Ai Generated"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "prev_hash",
+    "entry_hash",
+    "timestamp",
+    "user_id",
+    "action",
+    "resource_type",
+    "resource_id",
+    "details",
+    "ai_generated"
+  ],
+  "title": "AuditLogRead"
+}
+
+
AuditView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "module_id": {
+      "type": "string",
+      "title": "Module Id"
+    },
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    },
+    "previous_hash": {
+      "type": "string",
+      "title": "Previous Hash"
+    },
+    "entry_hash": {
+      "type": "string",
+      "title": "Entry Hash"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "module_id",
+    "action",
+    "summary",
+    "created_at_unix_seconds",
+    "previous_hash",
+    "entry_hash"
+  ],
+  "title": "AuditView"
+}
+
+
BearerResponse
+{
+  "properties": {
+    "access_token": {
+      "type": "string",
+      "title": "Access Token"
+    },
+    "token_type": {
+      "type": "string",
+      "title": "Token Type"
+    }
+  },
+  "type": "object",
+  "required": [
+    "access_token",
+    "token_type"
+  ],
+  "title": "BearerResponse"
+}
+
+
Body_auth_jwt_login_auth_jwt_login_post
+{
+  "properties": {
+    "grant_type": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^password$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Grant Type"
+    },
+    "username": {
+      "type": "string",
+      "title": "Username"
+    },
+    "password": {
+      "type": "string",
+      "format": "password",
+      "title": "Password"
+    },
+    "scope": {
+      "type": "string",
+      "title": "Scope",
+      "default": ""
+    },
+    "client_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Client Id"
+    },
+    "client_secret": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "format": "password",
+      "title": "Client Secret"
+    }
+  },
+  "type": "object",
+  "required": [
+    "username",
+    "password"
+  ],
+  "title": "Body_auth_jwt_login_auth_jwt_login_post"
+}
+
+
Body_upload_file_datasources_upload_post
+{
+  "properties": {
+    "file": {
+      "type": "string",
+      "contentMediaType": "application/octet-stream",
+      "title": "File"
+    }
+  },
+  "type": "object",
+  "required": [
+    "file"
+  ],
+  "title": "Body_upload_file_datasources_upload_post"
+}
+
+
CalculateDeadlineCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "calculate-records-deadline",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/CalculateDeadlinePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "CalculateDeadlineCommand"
+}
+
+
CalculateDeadlinePayload
+{
+  "properties": {
+    "deadlineReceivedDate": {
+      "type": "string",
+      "title": "Deadlinereceiveddate"
+    },
+    "deadlineRuleName": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Deadlinerulename"
+    },
+    "deadlineDayCount": {
+      "type": "string",
+      "title": "Deadlinedaycount"
+    },
+    "deadlineDayType": {
+      "type": "string",
+      "title": "Deadlinedaytype"
+    },
+    "deadlineBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Deadlinebasis"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "deadlineReceivedDate",
+    "deadlineRuleName",
+    "deadlineDayCount",
+    "deadlineDayType",
+    "deadlineBasis"
+  ],
+  "title": "CalculateDeadlinePayload"
+}
+
+
ChapterCreate
+{
+  "properties": {
+    "chapter_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Chapter Id"
+    },
+    "title_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title Id"
+    },
+    "chapter_number": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Chapter Number"
+    },
+    "chapter_name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Chapter Name"
+    },
+    "sort_order": {
+      "type": "integer",
+      "title": "Sort Order",
+      "default": 0
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title_id",
+    "chapter_number",
+    "chapter_name"
+  ],
+  "title": "ChapterCreate",
+  "description": "Request body for creating a code chapter."
+}
+
+
CitedSection
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "citation": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Citation"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "version": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Version",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "citation"
+  ],
+  "title": "CitedSection",
+  "description": "One resolved public Code section; never a caller-supplied quotation."
+}
+
+
CityProfileCreate
+{
+  "properties": {
+    "city_name": {
+      "type": "string",
+      "title": "City Name"
+    },
+    "state": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State"
+    },
+    "county": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "County"
+    },
+    "population_band": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Population Band"
+    },
+    "email_platform": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email Platform"
+    },
+    "has_dedicated_it": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Has Dedicated It"
+    },
+    "monthly_request_volume": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Monthly Request Volume"
+    },
+    "profile_data": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Profile Data",
+      "default": {}
+    },
+    "gap_map": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Gap Map",
+      "default": {}
+    }
+  },
+  "type": "object",
+  "required": [
+    "city_name"
+  ],
+  "title": "CityProfileCreate"
+}
+
+
CityProfileRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "city_name": {
+      "type": "string",
+      "title": "City Name"
+    },
+    "state": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State"
+    },
+    "county": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "County"
+    },
+    "population_band": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Population Band"
+    },
+    "email_platform": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email Platform"
+    },
+    "has_dedicated_it": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Has Dedicated It"
+    },
+    "monthly_request_volume": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Monthly Request Volume"
+    },
+    "onboarding_status": {
+      "type": "string",
+      "title": "Onboarding Status"
+    },
+    "profile_data": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Profile Data"
+    },
+    "gap_map": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Gap Map"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "updated_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "city_name",
+    "state",
+    "county",
+    "population_band",
+    "email_platform",
+    "has_dedicated_it",
+    "monthly_request_volume",
+    "onboarding_status",
+    "profile_data",
+    "gap_map",
+    "created_at",
+    "updated_at"
+  ],
+  "title": "CityProfileRead"
+}
+
+
CityProfileUpdate
+{
+  "properties": {
+    "city_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "City Name"
+    },
+    "state": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State"
+    },
+    "county": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "County"
+    },
+    "population_band": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Population Band"
+    },
+    "email_platform": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email Platform"
+    },
+    "has_dedicated_it": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Has Dedicated It"
+    },
+    "monthly_request_volume": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Monthly Request Volume"
+    },
+    "onboarding_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Onboarding Status"
+    },
+    "profile_data": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Profile Data"
+    },
+    "gap_map": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Gap Map"
+    }
+  },
+  "type": "object",
+  "title": "CityProfileUpdate"
+}
+
+
ClarificationCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "request-records-clarification",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ClarificationPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "ClarificationCommand"
+}
+
+
ClarificationPayload
+{
+  "properties": {
+    "clarificationNote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Clarificationnote"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "clarificationNote"
+  ],
+  "title": "ClarificationPayload"
+}
+
+
Closeout
+{
+  "properties": {
+    "decision_id": {
+      "type": "string",
+      "pattern": "^[A-Za-z0-9_-]{1,64}$",
+      "title": "Decision Id"
+    },
+    "version_id": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Version Id"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "version_label": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Version Label"
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 1000000,
+      "minLength": 1,
+      "title": "Body"
+    },
+    "effective_start": {
+      "type": "string",
+      "format": "date",
+      "title": "Effective Start"
+    },
+    "effective_end": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective End"
+    },
+    "is_current": {
+      "type": "boolean",
+      "title": "Is Current"
+    },
+    "reconciliation_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reconciliation Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "decision_id",
+    "version_id",
+    "source_id",
+    "version_label",
+    "body",
+    "effective_start",
+    "is_current"
+  ],
+  "title": "Closeout"
+}
+
+
CodeContext
+{
+  "properties": {
+    "section_number": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Section Number"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "section_number"
+  ],
+  "title": "CodeContext"
+}
+
+
CodeLink
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "const": "code",
+      "title": "Provider",
+      "default": "code"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "CodeLink"
+}
+
+
CodeSearch
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "CodeSearch"
+}
+
+
CodeSourceSelection
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 200,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "CodeSourceSelection"
+}
+
+
CompleteArtifact
+{
+  "properties": {
+    "export_path": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Export Path"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "export_path"
+  ],
+  "title": "CompleteArtifact"
+}
+
+
ConnectionSearch
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "enum": [
+        "meetings",
+        "zoning"
+      ],
+      "title": "Provider"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "query"
+  ],
+  "title": "ConnectionSearch"
+}
+
+
CoverageGapResponse
+{
+  "properties": {
+    "jurisdictions_without_rules": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Jurisdictions Without Rules"
+    },
+    "departments_without_staff": {
+      "items": {
+        "additionalProperties": true,
+        "type": "object"
+      },
+      "type": "array",
+      "title": "Departments Without Staff"
+    },
+    "uncovered_categories": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Uncovered Categories"
+    },
+    "total_gaps": {
+      "type": "integer",
+      "title": "Total Gaps"
+    }
+  },
+  "type": "object",
+  "required": [
+    "jurisdictions_without_rules",
+    "departments_without_staff",
+    "uncovered_categories",
+    "total_gaps"
+  ],
+  "title": "CoverageGapResponse"
+}
+
+
DataSourceAdminRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "source_type": {
+      "$ref": "#/components/schemas/SourceType"
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "type": "boolean",
+      "title": "Schedule Enabled",
+      "default": true
+    },
+    "next_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Next Sync At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "last_ingestion_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Ingestion At"
+    },
+    "last_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync At"
+    },
+    "last_sync_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync Status"
+    },
+    "last_error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Error Message"
+    },
+    "consecutive_failure_count": {
+      "type": "integer",
+      "title": "Consecutive Failure Count",
+      "default": 0
+    },
+    "sync_paused": {
+      "type": "boolean",
+      "title": "Sync Paused",
+      "default": false
+    },
+    "health_status": {
+      "type": "string",
+      "title": "Health Status",
+      "default": "healthy"
+    },
+    "active_failure_count": {
+      "type": "integer",
+      "title": "Active Failure Count",
+      "default": 0
+    },
+    "connector_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connector Type"
+    },
+    "updated_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Updated At"
+    },
+    "connection_config": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Connection Config"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "source_type",
+    "is_active",
+    "created_by",
+    "created_at",
+    "last_ingestion_at",
+    "connection_config"
+  ],
+  "title": "DataSourceAdminRead",
+  "description": "Full datasource shape including connection_config. Returned only by admin-gated endpoints."
+}
+
+
DataSourceCreate
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "source_type": {
+      "$ref": "#/components/schemas/SourceType"
+    },
+    "connection_config": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Connection Config",
+      "default": {}
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "type": "boolean",
+      "title": "Schedule Enabled",
+      "default": true
+    }
+  },
+  "type": "object",
+  "required": [
+    "name",
+    "source_type"
+  ],
+  "title": "DataSourceCreate"
+}
+
+
DataSourceRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "source_type": {
+      "$ref": "#/components/schemas/SourceType"
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "type": "boolean",
+      "title": "Schedule Enabled",
+      "default": true
+    },
+    "next_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Next Sync At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "last_ingestion_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Ingestion At"
+    },
+    "last_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync At"
+    },
+    "last_sync_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync Status"
+    },
+    "last_error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Error Message"
+    },
+    "consecutive_failure_count": {
+      "type": "integer",
+      "title": "Consecutive Failure Count",
+      "default": 0
+    },
+    "sync_paused": {
+      "type": "boolean",
+      "title": "Sync Paused",
+      "default": false
+    },
+    "health_status": {
+      "type": "string",
+      "title": "Health Status",
+      "default": "healthy"
+    },
+    "active_failure_count": {
+      "type": "integer",
+      "title": "Active Failure Count",
+      "default": 0
+    },
+    "connector_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connector Type"
+    },
+    "updated_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "source_type",
+    "is_active",
+    "created_by",
+    "created_at",
+    "last_ingestion_at"
+  ],
+  "title": "DataSourceRead",
+  "description": "Redacted datasource shape — safe for non-admin roles. connection_config omitted."
+}
+
+
DataSourceUpdate
+{
+  "properties": {
+    "name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Name"
+    },
+    "connection_config": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connection Config"
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Schedule Enabled"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "DataSourceUpdate"
+}
+
+
DeadlineCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "set-records-deadline",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/DeadlinePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "DeadlineCommand"
+}
+
+
DeadlinePayload
+{
+  "properties": {
+    "deadline": {
+      "type": "string",
+      "title": "Deadline"
+    },
+    "deadlineBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Deadlinebasis"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "deadline",
+    "deadlineBasis"
+  ],
+  "title": "DeadlinePayload"
+}
+
+
Decision
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "pattern": "^[A-Za-z0-9_-]{1,64}$",
+      "title": "Id"
+    },
+    "outcome": {
+      "type": "string",
+      "enum": [
+        "adopted",
+        "not_adopted",
+        "deferred",
+        "withdrawn"
+      ],
+      "title": "Outcome"
+    },
+    "decided_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Decided At"
+    },
+    "decision_text": {
+      "type": "string",
+      "maxLength": 1000000,
+      "minLength": 1,
+      "title": "Decision Text"
+    },
+    "supporting_references": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Supporting References"
+    },
+    "supersedes_decision_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^[A-Za-z0-9_-]{1,64}$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supersedes Decision Id"
+    },
+    "reconciliation_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reconciliation Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "outcome",
+    "decision_text"
+  ],
+  "title": "Decision"
+}
+
+
DepartmentCreate
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "code": {
+      "type": "string",
+      "title": "Code"
+    },
+    "contact_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Contact Email"
+    }
+  },
+  "type": "object",
+  "required": [
+    "name",
+    "code"
+  ],
+  "title": "DepartmentCreate"
+}
+
+
DepartmentRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "code": {
+      "type": "string",
+      "title": "Code"
+    },
+    "contact_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Contact Email"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "code",
+    "contact_email",
+    "created_at"
+  ],
+  "title": "DepartmentRead"
+}
+
+
DepartmentUpdate
+{
+  "properties": {
+    "name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Name"
+    },
+    "code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Code"
+    },
+    "contact_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Contact Email"
+    }
+  },
+  "type": "object",
+  "title": "DepartmentUpdate"
+}
+
+
DisclosureTemplateCreate
+{
+  "properties": {
+    "template_type": {
+      "type": "string",
+      "title": "Template Type"
+    },
+    "state_code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State Code"
+    },
+    "content": {
+      "type": "string",
+      "title": "Content"
+    }
+  },
+  "type": "object",
+  "required": [
+    "template_type",
+    "content"
+  ],
+  "title": "DisclosureTemplateCreate"
+}
+
+
DisclosureTemplateRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "template_type": {
+      "type": "string",
+      "title": "Template Type"
+    },
+    "state_code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State Code"
+    },
+    "content": {
+      "type": "string",
+      "title": "Content"
+    },
+    "version": {
+      "type": "integer",
+      "title": "Version"
+    },
+    "updated_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Updated By"
+    },
+    "updated_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "template_type",
+    "state_code",
+    "content",
+    "version",
+    "updated_by",
+    "updated_at"
+  ],
+  "title": "DisclosureTemplateRead"
+}
+
+
DisclosureTemplateRendered
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "template_type": {
+      "type": "string",
+      "title": "Template Type"
+    },
+    "rendered_content": {
+      "type": "string",
+      "title": "Rendered Content"
+    },
+    "has_unresolved_variables": {
+      "type": "boolean",
+      "title": "Has Unresolved Variables"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "template_type",
+    "rendered_content",
+    "has_unresolved_variables"
+  ],
+  "title": "DisclosureTemplateRendered"
+}
+
+
DisclosureTemplateUpdate
+{
+  "properties": {
+    "content": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Content"
+    },
+    "state_code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State Code"
+    }
+  },
+  "type": "object",
+  "title": "DisclosureTemplateUpdate"
+}
+
+
DocumentChunkRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "chunk_index": {
+      "type": "integer",
+      "title": "Chunk Index"
+    },
+    "content_text": {
+      "type": "string",
+      "title": "Content Text"
+    },
+    "token_count": {
+      "type": "integer",
+      "title": "Token Count"
+    },
+    "page_number": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Page Number"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "document_id",
+    "chunk_index",
+    "content_text",
+    "token_count",
+    "page_number"
+  ],
+  "title": "DocumentChunkRead"
+}
+
+
DocumentRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "source_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Source Id"
+    },
+    "source_path": {
+      "type": "string",
+      "title": "Source Path"
+    },
+    "filename": {
+      "type": "string",
+      "title": "Filename"
+    },
+    "file_type": {
+      "type": "string",
+      "title": "File Type"
+    },
+    "file_hash": {
+      "type": "string",
+      "title": "File Hash"
+    },
+    "file_size": {
+      "type": "integer",
+      "title": "File Size"
+    },
+    "ingestion_status": {
+      "$ref": "#/components/schemas/IngestionStatus"
+    },
+    "ingestion_error": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ingestion Error"
+    },
+    "chunk_count": {
+      "type": "integer",
+      "title": "Chunk Count"
+    },
+    "ingested_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ingested At"
+    },
+    "connector_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connector Type"
+    },
+    "updated_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "source_id",
+    "source_path",
+    "filename",
+    "file_type",
+    "file_hash",
+    "file_size",
+    "ingestion_status",
+    "ingestion_error",
+    "chunk_count",
+    "ingested_at"
+  ],
+  "title": "DocumentRead"
+}
+
+
DraftCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "draft-records-response",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/DraftPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "DraftCommand"
+}
+
+
DraftInput
+{
+  "properties": {
+    "source_materials": {
+      "items": {
+        "$ref": "#/components/schemas/SourceInput"
+      },
+      "type": "array",
+      "title": "Source Materials"
+    },
+    "sentences": {
+      "items": {
+        "$ref": "#/components/schemas/SentenceInput"
+      },
+      "type": "array",
+      "minItems": 1,
+      "title": "Sentences"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sentences"
+  ],
+  "title": "DraftInput"
+}
+
+
DraftPayload
+{
+  "properties": {
+    "responseDraft": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Responsedraft"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "responseDraft"
+  ],
+  "title": "DraftPayload"
+}
+
+
ErrorModel
+{
+  "properties": {
+    "detail": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "additionalProperties": {
+            "type": "string"
+          },
+          "type": "object"
+        }
+      ],
+      "title": "Detail"
+    }
+  },
+  "type": "object",
+  "required": [
+    "detail"
+  ],
+  "title": "ErrorModel"
+}
+
+
Evidence
+{
+  "properties": {
+    "filename": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$",
+      "title": "Filename"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Description"
+    },
+    "media_type": {
+      "type": "string",
+      "enum": [
+        "text/plain",
+        "image/jpeg",
+        "image/png",
+        "image/webp",
+        "application/pdf",
+        "audio/webm",
+        "audio/ogg",
+        "audio/wav",
+        "audio/mpeg",
+        "audio/mp4"
+      ],
+      "title": "Media Type"
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 14000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "filename",
+    "description",
+    "media_type",
+    "content_base64",
+    "sha256"
+  ],
+  "title": "Evidence"
+}
+
+
EvidenceItem
+{
+  "properties": {
+    "filename": {
+      "type": "string",
+      "maxLength": 151,
+      "minLength": 1,
+      "title": "Filename"
+    },
+    "media_type": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Media Type"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Description",
+      "default": ""
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 14000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "filename",
+    "media_type",
+    "content_base64",
+    "sha256"
+  ],
+  "title": "EvidenceItem"
+}
+
+
EvidenceItems
+{
+  "properties": {
+    "items": {
+      "items": {
+        "$ref": "#/components/schemas/EvidenceItem"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "minItems": 1,
+      "title": "Items"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "items"
+  ],
+  "title": "EvidenceItems"
+}
+
+
ExemptionAccuracyReport
+{
+  "properties": {
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "total_flags": {
+      "type": "integer",
+      "title": "Total Flags"
+    },
+    "accepted": {
+      "type": "integer",
+      "title": "Accepted"
+    },
+    "rejected": {
+      "type": "integer",
+      "title": "Rejected"
+    },
+    "pending": {
+      "type": "integer",
+      "title": "Pending"
+    },
+    "acceptance_rate": {
+      "type": "number",
+      "title": "Acceptance Rate"
+    }
+  },
+  "type": "object",
+  "required": [
+    "category",
+    "total_flags",
+    "accepted",
+    "rejected",
+    "pending",
+    "acceptance_rate"
+  ],
+  "title": "ExemptionAccuracyReport"
+}
+
+
ExemptionDashboard
+{
+  "properties": {
+    "total_flags": {
+      "type": "integer",
+      "title": "Total Flags"
+    },
+    "by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "By Status"
+    },
+    "by_category": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "By Category"
+    },
+    "acceptance_rate": {
+      "type": "number",
+      "title": "Acceptance Rate"
+    },
+    "total_rules": {
+      "type": "integer",
+      "title": "Total Rules"
+    },
+    "active_rules": {
+      "type": "integer",
+      "title": "Active Rules"
+    }
+  },
+  "type": "object",
+  "required": [
+    "total_flags",
+    "by_status",
+    "by_category",
+    "acceptance_rate",
+    "total_rules",
+    "active_rules"
+  ],
+  "title": "ExemptionDashboard"
+}
+
+
ExemptionDecisionCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-exemption-decision",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ExemptionDecisionPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "ExemptionDecisionCommand"
+}
+
+
ExemptionDecisionPayload
+{
+  "properties": {
+    "exemptionSource": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionsource"
+    },
+    "exemptionKind": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionkind"
+    },
+    "exemptionFinding": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionfinding"
+    },
+    "exemptionDecision": {
+      "type": "string",
+      "enum": [
+        "release",
+        "redact",
+        "exempt"
+      ],
+      "title": "Exemptiondecision"
+    },
+    "exemptionBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionbasis"
+    },
+    "exemptionReviewer": {
+      "type": "string",
+      "title": "Exemptionreviewer",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "exemptionSource",
+    "exemptionKind",
+    "exemptionFinding",
+    "exemptionDecision",
+    "exemptionBasis"
+  ],
+  "title": "ExemptionDecisionPayload"
+}
+
+
ExemptionDecisionView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "source": {
+      "type": "string",
+      "title": "Source"
+    },
+    "kind": {
+      "type": "string",
+      "title": "Kind"
+    },
+    "finding": {
+      "type": "string",
+      "title": "Finding"
+    },
+    "decision": {
+      "type": "string",
+      "enum": [
+        "release",
+        "redact",
+        "exempt"
+      ],
+      "title": "Decision"
+    },
+    "basis": {
+      "type": "string",
+      "title": "Basis"
+    },
+    "reviewer": {
+      "type": "string",
+      "title": "Reviewer"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "source",
+    "kind",
+    "finding",
+    "decision",
+    "basis",
+    "reviewer",
+    "created_at_unix_seconds"
+  ],
+  "title": "ExemptionDecisionView"
+}
+
+
ExemptionFlagRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "chunk_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Chunk Id"
+    },
+    "rule_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Rule Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "matched_text": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Matched Text"
+    },
+    "confidence": {
+      "type": "number",
+      "title": "Confidence"
+    },
+    "status": {
+      "$ref": "#/components/schemas/FlagStatus"
+    },
+    "reviewed_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reviewed By"
+    },
+    "reviewed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reviewed At"
+    },
+    "review_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Reason"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "chunk_id",
+    "rule_id",
+    "request_id",
+    "category",
+    "matched_text",
+    "confidence",
+    "status",
+    "reviewed_by",
+    "reviewed_at",
+    "review_reason",
+    "created_at"
+  ],
+  "title": "ExemptionFlagRead"
+}
+
+
ExemptionFlagReview
+{
+  "properties": {
+    "status": {
+      "$ref": "#/components/schemas/FlagStatus"
+    },
+    "review_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Reason"
+    }
+  },
+  "type": "object",
+  "required": [
+    "status"
+  ],
+  "title": "ExemptionFlagReview"
+}
+
+
ExemptionNoteCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-exemption-review",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ExemptionNotePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "ExemptionNoteCommand"
+}
+
+
ExemptionNotePayload
+{
+  "properties": {
+    "exemptionNote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionnote"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "exemptionNote"
+  ],
+  "title": "ExemptionNotePayload"
+}
+
+
ExemptionRuleCreate
+{
+  "properties": {
+    "state_code": {
+      "type": "string",
+      "title": "State Code"
+    },
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "rule_type": {
+      "$ref": "#/components/schemas/RuleType"
+    },
+    "rule_definition": {
+      "type": "string",
+      "title": "Rule Definition"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "enabled": {
+      "type": "boolean",
+      "title": "Enabled",
+      "default": true
+    }
+  },
+  "type": "object",
+  "required": [
+    "state_code",
+    "category",
+    "rule_type",
+    "rule_definition"
+  ],
+  "title": "ExemptionRuleCreate"
+}
+
+
ExemptionRuleRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "state_code": {
+      "type": "string",
+      "title": "State Code"
+    },
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "rule_type": {
+      "$ref": "#/components/schemas/RuleType"
+    },
+    "rule_definition": {
+      "type": "string",
+      "title": "Rule Definition"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "enabled": {
+      "type": "boolean",
+      "title": "Enabled"
+    },
+    "version": {
+      "type": "integer",
+      "title": "Version",
+      "default": 1
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "state_code",
+    "category",
+    "rule_type",
+    "rule_definition",
+    "description",
+    "enabled",
+    "created_by",
+    "created_at"
+  ],
+  "title": "ExemptionRuleRead"
+}
+
+
ExemptionRuleUpdate
+{
+  "properties": {
+    "rule_definition": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Rule Definition"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "enabled": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Enabled"
+    }
+  },
+  "type": "object",
+  "title": "ExemptionRuleUpdate"
+}
+
+
ExportReceipt
+{
+  "properties": {
+    "export_path": {
+      "type": "string",
+      "maxLength": 32768,
+      "minLength": 1,
+      "title": "Export Path"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "export_path"
+  ],
+  "title": "ExportReceipt"
+}
+
+
FeeEstimateCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "estimate-records-fee",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/FeeEstimatePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "FeeEstimateCommand"
+}
+
+
FeeEstimatePayload
+{
+  "properties": {
+    "feeEstimate": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feeestimate"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "feeEstimate"
+  ],
+  "title": "FeeEstimatePayload"
+}
+
+
FeeEstimateRequest
+{
+  "properties": {
+    "page_count": {
+      "type": "integer",
+      "title": "Page Count"
+    },
+    "fee_schedule_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Fee Schedule Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "page_count",
+    "fee_schedule_id"
+  ],
+  "title": "FeeEstimateRequest"
+}
+
+
FeeEstimateResponse
+{
+  "properties": {
+    "page_count": {
+      "type": "integer",
+      "title": "Page Count"
+    },
+    "unit_price": {
+      "type": "number",
+      "title": "Unit Price"
+    },
+    "total": {
+      "type": "number",
+      "title": "Total"
+    },
+    "fee_type": {
+      "type": "string",
+      "title": "Fee Type"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    }
+  },
+  "type": "object",
+  "required": [
+    "page_count",
+    "unit_price",
+    "total",
+    "fee_type",
+    "description"
+  ],
+  "title": "FeeEstimateResponse"
+}
+
+
FeeLineCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-fee-line",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/FeeLinePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "FeeLineCommand"
+}
+
+
FeeLineItemCreate
+{
+  "properties": {
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "quantity": {
+      "type": "integer",
+      "title": "Quantity",
+      "default": 1
+    },
+    "unit_price": {
+      "type": "number",
+      "title": "Unit Price"
+    },
+    "fee_schedule_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Schedule Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "description",
+    "unit_price"
+  ],
+  "title": "FeeLineItemCreate"
+}
+
+
FeeLineItemRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "fee_schedule_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Schedule Id"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "quantity": {
+      "type": "integer",
+      "title": "Quantity"
+    },
+    "unit_price": {
+      "type": "number",
+      "title": "Unit Price"
+    },
+    "total": {
+      "type": "number",
+      "title": "Total"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "fee_schedule_id",
+    "description",
+    "quantity",
+    "unit_price",
+    "total",
+    "status",
+    "created_at"
+  ],
+  "title": "FeeLineItemRead"
+}
+
+
FeeLinePayload
+{
+  "properties": {
+    "feeLineDescription": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feelinedescription"
+    },
+    "feeScheduleBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feeschedulebasis"
+    },
+    "feeLineAmount": {
+      "type": "string",
+      "title": "Feelineamount"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "feeLineDescription",
+    "feeScheduleBasis",
+    "feeLineAmount"
+  ],
+  "title": "FeeLinePayload"
+}
+
+
FeeLineView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "schedule_basis": {
+      "type": "string",
+      "title": "Schedule Basis"
+    },
+    "amount_cents": {
+      "type": "integer",
+      "title": "Amount Cents"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "description",
+    "schedule_basis",
+    "amount_cents",
+    "created_at_unix_seconds"
+  ],
+  "title": "FeeLineView"
+}
+
+
FeeScheduleCreate
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "title": "Jurisdiction"
+    },
+    "fee_type": {
+      "type": "string",
+      "title": "Fee Type"
+    },
+    "amount": {
+      "type": "number",
+      "title": "Amount"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "effective_date": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective Date"
+    }
+  },
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "fee_type",
+    "amount"
+  ],
+  "title": "FeeScheduleCreate"
+}
+
+
FeeScheduleRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "jurisdiction": {
+      "type": "string",
+      "title": "Jurisdiction"
+    },
+    "fee_type": {
+      "type": "string",
+      "title": "Fee Type"
+    },
+    "amount": {
+      "type": "number",
+      "title": "Amount"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "effective_date": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective Date"
+    },
+    "created_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "jurisdiction",
+    "fee_type",
+    "amount",
+    "description",
+    "effective_date",
+    "created_by",
+    "created_at"
+  ],
+  "title": "FeeScheduleRead"
+}
+
+
FeeScheduleUpdate
+{
+  "properties": {
+    "fee_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Type"
+    },
+    "amount": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Amount"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "effective_date": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective Date"
+    }
+  },
+  "type": "object",
+  "title": "FeeScheduleUpdate"
+}
+
+
FeeWaiverCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "waive-records-fee",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/FeeWaiverPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "FeeWaiverCommand"
+}
+
+
FeeWaiverCreateRequest
+{
+  "properties": {
+    "waiver_type": {
+      "type": "string",
+      "title": "Waiver Type"
+    },
+    "reason": {
+      "type": "string",
+      "title": "Reason"
+    }
+  },
+  "type": "object",
+  "required": [
+    "waiver_type",
+    "reason"
+  ],
+  "title": "FeeWaiverCreateRequest"
+}
+
+
FeeWaiverPayload
+{
+  "properties": {
+    "feeWaiverReason": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feewaiverreason"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "feeWaiverReason"
+  ],
+  "title": "FeeWaiverPayload"
+}
+
+
FeeWaiverReadResponse
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "waiver_type": {
+      "type": "string",
+      "title": "Waiver Type"
+    },
+    "reason": {
+      "type": "string",
+      "title": "Reason"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    },
+    "created_at": {
+      "type": "string",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "waiver_type",
+    "reason",
+    "status",
+    "created_at"
+  ],
+  "title": "FeeWaiverReadResponse"
+}
+
+
FeeWaiverReviewRequest
+{
+  "properties": {
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    }
+  },
+  "type": "object",
+  "required": [
+    "status"
+  ],
+  "title": "FeeWaiverReviewRequest"
+}
+
+
FinishCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "fulfill-records-request",
+        "close-records-request"
+      ],
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/NativePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "FinishCommand"
+}
+
+
FlagStatus
+{
+  "type": "string",
+  "enum": [
+    "flagged",
+    "reviewed",
+    "accepted",
+    "rejected"
+  ],
+  "title": "FlagStatus"
+}
+
+
FormPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "form-plan",
+      "title": "Action"
+    },
+    "formName": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Formname",
+      "default": ""
+    },
+    "fields": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 50,
+      "title": "Fields"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "FormPlan"
+}
+
+
GeneratedDraft
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "model": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Model"
+    },
+    "previous_response_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Previous Response Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text",
+    "model",
+    "previous_response_sha256"
+  ],
+  "title": "GeneratedDraft"
+}
+
+
HTTPValidationError
+{
+  "properties": {
+    "detail": {
+      "items": {
+        "$ref": "#/components/schemas/ValidationError"
+      },
+      "type": "array",
+      "title": "Detail"
+    }
+  },
+  "type": "object",
+  "title": "HTTPValidationError"
+}
+
+
Handoff
+{
+  "properties": {
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "request_id"
+  ],
+  "title": "Handoff"
+}
+
+
ImportBundleCreate
+{
+  "properties": {
+    "job_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Job Id"
+    },
+    "connector_type": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Connector Type"
+    },
+    "source": {
+      "$ref": "#/components/schemas/SourceCreate"
+    },
+    "sources": {
+      "items": {
+        "$ref": "#/components/schemas/SourceCreate"
+      },
+      "type": "array",
+      "title": "Sources"
+    },
+    "titles": {
+      "items": {
+        "$ref": "#/components/schemas/TitleCreate"
+      },
+      "type": "array",
+      "title": "Titles"
+    },
+    "chapters": {
+      "items": {
+        "$ref": "#/components/schemas/ChapterCreate"
+      },
+      "type": "array",
+      "title": "Chapters"
+    },
+    "sections": {
+      "items": {
+        "$ref": "#/components/schemas/SectionCreate"
+      },
+      "type": "array",
+      "title": "Sections"
+    },
+    "versions": {
+      "items": {
+        "$ref": "#/components/schemas/SectionVersionCreate"
+      },
+      "type": "array",
+      "title": "Versions"
+    },
+    "provenance": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Provenance"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "connector_type",
+    "source"
+  ],
+  "title": "ImportBundleCreate",
+  "description": "Request body for local fixture/file-drop import jobs."
+}
+
+
InclusionStatus
+{
+  "type": "string",
+  "enum": [
+    "included",
+    "excluded",
+    "pending"
+  ],
+  "title": "InclusionStatus"
+}
+
+
IngestionStats
+{
+  "properties": {
+    "total_sources": {
+      "type": "integer",
+      "title": "Total Sources"
+    },
+    "active_sources": {
+      "type": "integer",
+      "title": "Active Sources"
+    },
+    "total_documents": {
+      "type": "integer",
+      "title": "Total Documents"
+    },
+    "documents_by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "Documents By Status"
+    },
+    "total_chunks": {
+      "type": "integer",
+      "title": "Total Chunks"
+    }
+  },
+  "type": "object",
+  "required": [
+    "total_sources",
+    "active_sources",
+    "total_documents",
+    "documents_by_status",
+    "total_chunks"
+  ],
+  "title": "IngestionStats"
+}
+
+
IngestionStatus
+{
+  "type": "string",
+  "enum": [
+    "pending",
+    "processing",
+    "completed",
+    "failed"
+  ],
+  "title": "IngestionStatus"
+}
+
+
InitiativeInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "policy": {
+      "$ref": "#/components/schemas/PolicySelection"
+    },
+    "responsible_staff": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Responsible Staff"
+    },
+    "target": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "string"
+        }
+      ],
+      "title": "Target"
+    },
+    "unit": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Unit"
+    },
+    "due_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Due On"
+    },
+    "status": {
+      "type": "string",
+      "enum": [
+        "planned",
+        "active",
+        "completed",
+        "cancelled"
+      ],
+      "title": "Status",
+      "default": "planned"
+    },
+    "milestones": {
+      "items": {
+        "$ref": "#/components/schemas/Milestone"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "title": "Milestones"
+    },
+    "measurements": {
+      "items": {
+        "$ref": "#/components/schemas/Measurement"
+      },
+      "type": "array",
+      "maxItems": 1000,
+      "title": "Measurements"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "policy",
+    "responsible_staff",
+    "target",
+    "unit",
+    "due_on",
+    "note"
+  ],
+  "title": "InitiativeInput"
+}
+
+
InspectionInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "property_reference": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Property Reference"
+    },
+    "inspection_reference": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Inspection Reference"
+    },
+    "dataset_kind": {
+      "type": "string",
+      "enum": [
+        "municipal",
+        "fictional"
+      ],
+      "title": "Dataset Kind"
+    },
+    "inspector_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "minLength": 1,
+      "title": "Inspector Notes"
+    },
+    "photo_observations": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Photo Observations"
+    },
+    "voice_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Voice Notes",
+      "default": ""
+    },
+    "evidence": {
+      "items": {
+        "$ref": "#/components/schemas/Evidence"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "title": "Evidence"
+    },
+    "linked_sources": {
+      "items": {
+        "$ref": "#/components/schemas/townlight_inspections__workflow_models__SourceLink"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Linked Sources"
+    },
+    "assigned_to": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Assigned To",
+      "default": ""
+    },
+    "staff_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Staff Notes",
+      "default": ""
+    },
+    "notice_draft": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Notice Draft",
+      "default": ""
+    },
+    "review_state": {
+      "type": "string",
+      "enum": [
+        "draft",
+        "follow_up",
+        "reviewed"
+      ],
+      "title": "Review State",
+      "default": "draft"
+    },
+    "review_notes": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Review Notes",
+      "default": ""
+    },
+    "public_summary": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Public Summary",
+      "default": ""
+    },
+    "analysis": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/AnalysisRecord"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "property_reference",
+    "inspection_reference",
+    "dataset_kind",
+    "inspector_notes"
+  ],
+  "title": "InspectionInput"
+}
+
+
IntakeInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "project_name": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Project Name"
+    },
+    "project_description": {
+      "type": "string",
+      "maxLength": 10000,
+      "minLength": 1,
+      "title": "Project Description"
+    },
+    "location": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Location"
+    },
+    "applicant_contact": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Applicant Contact",
+      "default": ""
+    },
+    "requirement_revision": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Requirement Revision"
+    },
+    "materials": {
+      "items": {
+        "$ref": "#/components/schemas/MaterialReview"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "minItems": 1,
+      "title": "Materials"
+    },
+    "linked_sources": {
+      "items": {
+        "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Linked Sources"
+    },
+    "staff_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Staff Notes",
+      "default": ""
+    },
+    "assigned_to": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Assigned To",
+      "default": ""
+    },
+    "review_state": {
+      "type": "string",
+      "enum": [
+        "draft",
+        "follow_up",
+        "reviewed"
+      ],
+      "title": "Review State",
+      "default": "draft"
+    },
+    "review_notes": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Review Notes",
+      "default": ""
+    },
+    "public_summary": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Public Summary",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "project_name",
+    "project_description",
+    "location",
+    "requirement_revision",
+    "materials"
+  ],
+  "title": "IntakeInput"
+}
+
+
InterpretationNoteCreate
+{
+  "properties": {
+    "note_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Note Id"
+    },
+    "note_text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Note Text"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "note_text"
+  ],
+  "title": "InterpretationNoteCreate",
+  "description": "Request body for staff-only interpretation notes."
+}
+
+
InterviewRequest
+{
+  "properties": {
+    "last_answer": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Answer"
+    },
+    "last_field": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Field"
+    },
+    "skipped_fields": {
+      "anyOf": [
+        {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Skipped Fields"
+    }
+  },
+  "type": "object",
+  "title": "InterviewRequest"
+}
+
+
InterviewResponse
+{
+  "properties": {
+    "question": {
+      "type": "string",
+      "title": "Question"
+    },
+    "target_field": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Target Field"
+    },
+    "all_complete": {
+      "type": "boolean",
+      "title": "All Complete"
+    },
+    "completed_fields": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Completed Fields"
+    },
+    "onboarding_status": {
+      "type": "string",
+      "title": "Onboarding Status"
+    },
+    "skipped_fields": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Skipped Fields"
+    }
+  },
+  "type": "object",
+  "required": [
+    "question",
+    "target_field",
+    "all_complete",
+    "completed_fields",
+    "onboarding_status",
+    "skipped_fields"
+  ],
+  "title": "InterviewResponse"
+}
+
+
ManagedFileReceipt
+{
+  "properties": {
+    "original_path": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Original Path"
+    },
+    "stored_path": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Stored Path"
+    },
+    "file_name": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "File Name"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Sha256"
+    },
+    "size_bytes": {
+      "type": "integer",
+      "maximum": 2147483647.0,
+      "minimum": 0.0,
+      "title": "Size Bytes"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "original_path",
+    "stored_path",
+    "file_name",
+    "sha256",
+    "size_bytes"
+  ],
+  "title": "ManagedFileReceipt"
+}
+
+
ManagedSource
+{
+  "properties": {
+    "original_path": {
+      "type": "string",
+      "title": "Original Path"
+    },
+    "stored_path": {
+      "type": "string",
+      "title": "Stored Path"
+    },
+    "file_name": {
+      "type": "string",
+      "title": "File Name"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Sha256"
+    },
+    "size_bytes": {
+      "type": "integer",
+      "minimum": 0.0,
+      "title": "Size Bytes"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "original_path",
+    "stored_path",
+    "file_name",
+    "sha256",
+    "size_bytes"
+  ],
+  "title": "ManagedSource"
+}
+
+
Material
+{
+  "properties": {
+    "material_id": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9_-]{1,80}$",
+      "title": "Material Id"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Description"
+    },
+    "citation": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Citation"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "material_id",
+    "description",
+    "citation"
+  ],
+  "title": "Material"
+}
+
+
MaterialReview
+{
+  "properties": {
+    "material_id": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Material Id"
+    },
+    "status": {
+      "type": "string",
+      "enum": [
+        "not_reviewed",
+        "provided",
+        "missing",
+        "unclear"
+      ],
+      "title": "Status",
+      "default": "not_reviewed"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Note",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "material_id"
+  ],
+  "title": "MaterialReview"
+}
+
+
Measurement
+{
+  "properties": {
+    "recorded_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Recorded On"
+    },
+    "value": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "string"
+        }
+      ],
+      "title": "Value"
+    },
+    "evidence": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Evidence"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "recorded_on",
+    "value",
+    "evidence"
+  ],
+  "title": "Measurement"
+}
+
+
MediaAnalysis
+{
+  "properties": {
+    "items": {
+      "items": {
+        "$ref": "#/components/schemas/EvidenceItem"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "minItems": 1,
+      "title": "Items"
+    },
+    "code_links": {
+      "items": {
+        "$ref": "#/components/schemas/CodeLink"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Code Links"
+    },
+    "inspector_supplied_text": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Inspector Supplied Text",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "items"
+  ],
+  "title": "MediaAnalysis"
+}
+
+
MeetingInput
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "scheduled_start": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Scheduled Start"
+    },
+    "location": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Location"
+    },
+    "meeting_type": {
+      "type": "string",
+      "enum": [
+        "regular",
+        "special",
+        "emergency",
+        "closed_session",
+        "executive"
+      ],
+      "title": "Meeting Type",
+      "default": "regular"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "scheduled_start",
+    "location"
+  ],
+  "title": "MeetingInput"
+}
+
+
MeetingLink
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 200,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    },
+    "relation": {
+      "type": "string",
+      "enum": [
+        "hearing",
+        "context",
+        "precedent"
+      ],
+      "title": "Relation"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256",
+    "relation"
+  ],
+  "title": "MeetingLink"
+}
+
+
MeetingSearch
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "MeetingSearch"
+}
+
+
MeetingStageInput
+{
+  "properties": {
+    "to_status": {
+      "type": "string",
+      "enum": [
+        "SCHEDULED",
+        "NOTICED",
+        "PACKET_POSTED",
+        "IN_PROGRESS",
+        "RECESSED",
+        "ADJOURNED",
+        "TRANSCRIPT_READY",
+        "MINUTES_DRAFTED",
+        "MINUTES_POSTED",
+        "MINUTES_ADOPTED",
+        "MINUTES_SIGNED",
+        "ARCHIVED",
+        "CANCELLED"
+      ],
+      "title": "To Status"
+    },
+    "statutory_basis": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Basis"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "to_status"
+  ],
+  "title": "MeetingStageInput"
+}
+
+
MeetingsSearch
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "MeetingsSearch"
+}
+
+
MeetingsSourceSelection
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 200,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "MeetingsSourceSelection"
+}
+
+
MessageCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-message",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/MessagePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "MessageCommand"
+}
+
+
MessageCreate
+{
+  "properties": {
+    "message_text": {
+      "type": "string",
+      "title": "Message Text"
+    },
+    "is_internal": {
+      "type": "boolean",
+      "title": "Is Internal",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "message_text"
+  ],
+  "title": "MessageCreate"
+}
+
+
MessagePayload
+{
+  "properties": {
+    "requestMessageBody": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestmessagebody"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requestMessageBody"
+  ],
+  "title": "MessagePayload"
+}
+
+
MessageRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "sender_type": {
+      "type": "string",
+      "title": "Sender Type"
+    },
+    "sender_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sender Id"
+    },
+    "message_text": {
+      "type": "string",
+      "title": "Message Text"
+    },
+    "is_internal": {
+      "type": "boolean",
+      "title": "Is Internal"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "sender_type",
+    "sender_id",
+    "message_text",
+    "is_internal",
+    "created_at"
+  ],
+  "title": "MessageRead"
+}
+
+
MessageView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "author": {
+      "type": "string",
+      "title": "Author"
+    },
+    "author_role": {
+      "type": "string",
+      "title": "Author Role"
+    },
+    "body": {
+      "type": "string",
+      "title": "Body"
+    },
+    "visibility": {
+      "type": "string",
+      "title": "Visibility"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "author",
+    "author_role",
+    "body",
+    "visibility",
+    "created_at_unix_seconds"
+  ],
+  "title": "MessageView"
+}
+
+
Milestone
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "due_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Due On"
+    },
+    "completed_on": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Completed On"
+    },
+    "evidence": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Evidence",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "due_on"
+  ],
+  "title": "Milestone"
+}
+
+
MinutesDecision
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "post",
+        "adopt",
+        "sign"
+      ],
+      "title": "Action"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "MinutesDecision"
+}
+
+
ModelRegistryCreate
+{
+  "properties": {
+    "model_name": {
+      "type": "string",
+      "title": "Model Name"
+    },
+    "model_version": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Version"
+    },
+    "parameter_count": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parameter Count"
+    },
+    "license": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "License"
+    },
+    "model_card_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Card Url"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active",
+      "default": false
+    },
+    "context_window_size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Context Window Size"
+    },
+    "supports_ner": {
+      "type": "boolean",
+      "title": "Supports Ner",
+      "default": false
+    },
+    "supports_vision": {
+      "type": "boolean",
+      "title": "Supports Vision",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "model_name"
+  ],
+  "title": "ModelRegistryCreate",
+  "description": "Schema for creating a new model_registry record (POST body)."
+}
+
+
ModelRegistryRead
+{
+  "properties": {
+    "id": {
+      "type": "integer",
+      "title": "Id"
+    },
+    "model_name": {
+      "type": "string",
+      "title": "Model Name"
+    },
+    "model_version": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Version"
+    },
+    "parameter_count": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parameter Count"
+    },
+    "license": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "License"
+    },
+    "model_card_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Card Url"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "added_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Added At"
+    },
+    "context_window_size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Context Window Size"
+    },
+    "supports_ner": {
+      "type": "boolean",
+      "title": "Supports Ner"
+    },
+    "supports_vision": {
+      "type": "boolean",
+      "title": "Supports Vision"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "model_name",
+    "is_active",
+    "supports_ner",
+    "supports_vision"
+  ],
+  "title": "ModelRegistryRead",
+  "description": "Schema for returning a model_registry record (GET response).\n\n``from_attributes=True`` allows construction directly from an ORM instance."
+}
+
+
ModelRegistryUpdate
+{
+  "properties": {
+    "model_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Name"
+    },
+    "model_version": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Version"
+    },
+    "parameter_count": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parameter Count"
+    },
+    "license": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "License"
+    },
+    "model_card_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Card Url"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    },
+    "context_window_size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Context Window Size"
+    },
+    "supports_ner": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supports Ner"
+    },
+    "supports_vision": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supports Vision"
+    }
+  },
+  "type": "object",
+  "title": "ModelRegistryUpdate",
+  "description": "Schema for partially updating a model_registry record (PATCH body).\n\nEvery field is optional so callers can send only the fields they want to\nchange."
+}
+
+
MotionCorrection
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "reason": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Reason"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text",
+    "reason"
+  ],
+  "title": "MotionCorrection"
+}
+
+
MotionInput
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "seconded_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "minLength": 1
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Seconded By"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text"
+  ],
+  "title": "MotionInput"
+}
+
+
NativePayload
+{
+  "properties": {},
+  "additionalProperties": false,
+  "type": "object",
+  "title": "NativePayload"
+}
+
+
NativeRequestRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "requester_name": {
+      "type": "string",
+      "title": "Requester Name"
+    },
+    "requester_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Email"
+    },
+    "requester_phone": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Phone"
+    },
+    "requester_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Type"
+    },
+    "date_received": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Date Received"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "status": {
+      "$ref": "#/components/schemas/RequestStatus"
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "created_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "response_draft": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Response Draft"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    },
+    "estimated_fee": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Estimated Fee"
+    },
+    "fee_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Status"
+    },
+    "fee_waiver_requested": {
+      "type": "boolean",
+      "title": "Fee Waiver Requested",
+      "default": false
+    },
+    "priority": {
+      "type": "string",
+      "title": "Priority",
+      "default": "normal"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    },
+    "closed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closed At"
+    },
+    "closure_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closure Reason"
+    },
+    "desktop_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Desktop Id"
+    },
+    "public_tracking_number": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Public Tracking Number"
+    },
+    "submitted_via": {
+      "type": "string",
+      "title": "Submitted Via"
+    },
+    "deadline_label": {
+      "type": "string",
+      "title": "Deadline Label"
+    },
+    "deadline_basis": {
+      "type": "string",
+      "title": "Deadline Basis"
+    },
+    "deadline_reviewed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Deadline Reviewed At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "requester_name",
+    "requester_email",
+    "date_received",
+    "statutory_deadline",
+    "description",
+    "status",
+    "assigned_to",
+    "created_by",
+    "created_at",
+    "response_draft",
+    "review_notes",
+    "desktop_id",
+    "public_tracking_number",
+    "submitted_via",
+    "deadline_label",
+    "deadline_basis",
+    "deadline_reviewed_at"
+  ],
+  "title": "NativeRequestRead"
+}
+
+
NoticeDocumentInput
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text"
+  ],
+  "title": "NoticeDocumentInput"
+}
+
+
NoticeDraft
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 100000,
+      "minLength": 1,
+      "title": "Body"
+    },
+    "notice_type": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Notice Type"
+    },
+    "statutory_basis": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Statutory Basis"
+    },
+    "event_date": {
+      "type": "string",
+      "format": "date",
+      "title": "Event Date"
+    },
+    "lead_days": {
+      "type": "integer",
+      "maximum": 365.0,
+      "minimum": 0.0,
+      "title": "Lead Days"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "body",
+    "notice_type",
+    "statutory_basis",
+    "event_date",
+    "lead_days"
+  ],
+  "title": "NoticeDraft"
+}
+
+
NoticeInput
+{
+  "properties": {
+    "notice_type": {
+      "type": "string",
+      "enum": [
+        "regular",
+        "special",
+        "emergency",
+        "closed_session",
+        "executive"
+      ],
+      "title": "Notice Type"
+    },
+    "posted_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Posted At"
+    },
+    "minimum_notice_hours": {
+      "type": "integer",
+      "minimum": 0.0,
+      "title": "Minimum Notice Hours"
+    },
+    "statutory_basis": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Basis"
+    },
+    "approved_by": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Approved By"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "notice_type",
+    "posted_at",
+    "minimum_notice_hours"
+  ],
+  "title": "NoticeInput"
+}
+
+
NoticeProofInput
+{
+  "properties": {
+    "location": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Location"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note",
+      "default": ""
+    },
+    "document_delivery_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Document Delivery Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "location"
+  ],
+  "title": "NoticeProofInput"
+}
+
+
NotificationLogRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "template_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Template Id"
+    },
+    "recipient_email": {
+      "type": "string",
+      "title": "Recipient Email"
+    },
+    "request_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Request Id"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "sent_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sent At"
+    },
+    "error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Message"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "template_id",
+    "recipient_email",
+    "request_id",
+    "channel",
+    "status",
+    "sent_at",
+    "error_message",
+    "created_at"
+  ],
+  "title": "NotificationLogRead"
+}
+
+
NotificationTemplateCreate
+{
+  "properties": {
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel",
+      "default": "email"
+    },
+    "subject_template": {
+      "type": "string",
+      "title": "Subject Template"
+    },
+    "body_template": {
+      "type": "string",
+      "title": "Body Template"
+    }
+  },
+  "type": "object",
+  "required": [
+    "event_type",
+    "subject_template",
+    "body_template"
+  ],
+  "title": "NotificationTemplateCreate"
+}
+
+
NotificationTemplateRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel"
+    },
+    "subject_template": {
+      "type": "string",
+      "title": "Subject Template"
+    },
+    "body_template": {
+      "type": "string",
+      "title": "Body Template"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "event_type",
+    "channel",
+    "subject_template",
+    "body_template",
+    "is_active",
+    "created_at"
+  ],
+  "title": "NotificationTemplateRead"
+}
+
+
NotificationTemplateUpdate
+{
+  "properties": {
+    "subject_template": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Subject Template"
+    },
+    "body_template": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Body Template"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "NotificationTemplateUpdate"
+}
+
+
NotificationView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "notification_id": {
+      "type": "string",
+      "title": "Notification Id"
+    },
+    "module_id": {
+      "type": "string",
+      "title": "Module Id"
+    },
+    "record_id": {
+      "type": "string",
+      "title": "Record Id"
+    },
+    "audience": {
+      "type": "string",
+      "title": "Audience"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel"
+    },
+    "subject": {
+      "type": "string",
+      "title": "Subject"
+    },
+    "body": {
+      "type": "string",
+      "title": "Body"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    },
+    "sent_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sent At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "notification_id",
+    "module_id",
+    "record_id",
+    "audience",
+    "channel",
+    "subject",
+    "body",
+    "status",
+    "created_at_unix_seconds",
+    "sent_at_unix_seconds"
+  ],
+  "title": "NotificationView"
+}
+
+
OllamaModelInfo
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Size"
+    },
+    "details": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Details"
+    }
+  },
+  "type": "object",
+  "required": [
+    "name"
+  ],
+  "title": "OllamaModelInfo"
+}
+
+
OllamaStatus
+{
+  "properties": {
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "models": {
+      "items": {
+        "$ref": "#/components/schemas/OllamaModelInfo"
+      },
+      "type": "array",
+      "title": "Models"
+    }
+  },
+  "type": "object",
+  "required": [
+    "status",
+    "models"
+  ],
+  "title": "OllamaStatus"
+}
+
+
OperationalMetrics
+{
+  "properties": {
+    "average_response_time_days": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Average Response Time Days"
+    },
+    "median_response_time_days": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Median Response Time Days"
+    },
+    "requests_by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "Requests By Status"
+    },
+    "requests_by_department": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "Requests By Department"
+    },
+    "deadline_compliance_rate": {
+      "type": "number",
+      "title": "Deadline Compliance Rate"
+    },
+    "total_open": {
+      "type": "integer",
+      "title": "Total Open"
+    },
+    "total_closed": {
+      "type": "integer",
+      "title": "Total Closed"
+    },
+    "total_overdue": {
+      "type": "integer",
+      "title": "Total Overdue"
+    },
+    "clarification_frequency": {
+      "type": "number",
+      "title": "Clarification Frequency"
+    },
+    "top_request_topics": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Top Request Topics"
+    }
+  },
+  "type": "object",
+  "required": [
+    "average_response_time_days",
+    "median_response_time_days",
+    "requests_by_status",
+    "requests_by_department",
+    "deadline_compliance_rate",
+    "total_open",
+    "total_closed",
+    "total_overdue",
+    "clarification_frequency",
+    "top_request_topics"
+  ],
+  "title": "OperationalMetrics"
+}
+
+
Outline
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "question_ids": {
+      "items": {
+        "type": "string",
+        "format": "uuid"
+      },
+      "type": "array",
+      "maxItems": 50,
+      "minItems": 1,
+      "title": "Question Ids"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "question_ids"
+  ],
+  "title": "Outline"
+}
+
+
Packet
+{
+  "properties": {
+    "expected_revision": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Expected Revision"
+    },
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "staff_only",
+        "records_copy"
+      ],
+      "title": "Visibility"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "expected_revision",
+    "visibility"
+  ],
+  "title": "Packet"
+}
+
+
PacketInput
+{
+  "properties": {
+    "agenda_item_ids": {
+      "items": {
+        "type": "string",
+        "format": "uuid"
+      },
+      "type": "array",
+      "title": "Agenda Item Ids"
+    },
+    "source_files": {
+      "items": {
+        "$ref": "#/components/schemas/ManagedSource"
+      },
+      "type": "array",
+      "title": "Source Files"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "agenda_item_ids"
+  ],
+  "title": "PacketInput"
+}
+
+
Pathway
+{
+  "properties": {
+    "project_type": {
+      "type": "string",
+      "maxLength": 120,
+      "minLength": 1,
+      "title": "Project Type"
+    },
+    "proposal": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Proposal",
+      "default": ""
+    },
+    "location_context": {
+      "type": "string",
+      "maxLength": 1000,
+      "title": "Location Context",
+      "default": ""
+    },
+    "requirement_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requirement Revision"
+    },
+    "fee_link": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "project_type"
+  ],
+  "title": "Pathway"
+}
+
+
PathwayStep
+{
+  "properties": {
+    "step": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Step"
+    },
+    "citation": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Citation"
+    },
+    "typical_time": {
+      "type": "string",
+      "maxLength": 1000,
+      "title": "Typical Time",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "step",
+    "citation"
+  ],
+  "title": "PathwayStep"
+}
+
+
PlainLanguageSummaryCreate
+{
+  "properties": {
+    "summary_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Summary Id"
+    },
+    "section_version_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Version Id"
+    },
+    "summary_text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Summary Text"
+    },
+    "language_code": {
+      "type": "string",
+      "title": "Language Code",
+      "default": "en"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "section_version_id",
+    "summary_text"
+  ],
+  "title": "PlainLanguageSummaryCreate",
+  "description": "Request body for staff-drafted plain-language summaries."
+}
+
+
PolicySelection
+{
+  "properties": {
+    "plan_id": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Plan Id"
+    },
+    "revision_id": {
+      "type": "string",
+      "maxLength": 36,
+      "minLength": 36,
+      "title": "Revision Id"
+    },
+    "policy_id": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Policy Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "plan_id",
+    "revision_id",
+    "policy_id"
+  ],
+  "title": "PolicySelection"
+}
+
+
PortalModeResponse
+{
+  "properties": {
+    "mode": {
+      "type": "string",
+      "enum": [
+        "public",
+        "private"
+      ],
+      "title": "Mode",
+      "description": "Active portal posture for this deployment. ``public`` = minimal resident surface (landing + authenticated records-request submission + resident registration) reachable without staff auth. ``private`` = staff-only; no public routes, no resident self-registration."
+    }
+  },
+  "type": "object",
+  "required": [
+    "mode"
+  ],
+  "title": "PortalModeResponse",
+  "description": "T5D — schema for ``GET /config/portal-mode``.\n\nExposed to the frontend on boot so it can branch routing without a\nuser-identity lookup. The payload is intentionally the single field\nbelow — no staff config, no user state, no schema version."
+}
+
+
PrepareArtifact
+{
+  "properties": {
+    "kind": {
+      "type": "string",
+      "enum": [
+        "response",
+        "release-package"
+      ],
+      "title": "Kind"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "kind"
+  ],
+  "title": "PrepareArtifact"
+}
+
+
Proof
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    },
+    "filename": {
+      "type": "string",
+      "maxLength": 150,
+      "minLength": 1,
+      "title": "Filename"
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 7000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "location": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Location"
+    },
+    "published_at": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Published At"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence",
+    "filename",
+    "content_base64",
+    "location",
+    "published_at"
+  ],
+  "title": "Proof"
+}
+
+
Proposal
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "pattern": "^[A-Za-z0-9_-]{1,64}$",
+      "title": "Id"
+    },
+    "version_id": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Version Id"
+    },
+    "meeting_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Meeting Id"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "ordinance_number": {
+      "type": "string",
+      "maxLength": 120,
+      "minLength": 1,
+      "title": "Ordinance Number"
+    },
+    "proposed_text": {
+      "type": "string",
+      "maxLength": 1000000,
+      "minLength": 1,
+      "title": "Proposed Text"
+    },
+    "supersedes_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^[A-Za-z0-9_-]{1,64}$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supersedes Id"
+    },
+    "reconciliation_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reconciliation Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "version_id",
+    "meeting_id",
+    "title",
+    "ordinance_number",
+    "proposed_text"
+  ],
+  "title": "Proposal"
+}
+
+
PublicExplore
+{
+  "properties": {
+    "goal": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Goal",
+      "default": ""
+    },
+    "topic": {
+      "type": "string",
+      "maxLength": 160,
+      "title": "Topic",
+      "default": ""
+    },
+    "neighborhood": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Neighborhood",
+      "default": ""
+    },
+    "plan_type": {
+      "type": "string",
+      "maxLength": 120,
+      "title": "Plan Type",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "PublicExplore"
+}
+
+
PublicIntake
+{
+  "properties": {
+    "requester": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requester"
+    },
+    "requesterContact": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestercontact"
+    },
+    "summary": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Summary"
+    },
+    "deadline": {
+      "type": "string",
+      "title": "Deadline",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requester",
+    "requesterContact",
+    "summary"
+  ],
+  "title": "PublicIntake"
+}
+
+
PublicLookup
+{
+  "properties": {
+    "trackingNumber": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Trackingnumber"
+    },
+    "requesterContact": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestercontact"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "trackingNumber",
+    "requesterContact"
+  ],
+  "title": "PublicLookup"
+}
+
+
PublicMessage
+{
+  "properties": {
+    "trackingNumber": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Trackingnumber"
+    },
+    "requesterContact": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestercontact"
+    },
+    "publicRequestMessage": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Publicrequestmessage"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "trackingNumber",
+    "requesterContact",
+    "publicRequestMessage"
+  ],
+  "title": "PublicMessage"
+}
+
+
PublicStatusView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "label": {
+      "type": "string",
+      "title": "Label"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "label",
+    "summary",
+    "status",
+    "created_at_unix_seconds"
+  ],
+  "title": "PublicStatusView"
+}
+
+
PublicationView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "source_module": {
+      "type": "string",
+      "title": "Source Module"
+    },
+    "source_record_id": {
+      "type": "string",
+      "title": "Source Record Id"
+    },
+    "record_type": {
+      "type": "string",
+      "title": "Record Type"
+    },
+    "public_payload": {
+      "type": "string",
+      "title": "Public Payload"
+    },
+    "payload_hash": {
+      "type": "string",
+      "title": "Payload Hash"
+    },
+    "published_at_unix_seconds": {
+      "type": "integer",
+      "title": "Published At Unix Seconds"
+    },
+    "retracted_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Retracted At Unix Seconds"
+    },
+    "retracted_by": {
+      "type": "string",
+      "title": "Retracted By",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "source_module",
+    "source_record_id",
+    "record_type",
+    "public_payload",
+    "payload_hash",
+    "published_at_unix_seconds"
+  ],
+  "title": "PublicationView"
+}
+
+
PublishingPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "publishing-workflow",
+      "title": "Action"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "hasReview": {
+      "type": "boolean",
+      "title": "Hasreview",
+      "default": false
+    },
+    "hasPlainLanguage": {
+      "type": "boolean",
+      "title": "Hasplainlanguage",
+      "default": false
+    },
+    "hasTranslationReview": {
+      "type": "boolean",
+      "title": "Hastranslationreview",
+      "default": false
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "PublishingPlan"
+}
+
+
Question
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    },
+    "question": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Question"
+    },
+    "kind": {
+      "type": "string",
+      "enum": [
+        "use",
+        "dimension"
+      ],
+      "title": "Kind"
+    },
+    "key": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Key"
+    },
+    "audience": {
+      "type": "string",
+      "enum": [
+        "resident",
+        "staff"
+      ],
+      "title": "Audience",
+      "default": "resident"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "query",
+    "question",
+    "kind",
+    "key"
+  ],
+  "title": "Question"
+}
+
+
QuestionAnswerRequest
+{
+  "properties": {
+    "question": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Question"
+    },
+    "section_number": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Section Number"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "question"
+  ],
+  "title": "QuestionAnswerRequest",
+  "description": "Request body for citation-grounded code Q&A."
+}
+
+
RecordsDocumentView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "attachment_id": {
+      "type": "string",
+      "title": "Attachment Id"
+    },
+    "title": {
+      "type": "string",
+      "title": "Title"
+    },
+    "original_path": {
+      "type": "string",
+      "title": "Original Path"
+    },
+    "stored_path": {
+      "type": "string",
+      "title": "Stored Path"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation"
+    },
+    "sha256": {
+      "type": "string",
+      "title": "Sha256"
+    },
+    "size_bytes": {
+      "type": "integer",
+      "title": "Size Bytes"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "added_by": {
+      "type": "string",
+      "title": "Added By"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    },
+    "release_original_path": {
+      "type": "string",
+      "title": "Release Original Path",
+      "default": ""
+    },
+    "release_stored_path": {
+      "type": "string",
+      "title": "Release Stored Path",
+      "default": ""
+    },
+    "release_file_name": {
+      "type": "string",
+      "title": "Release File Name",
+      "default": ""
+    },
+    "release_sha256": {
+      "type": "string",
+      "title": "Release Sha256",
+      "default": ""
+    },
+    "release_size_bytes": {
+      "type": "integer",
+      "title": "Release Size Bytes",
+      "default": 0
+    },
+    "release_status": {
+      "type": "string",
+      "title": "Release Status",
+      "default": ""
+    },
+    "release_note": {
+      "type": "string",
+      "title": "Release Note",
+      "default": ""
+    },
+    "release_added_by": {
+      "type": "string",
+      "title": "Release Added By",
+      "default": ""
+    },
+    "release_added_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Release Added At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "attachment_id",
+    "title",
+    "original_path",
+    "stored_path",
+    "citation",
+    "sha256",
+    "size_bytes",
+    "status",
+    "added_by",
+    "created_at_unix_seconds"
+  ],
+  "title": "RecordsDocumentView"
+}
+
+
RecordsOperationRead
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "message": {
+      "type": "string",
+      "title": "Message"
+    },
+    "request": {
+      "$ref": "#/components/schemas/RecordsView"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "message",
+    "request"
+  ],
+  "title": "RecordsOperationRead"
+}
+
+
RecordsStateRead
+{
+  "properties": {
+    "demo_fixture": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Demo Fixture"
+    },
+    "records_requests": {
+      "items": {
+        "$ref": "#/components/schemas/RecordsView"
+      },
+      "type": "array",
+      "title": "Records Requests"
+    },
+    "notification_events": {
+      "items": {
+        "$ref": "#/components/schemas/NotificationView"
+      },
+      "type": "array",
+      "title": "Notification Events"
+    },
+    "publication_events": {
+      "items": {
+        "$ref": "#/components/schemas/PublicationView"
+      },
+      "type": "array",
+      "title": "Publication Events"
+    },
+    "audit_entries": {
+      "items": {
+        "$ref": "#/components/schemas/AuditView"
+      },
+      "type": "array",
+      "title": "Audit Entries"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "records_requests"
+  ],
+  "title": "RecordsStateRead"
+}
+
+
RecordsView
+{
+  "properties": {
+    "request_id": {
+      "type": "string",
+      "title": "Request Id"
+    },
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "public_tracking_number": {
+      "type": "string",
+      "title": "Public Tracking Number"
+    },
+    "requester": {
+      "type": "string",
+      "title": "Requester"
+    },
+    "requester_contact": {
+      "type": "string",
+      "title": "Requester Contact"
+    },
+    "submitted_via": {
+      "type": "string",
+      "title": "Submitted Via"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "deadline": {
+      "type": "string",
+      "title": "Deadline"
+    },
+    "deadline_basis": {
+      "type": "string",
+      "title": "Deadline Basis"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "assigned_to": {
+      "type": "string",
+      "title": "Assigned To"
+    },
+    "clarification_notes": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Clarification Notes"
+    },
+    "search_notes": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Search Notes"
+    },
+    "search_sessions": {
+      "items": {
+        "$ref": "#/components/schemas/SearchReceiptView"
+      },
+      "type": "array",
+      "title": "Search Sessions"
+    },
+    "exemption_reviews": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Exemption Reviews"
+    },
+    "exemption_decisions": {
+      "items": {
+        "$ref": "#/components/schemas/ExemptionDecisionView"
+      },
+      "type": "array",
+      "title": "Exemption Decisions"
+    },
+    "fee_estimate": {
+      "type": "string",
+      "title": "Fee Estimate"
+    },
+    "fee_line_items": {
+      "items": {
+        "$ref": "#/components/schemas/FeeLineView"
+      },
+      "type": "array",
+      "title": "Fee Line Items"
+    },
+    "fee_waiver_reason": {
+      "type": "string",
+      "title": "Fee Waiver Reason"
+    },
+    "citations": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Citations"
+    },
+    "response_draft": {
+      "type": "string",
+      "title": "Response Draft"
+    },
+    "approval_notes": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Approval Notes"
+    },
+    "exports": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Exports"
+    },
+    "documents": {
+      "items": {
+        "$ref": "#/components/schemas/RecordsDocumentView"
+      },
+      "type": "array",
+      "title": "Documents"
+    },
+    "release_packages": {
+      "items": {
+        "$ref": "#/components/schemas/ReleasePackageView"
+      },
+      "type": "array",
+      "title": "Release Packages"
+    },
+    "timeline": {
+      "items": {
+        "$ref": "#/components/schemas/TimelineView"
+      },
+      "type": "array",
+      "title": "Timeline"
+    },
+    "public_status_events": {
+      "items": {
+        "$ref": "#/components/schemas/PublicStatusView"
+      },
+      "type": "array",
+      "title": "Public Status Events"
+    },
+    "messages": {
+      "items": {
+        "$ref": "#/components/schemas/MessageView"
+      },
+      "type": "array",
+      "title": "Messages"
+    },
+    "deadline_reviewed_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Deadline Reviewed At Unix Seconds"
+    },
+    "approved_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Approved At Unix Seconds"
+    },
+    "fulfilled_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fulfilled At Unix Seconds"
+    },
+    "closed_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closed At Unix Seconds"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "request_id",
+    "id",
+    "public_tracking_number",
+    "requester",
+    "requester_contact",
+    "submitted_via",
+    "summary",
+    "deadline",
+    "deadline_basis",
+    "status",
+    "assigned_to",
+    "clarification_notes",
+    "search_notes",
+    "search_sessions",
+    "exemption_reviews",
+    "exemption_decisions",
+    "fee_estimate",
+    "fee_line_items",
+    "fee_waiver_reason",
+    "citations",
+    "response_draft",
+    "approval_notes",
+    "exports",
+    "timeline",
+    "public_status_events",
+    "messages",
+    "deadline_reviewed_at_unix_seconds",
+    "approved_at_unix_seconds",
+    "fulfilled_at_unix_seconds",
+    "closed_at_unix_seconds",
+    "created_at_unix_seconds"
+  ],
+  "title": "RecordsView"
+}
+
+
ReleasePackageView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "export_path": {
+      "type": "string",
+      "title": "Export Path"
+    },
+    "package_hash": {
+      "type": "string",
+      "title": "Package Hash"
+    },
+    "document_count": {
+      "type": "integer",
+      "title": "Document Count"
+    },
+    "release_artifact_count": {
+      "type": "integer",
+      "title": "Release Artifact Count"
+    },
+    "search_session_count": {
+      "type": "integer",
+      "title": "Search Session Count"
+    },
+    "release_count": {
+      "type": "integer",
+      "title": "Release Count"
+    },
+    "redacted_count": {
+      "type": "integer",
+      "title": "Redacted Count"
+    },
+    "exempt_count": {
+      "type": "integer",
+      "title": "Exempt Count"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "export_path",
+    "package_hash",
+    "document_count",
+    "release_artifact_count",
+    "search_session_count",
+    "release_count",
+    "redacted_count",
+    "exempt_count",
+    "created_at_unix_seconds"
+  ],
+  "title": "ReleasePackageView"
+}
+
+
RepeatLookup
+{
+  "properties": {
+    "property_reference": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Property Reference"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "property_reference"
+  ],
+  "title": "RepeatLookup"
+}
+
+
RequestCreate
+{
+  "properties": {
+    "requester_name": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Requester Name"
+    },
+    "requester_email": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 255
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Email"
+    },
+    "requester_phone": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 50
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Phone"
+    },
+    "requester_type": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 100
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Type"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Description"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "priority": {
+      "type": "string",
+      "title": "Priority",
+      "default": "normal"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^(narrow|moderate|broad)$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "requester_name",
+    "description"
+  ],
+  "title": "RequestCreate"
+}
+
+
RequestDocumentAdd
+{
+  "properties": {
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "relevance_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Relevance Note"
+    }
+  },
+  "type": "object",
+  "required": [
+    "document_id"
+  ],
+  "title": "RequestDocumentAdd"
+}
+
+
RequestDocumentRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "relevance_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Relevance Note"
+    },
+    "exemption_flags": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Exemption Flags"
+    },
+    "inclusion_status": {
+      "$ref": "#/components/schemas/InclusionStatus"
+    },
+    "attached_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Attached At"
+    },
+    "attached_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Attached By"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "document_id",
+    "relevance_note",
+    "exemption_flags",
+    "inclusion_status",
+    "attached_at",
+    "attached_by"
+  ],
+  "title": "RequestDocumentRead"
+}
+
+
RequestRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "requester_name": {
+      "type": "string",
+      "title": "Requester Name"
+    },
+    "requester_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Email"
+    },
+    "requester_phone": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Phone"
+    },
+    "requester_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Type"
+    },
+    "date_received": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Date Received"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "status": {
+      "$ref": "#/components/schemas/RequestStatus"
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "created_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "response_draft": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Response Draft"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    },
+    "estimated_fee": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Estimated Fee"
+    },
+    "fee_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Status"
+    },
+    "fee_waiver_requested": {
+      "type": "boolean",
+      "title": "Fee Waiver Requested",
+      "default": false
+    },
+    "priority": {
+      "type": "string",
+      "title": "Priority",
+      "default": "normal"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    },
+    "closed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closed At"
+    },
+    "closure_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closure Reason"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "requester_name",
+    "requester_email",
+    "date_received",
+    "statutory_deadline",
+    "description",
+    "status",
+    "assigned_to",
+    "created_by",
+    "created_at",
+    "response_draft",
+    "review_notes"
+  ],
+  "title": "RequestRead"
+}
+
+
RequestStats
+{
+  "properties": {
+    "total_requests": {
+      "type": "integer",
+      "title": "Total Requests"
+    },
+    "by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "By Status"
+    },
+    "approaching_deadline": {
+      "type": "integer",
+      "title": "Approaching Deadline"
+    },
+    "overdue": {
+      "type": "integer",
+      "title": "Overdue"
+    }
+  },
+  "type": "object",
+  "required": [
+    "total_requests",
+    "by_status",
+    "approaching_deadline",
+    "overdue"
+  ],
+  "title": "RequestStats"
+}
+
+
RequestStatus
+{
+  "type": "string",
+  "enum": [
+    "received",
+    "clarification_needed",
+    "assigned",
+    "searching",
+    "in_review",
+    "ready_for_release",
+    "drafted",
+    "approved",
+    "fulfilled",
+    "closed"
+  ],
+  "title": "RequestStatus"
+}
+
+
RequestUpdate
+{
+  "properties": {
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/RequestStatus"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "response_draft": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Response Draft"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    }
+  },
+  "type": "object",
+  "title": "RequestUpdate"
+}
+
+
RequirementBundle
+{
+  "properties": {
+    "requirement_id": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9_-]{1,100}$",
+      "title": "Requirement Id"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "project_type": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Project Type"
+    },
+    "source_reference": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Source Reference"
+    },
+    "source_date": {
+      "type": "string",
+      "format": "date",
+      "title": "Source Date"
+    },
+    "effective_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Effective On"
+    },
+    "dataset_kind": {
+      "type": "string",
+      "enum": [
+        "municipal",
+        "fictional"
+      ],
+      "title": "Dataset Kind"
+    },
+    "filename": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$",
+      "title": "Filename"
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 14000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Sha256"
+    },
+    "materials": {
+      "items": {
+        "$ref": "#/components/schemas/Material"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "minItems": 1,
+      "title": "Materials"
+    },
+    "pathway": {
+      "items": {
+        "$ref": "#/components/schemas/PathwayStep"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "title": "Pathway"
+    },
+    "fee_link": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    },
+    "staff_note": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Staff Note",
+      "default": ""
+    },
+    "change_note": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Change Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requirement_id",
+    "title",
+    "jurisdiction",
+    "project_type",
+    "source_reference",
+    "source_date",
+    "effective_on",
+    "dataset_kind",
+    "filename",
+    "content_base64",
+    "sha256",
+    "materials",
+    "change_note"
+  ],
+  "title": "RequirementBundle"
+}
+
+
ResponseLetterCreate
+{
+  "properties": {
+    "template_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Template Id"
+    }
+  },
+  "type": "object",
+  "title": "ResponseLetterCreate"
+}
+
+
ResponseLetterRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "template_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Template Id"
+    },
+    "generated_content": {
+      "type": "string",
+      "title": "Generated Content"
+    },
+    "edited_content": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Edited Content"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "generated_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Generated By"
+    },
+    "approved_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Approved By"
+    },
+    "sent_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sent At"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "template_id",
+    "generated_content",
+    "edited_content",
+    "status",
+    "generated_by",
+    "approved_by",
+    "sent_at",
+    "created_at"
+  ],
+  "title": "ResponseLetterRead"
+}
+
+
ResponseLetterUpdate
+{
+  "properties": {
+    "edited_content": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Edited Content"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Status"
+    }
+  },
+  "type": "object",
+  "title": "ResponseLetterUpdate"
+}
+
+
ReviewInput
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 5000,
+      "title": "Body",
+      "default": ""
+    },
+    "hasAltText": {
+      "type": "boolean",
+      "title": "Hasalttext",
+      "default": false
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": "en"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "ReviewInput"
+}
+
+
Revision
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    },
+    "document": {
+      "$ref": "#/components/schemas/NoticeDraft"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence",
+    "document"
+  ],
+  "title": "Revision"
+}
+
+
RewriteInput
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "plain-language",
+        "language-variant"
+      ],
+      "title": "Action"
+    },
+    "text": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Text"
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "text"
+  ],
+  "title": "RewriteInput"
+}
+
+
RewriteResult
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "plain-language",
+        "language-variant"
+      ],
+      "title": "Action"
+    },
+    "text": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Text"
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": ""
+    },
+    "outcome": {
+      "type": "string",
+      "enum": [
+        "generated",
+        "unavailable"
+      ],
+      "title": "Outcome"
+    },
+    "generated": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 100000
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Generated"
+    },
+    "model": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 200
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "text",
+    "outcome"
+  ],
+  "title": "RewriteResult"
+}
+
+
Rule
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "zone_code": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Zone Code"
+    },
+    "key": {
+      "type": "string",
+      "maxLength": 120,
+      "minLength": 1,
+      "title": "Key"
+    },
+    "section_number": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Section Number"
+    },
+    "kind": {
+      "type": "string",
+      "enum": [
+        "use",
+        "dimension"
+      ],
+      "title": "Kind"
+    },
+    "value": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Value"
+    },
+    "overlay_code": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 255
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Overlay Code"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "zone_code",
+    "key",
+    "section_number",
+    "kind",
+    "value"
+  ],
+  "title": "Rule"
+}
+
+
RuleTestMatch
+{
+  "properties": {
+    "matched_text": {
+      "type": "string",
+      "title": "Matched Text"
+    },
+    "start": {
+      "type": "integer",
+      "title": "Start"
+    },
+    "end": {
+      "type": "integer",
+      "title": "End"
+    }
+  },
+  "type": "object",
+  "required": [
+    "matched_text",
+    "start",
+    "end"
+  ],
+  "title": "RuleTestMatch"
+}
+
+
RuleTestRequest
+{
+  "properties": {
+    "sample_text": {
+      "type": "string",
+      "title": "Sample Text"
+    }
+  },
+  "type": "object",
+  "required": [
+    "sample_text"
+  ],
+  "title": "RuleTestRequest"
+}
+
+
RuleTestResponse
+{
+  "properties": {
+    "rule_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Rule Id"
+    },
+    "rule_type": {
+      "type": "string",
+      "title": "Rule Type"
+    },
+    "matched": {
+      "type": "boolean",
+      "title": "Matched"
+    },
+    "matches": {
+      "items": {
+        "$ref": "#/components/schemas/RuleTestMatch"
+      },
+      "type": "array",
+      "title": "Matches"
+    }
+  },
+  "type": "object",
+  "required": [
+    "rule_id",
+    "rule_type",
+    "matched",
+    "matches"
+  ],
+  "title": "RuleTestResponse"
+}
+
+
RuleType
+{
+  "type": "string",
+  "enum": [
+    "regex",
+    "keyword",
+    "llm_prompt"
+  ],
+  "title": "RuleType"
+}
+
+
SaveReview
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 5000,
+      "title": "Body",
+      "default": ""
+    },
+    "hasAltText": {
+      "type": "boolean",
+      "title": "Hasalttext",
+      "default": false
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": "en"
+    },
+    "ai_analysis": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 100000
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ai Analysis"
+    },
+    "ai_analysis_model": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 200
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ai Analysis Model"
+    },
+    "ai_outcome": {
+      "type": "string",
+      "enum": [
+        "generated",
+        "unavailable",
+        "failed"
+      ],
+      "title": "Ai Outcome"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "ai_outcome"
+  ],
+  "title": "SaveReview"
+}
+
+
SearchFilterOptions
+{
+  "properties": {
+    "file_types": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "File Types"
+    },
+    "source_names": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Source Names"
+    },
+    "departments": {
+      "items": {
+        "additionalProperties": true,
+        "type": "object"
+      },
+      "type": "array",
+      "title": "Departments",
+      "default": []
+    },
+    "date_range": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Date Range"
+    }
+  },
+  "type": "object",
+  "required": [
+    "file_types",
+    "source_names"
+  ],
+  "title": "SearchFilterOptions"
+}
+
+
SearchInput
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "SearchInput"
+}
+
+
SearchNoteCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "record-records-search",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/SearchNotePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "SearchNoteCommand"
+}
+
+
SearchNotePayload
+{
+  "properties": {
+    "sourceNote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Sourcenote"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sourceNote"
+  ],
+  "title": "SearchNotePayload"
+}
+
+
SearchReceiptCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "record-records-search-session",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/SearchReceiptPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "SearchReceiptCommand"
+}
+
+
SearchReceiptPayload
+{
+  "properties": {
+    "searchQuery": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchquery"
+    },
+    "searchLocations": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchlocations"
+    },
+    "searchResultTitle": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchresulttitle"
+    },
+    "searchResultCitation": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchresultcitation"
+    },
+    "searchResultSummary": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchresultsummary"
+    },
+    "searchResultStatus": {
+      "type": "string",
+      "title": "Searchresultstatus",
+      "default": ""
+    },
+    "searchReviewer": {
+      "type": "string",
+      "title": "Searchreviewer",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "searchQuery",
+    "searchLocations",
+    "searchResultTitle",
+    "searchResultCitation",
+    "searchResultSummary"
+  ],
+  "title": "SearchReceiptPayload"
+}
+
+
SearchReceiptView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "query": {
+      "type": "string",
+      "title": "Query"
+    },
+    "locations": {
+      "type": "string",
+      "title": "Locations"
+    },
+    "reviewer": {
+      "type": "string",
+      "title": "Reviewer"
+    },
+    "results": {
+      "items": {
+        "$ref": "#/components/schemas/SearchResultView"
+      },
+      "type": "array",
+      "title": "Results"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "query",
+    "locations",
+    "reviewer",
+    "results",
+    "created_at_unix_seconds"
+  ],
+  "title": "SearchReceiptView"
+}
+
+
SearchRequest
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "title": "Query"
+    },
+    "session_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Session Id"
+    },
+    "filters": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Filters"
+    },
+    "limit": {
+      "type": "integer",
+      "maximum": 50.0,
+      "title": "Limit",
+      "default": 10
+    },
+    "synthesize": {
+      "type": "boolean",
+      "title": "Synthesize",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "SearchRequest"
+}
+
+
SearchResponse
+{
+  "properties": {
+    "query_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Query Id"
+    },
+    "session_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Session Id"
+    },
+    "query_text": {
+      "type": "string",
+      "title": "Query Text"
+    },
+    "results": {
+      "items": {
+        "$ref": "#/components/schemas/SearchResultItem"
+      },
+      "type": "array",
+      "title": "Results"
+    },
+    "results_count": {
+      "type": "integer",
+      "title": "Results Count"
+    },
+    "synthesized_answer": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Synthesized Answer"
+    },
+    "ai_generated": {
+      "type": "boolean",
+      "title": "Ai Generated",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "query_id",
+    "session_id",
+    "query_text",
+    "results",
+    "results_count"
+  ],
+  "title": "SearchResponse"
+}
+
+
SearchResultItem
+{
+  "properties": {
+    "chunk_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Chunk Id"
+    },
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "filename": {
+      "type": "string",
+      "title": "Filename"
+    },
+    "file_type": {
+      "type": "string",
+      "title": "File Type"
+    },
+    "source_path": {
+      "type": "string",
+      "title": "Source Path"
+    },
+    "page_number": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Page Number"
+    },
+    "content_text": {
+      "type": "string",
+      "title": "Content Text"
+    },
+    "similarity_score": {
+      "type": "number",
+      "title": "Similarity Score"
+    },
+    "rank": {
+      "type": "integer",
+      "title": "Rank"
+    }
+  },
+  "type": "object",
+  "required": [
+    "chunk_id",
+    "document_id",
+    "filename",
+    "file_type",
+    "source_path",
+    "page_number",
+    "content_text",
+    "similarity_score",
+    "rank"
+  ],
+  "title": "SearchResultItem"
+}
+
+
SearchResultView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "title": {
+      "type": "string",
+      "title": "Title"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "title",
+    "citation",
+    "summary",
+    "status"
+  ],
+  "title": "SearchResultView"
+}
+
+
SearchSessionRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "user_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "User Id"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "queries": {
+      "items": {
+        "additionalProperties": true,
+        "type": "object"
+      },
+      "type": "array",
+      "title": "Queries",
+      "default": []
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "user_id",
+    "created_at"
+  ],
+  "title": "SearchSessionRead"
+}
+
+
SectionCreate
+{
+  "properties": {
+    "section_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Section Id"
+    },
+    "chapter_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Chapter Id"
+    },
+    "section_number": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Number"
+    },
+    "section_heading": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Heading"
+    },
+    "parent_section_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parent Section Id"
+    },
+    "sort_order": {
+      "type": "integer",
+      "title": "Sort Order",
+      "default": 0
+    },
+    "administrative_regulation_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Administrative Regulation Refs"
+    },
+    "resolution_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Resolution Refs"
+    },
+    "policy_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Policy Refs"
+    },
+    "approved_summary_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Approved Summary Refs"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "chapter_id",
+    "section_number",
+    "section_heading"
+  ],
+  "title": "SectionCreate",
+  "description": "Request body for creating a code section or subsection."
+}
+
+
SectionVersionCreate
+{
+  "properties": {
+    "version_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Version Id"
+    },
+    "section_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Id"
+    },
+    "source_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "version_label": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Version Label"
+    },
+    "body": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Body"
+    },
+    "effective_start": {
+      "type": "string",
+      "format": "date",
+      "title": "Effective Start"
+    },
+    "effective_end": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective End"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    },
+    "is_current": {
+      "type": "boolean",
+      "title": "Is Current",
+      "default": false
+    },
+    "adoption_event_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Adoption Event Id"
+    },
+    "amendment_event_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Amendment Event Id"
+    },
+    "amendment_summary": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Amendment Summary"
+    },
+    "prior_version_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Prior Version Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "section_id",
+    "source_id",
+    "version_label",
+    "body",
+    "effective_start"
+  ],
+  "title": "SectionVersionCreate",
+  "description": "Request body for adding an immutable section version."
+}
+
+
Selection
+{
+  "properties": {
+    "recording_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Recording Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "recording_id",
+    "expected_sha256"
+  ],
+  "title": "Selection"
+}
+
+
SentenceInput
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "citations": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Citations"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text"
+  ],
+  "title": "SentenceInput"
+}
+
+
ServiceAccountCreate
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole",
+      "default": "read_only"
+    }
+  },
+  "type": "object",
+  "required": [
+    "name"
+  ],
+  "title": "ServiceAccountCreate"
+}
+
+
ServiceAccountCreated
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "api_key": {
+      "type": "string",
+      "title": "Api Key"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "role",
+    "created_by",
+    "created_at",
+    "is_active",
+    "api_key"
+  ],
+  "title": "ServiceAccountCreated",
+  "description": "Returned only on creation — includes the plaintext API key (shown once)."
+}
+
+
ServiceAccountRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "role",
+    "created_by",
+    "created_at",
+    "is_active"
+  ],
+  "title": "ServiceAccountRead"
+}
+
+
ServiceAccountUpdate
+{
+  "properties": {
+    "role": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/UserRole"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "ServiceAccountUpdate"
+}
+
+
Snapshot
+{
+  "properties": {
+    "expected_revision": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Expected Revision"
+    },
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "staff_only",
+        "public"
+      ],
+      "title": "Visibility"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "expected_revision",
+    "visibility"
+  ],
+  "title": "Snapshot"
+}
+
+
SourceCreate
+{
+  "properties": {
+    "source_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Id"
+    },
+    "name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Name"
+    },
+    "publisher": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Publisher"
+    },
+    "source_type": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Type"
+    },
+    "source_category": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Category"
+    },
+    "source_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Url"
+    },
+    "file_reference": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "File Reference"
+    },
+    "retrieved_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Retrieved At"
+    },
+    "retrieval_method": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Retrieval Method"
+    },
+    "checksum": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Checksum"
+    },
+    "source_owner": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Owner"
+    },
+    "is_official": {
+      "type": "boolean",
+      "title": "Is Official",
+      "default": true
+    },
+    "official_status_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Official Status Note"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    },
+    "staff_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Staff Notes"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "name",
+    "publisher",
+    "source_type",
+    "source_category"
+  ],
+  "title": "SourceCreate",
+  "description": "Request body for registering an official or explicitly labeled source."
+}
+
+
SourceInput
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "label": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Label"
+    },
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "label",
+    "text"
+  ],
+  "title": "SourceInput"
+}
+
+
SourceSnapshot
+{
+  "properties": {
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "public",
+        "staff_only"
+      ],
+      "title": "Visibility"
+    },
+    "meeting_event_ids": {
+      "items": {
+        "type": "string",
+        "format": "uuid"
+      },
+      "type": "array",
+      "maxItems": 50,
+      "title": "Meeting Event Ids"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "visibility"
+  ],
+  "title": "SourceSnapshot"
+}
+
+
SourceType
+{
+  "type": "string",
+  "enum": [
+    "manual_drop",
+    "file_system",
+    "rest_api",
+    "odbc"
+  ],
+  "title": "SourceType"
+}
+
+
StaffRecordsIntake
+{
+  "properties": {
+    "requester": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requester"
+    },
+    "summary": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Summary"
+    },
+    "deadline": {
+      "type": "string",
+      "title": "Deadline"
+    },
+    "deadlineBasis": {
+      "type": "string",
+      "title": "Deadlinebasis",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requester",
+    "summary",
+    "deadline"
+  ],
+  "title": "StaffRecordsIntake",
+  "description": "Existing native create-records-request input; no caller-supplied actor."
+}
+
+
StandardsExplanation
+{
+  "properties": {
+    "question": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Question"
+    },
+    "process_section": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Process Section",
+      "default": ""
+    },
+    "zone_code": {
+      "type": "string",
+      "maxLength": 40,
+      "title": "Zone Code",
+      "default": ""
+    },
+    "rule_types": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "title": "Rule Types"
+    },
+    "observed": {
+      "additionalProperties": {
+        "type": "string"
+      },
+      "type": "object",
+      "title": "Observed"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "question"
+  ],
+  "title": "StandardsExplanation"
+}
+
+
SyncFailureRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "source_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Source Id"
+    },
+    "source_path": {
+      "type": "string",
+      "title": "Source Path"
+    },
+    "error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Message"
+    },
+    "error_class": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Class"
+    },
+    "http_status_code": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Http Status Code"
+    },
+    "retry_count": {
+      "type": "integer",
+      "title": "Retry Count"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "first_failed_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "First Failed At"
+    },
+    "last_retried_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Retried At"
+    },
+    "dismissed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Dismissed At"
+    },
+    "dismissed_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Dismissed By"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "source_id",
+    "source_path",
+    "error_message",
+    "error_class",
+    "http_status_code",
+    "retry_count",
+    "status",
+    "first_failed_at",
+    "last_retried_at",
+    "dismissed_at",
+    "dismissed_by"
+  ],
+  "title": "SyncFailureRead"
+}
+
+
SyncRunLogRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "source_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Source Id"
+    },
+    "started_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Started At"
+    },
+    "finished_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Finished At"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Status"
+    },
+    "records_attempted": {
+      "type": "integer",
+      "title": "Records Attempted"
+    },
+    "records_succeeded": {
+      "type": "integer",
+      "title": "Records Succeeded"
+    },
+    "records_failed": {
+      "type": "integer",
+      "title": "Records Failed"
+    },
+    "error_summary": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Summary"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "source_id",
+    "started_at",
+    "finished_at",
+    "status",
+    "records_attempted",
+    "records_succeeded",
+    "records_failed",
+    "error_summary"
+  ],
+  "title": "SyncRunLogRead"
+}
+
+
SystemStatus
+{
+  "properties": {
+    "version": {
+      "type": "string",
+      "title": "Version"
+    },
+    "database": {
+      "type": "string",
+      "title": "Database"
+    },
+    "ollama": {
+      "type": "string",
+      "title": "Ollama"
+    },
+    "redis": {
+      "type": "string",
+      "title": "Redis"
+    },
+    "user_count": {
+      "type": "integer",
+      "title": "User Count"
+    },
+    "audit_log_count": {
+      "type": "integer",
+      "title": "Audit Log Count"
+    },
+    "suite_session": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Suite Session"
+    }
+  },
+  "type": "object",
+  "required": [
+    "version",
+    "database",
+    "ollama",
+    "redis",
+    "user_count",
+    "audit_log_count"
+  ],
+  "title": "SystemStatus"
+}
+
+
TaggedPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "tagged-pdf",
+      "title": "Action"
+    },
+    "headingLevels": {
+      "items": {
+        "type": "integer",
+        "maximum": 4294967295.0,
+        "minimum": 0.0
+      },
+      "type": "array",
+      "maxItems": 50,
+      "title": "Headinglevels"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "TaggedPlan"
+}
+
+
TestConnectionRequest
+{
+  "properties": {
+    "source_type": {
+      "type": "string",
+      "title": "Source Type"
+    },
+    "host": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Host"
+    },
+    "port": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Port"
+    },
+    "path": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Path"
+    },
+    "username": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Username"
+    },
+    "password": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Password"
+    },
+    "rest_api_config": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Rest Api Config"
+    },
+    "odbc_config": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Odbc Config"
+    }
+  },
+  "type": "object",
+  "required": [
+    "source_type"
+  ],
+  "title": "TestConnectionRequest",
+  "description": "Dedicated schema for test-connection. NOT the create schema.\n\nSecurity: credentials in this request body are never persisted, never\nwritten to audit logs, and never returned in the response."
+}
+
+
TestConnectionResponse
+{
+  "properties": {
+    "success": {
+      "type": "boolean",
+      "title": "Success"
+    },
+    "message": {
+      "type": "string",
+      "title": "Message"
+    },
+    "latency_ms": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Latency Ms"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Status"
+    },
+    "warning": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Warning"
+    },
+    "differing_keys": {
+      "anyOf": [
+        {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Differing Keys"
+    }
+  },
+  "type": "object",
+  "required": [
+    "success",
+    "message"
+  ],
+  "title": "TestConnectionResponse"
+}
+
+
TimelineEventCreate
+{
+  "properties": {
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "internal_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Internal Note"
+    }
+  },
+  "type": "object",
+  "required": [
+    "event_type",
+    "description"
+  ],
+  "title": "TimelineEventCreate"
+}
+
+
TimelineEventRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "actor_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Actor Id"
+    },
+    "actor_role": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Actor Role"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "internal_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Internal Note"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "event_type",
+    "actor_id",
+    "actor_role",
+    "description",
+    "internal_note",
+    "created_at"
+  ],
+  "title": "TimelineEventRead"
+}
+
+
TimelineView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "actor": {
+      "type": "string",
+      "title": "Actor"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "action",
+    "actor",
+    "note",
+    "created_at_unix_seconds"
+  ],
+  "title": "TimelineView"
+}
+
+
TitleCreate
+{
+  "properties": {
+    "title_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Title Id"
+    },
+    "title_number": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title Number"
+    },
+    "title_name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title Name"
+    },
+    "sort_order": {
+      "type": "integer",
+      "title": "Sort Order",
+      "default": 0
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title_number",
+    "title_name"
+  ],
+  "title": "TitleCreate",
+  "description": "Request body for creating a code title."
+}
+
+
TranscriptInput
+{
+  "properties": {
+    "source_label": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Label"
+    },
+    "transcript_text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Transcript Text"
+    },
+    "correction_of_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Correction Of Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_label",
+    "transcript_text"
+  ],
+  "title": "TranscriptInput"
+}
+
+
UserRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "email": {
+      "type": "string",
+      "format": "email",
+      "title": "Email"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active",
+      "default": true
+    },
+    "is_superuser": {
+      "type": "boolean",
+      "title": "Is Superuser",
+      "default": false
+    },
+    "is_verified": {
+      "type": "boolean",
+      "title": "Is Verified",
+      "default": false
+    },
+    "full_name": {
+      "type": "string",
+      "title": "Full Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "last_login": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Login"
+    },
+    "must_change_password": {
+      "type": "boolean",
+      "title": "Must Change Password",
+      "default": false
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "email",
+    "full_name",
+    "role",
+    "created_at",
+    "last_login"
+  ],
+  "title": "UserRead"
+}
+
+
UserRole
+{
+  "type": "string",
+  "enum": [
+    "admin",
+    "staff",
+    "reviewer",
+    "read_only",
+    "liaison",
+    "public"
+  ],
+  "title": "UserRole"
+}
+
+
UserSelfUpdate
+{
+  "properties": {
+    "password": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Password"
+    },
+    "email": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "email"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    },
+    "is_superuser": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Superuser"
+    },
+    "is_verified": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Verified"
+    },
+    "full_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Full Name"
+    }
+  },
+  "type": "object",
+  "title": "UserSelfUpdate",
+  "description": "Schema for user self-update via PATCH /users/me.\n\nExcludes role and department_id. Any payload containing those fields is\nrejected at parse time (HTTP 422). Role and department changes require\nadmin privileges via /admin/users/{id}."
+}
+
+
UserUpdateRequest
+{
+  "properties": {
+    "full_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Full Name"
+    },
+    "role": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Role"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "UserUpdateRequest"
+}
+
+
ValidationError
+{
+  "properties": {
+    "loc": {
+      "items": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "integer"
+          }
+        ]
+      },
+      "type": "array",
+      "title": "Location"
+    },
+    "msg": {
+      "type": "string",
+      "title": "Message"
+    },
+    "type": {
+      "type": "string",
+      "title": "Error Type"
+    },
+    "input": {
+      "title": "Input"
+    },
+    "ctx": {
+      "type": "object",
+      "title": "Context"
+    }
+  },
+  "type": "object",
+  "required": [
+    "loc",
+    "msg",
+    "type"
+  ],
+  "title": "ValidationError"
+}
+
+
Version
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence"
+  ],
+  "title": "Version"
+}
+
+
VoteCorrection
+{
+  "properties": {
+    "vote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Vote"
+    },
+    "reason": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Reason"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "vote",
+    "reason"
+  ],
+  "title": "VoteCorrection"
+}
+
+
VoteInput
+{
+  "properties": {
+    "voter_name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Voter Name"
+    },
+    "vote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Vote"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "voter_name",
+    "vote"
+  ],
+  "title": "VoteInput"
+}
+
+
_ParcelLookupIn
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "query"
+  ],
+  "title": "_ParcelLookupIn"
+}
+
+
townlight_inspections__workflow_models__SourceLink
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "const": "code",
+      "title": "Provider",
+      "default": "code"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "SourceLink"
+}
+
+
townlight_permitting__workflow_models__SourceLink
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "enum": [
+        "code",
+        "zoning"
+      ],
+      "title": "Provider"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "SourceLink"
+}
+
+
townlight_runtime__inspections_bridge__Search
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "const": "code",
+      "title": "Provider"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "query"
+  ],
+  "title": "Search"
+}
+
+
townlight_runtime__notice_bridge__Review
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence",
+    "note"
+  ],
+  "title": "Review"
+}
+
+
townlight_runtime__permitting_bridge__Import
+{
+  "properties": {
+    "bundle": {
+      "$ref": "#/components/schemas/RequirementBundle"
+    },
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "bundle"
+  ],
+  "title": "Import"
+}
+
+
townlight_runtime__permitting_bridge__Search
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "enum": [
+        "code",
+        "zoning"
+      ],
+      "title": "Provider"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "query"
+  ],
+  "title": "Search"
+}
+
+
townlight_runtime__planning_bridge__Import
+{
+  "properties": {
+    "bundle": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Bundle"
+    },
+    "expected_previous_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Previous Revision"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "bundle"
+  ],
+  "title": "Import"
+}
+
+
townlight_runtime__planning_bridge__Search
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Query"
+    },
+    "plan_type": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 40
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Plan Type"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "Search"
+}
+
+
townlight_runtime__zoning_bridge__Review
+{
+  "properties": {
+    "answer": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Answer",
+      "default": ""
+    },
+    "notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Notes",
+      "default": ""
+    },
+    "queue_status": {
+      "type": "string",
+      "enum": [
+        "open",
+        "in_review",
+        "resolved",
+        "closed"
+      ],
+      "title": "Queue Status",
+      "default": "resolved"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "Review"
+}
+
Townlight · AGPL-3.0-only · Source schema evidence only
\ No newline at end of file diff --git a/docs/beta-1/api/records-openapi.json b/docs/beta-1/api/records-openapi.json new file mode 100644 index 0000000..bfe2814 --- /dev/null +++ b/docs/beta-1/api/records-openapi.json @@ -0,0 +1,19234 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "Townlight Records", + "description": "Prepared source schema for the actual native composition; installed acceptance remains pending. Exported without lifespan, migrations or database/network access.", + "version": "1.8.0.dev2" + }, + "paths": { + "/auth/jwt/login": { + "post": { + "tags": [ + "auth" + ], + "summary": "Auth:Jwt.Login", + "operationId": "auth_jwt_login_auth_jwt_login_post", + "requestBody": { + "content": { + "application/x-www-form-urlencoded": { + "schema": { + "$ref": "#/components/schemas/Body_auth_jwt_login_auth_jwt_login_post" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BearerResponse" + }, + "example": { + "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiOTIyMWZmYzktNjQwZi00MzcyLTg2ZDMtY2U2NDJjYmE1NjAzIiwiYXVkIjoiZmFzdGFwaS11c2VyczphdXRoIiwiZXhwIjoxNTcxNTA0MTkzfQ.M10bjOe45I5Ncu_uXvOmVV8QxnL-nZfcH96U90JaocI", + "token_type": "bearer" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorModel" + }, + "examples": { + "LOGIN_BAD_CREDENTIALS": { + "summary": "Bad credentials or the user is inactive.", + "value": { + "detail": "LOGIN_BAD_CREDENTIALS" + } + }, + "LOGIN_USER_NOT_VERIFIED": { + "summary": "The user is not verified.", + "value": { + "detail": "LOGIN_USER_NOT_VERIFIED" + } + } + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/auth/jwt/logout": { + "post": { + "tags": [ + "auth" + ], + "summary": "Auth:Jwt.Logout", + "operationId": "auth_jwt_logout_auth_jwt_logout_post", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "401": { + "description": "Missing token or inactive user." + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/users/me": { + "get": { + "tags": [ + "users" + ], + "summary": "Users:Current User", + "operationId": "users_current_user_users_me_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserRead" + } + } + } + }, + "401": { + "description": "Missing token or inactive user." + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + }, + "patch": { + "tags": [ + "users" + ], + "summary": "Users:Patch Current User", + "operationId": "users_patch_current_user_users_me_patch", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserSelfUpdate" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserRead" + } + } + } + }, + "401": { + "description": "Missing token or inactive user." + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorModel" + }, + "examples": { + "UPDATE_USER_EMAIL_ALREADY_EXISTS": { + "summary": "A user with this email already exists.", + "value": { + "detail": "UPDATE_USER_EMAIL_ALREADY_EXISTS" + } + }, + "UPDATE_USER_INVALID_PASSWORD": { + "summary": "Password validation failed.", + "value": { + "detail": { + "code": "UPDATE_USER_INVALID_PASSWORD", + "reason": "Password should beat least 3 characters" + } + } + } + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/users/{id}": { + "get": { + "tags": [ + "users" + ], + "summary": "Users:User", + "operationId": "users_user_users__id__get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserRead" + } + } + } + }, + "401": { + "description": "Missing token or inactive user." + }, + "403": { + "description": "Not a superuser." + }, + "404": { + "description": "The user does not exist." + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "patch": { + "tags": [ + "users" + ], + "summary": "Users:Patch User", + "operationId": "users_patch_user_users__id__patch", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserSelfUpdate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserRead" + } + } + } + }, + "401": { + "description": "Missing token or inactive user." + }, + "403": { + "description": "Not a superuser." + }, + "404": { + "description": "The user does not exist." + }, + "400": { + "content": { + "application/json": { + "examples": { + "UPDATE_USER_EMAIL_ALREADY_EXISTS": { + "summary": "A user with this email already exists.", + "value": { + "detail": "UPDATE_USER_EMAIL_ALREADY_EXISTS" + } + }, + "UPDATE_USER_INVALID_PASSWORD": { + "summary": "Password validation failed.", + "value": { + "detail": { + "code": "UPDATE_USER_INVALID_PASSWORD", + "reason": "Password should beat least 3 characters" + } + } + } + }, + "schema": { + "$ref": "#/components/schemas/ErrorModel" + } + } + }, + "description": "Bad Request" + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "delete": { + "tags": [ + "users" + ], + "summary": "Users:Delete User", + "operationId": "users_delete_user_users__id__delete", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Id" + } + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "401": { + "description": "Missing token or inactive user." + }, + "403": { + "description": "Not a superuser." + }, + "404": { + "description": "The user does not exist." + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/config/portal-mode": { + "get": { + "tags": [ + "public" + ], + "summary": "Get the deployment's current portal posture.", + "operationId": "get_portal_mode_config_portal_mode_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PortalModeResponse" + } + } + } + } + } + } + }, + "/audit/logs": { + "get": { + "tags": [ + "audit" + ], + "summary": "List Audit Logs", + "operationId": "list_audit_logs_audit_logs_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "action", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Action" + } + }, + { + "name": "resource_type", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Resource Type" + } + }, + { + "name": "user_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "User Id" + } + }, + { + "name": "start_date", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Start Date" + } + }, + { + "name": "end_date", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "End Date" + } + }, + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 200, + "default": 50, + "title": "Limit" + } + }, + { + "name": "offset", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "default": 0, + "title": "Offset" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AuditLogRead" + }, + "title": "Response List Audit Logs Audit Logs Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/audit/verify": { + "get": { + "tags": [ + "audit" + ], + "summary": "Verify Audit Chain", + "operationId": "verify_audit_chain_audit_verify_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuditChainVerification" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/audit/export": { + "get": { + "tags": [ + "audit" + ], + "summary": "Export Audit Logs", + "operationId": "export_audit_logs_audit_export_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "format", + "in": "query", + "required": false, + "schema": { + "type": "string", + "default": "json", + "title": "Format" + } + }, + { + "name": "start_date", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Start Date" + } + }, + { + "name": "end_date", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "End Date" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/service-accounts/": { + "get": { + "tags": [ + "service-accounts" + ], + "summary": "List Service Accounts", + "operationId": "list_service_accounts_service_accounts__get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/ServiceAccountRead" + }, + "type": "array", + "title": "Response List Service Accounts Service Accounts Get" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + }, + "post": { + "tags": [ + "service-accounts" + ], + "summary": "Create Service Account", + "operationId": "create_service_account_service_accounts__post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceAccountCreate" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceAccountCreated" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/service-accounts/{account_id}": { + "patch": { + "tags": [ + "service-accounts" + ], + "summary": "Update Service Account", + "operationId": "update_service_account_service_accounts__account_id__patch", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "account_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Account Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceAccountUpdate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceAccountRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/admin/status": { + "get": { + "tags": [ + "admin" + ], + "summary": "System Status", + "operationId": "system_status_admin_status_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SystemStatus" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/admin/users": { + "get": { + "tags": [ + "admin" + ], + "summary": "List Users", + "description": "List all users. Admin only.", + "operationId": "list_users_admin_users_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/UserRead" + }, + "type": "array", + "title": "Response List Users Admin Users Get" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + }, + "post": { + "tags": [ + "admin" + ], + "summary": "Create User", + "description": "Create a new user. Admin only.", + "operationId": "create_user_admin_users_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AdminUserCreateRequest" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AdminUserCreateResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/admin/users/{user_id}": { + "patch": { + "tags": [ + "admin" + ], + "summary": "Update User", + "description": "Update user fields. Admin only.\n\nGuards against self-demotion: admins cannot change their own role.", + "operationId": "update_user_admin_users__user_id__patch", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "user_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "User Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserUpdateRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AdminUserCreateResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/admin/models": { + "get": { + "tags": [ + "admin" + ], + "summary": "List Models", + "operationId": "list_models_admin_models_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OllamaStatus" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/admin/models/registry": { + "get": { + "tags": [ + "admin" + ], + "summary": "List Model Registry", + "operationId": "list_model_registry_admin_models_registry_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/ModelRegistryRead" + }, + "type": "array", + "title": "Response List Model Registry Admin Models Registry Get" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + }, + "post": { + "tags": [ + "admin" + ], + "summary": "Register Model", + "operationId": "register_model_admin_models_registry_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ModelRegistryCreate" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ModelRegistryRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/admin/models/registry/{model_id}": { + "patch": { + "tags": [ + "admin" + ], + "summary": "Update Model Registry", + "operationId": "update_model_registry_admin_models_registry__model_id__patch", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "model_id", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "title": "Model Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ModelRegistryUpdate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ModelRegistryRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "delete": { + "tags": [ + "admin" + ], + "summary": "Delete Model Registry", + "operationId": "delete_model_registry_admin_models_registry__model_id__delete", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "model_id", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "title": "Model Id" + } + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/admin/fee-schedules": { + "get": { + "tags": [ + "admin" + ], + "summary": "List Fee Schedules", + "description": "List all fee schedules. Admin only.", + "operationId": "list_fee_schedules_admin_fee_schedules_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "jurisdiction", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Jurisdiction" + } + }, + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "default": 50, + "title": "Limit" + } + }, + { + "name": "offset", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "default": 0, + "title": "Offset" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FeeScheduleRead" + }, + "title": "Response List Fee Schedules Admin Fee Schedules Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "tags": [ + "admin" + ], + "summary": "Create Fee Schedule", + "description": "Create a new fee schedule. Admin only.", + "operationId": "create_fee_schedule_admin_fee_schedules_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FeeScheduleCreate" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FeeScheduleRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/admin/fee-schedules/{schedule_id}": { + "patch": { + "tags": [ + "admin" + ], + "summary": "Update Fee Schedule", + "description": "Update a fee schedule. Admin only.", + "operationId": "update_fee_schedule_admin_fee_schedules__schedule_id__patch", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "schedule_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Schedule Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FeeScheduleUpdate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FeeScheduleRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "delete": { + "tags": [ + "admin" + ], + "summary": "Delete Fee Schedule", + "description": "Delete a fee schedule. Admin only.", + "operationId": "delete_fee_schedule_admin_fee_schedules__schedule_id__delete", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "schedule_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Schedule Id" + } + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/admin/coverage-gaps": { + "get": { + "tags": [ + "admin" + ], + "summary": "Get Coverage Gaps", + "description": "Identify coverage gaps across jurisdictions, departments, and exemption categories.\n\nReturns:\n- Jurisdictions (state codes) that have no exemption rules\n- Departments with no assigned staff users\n- Exemption categories without any active rules", + "operationId": "get_coverage_gaps_admin_coverage_gaps_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CoverageGapResponse" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/datasources/": { + "get": { + "tags": [ + "datasources" + ], + "summary": "List Datasources", + "operationId": "list_datasources_datasources__get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/DataSourceRead" + }, + "type": "array", + "title": "Response List Datasources Datasources Get" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + }, + "post": { + "tags": [ + "datasources" + ], + "summary": "Create Datasource", + "operationId": "create_datasource_datasources__post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataSourceCreate" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataSourceAdminRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/datasources/{source_id}": { + "patch": { + "tags": [ + "datasources" + ], + "summary": "Update Datasource", + "operationId": "update_datasource_datasources__source_id__patch", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "source_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Source Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataSourceUpdate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataSourceAdminRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/datasources/{source_id}/ingest": { + "post": { + "tags": [ + "datasources" + ], + "summary": "Trigger Ingestion", + "operationId": "trigger_ingestion_datasources__source_id__ingest_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "source_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Source Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/datasources/upload": { + "post": { + "tags": [ + "datasources" + ], + "summary": "Upload File", + "operationId": "upload_file_datasources_upload_post", + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "$ref": "#/components/schemas/Body_upload_file_datasources_upload_post" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/datasources/documents/{document_id}/re-ingest": { + "post": { + "tags": [ + "datasources" + ], + "summary": "Re Ingest Document", + "description": "Re-ingest a failed document. Resets status to pending and queues for processing.", + "operationId": "re_ingest_document_datasources_documents__document_id__re_ingest_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "document_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Document Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/datasources/stats": { + "get": { + "tags": [ + "datasources" + ], + "summary": "Ingestion Stats", + "operationId": "ingestion_stats_datasources_stats_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IngestionStats" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/datasources/test-connection": { + "post": { + "tags": [ + "datasources" + ], + "summary": "Test Connection", + "description": "Test connectivity to a data source without persisting anything.\n\nThis endpoint validates the connection parameters and attempts a test\nconnection. Credentials are NOT persisted, NOT logged, and NOT returned.", + "operationId": "test_connection_datasources_test_connection_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TestConnectionRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TestConnectionResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/documents/": { + "get": { + "tags": [ + "documents" + ], + "summary": "List Documents", + "operationId": "list_documents_documents__get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "source_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Source Id" + } + }, + { + "name": "status", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/IngestionStatus" + }, + { + "type": "null" + } + ], + "title": "Status" + } + }, + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 500, + "default": 50, + "title": "Limit" + } + }, + { + "name": "offset", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "default": 0, + "title": "Offset" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DocumentRead" + }, + "title": "Response List Documents Documents Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/documents/{document_id}": { + "get": { + "tags": [ + "documents" + ], + "summary": "Get Document", + "operationId": "get_document_documents__document_id__get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "document_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Document Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DocumentRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/documents/{document_id}/chunks": { + "get": { + "tags": [ + "documents" + ], + "summary": "List Chunks", + "operationId": "list_chunks_documents__document_id__chunks_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "document_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Document Id" + } + }, + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 500, + "default": 50, + "title": "Limit" + } + }, + { + "name": "offset", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "default": 0, + "title": "Offset" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DocumentChunkRead" + }, + "title": "Response List Chunks Documents Document Id Chunks Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/datasources/{source_id}/sync-failures": { + "get": { + "tags": [ + "sync-failures" + ], + "summary": "List Sync Failures", + "operationId": "list_sync_failures_datasources__source_id__sync_failures_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "source_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Source Id" + } + }, + { + "name": "status", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Filter by status", + "title": "Status" + }, + "description": "Filter by status" + }, + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 500, + "minimum": 1, + "default": 50, + "title": "Limit" + } + }, + { + "name": "offset", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "minimum": 0, + "default": 0, + "title": "Offset" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SyncFailureRead" + }, + "title": "Response List Sync Failures Datasources Source Id Sync Failures Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/datasources/{source_id}/sync-failures/{failure_id}/retry": { + "post": { + "tags": [ + "sync-failures" + ], + "summary": "Retry Sync Failure", + "operationId": "retry_sync_failure_datasources__source_id__sync_failures__failure_id__retry_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "source_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Source Id" + } + }, + { + "name": "failure_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Failure Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/datasources/{source_id}/sync-failures/{failure_id}/dismiss": { + "post": { + "tags": [ + "sync-failures" + ], + "summary": "Dismiss Sync Failure", + "operationId": "dismiss_sync_failure_datasources__source_id__sync_failures__failure_id__dismiss_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "source_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Source Id" + } + }, + { + "name": "failure_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Failure Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/datasources/{source_id}/sync-failures/retry-all": { + "post": { + "tags": [ + "sync-failures" + ], + "summary": "Retry All Sync Failures", + "operationId": "retry_all_sync_failures_datasources__source_id__sync_failures_retry_all_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "source_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Source Id" + } + }, + { + "name": "status", + "in": "query", + "required": true, + "schema": { + "type": "string", + "description": "Status to reset — required", + "title": "Status" + }, + "description": "Status to reset — required" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/datasources/{source_id}/sync-failures/dismiss-all": { + "post": { + "tags": [ + "sync-failures" + ], + "summary": "Dismiss All Sync Failures", + "operationId": "dismiss_all_sync_failures_datasources__source_id__sync_failures_dismiss_all_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "source_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Source Id" + } + }, + { + "name": "status", + "in": "query", + "required": true, + "schema": { + "type": "string", + "description": "Status to dismiss — required", + "title": "Status" + }, + "description": "Status to dismiss — required" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/datasources/{source_id}/unpause": { + "post": { + "tags": [ + "sync-failures" + ], + "summary": "Unpause Source", + "operationId": "unpause_source_datasources__source_id__unpause_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "source_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Source Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/datasources/{source_id}/sync-run-log": { + "get": { + "tags": [ + "sync-failures" + ], + "summary": "Get Sync Run Log", + "operationId": "get_sync_run_log_datasources__source_id__sync_run_log_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "source_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Source Id" + } + }, + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 100, + "minimum": 1, + "default": 20, + "title": "Limit" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SyncRunLogRead" + }, + "title": "Response Get Sync Run Log Datasources Source Id Sync Run Log Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/search/query": { + "post": { + "tags": [ + "search" + ], + "summary": "Execute Search", + "description": "Execute a hybrid search query. Optionally synthesize an LLM answer.", + "operationId": "execute_search_search_query_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SearchRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SearchResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/search/sessions": { + "get": { + "tags": [ + "search" + ], + "summary": "List Sessions", + "description": "List the current user's search sessions.", + "operationId": "list_sessions_search_sessions_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "default": 20, + "title": "Limit" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SearchSessionRead" + }, + "title": "Response List Sessions Search Sessions Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/search/sessions/{session_id}": { + "get": { + "tags": [ + "search" + ], + "summary": "Get Session", + "description": "Get a search session with its query history.", + "operationId": "get_session_search_sessions__session_id__get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "session_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Session Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SearchSessionRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/search/filters": { + "get": { + "tags": [ + "search" + ], + "summary": "Get Filter Options", + "description": "Get available filter values for search.", + "operationId": "get_filter_options_search_filters_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SearchFilterOptions" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/search/export": { + "get": { + "tags": [ + "search" + ], + "summary": "Export Search Results", + "description": "Export search results as CSV. Runs a search and streams the results.", + "operationId": "export_search_results_search_export_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "query", + "in": "query", + "required": true, + "schema": { + "type": "string", + "title": "Query" + } + }, + { + "name": "format", + "in": "query", + "required": false, + "schema": { + "type": "string", + "default": "csv", + "title": "Format" + } + }, + { + "name": "department_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Department Id" + } + }, + { + "name": "file_type", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "File Type" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/requests/": { + "post": { + "tags": [ + "requests" + ], + "summary": "Create Request", + "operationId": "create_request_requests__post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RequestCreate" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RequestRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "get": { + "tags": [ + "requests" + ], + "summary": "List Requests", + "operationId": "list_requests_requests__get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "status", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/RequestStatus" + }, + { + "type": "null" + } + ], + "title": "Status" + } + }, + { + "name": "assigned_to", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + } + }, + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "default": 50, + "title": "Limit" + } + }, + { + "name": "offset", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "default": 0, + "title": "Offset" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RequestRead" + }, + "title": "Response List Requests Requests Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/requests/stats": { + "get": { + "tags": [ + "requests" + ], + "summary": "Request Stats", + "operationId": "request_stats_requests_stats_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RequestStats" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/requests/{request_id}": { + "get": { + "tags": [ + "requests" + ], + "summary": "Get Request", + "operationId": "get_request_requests__request_id__get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RequestRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "patch": { + "tags": [ + "requests" + ], + "summary": "Update Request", + "operationId": "update_request_requests__request_id__patch", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RequestUpdate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RequestRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/requests/{request_id}/documents": { + "post": { + "tags": [ + "requests" + ], + "summary": "Attach Document", + "operationId": "attach_document_requests__request_id__documents_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RequestDocumentAdd" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RequestDocumentRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "get": { + "tags": [ + "requests" + ], + "summary": "List Attached Documents", + "operationId": "list_attached_documents_requests__request_id__documents_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RequestDocumentRead" + }, + "title": "Response List Attached Documents Requests Request Id Documents Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/requests/{request_id}/documents/{doc_id}": { + "delete": { + "tags": [ + "requests" + ], + "summary": "Remove Document", + "operationId": "remove_document_requests__request_id__documents__doc_id__delete", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "doc_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Doc Id" + } + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/requests/{request_id}/submit-review": { + "post": { + "tags": [ + "requests" + ], + "summary": "Submit For Review", + "operationId": "submit_for_review_requests__request_id__submit_review_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RequestRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/requests/{request_id}/ready-for-release": { + "post": { + "tags": [ + "requests" + ], + "summary": "Mark Ready For Release", + "operationId": "mark_ready_for_release_requests__request_id__ready_for_release_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RequestRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/requests/{request_id}/approve": { + "post": { + "tags": [ + "requests" + ], + "summary": "Approve Request", + "operationId": "approve_request_requests__request_id__approve_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RequestRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/requests/{request_id}/reject": { + "post": { + "tags": [ + "requests" + ], + "summary": "Reject Request", + "operationId": "reject_request_requests__request_id__reject_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "reason", + "in": "query", + "required": false, + "schema": { + "type": "string", + "default": "", + "title": "Reason" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RequestRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/requests/{request_id}/timeline": { + "get": { + "tags": [ + "requests" + ], + "summary": "Get Timeline", + "operationId": "get_timeline_requests__request_id__timeline_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TimelineEventRead" + }, + "title": "Response Get Timeline Requests Request Id Timeline Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "tags": [ + "requests" + ], + "summary": "Add Timeline Event", + "operationId": "add_timeline_event_requests__request_id__timeline_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TimelineEventCreate" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TimelineEventRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/requests/{request_id}/messages": { + "get": { + "tags": [ + "requests" + ], + "summary": "Get Messages", + "operationId": "get_messages_requests__request_id__messages_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/MessageRead" + }, + "title": "Response Get Messages Requests Request Id Messages Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "tags": [ + "requests" + ], + "summary": "Add Message", + "operationId": "add_message_requests__request_id__messages_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MessageCreate" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MessageRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/requests/{request_id}/fees": { + "get": { + "tags": [ + "requests" + ], + "summary": "Get Fees", + "operationId": "get_fees_requests__request_id__fees_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FeeLineItemRead" + }, + "title": "Response Get Fees Requests Request Id Fees Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "tags": [ + "requests" + ], + "summary": "Add Fee", + "operationId": "add_fee_requests__request_id__fees_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FeeLineItemCreate" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FeeLineItemRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/requests/{request_id}/estimate-fees": { + "post": { + "tags": [ + "requests" + ], + "summary": "Estimate Fees", + "description": "Estimate fees based on staff-entered page count and fee schedule.\n\nPage count is a manual staff estimate — not inferred from ingested docs.", + "operationId": "estimate_fees_requests__request_id__estimate_fees_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FeeEstimateRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FeeEstimateResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/requests/{request_id}/fee-waiver": { + "post": { + "tags": [ + "requests" + ], + "summary": "Create Fee Waiver", + "description": "Request a fee waiver for this records request.", + "operationId": "create_fee_waiver_requests__request_id__fee_waiver_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FeeWaiverCreateRequest" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FeeWaiverReadResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/requests/{request_id}/fee-waiver/{waiver_id}": { + "patch": { + "tags": [ + "requests" + ], + "summary": "Review Fee Waiver", + "description": "Approve or deny a fee waiver. Reviewer/Admin only.", + "operationId": "review_fee_waiver_requests__request_id__fee_waiver__waiver_id__patch", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "waiver_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Waiver Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FeeWaiverReviewRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FeeWaiverReadResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/requests/{request_id}/response-letter": { + "post": { + "tags": [ + "requests" + ], + "summary": "Generate Response Letter", + "description": "Generate a draft response letter for a records request.\n\nAttempts LLM generation via Ollama first; falls back to a structured\ntemplate if the LLM is unavailable.", + "operationId": "generate_response_letter_requests__request_id__response_letter_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/ResponseLetterCreate" + }, + { + "type": "null" + } + ], + "title": "Data" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResponseLetterRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "get": { + "tags": [ + "requests" + ], + "summary": "Get Response Letter", + "description": "Get the latest response letter for a request.", + "operationId": "get_response_letter_requests__request_id__response_letter_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResponseLetterRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/requests/{request_id}/response-letter/{letter_id}": { + "patch": { + "tags": [ + "requests" + ], + "summary": "Update Response Letter", + "description": "Update a response letter's edited content or status.\n\nStatus changes to 'approved' require REVIEWER role.", + "operationId": "update_response_letter_requests__request_id__response_letter__letter_id__patch", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "letter_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Letter Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResponseLetterUpdate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResponseLetterRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/exemptions/rules/": { + "post": { + "tags": [ + "exemptions" + ], + "summary": "Create Rule", + "operationId": "create_rule_exemptions_rules__post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExemptionRuleCreate" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExemptionRuleRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "get": { + "tags": [ + "exemptions" + ], + "summary": "List Rules", + "operationId": "list_rules_exemptions_rules__get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "state_code", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State Code" + } + }, + { + "name": "enabled", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Enabled" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ExemptionRuleRead" + }, + "title": "Response List Rules Exemptions Rules Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/exemptions/rules/{rule_id}": { + "patch": { + "tags": [ + "exemptions" + ], + "summary": "Update Rule", + "operationId": "update_rule_exemptions_rules__rule_id__patch", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "rule_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Rule Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExemptionRuleUpdate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExemptionRuleRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/exemptions/rules/{rule_id}/history": { + "get": { + "tags": [ + "exemptions" + ], + "summary": "Get Rule History", + "description": "Get audit history for an exemption rule.", + "operationId": "get_rule_history_exemptions_rules__rule_id__history_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "rule_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Rule Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/exemptions/rules/{rule_id}/test": { + "post": { + "tags": [ + "exemptions" + ], + "summary": "Test Rule", + "description": "Test a rule against sample text. Returns match results.\n\nUses the `regex` library with timeout=2s to prevent ReDoS on\nadmin-entered patterns.", + "operationId": "test_rule_exemptions_rules__rule_id__test_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "rule_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Rule Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RuleTestRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RuleTestResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/exemptions/scan/{request_id}": { + "post": { + "tags": [ + "exemptions" + ], + "summary": "Scan For Exemptions", + "description": "Scan all documents attached to a request for exemptions.", + "operationId": "scan_for_exemptions_exemptions_scan__request_id__post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "state_code", + "in": "query", + "required": false, + "schema": { + "type": "string", + "pattern": "^[A-Z]{2}$", + "default": "CO", + "title": "State Code" + } + }, + { + "name": "use_llm", + "in": "query", + "required": false, + "schema": { + "type": "boolean", + "default": false, + "title": "Use Llm" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/exemptions/flags/{request_id}": { + "get": { + "tags": [ + "exemptions" + ], + "summary": "List Flags", + "operationId": "list_flags_exemptions_flags__request_id__get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "status", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/FlagStatus" + }, + { + "type": "null" + } + ], + "title": "Status" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ExemptionFlagRead" + }, + "title": "Response List Flags Exemptions Flags Request Id Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/exemptions/flags/{flag_id}": { + "patch": { + "tags": [ + "exemptions" + ], + "summary": "Review Flag", + "operationId": "review_flag_exemptions_flags__flag_id__patch", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "flag_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Flag Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExemptionFlagReview" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExemptionFlagRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/exemptions/dashboard/accuracy": { + "get": { + "tags": [ + "exemptions" + ], + "summary": "Exemption Accuracy", + "description": "Acceptance/rejection rates by category, optionally filtered by department.", + "operationId": "exemption_accuracy_exemptions_dashboard_accuracy_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "department_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + } + }, + { + "name": "date_from", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Date From" + } + }, + { + "name": "date_to", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Date To" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ExemptionAccuracyReport" + }, + "title": "Response Exemption Accuracy Exemptions Dashboard Accuracy Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/exemptions/dashboard/export": { + "get": { + "tags": [ + "exemptions" + ], + "summary": "Export Flag Data", + "description": "Export exemption flag data as JSON or CSV.", + "operationId": "export_flag_data_exemptions_dashboard_export_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "format", + "in": "query", + "required": false, + "schema": { + "type": "string", + "default": "json", + "title": "Format" + } + }, + { + "name": "date_from", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Date From" + } + }, + { + "name": "date_to", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Date To" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/exemptions/dashboard": { + "get": { + "tags": [ + "exemptions" + ], + "summary": "Exemption Dashboard", + "operationId": "exemption_dashboard_exemptions_dashboard_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExemptionDashboard" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/exemptions/templates/": { + "get": { + "tags": [ + "exemptions" + ], + "summary": "List Templates", + "operationId": "list_templates_exemptions_templates__get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "template_type", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Template Type" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DisclosureTemplateRead" + }, + "title": "Response List Templates Exemptions Templates Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "tags": [ + "exemptions" + ], + "summary": "Create Template", + "operationId": "create_template_exemptions_templates__post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DisclosureTemplateCreate" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DisclosureTemplateRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/exemptions/templates/{template_id}/render": { + "get": { + "tags": [ + "exemptions" + ], + "summary": "Render Template", + "description": "Render a template with city profile variables substituted.", + "operationId": "render_template_exemptions_templates__template_id__render_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "template_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Template Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DisclosureTemplateRendered" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/exemptions/templates/{template_id}": { + "put": { + "tags": [ + "exemptions" + ], + "summary": "Update Template", + "operationId": "update_template_exemptions_templates__template_id__put", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "template_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Template Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DisclosureTemplateUpdate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DisclosureTemplateRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/analytics/operational": { + "get": { + "tags": [ + "analytics" + ], + "summary": "Get Operational Metrics", + "operationId": "get_operational_metrics_analytics_operational_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OperationalMetrics" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/city-profile": { + "get": { + "tags": [ + "city-profile" + ], + "summary": "Get City Profile", + "operationId": "get_city_profile_city_profile_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/CityProfileRead" + }, + { + "type": "null" + } + ], + "title": "Response Get City Profile City Profile Get" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + }, + "post": { + "tags": [ + "city-profile" + ], + "summary": "Create City Profile", + "operationId": "create_city_profile_city_profile_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CityProfileCreate" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CityProfileRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + }, + "patch": { + "tags": [ + "city-profile" + ], + "summary": "Update City Profile", + "operationId": "update_city_profile_city_profile_patch", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CityProfileUpdate" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CityProfileRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/onboarding/interview": { + "post": { + "tags": [ + "onboarding" + ], + "summary": "Get Next Question", + "description": "Generate the next onboarding question and persist the last answer.", + "operationId": "get_next_question_onboarding_interview_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InterviewRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InterviewResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/catalog/domains": { + "get": { + "tags": [ + "catalog" + ], + "summary": "List Domains", + "operationId": "list_domains_catalog_domains_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/catalog/systems": { + "get": { + "tags": [ + "catalog" + ], + "summary": "List Systems", + "operationId": "list_systems_catalog_systems_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "domain", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Domain" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/catalog/connectors": { + "get": { + "tags": [ + "catalog" + ], + "summary": "List Connectors", + "operationId": "list_connectors_catalog_connectors_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "domain", + "in": "query", + "required": true, + "schema": { + "type": "string", + "title": "Domain" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/catalog/load": { + "post": { + "tags": [ + "catalog" + ], + "summary": "Trigger Catalog Load", + "operationId": "trigger_catalog_load_catalog_load_post", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/notifications/templates": { + "get": { + "tags": [ + "notifications" + ], + "summary": "List Templates", + "description": "List all notification templates.", + "operationId": "list_templates_notifications_templates_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/NotificationTemplateRead" + }, + "type": "array", + "title": "Response List Templates Notifications Templates Get" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + }, + "post": { + "tags": [ + "notifications" + ], + "summary": "Create Template", + "description": "Create a new notification template (admin only).", + "operationId": "create_template_notifications_templates_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotificationTemplateCreate" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotificationTemplateRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/notifications/templates/{template_id}": { + "patch": { + "tags": [ + "notifications" + ], + "summary": "Update Template", + "description": "Update a notification template (admin only).", + "operationId": "update_template_notifications_templates__template_id__patch", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "template_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Template Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotificationTemplateUpdate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotificationTemplateRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/notifications/log": { + "get": { + "tags": [ + "notifications" + ], + "summary": "List Notification Log", + "description": "List recent notification log entries.", + "operationId": "list_notification_log_notifications_log_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 200, + "default": 50, + "title": "Limit" + } + }, + { + "name": "request_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Request Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/NotificationLogRead" + }, + "title": "Response List Notification Log Notifications Log Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/departments/": { + "get": { + "tags": [ + "departments" + ], + "summary": "List Departments", + "operationId": "list_departments_departments__get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/DepartmentRead" + }, + "type": "array", + "title": "Response List Departments Departments Get" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + }, + "post": { + "tags": [ + "departments" + ], + "summary": "Create Department", + "operationId": "create_department_departments__post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DepartmentCreate" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DepartmentRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/departments/{dept_id}": { + "get": { + "tags": [ + "departments" + ], + "summary": "Get Department", + "operationId": "get_department_departments__dept_id__get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "dept_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Dept Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DepartmentRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "patch": { + "tags": [ + "departments" + ], + "summary": "Update Department", + "operationId": "update_department_departments__dept_id__patch", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "dept_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Dept Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DepartmentUpdate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DepartmentRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "delete": { + "tags": [ + "departments" + ], + "summary": "Delete Department", + "operationId": "delete_department_departments__dept_id__delete", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "dept_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Dept Id" + } + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/station/context": { + "get": { + "tags": [ + "native-desktop", + "station-integration" + ], + "summary": "Context", + "operationId": "context_desktop_v1_station_context_get", + "parameters": [ + { + "name": "capability", + "in": "query", + "required": true, + "schema": { + "enum": [ + "capture", + "read" + ], + "type": "string", + "title": "Capability" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/requests/{request_id}/station-recordings": { + "post": { + "tags": [ + "native-desktop", + "station-integration" + ], + "summary": "Attach", + "operationId": "attach_desktop_v1_requests__request_id__station_recordings_post", + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Selection" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordsOperationRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/public/records-state": { + "get": { + "tags": [ + "native-desktop" + ], + "summary": "Public Records State", + "operationId": "public_records_state_desktop_v1_public_records_state_get", + "parameters": [ + { + "name": "X-Townlight-Public", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Public" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordsStateRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/public/requests": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Public Records Intake", + "operationId": "public_records_intake_desktop_v1_public_requests_post", + "parameters": [ + { + "name": "X-Townlight-Public", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Public" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PublicIntake" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/public/lookup": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Public Records Lookup", + "operationId": "public_records_lookup_desktop_v1_public_lookup_post", + "parameters": [ + { + "name": "X-Townlight-Public", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Public" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PublicLookup" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/public/messages": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Public Records Message", + "operationId": "public_records_message_desktop_v1_public_messages_post", + "parameters": [ + { + "name": "X-Townlight-Public", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Public" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PublicMessage" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/permitting-sources/search": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Search Permitting Sources", + "operationId": "search_permitting_sources_desktop_v1_permitting_sources_search_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MeetingsSearch" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/requests/{request_id}/permitting-sources": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Attach Permitting Source", + "operationId": "attach_permitting_source_desktop_v1_requests__request_id__permitting_sources_post", + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MeetingsSourceSelection" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordsOperationRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/inspections-sources/search": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Search Inspections Sources", + "operationId": "search_inspections_sources_desktop_v1_inspections_sources_search_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MeetingsSearch" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/requests/{request_id}/inspections-sources": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Attach Inspections Source", + "operationId": "attach_inspections_source_desktop_v1_requests__request_id__inspections_sources_post", + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MeetingsSourceSelection" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordsOperationRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning-sources/search": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Search Planning Sources", + "operationId": "search_planning_sources_desktop_v1_planning_sources_search_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MeetingsSearch" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/requests/{request_id}/planning-sources": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Attach Planning Source", + "operationId": "attach_planning_source_desktop_v1_requests__request_id__planning_sources_post", + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MeetingsSourceSelection" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordsOperationRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/zoning-sources/search": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Search Zoning Sources", + "operationId": "search_zoning_sources_desktop_v1_zoning_sources_search_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MeetingsSearch" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/requests/{request_id}/zoning-sources": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Attach Zoning Source", + "operationId": "attach_zoning_source_desktop_v1_requests__request_id__zoning_sources_post", + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MeetingsSourceSelection" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordsOperationRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/records-state": { + "get": { + "tags": [ + "native-desktop" + ], + "summary": "Get Native Records State", + "operationId": "get_native_records_state_desktop_v1_records_state_get", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordsStateRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings-sources/search": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Search Meetings Sources", + "operationId": "search_meetings_sources_desktop_v1_meetings_sources_search_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MeetingsSearch" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/requests/{request_id}/meetings-sources": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Attach Meetings Source", + "operationId": "attach_meetings_source_desktop_v1_requests__request_id__meetings_sources_post", + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MeetingsSourceSelection" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordsOperationRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/code-sources/search": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Search Code Sources", + "operationId": "search_code_sources_desktop_v1_code_sources_search_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CodeSearch" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/requests/{request_id}/code-sources": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Attach Code Source", + "operationId": "attach_code_source_desktop_v1_requests__request_id__code_sources_post", + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CodeSourceSelection" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordsOperationRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/notifications/{notification_id}/sent": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Mark Native Notification Sent", + "operationId": "mark_native_notification_sent_desktop_v1_notifications__notification_id__sent_post", + "parameters": [ + { + "name": "notification_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Notification Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordsStateRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/requests/{request_id}/documents": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Attach Native Document", + "operationId": "attach_native_document_desktop_v1_requests__request_id__documents_post", + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AttachDocument" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordsOperationRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/requests/{request_id}/documents/{attachment_id}/release-copy": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Attach Native Release Copy", + "operationId": "attach_native_release_copy_desktop_v1_requests__request_id__documents__attachment_id__release_copy_post", + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "attachment_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Attachment Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AttachReleaseCopy" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordsOperationRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/requests/{request_id}/artifacts": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Prepare Native Artifact", + "operationId": "prepare_native_artifact_desktop_v1_requests__request_id__artifacts_post", + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PrepareArtifact" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ArtifactPlan" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/requests/{request_id}/artifacts/{artifact_id}/complete": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Complete Native Artifact", + "operationId": "complete_native_artifact_desktop_v1_requests__request_id__artifacts__artifact_id__complete_post", + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "artifact_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Artifact Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CompleteArtifact" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordsOperationRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/requests": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Create Native Request", + "operationId": "create_native_request_desktop_v1_requests_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StaffRecordsIntake" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NativeRequestRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/requests/{request_id}": { + "get": { + "tags": [ + "native-desktop" + ], + "summary": "Get Native Request", + "operationId": "get_native_request_desktop_v1_requests__request_id__get", + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NativeRequestRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/requests/{request_id}/view": { + "get": { + "tags": [ + "native-desktop" + ], + "summary": "Get Native Request View", + "operationId": "get_native_request_view_desktop_v1_requests__request_id__view_get", + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordsView" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/requests/{request_id}/draft-context": { + "get": { + "tags": [ + "native-desktop" + ], + "summary": "Native Draft Context", + "operationId": "native_draft_context_desktop_v1_requests__request_id__draft_context_get", + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/requests/{request_id}/generated-draft": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Native Generated Draft", + "operationId": "native_generated_draft_desktop_v1_requests__request_id__generated_draft_post", + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GeneratedDraft" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordsOperationRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/requests/{request_id}/actions": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Native Request Operation", + "operationId": "native_request_operation_desktop_v1_requests__request_id__actions_post", + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "oneOf": [ + { + "$ref": "#/components/schemas/AssignCommand" + }, + { + "$ref": "#/components/schemas/DeadlineCommand" + }, + { + "$ref": "#/components/schemas/CalculateDeadlineCommand" + }, + { + "$ref": "#/components/schemas/ClarificationCommand" + }, + { + "$ref": "#/components/schemas/MessageCommand" + }, + { + "$ref": "#/components/schemas/SearchNoteCommand" + }, + { + "$ref": "#/components/schemas/SearchReceiptCommand" + }, + { + "$ref": "#/components/schemas/ExemptionNoteCommand" + }, + { + "$ref": "#/components/schemas/ExemptionDecisionCommand" + }, + { + "$ref": "#/components/schemas/FeeEstimateCommand" + }, + { + "$ref": "#/components/schemas/FeeLineCommand" + }, + { + "$ref": "#/components/schemas/FeeWaiverCommand" + }, + { + "$ref": "#/components/schemas/DraftCommand" + }, + { + "$ref": "#/components/schemas/ApprovalCommand" + }, + { + "$ref": "#/components/schemas/FinishCommand" + } + ], + "discriminator": { + "propertyName": "action", + "mapping": { + "assign-records-request": "#/components/schemas/AssignCommand", + "set-records-deadline": "#/components/schemas/DeadlineCommand", + "calculate-records-deadline": "#/components/schemas/CalculateDeadlineCommand", + "request-records-clarification": "#/components/schemas/ClarificationCommand", + "add-records-message": "#/components/schemas/MessageCommand", + "record-records-search": "#/components/schemas/SearchNoteCommand", + "record-records-search-session": "#/components/schemas/SearchReceiptCommand", + "add-records-exemption-review": "#/components/schemas/ExemptionNoteCommand", + "add-records-exemption-decision": "#/components/schemas/ExemptionDecisionCommand", + "estimate-records-fee": "#/components/schemas/FeeEstimateCommand", + "add-records-fee-line": "#/components/schemas/FeeLineCommand", + "waive-records-fee": "#/components/schemas/FeeWaiverCommand", + "draft-records-response": "#/components/schemas/DraftCommand", + "approve-records-response": "#/components/schemas/ApprovalCommand", + "fulfill-records-request": "#/components/schemas/FinishCommand", + "close-records-request": "#/components/schemas/FinishCommand" + } + }, + "title": "Command" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordsOperationRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/health": { + "get": { + "summary": "Health", + "operationId": "health_health_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + } + } + } + }, + "/desktop/v1/access/state": { + "get": { + "tags": [ + "native-access" + ], + "summary": "Access State", + "operationId": "access_state_desktop_v1_access_state_get", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/access/review-context": { + "post": { + "tags": [ + "native-access" + ], + "summary": "Review Context", + "operationId": "review_context_desktop_v1_access_review_context_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReviewInput" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/access/reviews": { + "post": { + "tags": [ + "native-access" + ], + "summary": "Save Review", + "operationId": "save_review_desktop_v1_access_reviews_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SaveReview" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/access/reviews/{review_id}/delete": { + "post": { + "tags": [ + "native-access" + ], + "summary": "Delete Review", + "operationId": "delete_review_desktop_v1_access_reviews__review_id__delete_post", + "parameters": [ + { + "name": "review_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Review Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/access/tools": { + "post": { + "tags": [ + "native-access" + ], + "summary": "Tool", + "operationId": "tool_desktop_v1_access_tools_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "oneOf": [ + { + "$ref": "#/components/schemas/FormPlan" + }, + { + "$ref": "#/components/schemas/PublishingPlan" + }, + { + "$ref": "#/components/schemas/AdaPlan" + }, + { + "$ref": "#/components/schemas/TaggedPlan" + } + ], + "discriminator": { + "propertyName": "action", + "mapping": { + "form-plan": "#/components/schemas/FormPlan", + "publishing-workflow": "#/components/schemas/PublishingPlan", + "ada-title-ii": "#/components/schemas/AdaPlan", + "tagged-pdf": "#/components/schemas/TaggedPlan" + } + }, + "title": "Data" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/access/rewrite-context": { + "post": { + "tags": [ + "native-access" + ], + "summary": "Rewrite Context", + "operationId": "rewrite_context_desktop_v1_access_rewrite_context_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RewriteInput" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/access/rewrite-result": { + "post": { + "tags": [ + "native-access" + ], + "summary": "Rewrite Result", + "operationId": "rewrite_result_desktop_v1_access_rewrite_result_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RewriteResult" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/access/reviews/{review_id}/export": { + "post": { + "tags": [ + "native-access" + ], + "summary": "Prepare Export", + "operationId": "prepare_export_desktop_v1_access_reviews__review_id__export_post", + "parameters": [ + { + "name": "review_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Review Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/access/exports/{artifact_id}/complete": { + "post": { + "tags": [ + "native-access" + ], + "summary": "Complete Export", + "operationId": "complete_export_desktop_v1_access_exports__artifact_id__complete_post", + "parameters": [ + { + "name": "artifact_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Artifact Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExportReceipt" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/suite/state": { + "get": { + "tags": [ + "native-records-snapshot" + ], + "summary": "Suite State", + "operationId": "suite_state_desktop_v1_suite_state_get", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/suite/search": { + "post": { + "tags": [ + "native-records-snapshot" + ], + "summary": "Search", + "operationId": "search_desktop_v1_suite_search_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SearchInput" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "ActionItemInput": { + "properties": { + "description": { + "type": "string", + "minLength": 1, + "title": "Description" + }, + "assigned_to": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "source_motion_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Source Motion Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "description" + ], + "title": "ActionItemInput" + }, + "AdaPlan": { + "properties": { + "action": { + "type": "string", + "const": "ada-title-ii", + "title": "Action" + }, + "serviceArea": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Servicearea" + }, + "hasCoordinatorReview": { + "type": "boolean", + "title": "Hascoordinatorreview", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "serviceArea" + ], + "title": "AdaPlan" + }, + "AdminUserCreateRequest": { + "properties": { + "email": { + "type": "string", + "title": "Email" + }, + "password": { + "type": "string", + "title": "Password" + }, + "full_name": { + "type": "string", + "title": "Full Name", + "default": "" + }, + "role": { + "type": "string", + "title": "Role", + "default": "staff" + } + }, + "type": "object", + "required": [ + "email", + "password" + ], + "title": "AdminUserCreateRequest" + }, + "AdminUserCreateResponse": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "email": { + "type": "string", + "title": "Email" + }, + "full_name": { + "type": "string", + "title": "Full Name" + }, + "role": { + "type": "string", + "title": "Role" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + } + }, + "type": "object", + "required": [ + "id", + "email", + "full_name", + "role", + "is_active" + ], + "title": "AdminUserCreateResponse" + }, + "AgendaAssignment": { + "properties": { + "meeting_id": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "meeting_id" + ], + "title": "AgendaAssignment" + }, + "AgendaInput": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "department_name": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Department Name" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "department_name" + ], + "title": "AgendaInput" + }, + "AgendaReviewInput": { + "properties": { + "to_status": { + "type": "string", + "enum": [ + "DRAFTED", + "SUBMITTED", + "DEPT_APPROVED", + "LEGAL_REVIEWED", + "CLERK_ACCEPTED", + "ON_AGENDA", + "IN_PACKET", + "POSTED", + "HEARD", + "DISPOSED", + "ARCHIVED" + ], + "title": "To Status" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "to_status" + ], + "title": "AgendaReviewInput" + }, + "AmendmentInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "policy": { + "$ref": "#/components/schemas/PolicySelection" + }, + "proposal": { + "type": "string", + "maxLength": 20000, + "minLength": 1, + "title": "Proposal" + }, + "responsible_staff": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Responsible Staff" + }, + "status": { + "type": "string", + "enum": [ + "draft", + "review", + "adopted", + "withdrawn" + ], + "title": "Status", + "default": "draft" + }, + "review_note": { + "type": "string", + "maxLength": 5000, + "title": "Review Note", + "default": "" + }, + "adoption_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Adoption Revision" + }, + "note": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "policy", + "proposal", + "responsible_staff", + "note" + ], + "title": "AmendmentInput" + }, + "AnalysisObservation": { + "properties": { + "source": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "title": "Source" + }, + "filename": { + "type": "string", + "maxLength": 160, + "title": "Filename", + "default": "" + }, + "media_type": { + "type": "string", + "maxLength": 80, + "title": "Media Type", + "default": "" + }, + "text": { + "type": "string", + "maxLength": 4000, + "minLength": 1, + "title": "Text" + }, + "adapter": { + "type": "string", + "maxLength": 120, + "title": "Adapter", + "default": "" + }, + "citation_source_ids": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 30, + "title": "Citation Source Ids" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source", + "text" + ], + "title": "AnalysisObservation", + "description": "One draft observation, named with the adapter that actually produced it." + }, + "AnalysisRecord": { + "properties": { + "observations": { + "items": { + "$ref": "#/components/schemas/AnalysisObservation" + }, + "type": "array", + "maxItems": 30, + "title": "Observations" + }, + "cited_sections": { + "items": { + "$ref": "#/components/schemas/CitedSection" + }, + "type": "array", + "maxItems": 30, + "title": "Cited Sections" + }, + "unavailable": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 30, + "title": "Unavailable" + }, + "runtime": { + "additionalProperties": true, + "type": "object", + "title": "Runtime" + }, + "review_required": { + "type": "boolean", + "title": "Review Required", + "default": true + } + }, + "additionalProperties": false, + "type": "object", + "title": "AnalysisRecord", + "description": "The adapter output that accompanies a saved inspection draft." + }, + "ApprovalCommand": { + "properties": { + "action": { + "type": "string", + "const": "approve-records-response", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ApprovalPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "ApprovalCommand" + }, + "ApprovalPayload": { + "properties": { + "approvalNote": { + "type": "string", + "title": "Approvalnote", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "title": "ApprovalPayload" + }, + "ArchiveInput": { + "properties": { + "visibility": { + "type": "string", + "enum": [ + "public", + "closed_session" + ], + "title": "Visibility" + }, + "packet_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Packet Id" + }, + "minutes_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Minutes Id" + }, + "plain_language_summary": { + "type": "string", + "title": "Plain Language Summary", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "visibility" + ], + "title": "ArchiveInput" + }, + "ArtifactPlan": { + "properties": { + "artifact_id": { + "type": "string", + "title": "Artifact Id" + }, + "file_name": { + "type": "string", + "title": "File Name" + }, + "content": { + "type": "string", + "title": "Content" + }, + "sha256": { + "type": "string", + "title": "Sha256" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "artifact_id", + "file_name", + "content", + "sha256", + "created_at_unix_seconds" + ], + "title": "ArtifactPlan" + }, + "AssignCommand": { + "properties": { + "action": { + "type": "string", + "const": "assign-records-request", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/AssignmentPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "AssignCommand" + }, + "AssignmentPayload": { + "properties": { + "assignedTo": { + "type": "string", + "minLength": 1, + "title": "Assignedto" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "assignedTo" + ], + "title": "AssignmentPayload" + }, + "AttachDocument": { + "properties": { + "title": { + "type": "string", + "minLength": 1, + "title": "Title" + }, + "citation": { + "type": "string", + "title": "Citation", + "default": "" + }, + "file": { + "$ref": "#/components/schemas/ManagedFileReceipt" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "file" + ], + "title": "AttachDocument" + }, + "AttachReleaseCopy": { + "properties": { + "status": { + "type": "string", + "enum": [ + "release-ready copy", + "redacted copy" + ], + "title": "Status" + }, + "note": { + "type": "string", + "title": "Note", + "default": "" + }, + "added_by": { + "type": "string", + "title": "Added By", + "default": "" + }, + "file": { + "$ref": "#/components/schemas/ManagedFileReceipt" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "status", + "file" + ], + "title": "AttachReleaseCopy" + }, + "AuditChainVerification": { + "properties": { + "is_valid": { + "type": "boolean", + "title": "Is Valid" + }, + "entries_checked": { + "type": "integer", + "title": "Entries Checked" + }, + "error_message": { + "type": "string", + "title": "Error Message" + } + }, + "type": "object", + "required": [ + "is_valid", + "entries_checked", + "error_message" + ], + "title": "AuditChainVerification" + }, + "AuditLogRead": { + "properties": { + "id": { + "type": "integer", + "title": "Id" + }, + "prev_hash": { + "type": "string", + "title": "Prev Hash" + }, + "entry_hash": { + "type": "string", + "title": "Entry Hash" + }, + "timestamp": { + "type": "string", + "format": "date-time", + "title": "Timestamp" + }, + "user_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "User Id" + }, + "action": { + "type": "string", + "title": "Action" + }, + "resource_type": { + "type": "string", + "title": "Resource Type" + }, + "resource_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Resource Id" + }, + "details": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Details" + }, + "ai_generated": { + "type": "boolean", + "title": "Ai Generated" + } + }, + "type": "object", + "required": [ + "id", + "prev_hash", + "entry_hash", + "timestamp", + "user_id", + "action", + "resource_type", + "resource_id", + "details", + "ai_generated" + ], + "title": "AuditLogRead" + }, + "AuditView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "module_id": { + "type": "string", + "title": "Module Id" + }, + "action": { + "type": "string", + "title": "Action" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + }, + "previous_hash": { + "type": "string", + "title": "Previous Hash" + }, + "entry_hash": { + "type": "string", + "title": "Entry Hash" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "module_id", + "action", + "summary", + "created_at_unix_seconds", + "previous_hash", + "entry_hash" + ], + "title": "AuditView" + }, + "BearerResponse": { + "properties": { + "access_token": { + "type": "string", + "title": "Access Token" + }, + "token_type": { + "type": "string", + "title": "Token Type" + } + }, + "type": "object", + "required": [ + "access_token", + "token_type" + ], + "title": "BearerResponse" + }, + "Body_auth_jwt_login_auth_jwt_login_post": { + "properties": { + "grant_type": { + "anyOf": [ + { + "type": "string", + "pattern": "^password$" + }, + { + "type": "null" + } + ], + "title": "Grant Type" + }, + "username": { + "type": "string", + "title": "Username" + }, + "password": { + "type": "string", + "format": "password", + "title": "Password" + }, + "scope": { + "type": "string", + "title": "Scope", + "default": "" + }, + "client_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Client Id" + }, + "client_secret": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "format": "password", + "title": "Client Secret" + } + }, + "type": "object", + "required": [ + "username", + "password" + ], + "title": "Body_auth_jwt_login_auth_jwt_login_post" + }, + "Body_upload_file_datasources_upload_post": { + "properties": { + "file": { + "type": "string", + "contentMediaType": "application/octet-stream", + "title": "File" + } + }, + "type": "object", + "required": [ + "file" + ], + "title": "Body_upload_file_datasources_upload_post" + }, + "CalculateDeadlineCommand": { + "properties": { + "action": { + "type": "string", + "const": "calculate-records-deadline", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/CalculateDeadlinePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "CalculateDeadlineCommand" + }, + "CalculateDeadlinePayload": { + "properties": { + "deadlineReceivedDate": { + "type": "string", + "title": "Deadlinereceiveddate" + }, + "deadlineRuleName": { + "type": "string", + "minLength": 1, + "title": "Deadlinerulename" + }, + "deadlineDayCount": { + "type": "string", + "title": "Deadlinedaycount" + }, + "deadlineDayType": { + "type": "string", + "title": "Deadlinedaytype" + }, + "deadlineBasis": { + "type": "string", + "minLength": 1, + "title": "Deadlinebasis" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "deadlineReceivedDate", + "deadlineRuleName", + "deadlineDayCount", + "deadlineDayType", + "deadlineBasis" + ], + "title": "CalculateDeadlinePayload" + }, + "ChapterCreate": { + "properties": { + "chapter_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Chapter Id" + }, + "title_id": { + "type": "string", + "minLength": 1, + "title": "Title Id" + }, + "chapter_number": { + "type": "string", + "minLength": 1, + "title": "Chapter Number" + }, + "chapter_name": { + "type": "string", + "minLength": 1, + "title": "Chapter Name" + }, + "sort_order": { + "type": "integer", + "title": "Sort Order", + "default": 0 + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title_id", + "chapter_number", + "chapter_name" + ], + "title": "ChapterCreate", + "description": "Request body for creating a code chapter." + }, + "CitedSection": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "citation": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Citation" + }, + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "version": { + "type": "string", + "maxLength": 80, + "title": "Version", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "citation" + ], + "title": "CitedSection", + "description": "One resolved public Code section; never a caller-supplied quotation." + }, + "CityProfileCreate": { + "properties": { + "city_name": { + "type": "string", + "title": "City Name" + }, + "state": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State" + }, + "county": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "County" + }, + "population_band": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Population Band" + }, + "email_platform": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Email Platform" + }, + "has_dedicated_it": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Has Dedicated It" + }, + "monthly_request_volume": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Monthly Request Volume" + }, + "profile_data": { + "additionalProperties": true, + "type": "object", + "title": "Profile Data", + "default": {} + }, + "gap_map": { + "additionalProperties": true, + "type": "object", + "title": "Gap Map", + "default": {} + } + }, + "type": "object", + "required": [ + "city_name" + ], + "title": "CityProfileCreate" + }, + "CityProfileRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "city_name": { + "type": "string", + "title": "City Name" + }, + "state": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State" + }, + "county": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "County" + }, + "population_band": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Population Band" + }, + "email_platform": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Email Platform" + }, + "has_dedicated_it": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Has Dedicated It" + }, + "monthly_request_volume": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Monthly Request Volume" + }, + "onboarding_status": { + "type": "string", + "title": "Onboarding Status" + }, + "profile_data": { + "additionalProperties": true, + "type": "object", + "title": "Profile Data" + }, + "gap_map": { + "additionalProperties": true, + "type": "object", + "title": "Gap Map" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "city_name", + "state", + "county", + "population_band", + "email_platform", + "has_dedicated_it", + "monthly_request_volume", + "onboarding_status", + "profile_data", + "gap_map", + "created_at", + "updated_at" + ], + "title": "CityProfileRead" + }, + "CityProfileUpdate": { + "properties": { + "city_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "City Name" + }, + "state": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State" + }, + "county": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "County" + }, + "population_band": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Population Band" + }, + "email_platform": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Email Platform" + }, + "has_dedicated_it": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Has Dedicated It" + }, + "monthly_request_volume": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Monthly Request Volume" + }, + "onboarding_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Onboarding Status" + }, + "profile_data": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Profile Data" + }, + "gap_map": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Gap Map" + } + }, + "type": "object", + "title": "CityProfileUpdate" + }, + "ClarificationCommand": { + "properties": { + "action": { + "type": "string", + "const": "request-records-clarification", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ClarificationPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "ClarificationCommand" + }, + "ClarificationPayload": { + "properties": { + "clarificationNote": { + "type": "string", + "minLength": 1, + "title": "Clarificationnote" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "clarificationNote" + ], + "title": "ClarificationPayload" + }, + "Closeout": { + "properties": { + "decision_id": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Decision Id" + }, + "version_id": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Version Id" + }, + "source_id": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Source Id" + }, + "version_label": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Version Label" + }, + "body": { + "type": "string", + "maxLength": 1000000, + "minLength": 1, + "title": "Body" + }, + "effective_start": { + "type": "string", + "format": "date", + "title": "Effective Start" + }, + "effective_end": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective End" + }, + "is_current": { + "type": "boolean", + "title": "Is Current" + }, + "reconciliation_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reconciliation Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "decision_id", + "version_id", + "source_id", + "version_label", + "body", + "effective_start", + "is_current" + ], + "title": "Closeout" + }, + "CodeContext": { + "properties": { + "section_number": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Section Number" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "section_number" + ], + "title": "CodeContext" + }, + "CodeLink": { + "properties": { + "provider": { + "type": "string", + "const": "code", + "title": "Provider", + "default": "code" + }, + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "CodeLink" + }, + "CodeSearch": { + "properties": { + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "CodeSearch" + }, + "CodeSourceSelection": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "CodeSourceSelection" + }, + "CompleteArtifact": { + "properties": { + "export_path": { + "type": "string", + "minLength": 1, + "title": "Export Path" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "export_path" + ], + "title": "CompleteArtifact" + }, + "ConnectionSearch": { + "properties": { + "provider": { + "type": "string", + "enum": [ + "meetings", + "zoning" + ], + "title": "Provider" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "query" + ], + "title": "ConnectionSearch" + }, + "CoverageGapResponse": { + "properties": { + "jurisdictions_without_rules": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Jurisdictions Without Rules" + }, + "departments_without_staff": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array", + "title": "Departments Without Staff" + }, + "uncovered_categories": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Uncovered Categories" + }, + "total_gaps": { + "type": "integer", + "title": "Total Gaps" + } + }, + "type": "object", + "required": [ + "jurisdictions_without_rules", + "departments_without_staff", + "uncovered_categories", + "total_gaps" + ], + "title": "CoverageGapResponse" + }, + "DataSourceAdminRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "source_type": { + "$ref": "#/components/schemas/SourceType" + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "type": "boolean", + "title": "Schedule Enabled", + "default": true + }, + "next_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Next Sync At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "last_ingestion_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Ingestion At" + }, + "last_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Sync At" + }, + "last_sync_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Sync Status" + }, + "last_error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Error Message" + }, + "consecutive_failure_count": { + "type": "integer", + "title": "Consecutive Failure Count", + "default": 0 + }, + "sync_paused": { + "type": "boolean", + "title": "Sync Paused", + "default": false + }, + "health_status": { + "type": "string", + "title": "Health Status", + "default": "healthy" + }, + "active_failure_count": { + "type": "integer", + "title": "Active Failure Count", + "default": 0 + }, + "connector_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Connector Type" + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At" + }, + "connection_config": { + "additionalProperties": true, + "type": "object", + "title": "Connection Config" + } + }, + "type": "object", + "required": [ + "id", + "name", + "source_type", + "is_active", + "created_by", + "created_at", + "last_ingestion_at", + "connection_config" + ], + "title": "DataSourceAdminRead", + "description": "Full datasource shape including connection_config. Returned only by admin-gated endpoints." + }, + "DataSourceCreate": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "source_type": { + "$ref": "#/components/schemas/SourceType" + }, + "connection_config": { + "additionalProperties": true, + "type": "object", + "title": "Connection Config", + "default": {} + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "type": "boolean", + "title": "Schedule Enabled", + "default": true + } + }, + "type": "object", + "required": [ + "name", + "source_type" + ], + "title": "DataSourceCreate" + }, + "DataSourceRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "source_type": { + "$ref": "#/components/schemas/SourceType" + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "type": "boolean", + "title": "Schedule Enabled", + "default": true + }, + "next_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Next Sync At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "last_ingestion_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Ingestion At" + }, + "last_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Sync At" + }, + "last_sync_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Sync Status" + }, + "last_error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Error Message" + }, + "consecutive_failure_count": { + "type": "integer", + "title": "Consecutive Failure Count", + "default": 0 + }, + "sync_paused": { + "type": "boolean", + "title": "Sync Paused", + "default": false + }, + "health_status": { + "type": "string", + "title": "Health Status", + "default": "healthy" + }, + "active_failure_count": { + "type": "integer", + "title": "Active Failure Count", + "default": 0 + }, + "connector_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Connector Type" + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "name", + "source_type", + "is_active", + "created_by", + "created_at", + "last_ingestion_at" + ], + "title": "DataSourceRead", + "description": "Redacted datasource shape — safe for non-admin roles. connection_config omitted." + }, + "DataSourceUpdate": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "connection_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Connection Config" + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Schedule Enabled" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "DataSourceUpdate" + }, + "DeadlineCommand": { + "properties": { + "action": { + "type": "string", + "const": "set-records-deadline", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/DeadlinePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "DeadlineCommand" + }, + "DeadlinePayload": { + "properties": { + "deadline": { + "type": "string", + "title": "Deadline" + }, + "deadlineBasis": { + "type": "string", + "minLength": 1, + "title": "Deadlinebasis" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "deadline", + "deadlineBasis" + ], + "title": "DeadlinePayload" + }, + "Decision": { + "properties": { + "id": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Id" + }, + "outcome": { + "type": "string", + "enum": [ + "adopted", + "not_adopted", + "deferred", + "withdrawn" + ], + "title": "Outcome" + }, + "decided_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Decided At" + }, + "decision_text": { + "type": "string", + "maxLength": 1000000, + "minLength": 1, + "title": "Decision Text" + }, + "supporting_references": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Supporting References" + }, + "supersedes_decision_id": { + "anyOf": [ + { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$" + }, + { + "type": "null" + } + ], + "title": "Supersedes Decision Id" + }, + "reconciliation_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reconciliation Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "outcome", + "decision_text" + ], + "title": "Decision" + }, + "DepartmentCreate": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "code": { + "type": "string", + "title": "Code" + }, + "contact_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Contact Email" + } + }, + "type": "object", + "required": [ + "name", + "code" + ], + "title": "DepartmentCreate" + }, + "DepartmentRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "code": { + "type": "string", + "title": "Code" + }, + "contact_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Contact Email" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "name", + "code", + "contact_email", + "created_at" + ], + "title": "DepartmentRead" + }, + "DepartmentUpdate": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Code" + }, + "contact_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Contact Email" + } + }, + "type": "object", + "title": "DepartmentUpdate" + }, + "DisclosureTemplateCreate": { + "properties": { + "template_type": { + "type": "string", + "title": "Template Type" + }, + "state_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State Code" + }, + "content": { + "type": "string", + "title": "Content" + } + }, + "type": "object", + "required": [ + "template_type", + "content" + ], + "title": "DisclosureTemplateCreate" + }, + "DisclosureTemplateRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "template_type": { + "type": "string", + "title": "Template Type" + }, + "state_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State Code" + }, + "content": { + "type": "string", + "title": "Content" + }, + "version": { + "type": "integer", + "title": "Version" + }, + "updated_by": { + "type": "string", + "format": "uuid", + "title": "Updated By" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "template_type", + "state_code", + "content", + "version", + "updated_by", + "updated_at" + ], + "title": "DisclosureTemplateRead" + }, + "DisclosureTemplateRendered": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "template_type": { + "type": "string", + "title": "Template Type" + }, + "rendered_content": { + "type": "string", + "title": "Rendered Content" + }, + "has_unresolved_variables": { + "type": "boolean", + "title": "Has Unresolved Variables" + } + }, + "type": "object", + "required": [ + "id", + "template_type", + "rendered_content", + "has_unresolved_variables" + ], + "title": "DisclosureTemplateRendered" + }, + "DisclosureTemplateUpdate": { + "properties": { + "content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Content" + }, + "state_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State Code" + } + }, + "type": "object", + "title": "DisclosureTemplateUpdate" + }, + "DocumentChunkRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "chunk_index": { + "type": "integer", + "title": "Chunk Index" + }, + "content_text": { + "type": "string", + "title": "Content Text" + }, + "token_count": { + "type": "integer", + "title": "Token Count" + }, + "page_number": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Page Number" + } + }, + "type": "object", + "required": [ + "id", + "document_id", + "chunk_index", + "content_text", + "token_count", + "page_number" + ], + "title": "DocumentChunkRead" + }, + "DocumentRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "source_id": { + "type": "string", + "format": "uuid", + "title": "Source Id" + }, + "source_path": { + "type": "string", + "title": "Source Path" + }, + "filename": { + "type": "string", + "title": "Filename" + }, + "file_type": { + "type": "string", + "title": "File Type" + }, + "file_hash": { + "type": "string", + "title": "File Hash" + }, + "file_size": { + "type": "integer", + "title": "File Size" + }, + "ingestion_status": { + "$ref": "#/components/schemas/IngestionStatus" + }, + "ingestion_error": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Ingestion Error" + }, + "chunk_count": { + "type": "integer", + "title": "Chunk Count" + }, + "ingested_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Ingested At" + }, + "connector_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Connector Type" + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "source_id", + "source_path", + "filename", + "file_type", + "file_hash", + "file_size", + "ingestion_status", + "ingestion_error", + "chunk_count", + "ingested_at" + ], + "title": "DocumentRead" + }, + "DraftCommand": { + "properties": { + "action": { + "type": "string", + "const": "draft-records-response", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/DraftPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "DraftCommand" + }, + "DraftInput": { + "properties": { + "source_materials": { + "items": { + "$ref": "#/components/schemas/SourceInput" + }, + "type": "array", + "title": "Source Materials" + }, + "sentences": { + "items": { + "$ref": "#/components/schemas/SentenceInput" + }, + "type": "array", + "minItems": 1, + "title": "Sentences" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sentences" + ], + "title": "DraftInput" + }, + "DraftPayload": { + "properties": { + "responseDraft": { + "type": "string", + "minLength": 1, + "title": "Responsedraft" + }, + "citation": { + "type": "string", + "title": "Citation", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "responseDraft" + ], + "title": "DraftPayload" + }, + "ErrorModel": { + "properties": { + "detail": { + "anyOf": [ + { + "type": "string" + }, + { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + ], + "title": "Detail" + } + }, + "type": "object", + "required": [ + "detail" + ], + "title": "ErrorModel" + }, + "Evidence": { + "properties": { + "filename": { + "type": "string", + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$", + "title": "Filename" + }, + "description": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Description" + }, + "media_type": { + "type": "string", + "enum": [ + "text/plain", + "image/jpeg", + "image/png", + "image/webp", + "application/pdf", + "audio/webm", + "audio/ogg", + "audio/wav", + "audio/mpeg", + "audio/mp4" + ], + "title": "Media Type" + }, + "content_base64": { + "type": "string", + "maxLength": 14000000, + "minLength": 1, + "title": "Content Base64" + }, + "sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "filename", + "description", + "media_type", + "content_base64", + "sha256" + ], + "title": "Evidence" + }, + "EvidenceItem": { + "properties": { + "filename": { + "type": "string", + "maxLength": 151, + "minLength": 1, + "title": "Filename" + }, + "media_type": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Media Type" + }, + "description": { + "type": "string", + "maxLength": 2000, + "title": "Description", + "default": "" + }, + "content_base64": { + "type": "string", + "maxLength": 14000000, + "minLength": 1, + "title": "Content Base64" + }, + "sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "filename", + "media_type", + "content_base64", + "sha256" + ], + "title": "EvidenceItem" + }, + "EvidenceItems": { + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/EvidenceItem" + }, + "type": "array", + "maxItems": 10, + "minItems": 1, + "title": "Items" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "items" + ], + "title": "EvidenceItems" + }, + "ExemptionAccuracyReport": { + "properties": { + "category": { + "type": "string", + "title": "Category" + }, + "total_flags": { + "type": "integer", + "title": "Total Flags" + }, + "accepted": { + "type": "integer", + "title": "Accepted" + }, + "rejected": { + "type": "integer", + "title": "Rejected" + }, + "pending": { + "type": "integer", + "title": "Pending" + }, + "acceptance_rate": { + "type": "number", + "title": "Acceptance Rate" + } + }, + "type": "object", + "required": [ + "category", + "total_flags", + "accepted", + "rejected", + "pending", + "acceptance_rate" + ], + "title": "ExemptionAccuracyReport" + }, + "ExemptionDashboard": { + "properties": { + "total_flags": { + "type": "integer", + "title": "Total Flags" + }, + "by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "By Status" + }, + "by_category": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "By Category" + }, + "acceptance_rate": { + "type": "number", + "title": "Acceptance Rate" + }, + "total_rules": { + "type": "integer", + "title": "Total Rules" + }, + "active_rules": { + "type": "integer", + "title": "Active Rules" + } + }, + "type": "object", + "required": [ + "total_flags", + "by_status", + "by_category", + "acceptance_rate", + "total_rules", + "active_rules" + ], + "title": "ExemptionDashboard" + }, + "ExemptionDecisionCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-exemption-decision", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ExemptionDecisionPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "ExemptionDecisionCommand" + }, + "ExemptionDecisionPayload": { + "properties": { + "exemptionSource": { + "type": "string", + "minLength": 1, + "title": "Exemptionsource" + }, + "exemptionKind": { + "type": "string", + "minLength": 1, + "title": "Exemptionkind" + }, + "exemptionFinding": { + "type": "string", + "minLength": 1, + "title": "Exemptionfinding" + }, + "exemptionDecision": { + "type": "string", + "enum": [ + "release", + "redact", + "exempt" + ], + "title": "Exemptiondecision" + }, + "exemptionBasis": { + "type": "string", + "minLength": 1, + "title": "Exemptionbasis" + }, + "exemptionReviewer": { + "type": "string", + "title": "Exemptionreviewer", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "exemptionSource", + "exemptionKind", + "exemptionFinding", + "exemptionDecision", + "exemptionBasis" + ], + "title": "ExemptionDecisionPayload" + }, + "ExemptionDecisionView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "source": { + "type": "string", + "title": "Source" + }, + "kind": { + "type": "string", + "title": "Kind" + }, + "finding": { + "type": "string", + "title": "Finding" + }, + "decision": { + "type": "string", + "enum": [ + "release", + "redact", + "exempt" + ], + "title": "Decision" + }, + "basis": { + "type": "string", + "title": "Basis" + }, + "reviewer": { + "type": "string", + "title": "Reviewer" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "source", + "kind", + "finding", + "decision", + "basis", + "reviewer", + "created_at_unix_seconds" + ], + "title": "ExemptionDecisionView" + }, + "ExemptionFlagRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "chunk_id": { + "type": "string", + "format": "uuid", + "title": "Chunk Id" + }, + "rule_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Rule Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "category": { + "type": "string", + "title": "Category" + }, + "matched_text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Matched Text" + }, + "confidence": { + "type": "number", + "title": "Confidence" + }, + "status": { + "$ref": "#/components/schemas/FlagStatus" + }, + "reviewed_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Reviewed By" + }, + "reviewed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Reviewed At" + }, + "review_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Reason" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "chunk_id", + "rule_id", + "request_id", + "category", + "matched_text", + "confidence", + "status", + "reviewed_by", + "reviewed_at", + "review_reason", + "created_at" + ], + "title": "ExemptionFlagRead" + }, + "ExemptionFlagReview": { + "properties": { + "status": { + "$ref": "#/components/schemas/FlagStatus" + }, + "review_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Reason" + } + }, + "type": "object", + "required": [ + "status" + ], + "title": "ExemptionFlagReview" + }, + "ExemptionNoteCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-exemption-review", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ExemptionNotePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "ExemptionNoteCommand" + }, + "ExemptionNotePayload": { + "properties": { + "exemptionNote": { + "type": "string", + "minLength": 1, + "title": "Exemptionnote" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "exemptionNote" + ], + "title": "ExemptionNotePayload" + }, + "ExemptionRuleCreate": { + "properties": { + "state_code": { + "type": "string", + "title": "State Code" + }, + "category": { + "type": "string", + "title": "Category" + }, + "rule_type": { + "$ref": "#/components/schemas/RuleType" + }, + "rule_definition": { + "type": "string", + "title": "Rule Definition" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "enabled": { + "type": "boolean", + "title": "Enabled", + "default": true + } + }, + "type": "object", + "required": [ + "state_code", + "category", + "rule_type", + "rule_definition" + ], + "title": "ExemptionRuleCreate" + }, + "ExemptionRuleRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "state_code": { + "type": "string", + "title": "State Code" + }, + "category": { + "type": "string", + "title": "Category" + }, + "rule_type": { + "$ref": "#/components/schemas/RuleType" + }, + "rule_definition": { + "type": "string", + "title": "Rule Definition" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "enabled": { + "type": "boolean", + "title": "Enabled" + }, + "version": { + "type": "integer", + "title": "Version", + "default": 1 + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "state_code", + "category", + "rule_type", + "rule_definition", + "description", + "enabled", + "created_by", + "created_at" + ], + "title": "ExemptionRuleRead" + }, + "ExemptionRuleUpdate": { + "properties": { + "rule_definition": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Rule Definition" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "enabled": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Enabled" + } + }, + "type": "object", + "title": "ExemptionRuleUpdate" + }, + "ExportReceipt": { + "properties": { + "export_path": { + "type": "string", + "maxLength": 32768, + "minLength": 1, + "title": "Export Path" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "export_path" + ], + "title": "ExportReceipt" + }, + "FeeEstimateCommand": { + "properties": { + "action": { + "type": "string", + "const": "estimate-records-fee", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/FeeEstimatePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "FeeEstimateCommand" + }, + "FeeEstimatePayload": { + "properties": { + "feeEstimate": { + "type": "string", + "minLength": 1, + "title": "Feeestimate" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "feeEstimate" + ], + "title": "FeeEstimatePayload" + }, + "FeeEstimateRequest": { + "properties": { + "page_count": { + "type": "integer", + "title": "Page Count" + }, + "fee_schedule_id": { + "type": "string", + "format": "uuid", + "title": "Fee Schedule Id" + } + }, + "type": "object", + "required": [ + "page_count", + "fee_schedule_id" + ], + "title": "FeeEstimateRequest" + }, + "FeeEstimateResponse": { + "properties": { + "page_count": { + "type": "integer", + "title": "Page Count" + }, + "unit_price": { + "type": "number", + "title": "Unit Price" + }, + "total": { + "type": "number", + "title": "Total" + }, + "fee_type": { + "type": "string", + "title": "Fee Type" + }, + "description": { + "type": "string", + "title": "Description" + } + }, + "type": "object", + "required": [ + "page_count", + "unit_price", + "total", + "fee_type", + "description" + ], + "title": "FeeEstimateResponse" + }, + "FeeLineCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-fee-line", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/FeeLinePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "FeeLineCommand" + }, + "FeeLineItemCreate": { + "properties": { + "description": { + "type": "string", + "title": "Description" + }, + "quantity": { + "type": "integer", + "title": "Quantity", + "default": 1 + }, + "unit_price": { + "type": "number", + "title": "Unit Price" + }, + "fee_schedule_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Fee Schedule Id" + } + }, + "type": "object", + "required": [ + "description", + "unit_price" + ], + "title": "FeeLineItemCreate" + }, + "FeeLineItemRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "fee_schedule_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Fee Schedule Id" + }, + "description": { + "type": "string", + "title": "Description" + }, + "quantity": { + "type": "integer", + "title": "Quantity" + }, + "unit_price": { + "type": "number", + "title": "Unit Price" + }, + "total": { + "type": "number", + "title": "Total" + }, + "status": { + "type": "string", + "title": "Status" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "fee_schedule_id", + "description", + "quantity", + "unit_price", + "total", + "status", + "created_at" + ], + "title": "FeeLineItemRead" + }, + "FeeLinePayload": { + "properties": { + "feeLineDescription": { + "type": "string", + "minLength": 1, + "title": "Feelinedescription" + }, + "feeScheduleBasis": { + "type": "string", + "minLength": 1, + "title": "Feeschedulebasis" + }, + "feeLineAmount": { + "type": "string", + "title": "Feelineamount" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "feeLineDescription", + "feeScheduleBasis", + "feeLineAmount" + ], + "title": "FeeLinePayload" + }, + "FeeLineView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "description": { + "type": "string", + "title": "Description" + }, + "schedule_basis": { + "type": "string", + "title": "Schedule Basis" + }, + "amount_cents": { + "type": "integer", + "title": "Amount Cents" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "description", + "schedule_basis", + "amount_cents", + "created_at_unix_seconds" + ], + "title": "FeeLineView" + }, + "FeeScheduleCreate": { + "properties": { + "jurisdiction": { + "type": "string", + "title": "Jurisdiction" + }, + "fee_type": { + "type": "string", + "title": "Fee Type" + }, + "amount": { + "type": "number", + "title": "Amount" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "effective_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective Date" + } + }, + "type": "object", + "required": [ + "jurisdiction", + "fee_type", + "amount" + ], + "title": "FeeScheduleCreate" + }, + "FeeScheduleRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "jurisdiction": { + "type": "string", + "title": "Jurisdiction" + }, + "fee_type": { + "type": "string", + "title": "Fee Type" + }, + "amount": { + "type": "number", + "title": "Amount" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "effective_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective Date" + }, + "created_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "jurisdiction", + "fee_type", + "amount", + "description", + "effective_date", + "created_by", + "created_at" + ], + "title": "FeeScheduleRead" + }, + "FeeScheduleUpdate": { + "properties": { + "fee_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Fee Type" + }, + "amount": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Amount" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "effective_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective Date" + } + }, + "type": "object", + "title": "FeeScheduleUpdate" + }, + "FeeWaiverCommand": { + "properties": { + "action": { + "type": "string", + "const": "waive-records-fee", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/FeeWaiverPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "FeeWaiverCommand" + }, + "FeeWaiverCreateRequest": { + "properties": { + "waiver_type": { + "type": "string", + "title": "Waiver Type" + }, + "reason": { + "type": "string", + "title": "Reason" + } + }, + "type": "object", + "required": [ + "waiver_type", + "reason" + ], + "title": "FeeWaiverCreateRequest" + }, + "FeeWaiverPayload": { + "properties": { + "feeWaiverReason": { + "type": "string", + "minLength": 1, + "title": "Feewaiverreason" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "feeWaiverReason" + ], + "title": "FeeWaiverPayload" + }, + "FeeWaiverReadResponse": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "waiver_type": { + "type": "string", + "title": "Waiver Type" + }, + "reason": { + "type": "string", + "title": "Reason" + }, + "status": { + "type": "string", + "title": "Status" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + }, + "created_at": { + "type": "string", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "waiver_type", + "reason", + "status", + "created_at" + ], + "title": "FeeWaiverReadResponse" + }, + "FeeWaiverReviewRequest": { + "properties": { + "status": { + "type": "string", + "title": "Status" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + } + }, + "type": "object", + "required": [ + "status" + ], + "title": "FeeWaiverReviewRequest" + }, + "FinishCommand": { + "properties": { + "action": { + "type": "string", + "enum": [ + "fulfill-records-request", + "close-records-request" + ], + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/NativePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "FinishCommand" + }, + "FlagStatus": { + "type": "string", + "enum": [ + "flagged", + "reviewed", + "accepted", + "rejected" + ], + "title": "FlagStatus" + }, + "FormPlan": { + "properties": { + "action": { + "type": "string", + "const": "form-plan", + "title": "Action" + }, + "formName": { + "type": "string", + "maxLength": 500, + "title": "Formname", + "default": "" + }, + "fields": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 50, + "title": "Fields" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "FormPlan" + }, + "GeneratedDraft": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "model": { + "type": "string", + "minLength": 1, + "title": "Model" + }, + "previous_response_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Previous Response Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text", + "model", + "previous_response_sha256" + ], + "title": "GeneratedDraft" + }, + "HTTPValidationError": { + "properties": { + "detail": { + "items": { + "$ref": "#/components/schemas/ValidationError" + }, + "type": "array", + "title": "Detail" + } + }, + "type": "object", + "title": "HTTPValidationError" + }, + "Handoff": { + "properties": { + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "request_id" + ], + "title": "Handoff" + }, + "ImportBundleCreate": { + "properties": { + "job_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Job Id" + }, + "connector_type": { + "type": "string", + "minLength": 1, + "title": "Connector Type" + }, + "source": { + "$ref": "#/components/schemas/SourceCreate" + }, + "sources": { + "items": { + "$ref": "#/components/schemas/SourceCreate" + }, + "type": "array", + "title": "Sources" + }, + "titles": { + "items": { + "$ref": "#/components/schemas/TitleCreate" + }, + "type": "array", + "title": "Titles" + }, + "chapters": { + "items": { + "$ref": "#/components/schemas/ChapterCreate" + }, + "type": "array", + "title": "Chapters" + }, + "sections": { + "items": { + "$ref": "#/components/schemas/SectionCreate" + }, + "type": "array", + "title": "Sections" + }, + "versions": { + "items": { + "$ref": "#/components/schemas/SectionVersionCreate" + }, + "type": "array", + "title": "Versions" + }, + "provenance": { + "additionalProperties": true, + "type": "object", + "title": "Provenance" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "connector_type", + "source" + ], + "title": "ImportBundleCreate", + "description": "Request body for local fixture/file-drop import jobs." + }, + "InclusionStatus": { + "type": "string", + "enum": [ + "included", + "excluded", + "pending" + ], + "title": "InclusionStatus" + }, + "IngestionStats": { + "properties": { + "total_sources": { + "type": "integer", + "title": "Total Sources" + }, + "active_sources": { + "type": "integer", + "title": "Active Sources" + }, + "total_documents": { + "type": "integer", + "title": "Total Documents" + }, + "documents_by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Documents By Status" + }, + "total_chunks": { + "type": "integer", + "title": "Total Chunks" + } + }, + "type": "object", + "required": [ + "total_sources", + "active_sources", + "total_documents", + "documents_by_status", + "total_chunks" + ], + "title": "IngestionStats" + }, + "IngestionStatus": { + "type": "string", + "enum": [ + "pending", + "processing", + "completed", + "failed" + ], + "title": "IngestionStatus" + }, + "InitiativeInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "policy": { + "$ref": "#/components/schemas/PolicySelection" + }, + "responsible_staff": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Responsible Staff" + }, + "target": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "title": "Target" + }, + "unit": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Unit" + }, + "due_on": { + "type": "string", + "format": "date", + "title": "Due On" + }, + "status": { + "type": "string", + "enum": [ + "planned", + "active", + "completed", + "cancelled" + ], + "title": "Status", + "default": "planned" + }, + "milestones": { + "items": { + "$ref": "#/components/schemas/Milestone" + }, + "type": "array", + "maxItems": 100, + "title": "Milestones" + }, + "measurements": { + "items": { + "$ref": "#/components/schemas/Measurement" + }, + "type": "array", + "maxItems": 1000, + "title": "Measurements" + }, + "note": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "policy", + "responsible_staff", + "target", + "unit", + "due_on", + "note" + ], + "title": "InitiativeInput" + }, + "InspectionInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "property_reference": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Property Reference" + }, + "inspection_reference": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Inspection Reference" + }, + "dataset_kind": { + "type": "string", + "enum": [ + "municipal", + "fictional" + ], + "title": "Dataset Kind" + }, + "inspector_notes": { + "type": "string", + "maxLength": 10000, + "minLength": 1, + "title": "Inspector Notes" + }, + "photo_observations": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 30, + "title": "Photo Observations" + }, + "voice_notes": { + "type": "string", + "maxLength": 10000, + "title": "Voice Notes", + "default": "" + }, + "evidence": { + "items": { + "$ref": "#/components/schemas/Evidence" + }, + "type": "array", + "maxItems": 10, + "title": "Evidence" + }, + "linked_sources": { + "items": { + "$ref": "#/components/schemas/townlight_inspections__workflow_models__SourceLink" + }, + "type": "array", + "maxItems": 30, + "title": "Linked Sources" + }, + "assigned_to": { + "type": "string", + "maxLength": 255, + "title": "Assigned To", + "default": "" + }, + "staff_notes": { + "type": "string", + "maxLength": 10000, + "title": "Staff Notes", + "default": "" + }, + "notice_draft": { + "type": "string", + "maxLength": 10000, + "title": "Notice Draft", + "default": "" + }, + "review_state": { + "type": "string", + "enum": [ + "draft", + "follow_up", + "reviewed" + ], + "title": "Review State", + "default": "draft" + }, + "review_notes": { + "type": "string", + "maxLength": 4000, + "title": "Review Notes", + "default": "" + }, + "public_summary": { + "type": "string", + "maxLength": 10000, + "title": "Public Summary", + "default": "" + }, + "analysis": { + "anyOf": [ + { + "$ref": "#/components/schemas/AnalysisRecord" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "property_reference", + "inspection_reference", + "dataset_kind", + "inspector_notes" + ], + "title": "InspectionInput" + }, + "IntakeInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "project_name": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Project Name" + }, + "project_description": { + "type": "string", + "maxLength": 10000, + "minLength": 1, + "title": "Project Description" + }, + "location": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Location" + }, + "applicant_contact": { + "type": "string", + "maxLength": 2000, + "title": "Applicant Contact", + "default": "" + }, + "requirement_revision": { + "type": "string", + "format": "uuid", + "title": "Requirement Revision" + }, + "materials": { + "items": { + "$ref": "#/components/schemas/MaterialReview" + }, + "type": "array", + "maxItems": 100, + "minItems": 1, + "title": "Materials" + }, + "linked_sources": { + "items": { + "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink" + }, + "type": "array", + "maxItems": 30, + "title": "Linked Sources" + }, + "staff_notes": { + "type": "string", + "maxLength": 10000, + "title": "Staff Notes", + "default": "" + }, + "assigned_to": { + "type": "string", + "maxLength": 255, + "title": "Assigned To", + "default": "" + }, + "review_state": { + "type": "string", + "enum": [ + "draft", + "follow_up", + "reviewed" + ], + "title": "Review State", + "default": "draft" + }, + "review_notes": { + "type": "string", + "maxLength": 4000, + "title": "Review Notes", + "default": "" + }, + "public_summary": { + "type": "string", + "maxLength": 10000, + "title": "Public Summary", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "project_name", + "project_description", + "location", + "requirement_revision", + "materials" + ], + "title": "IntakeInput" + }, + "InterpretationNoteCreate": { + "properties": { + "note_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Note Id" + }, + "note_text": { + "type": "string", + "minLength": 1, + "title": "Note Text" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "note_text" + ], + "title": "InterpretationNoteCreate", + "description": "Request body for staff-only interpretation notes." + }, + "InterviewRequest": { + "properties": { + "last_answer": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Answer" + }, + "last_field": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Field" + }, + "skipped_fields": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Skipped Fields" + } + }, + "type": "object", + "title": "InterviewRequest" + }, + "InterviewResponse": { + "properties": { + "question": { + "type": "string", + "title": "Question" + }, + "target_field": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Target Field" + }, + "all_complete": { + "type": "boolean", + "title": "All Complete" + }, + "completed_fields": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Completed Fields" + }, + "onboarding_status": { + "type": "string", + "title": "Onboarding Status" + }, + "skipped_fields": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Skipped Fields" + } + }, + "type": "object", + "required": [ + "question", + "target_field", + "all_complete", + "completed_fields", + "onboarding_status", + "skipped_fields" + ], + "title": "InterviewResponse" + }, + "ManagedFileReceipt": { + "properties": { + "original_path": { + "type": "string", + "minLength": 1, + "title": "Original Path" + }, + "stored_path": { + "type": "string", + "minLength": 1, + "title": "Stored Path" + }, + "file_name": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "File Name" + }, + "sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Sha256" + }, + "size_bytes": { + "type": "integer", + "maximum": 2147483647.0, + "minimum": 0.0, + "title": "Size Bytes" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "original_path", + "stored_path", + "file_name", + "sha256", + "size_bytes" + ], + "title": "ManagedFileReceipt" + }, + "ManagedSource": { + "properties": { + "original_path": { + "type": "string", + "title": "Original Path" + }, + "stored_path": { + "type": "string", + "title": "Stored Path" + }, + "file_name": { + "type": "string", + "title": "File Name" + }, + "sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Sha256" + }, + "size_bytes": { + "type": "integer", + "minimum": 0.0, + "title": "Size Bytes" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "original_path", + "stored_path", + "file_name", + "sha256", + "size_bytes" + ], + "title": "ManagedSource" + }, + "Material": { + "properties": { + "material_id": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]{1,80}$", + "title": "Material Id" + }, + "description": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Description" + }, + "citation": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Citation" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "material_id", + "description", + "citation" + ], + "title": "Material" + }, + "MaterialReview": { + "properties": { + "material_id": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Material Id" + }, + "status": { + "type": "string", + "enum": [ + "not_reviewed", + "provided", + "missing", + "unclear" + ], + "title": "Status", + "default": "not_reviewed" + }, + "note": { + "type": "string", + "maxLength": 2000, + "title": "Note", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "material_id" + ], + "title": "MaterialReview" + }, + "Measurement": { + "properties": { + "recorded_on": { + "type": "string", + "format": "date", + "title": "Recorded On" + }, + "value": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "title": "Value" + }, + "evidence": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Evidence" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "recorded_on", + "value", + "evidence" + ], + "title": "Measurement" + }, + "MediaAnalysis": { + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/EvidenceItem" + }, + "type": "array", + "maxItems": 10, + "minItems": 1, + "title": "Items" + }, + "code_links": { + "items": { + "$ref": "#/components/schemas/CodeLink" + }, + "type": "array", + "maxItems": 30, + "title": "Code Links" + }, + "inspector_supplied_text": { + "type": "string", + "maxLength": 10000, + "title": "Inspector Supplied Text", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "items" + ], + "title": "MediaAnalysis" + }, + "MeetingInput": { + "properties": { + "title": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Title" + }, + "scheduled_start": { + "type": "string", + "format": "date-time", + "title": "Scheduled Start" + }, + "location": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Location" + }, + "meeting_type": { + "type": "string", + "enum": [ + "regular", + "special", + "emergency", + "closed_session", + "executive" + ], + "title": "Meeting Type", + "default": "regular" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "scheduled_start", + "location" + ], + "title": "MeetingInput" + }, + "MeetingLink": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + }, + "relation": { + "type": "string", + "enum": [ + "hearing", + "context", + "precedent" + ], + "title": "Relation" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256", + "relation" + ], + "title": "MeetingLink" + }, + "MeetingSearch": { + "properties": { + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "MeetingSearch" + }, + "MeetingStageInput": { + "properties": { + "to_status": { + "type": "string", + "enum": [ + "SCHEDULED", + "NOTICED", + "PACKET_POSTED", + "IN_PROGRESS", + "RECESSED", + "ADJOURNED", + "TRANSCRIPT_READY", + "MINUTES_DRAFTED", + "MINUTES_POSTED", + "MINUTES_ADOPTED", + "MINUTES_SIGNED", + "ARCHIVED", + "CANCELLED" + ], + "title": "To Status" + }, + "statutory_basis": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Statutory Basis" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "to_status" + ], + "title": "MeetingStageInput" + }, + "MeetingsSearch": { + "properties": { + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "MeetingsSearch" + }, + "MeetingsSourceSelection": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "MeetingsSourceSelection" + }, + "MessageCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-message", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/MessagePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "MessageCommand" + }, + "MessageCreate": { + "properties": { + "message_text": { + "type": "string", + "title": "Message Text" + }, + "is_internal": { + "type": "boolean", + "title": "Is Internal", + "default": false + } + }, + "type": "object", + "required": [ + "message_text" + ], + "title": "MessageCreate" + }, + "MessagePayload": { + "properties": { + "requestMessageBody": { + "type": "string", + "minLength": 1, + "title": "Requestmessagebody" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requestMessageBody" + ], + "title": "MessagePayload" + }, + "MessageRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "sender_type": { + "type": "string", + "title": "Sender Type" + }, + "sender_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Sender Id" + }, + "message_text": { + "type": "string", + "title": "Message Text" + }, + "is_internal": { + "type": "boolean", + "title": "Is Internal" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "sender_type", + "sender_id", + "message_text", + "is_internal", + "created_at" + ], + "title": "MessageRead" + }, + "MessageView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "author": { + "type": "string", + "title": "Author" + }, + "author_role": { + "type": "string", + "title": "Author Role" + }, + "body": { + "type": "string", + "title": "Body" + }, + "visibility": { + "type": "string", + "title": "Visibility" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "author", + "author_role", + "body", + "visibility", + "created_at_unix_seconds" + ], + "title": "MessageView" + }, + "Milestone": { + "properties": { + "title": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Title" + }, + "due_on": { + "type": "string", + "format": "date", + "title": "Due On" + }, + "completed_on": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Completed On" + }, + "evidence": { + "type": "string", + "maxLength": 2000, + "title": "Evidence", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "due_on" + ], + "title": "Milestone" + }, + "MinutesDecision": { + "properties": { + "action": { + "type": "string", + "enum": [ + "post", + "adopt", + "sign" + ], + "title": "Action" + }, + "note": { + "type": "string", + "title": "Note", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "MinutesDecision" + }, + "ModelRegistryCreate": { + "properties": { + "model_name": { + "type": "string", + "title": "Model Name" + }, + "model_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Version" + }, + "parameter_count": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parameter Count" + }, + "license": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License" + }, + "model_card_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Card Url" + }, + "is_active": { + "type": "boolean", + "title": "Is Active", + "default": false + }, + "context_window_size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Context Window Size" + }, + "supports_ner": { + "type": "boolean", + "title": "Supports Ner", + "default": false + }, + "supports_vision": { + "type": "boolean", + "title": "Supports Vision", + "default": false + } + }, + "type": "object", + "required": [ + "model_name" + ], + "title": "ModelRegistryCreate", + "description": "Schema for creating a new model_registry record (POST body)." + }, + "ModelRegistryRead": { + "properties": { + "id": { + "type": "integer", + "title": "Id" + }, + "model_name": { + "type": "string", + "title": "Model Name" + }, + "model_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Version" + }, + "parameter_count": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parameter Count" + }, + "license": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License" + }, + "model_card_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Card Url" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "added_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Added At" + }, + "context_window_size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Context Window Size" + }, + "supports_ner": { + "type": "boolean", + "title": "Supports Ner" + }, + "supports_vision": { + "type": "boolean", + "title": "Supports Vision" + } + }, + "type": "object", + "required": [ + "id", + "model_name", + "is_active", + "supports_ner", + "supports_vision" + ], + "title": "ModelRegistryRead", + "description": "Schema for returning a model_registry record (GET response).\n\n``from_attributes=True`` allows construction directly from an ORM instance." + }, + "ModelRegistryUpdate": { + "properties": { + "model_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Name" + }, + "model_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Version" + }, + "parameter_count": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parameter Count" + }, + "license": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License" + }, + "model_card_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Card Url" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + }, + "context_window_size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Context Window Size" + }, + "supports_ner": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Supports Ner" + }, + "supports_vision": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Supports Vision" + } + }, + "type": "object", + "title": "ModelRegistryUpdate", + "description": "Schema for partially updating a model_registry record (PATCH body).\n\nEvery field is optional so callers can send only the fields they want to\nchange." + }, + "MotionCorrection": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "reason": { + "type": "string", + "minLength": 1, + "title": "Reason" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text", + "reason" + ], + "title": "MotionCorrection" + }, + "MotionInput": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "seconded_by": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Seconded By" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text" + ], + "title": "MotionInput" + }, + "NativePayload": { + "properties": {}, + "additionalProperties": false, + "type": "object", + "title": "NativePayload" + }, + "NativeRequestRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "requester_name": { + "type": "string", + "title": "Requester Name" + }, + "requester_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Email" + }, + "requester_phone": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Phone" + }, + "requester_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Type" + }, + "date_received": { + "type": "string", + "format": "date-time", + "title": "Date Received" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "description": { + "type": "string", + "title": "Description" + }, + "status": { + "$ref": "#/components/schemas/RequestStatus" + }, + "assigned_to": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "created_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "response_draft": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Response Draft" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + }, + "estimated_fee": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Estimated Fee" + }, + "fee_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Fee Status" + }, + "fee_waiver_requested": { + "type": "boolean", + "title": "Fee Waiver Requested", + "default": false + }, + "priority": { + "type": "string", + "title": "Priority", + "default": "normal" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + }, + "closed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Closed At" + }, + "closure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Closure Reason" + }, + "desktop_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Desktop Id" + }, + "public_tracking_number": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Public Tracking Number" + }, + "submitted_via": { + "type": "string", + "title": "Submitted Via" + }, + "deadline_label": { + "type": "string", + "title": "Deadline Label" + }, + "deadline_basis": { + "type": "string", + "title": "Deadline Basis" + }, + "deadline_reviewed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Deadline Reviewed At" + } + }, + "type": "object", + "required": [ + "id", + "requester_name", + "requester_email", + "date_received", + "statutory_deadline", + "description", + "status", + "assigned_to", + "created_by", + "created_at", + "response_draft", + "review_notes", + "desktop_id", + "public_tracking_number", + "submitted_via", + "deadline_label", + "deadline_basis", + "deadline_reviewed_at" + ], + "title": "NativeRequestRead" + }, + "NoticeDocumentInput": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text" + ], + "title": "NoticeDocumentInput" + }, + "NoticeDraft": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "body": { + "type": "string", + "maxLength": 100000, + "minLength": 1, + "title": "Body" + }, + "notice_type": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Notice Type" + }, + "statutory_basis": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Statutory Basis" + }, + "event_date": { + "type": "string", + "format": "date", + "title": "Event Date" + }, + "lead_days": { + "type": "integer", + "maximum": 365.0, + "minimum": 0.0, + "title": "Lead Days" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "body", + "notice_type", + "statutory_basis", + "event_date", + "lead_days" + ], + "title": "NoticeDraft" + }, + "NoticeInput": { + "properties": { + "notice_type": { + "type": "string", + "enum": [ + "regular", + "special", + "emergency", + "closed_session", + "executive" + ], + "title": "Notice Type" + }, + "posted_at": { + "type": "string", + "format": "date-time", + "title": "Posted At" + }, + "minimum_notice_hours": { + "type": "integer", + "minimum": 0.0, + "title": "Minimum Notice Hours" + }, + "statutory_basis": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Statutory Basis" + }, + "approved_by": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Approved By" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "notice_type", + "posted_at", + "minimum_notice_hours" + ], + "title": "NoticeInput" + }, + "NoticeProofInput": { + "properties": { + "location": { + "type": "string", + "minLength": 1, + "title": "Location" + }, + "note": { + "type": "string", + "title": "Note", + "default": "" + }, + "document_delivery_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Document Delivery Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "location" + ], + "title": "NoticeProofInput" + }, + "NotificationLogRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "template_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Template Id" + }, + "recipient_email": { + "type": "string", + "title": "Recipient Email" + }, + "request_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Request Id" + }, + "channel": { + "type": "string", + "title": "Channel" + }, + "status": { + "type": "string", + "title": "Status" + }, + "sent_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Sent At" + }, + "error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Message" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "template_id", + "recipient_email", + "request_id", + "channel", + "status", + "sent_at", + "error_message", + "created_at" + ], + "title": "NotificationLogRead" + }, + "NotificationTemplateCreate": { + "properties": { + "event_type": { + "type": "string", + "title": "Event Type" + }, + "channel": { + "type": "string", + "title": "Channel", + "default": "email" + }, + "subject_template": { + "type": "string", + "title": "Subject Template" + }, + "body_template": { + "type": "string", + "title": "Body Template" + } + }, + "type": "object", + "required": [ + "event_type", + "subject_template", + "body_template" + ], + "title": "NotificationTemplateCreate" + }, + "NotificationTemplateRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "event_type": { + "type": "string", + "title": "Event Type" + }, + "channel": { + "type": "string", + "title": "Channel" + }, + "subject_template": { + "type": "string", + "title": "Subject Template" + }, + "body_template": { + "type": "string", + "title": "Body Template" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "event_type", + "channel", + "subject_template", + "body_template", + "is_active", + "created_at" + ], + "title": "NotificationTemplateRead" + }, + "NotificationTemplateUpdate": { + "properties": { + "subject_template": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Subject Template" + }, + "body_template": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Body Template" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "NotificationTemplateUpdate" + }, + "NotificationView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "notification_id": { + "type": "string", + "title": "Notification Id" + }, + "module_id": { + "type": "string", + "title": "Module Id" + }, + "record_id": { + "type": "string", + "title": "Record Id" + }, + "audience": { + "type": "string", + "title": "Audience" + }, + "channel": { + "type": "string", + "title": "Channel" + }, + "subject": { + "type": "string", + "title": "Subject" + }, + "body": { + "type": "string", + "title": "Body" + }, + "status": { + "type": "string", + "title": "Status" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + }, + "sent_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Sent At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "notification_id", + "module_id", + "record_id", + "audience", + "channel", + "subject", + "body", + "status", + "created_at_unix_seconds", + "sent_at_unix_seconds" + ], + "title": "NotificationView" + }, + "OllamaModelInfo": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Size" + }, + "details": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Details" + } + }, + "type": "object", + "required": [ + "name" + ], + "title": "OllamaModelInfo" + }, + "OllamaStatus": { + "properties": { + "status": { + "type": "string", + "title": "Status" + }, + "models": { + "items": { + "$ref": "#/components/schemas/OllamaModelInfo" + }, + "type": "array", + "title": "Models" + } + }, + "type": "object", + "required": [ + "status", + "models" + ], + "title": "OllamaStatus" + }, + "OperationalMetrics": { + "properties": { + "average_response_time_days": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Average Response Time Days" + }, + "median_response_time_days": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Median Response Time Days" + }, + "requests_by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Requests By Status" + }, + "requests_by_department": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Requests By Department" + }, + "deadline_compliance_rate": { + "type": "number", + "title": "Deadline Compliance Rate" + }, + "total_open": { + "type": "integer", + "title": "Total Open" + }, + "total_closed": { + "type": "integer", + "title": "Total Closed" + }, + "total_overdue": { + "type": "integer", + "title": "Total Overdue" + }, + "clarification_frequency": { + "type": "number", + "title": "Clarification Frequency" + }, + "top_request_topics": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Top Request Topics" + } + }, + "type": "object", + "required": [ + "average_response_time_days", + "median_response_time_days", + "requests_by_status", + "requests_by_department", + "deadline_compliance_rate", + "total_open", + "total_closed", + "total_overdue", + "clarification_frequency", + "top_request_topics" + ], + "title": "OperationalMetrics" + }, + "Outline": { + "properties": { + "title": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Title" + }, + "question_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "maxItems": 50, + "minItems": 1, + "title": "Question Ids" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "question_ids" + ], + "title": "Outline" + }, + "Packet": { + "properties": { + "expected_revision": { + "type": "string", + "format": "uuid", + "title": "Expected Revision" + }, + "visibility": { + "type": "string", + "enum": [ + "staff_only", + "records_copy" + ], + "title": "Visibility" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "expected_revision", + "visibility" + ], + "title": "Packet" + }, + "PacketInput": { + "properties": { + "agenda_item_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "title": "Agenda Item Ids" + }, + "source_files": { + "items": { + "$ref": "#/components/schemas/ManagedSource" + }, + "type": "array", + "title": "Source Files" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "agenda_item_ids" + ], + "title": "PacketInput" + }, + "Pathway": { + "properties": { + "project_type": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Project Type" + }, + "proposal": { + "type": "string", + "maxLength": 4000, + "title": "Proposal", + "default": "" + }, + "location_context": { + "type": "string", + "maxLength": 1000, + "title": "Location Context", + "default": "" + }, + "requirement_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Requirement Revision" + }, + "fee_link": { + "anyOf": [ + { + "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "project_type" + ], + "title": "Pathway" + }, + "PathwayStep": { + "properties": { + "step": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Step" + }, + "citation": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Citation" + }, + "typical_time": { + "type": "string", + "maxLength": 1000, + "title": "Typical Time", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "step", + "citation" + ], + "title": "PathwayStep" + }, + "PlainLanguageSummaryCreate": { + "properties": { + "summary_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Summary Id" + }, + "section_version_id": { + "type": "string", + "minLength": 1, + "title": "Section Version Id" + }, + "summary_text": { + "type": "string", + "minLength": 1, + "title": "Summary Text" + }, + "language_code": { + "type": "string", + "title": "Language Code", + "default": "en" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "section_version_id", + "summary_text" + ], + "title": "PlainLanguageSummaryCreate", + "description": "Request body for staff-drafted plain-language summaries." + }, + "PolicySelection": { + "properties": { + "plan_id": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Plan Id" + }, + "revision_id": { + "type": "string", + "maxLength": 36, + "minLength": 36, + "title": "Revision Id" + }, + "policy_id": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Policy Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "plan_id", + "revision_id", + "policy_id" + ], + "title": "PolicySelection" + }, + "PortalModeResponse": { + "properties": { + "mode": { + "type": "string", + "enum": [ + "public", + "private" + ], + "title": "Mode", + "description": "Active portal posture for this deployment. ``public`` = minimal resident surface (landing + authenticated records-request submission + resident registration) reachable without staff auth. ``private`` = staff-only; no public routes, no resident self-registration." + } + }, + "type": "object", + "required": [ + "mode" + ], + "title": "PortalModeResponse", + "description": "T5D — schema for ``GET /config/portal-mode``.\n\nExposed to the frontend on boot so it can branch routing without a\nuser-identity lookup. The payload is intentionally the single field\nbelow — no staff config, no user state, no schema version." + }, + "PrepareArtifact": { + "properties": { + "kind": { + "type": "string", + "enum": [ + "response", + "release-package" + ], + "title": "Kind" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "kind" + ], + "title": "PrepareArtifact" + }, + "Proof": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + }, + "filename": { + "type": "string", + "maxLength": 150, + "minLength": 1, + "title": "Filename" + }, + "content_base64": { + "type": "string", + "maxLength": 7000000, + "minLength": 1, + "title": "Content Base64" + }, + "location": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Location" + }, + "published_at": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Published At" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence", + "filename", + "content_base64", + "location", + "published_at" + ], + "title": "Proof" + }, + "Proposal": { + "properties": { + "id": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Id" + }, + "version_id": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Version Id" + }, + "meeting_id": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "ordinance_number": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Ordinance Number" + }, + "proposed_text": { + "type": "string", + "maxLength": 1000000, + "minLength": 1, + "title": "Proposed Text" + }, + "supersedes_id": { + "anyOf": [ + { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$" + }, + { + "type": "null" + } + ], + "title": "Supersedes Id" + }, + "reconciliation_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reconciliation Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "version_id", + "meeting_id", + "title", + "ordinance_number", + "proposed_text" + ], + "title": "Proposal" + }, + "PublicExplore": { + "properties": { + "goal": { + "type": "string", + "maxLength": 500, + "title": "Goal", + "default": "" + }, + "topic": { + "type": "string", + "maxLength": 160, + "title": "Topic", + "default": "" + }, + "neighborhood": { + "type": "string", + "maxLength": 255, + "title": "Neighborhood", + "default": "" + }, + "plan_type": { + "type": "string", + "maxLength": 120, + "title": "Plan Type", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "title": "PublicExplore" + }, + "PublicIntake": { + "properties": { + "requester": { + "type": "string", + "minLength": 1, + "title": "Requester" + }, + "requesterContact": { + "type": "string", + "minLength": 1, + "title": "Requestercontact" + }, + "summary": { + "type": "string", + "minLength": 1, + "title": "Summary" + }, + "deadline": { + "type": "string", + "title": "Deadline", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requester", + "requesterContact", + "summary" + ], + "title": "PublicIntake" + }, + "PublicLookup": { + "properties": { + "trackingNumber": { + "type": "string", + "minLength": 1, + "title": "Trackingnumber" + }, + "requesterContact": { + "type": "string", + "minLength": 1, + "title": "Requestercontact" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "trackingNumber", + "requesterContact" + ], + "title": "PublicLookup" + }, + "PublicMessage": { + "properties": { + "trackingNumber": { + "type": "string", + "minLength": 1, + "title": "Trackingnumber" + }, + "requesterContact": { + "type": "string", + "minLength": 1, + "title": "Requestercontact" + }, + "publicRequestMessage": { + "type": "string", + "minLength": 1, + "title": "Publicrequestmessage" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "trackingNumber", + "requesterContact", + "publicRequestMessage" + ], + "title": "PublicMessage" + }, + "PublicStatusView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "label": { + "type": "string", + "title": "Label" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "status": { + "type": "string", + "title": "Status" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "label", + "summary", + "status", + "created_at_unix_seconds" + ], + "title": "PublicStatusView" + }, + "PublicationView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "source_module": { + "type": "string", + "title": "Source Module" + }, + "source_record_id": { + "type": "string", + "title": "Source Record Id" + }, + "record_type": { + "type": "string", + "title": "Record Type" + }, + "public_payload": { + "type": "string", + "title": "Public Payload" + }, + "payload_hash": { + "type": "string", + "title": "Payload Hash" + }, + "published_at_unix_seconds": { + "type": "integer", + "title": "Published At Unix Seconds" + }, + "retracted_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Retracted At Unix Seconds" + }, + "retracted_by": { + "type": "string", + "title": "Retracted By", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "source_module", + "source_record_id", + "record_type", + "public_payload", + "payload_hash", + "published_at_unix_seconds" + ], + "title": "PublicationView" + }, + "PublishingPlan": { + "properties": { + "action": { + "type": "string", + "const": "publishing-workflow", + "title": "Action" + }, + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "hasReview": { + "type": "boolean", + "title": "Hasreview", + "default": false + }, + "hasPlainLanguage": { + "type": "boolean", + "title": "Hasplainlanguage", + "default": false + }, + "hasTranslationReview": { + "type": "boolean", + "title": "Hastranslationreview", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "PublishingPlan" + }, + "Question": { + "properties": { + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + }, + "question": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Question" + }, + "kind": { + "type": "string", + "enum": [ + "use", + "dimension" + ], + "title": "Kind" + }, + "key": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Key" + }, + "audience": { + "type": "string", + "enum": [ + "resident", + "staff" + ], + "title": "Audience", + "default": "resident" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "jurisdiction", + "query", + "question", + "kind", + "key" + ], + "title": "Question" + }, + "QuestionAnswerRequest": { + "properties": { + "question": { + "type": "string", + "minLength": 1, + "title": "Question" + }, + "section_number": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Section Number" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "question" + ], + "title": "QuestionAnswerRequest", + "description": "Request body for citation-grounded code Q&A." + }, + "RecordsDocumentView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "attachment_id": { + "type": "string", + "title": "Attachment Id" + }, + "title": { + "type": "string", + "title": "Title" + }, + "original_path": { + "type": "string", + "title": "Original Path" + }, + "stored_path": { + "type": "string", + "title": "Stored Path" + }, + "citation": { + "type": "string", + "title": "Citation" + }, + "sha256": { + "type": "string", + "title": "Sha256" + }, + "size_bytes": { + "type": "integer", + "title": "Size Bytes" + }, + "status": { + "type": "string", + "title": "Status" + }, + "added_by": { + "type": "string", + "title": "Added By" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + }, + "release_original_path": { + "type": "string", + "title": "Release Original Path", + "default": "" + }, + "release_stored_path": { + "type": "string", + "title": "Release Stored Path", + "default": "" + }, + "release_file_name": { + "type": "string", + "title": "Release File Name", + "default": "" + }, + "release_sha256": { + "type": "string", + "title": "Release Sha256", + "default": "" + }, + "release_size_bytes": { + "type": "integer", + "title": "Release Size Bytes", + "default": 0 + }, + "release_status": { + "type": "string", + "title": "Release Status", + "default": "" + }, + "release_note": { + "type": "string", + "title": "Release Note", + "default": "" + }, + "release_added_by": { + "type": "string", + "title": "Release Added By", + "default": "" + }, + "release_added_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Release Added At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "attachment_id", + "title", + "original_path", + "stored_path", + "citation", + "sha256", + "size_bytes", + "status", + "added_by", + "created_at_unix_seconds" + ], + "title": "RecordsDocumentView" + }, + "RecordsOperationRead": { + "properties": { + "action": { + "type": "string", + "title": "Action" + }, + "message": { + "type": "string", + "title": "Message" + }, + "request": { + "$ref": "#/components/schemas/RecordsView" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "message", + "request" + ], + "title": "RecordsOperationRead" + }, + "RecordsStateRead": { + "properties": { + "demo_fixture": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Demo Fixture" + }, + "records_requests": { + "items": { + "$ref": "#/components/schemas/RecordsView" + }, + "type": "array", + "title": "Records Requests" + }, + "notification_events": { + "items": { + "$ref": "#/components/schemas/NotificationView" + }, + "type": "array", + "title": "Notification Events" + }, + "publication_events": { + "items": { + "$ref": "#/components/schemas/PublicationView" + }, + "type": "array", + "title": "Publication Events" + }, + "audit_entries": { + "items": { + "$ref": "#/components/schemas/AuditView" + }, + "type": "array", + "title": "Audit Entries" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "records_requests" + ], + "title": "RecordsStateRead" + }, + "RecordsView": { + "properties": { + "request_id": { + "type": "string", + "title": "Request Id" + }, + "id": { + "type": "string", + "title": "Id" + }, + "public_tracking_number": { + "type": "string", + "title": "Public Tracking Number" + }, + "requester": { + "type": "string", + "title": "Requester" + }, + "requester_contact": { + "type": "string", + "title": "Requester Contact" + }, + "submitted_via": { + "type": "string", + "title": "Submitted Via" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "deadline": { + "type": "string", + "title": "Deadline" + }, + "deadline_basis": { + "type": "string", + "title": "Deadline Basis" + }, + "status": { + "type": "string", + "title": "Status" + }, + "assigned_to": { + "type": "string", + "title": "Assigned To" + }, + "clarification_notes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Clarification Notes" + }, + "search_notes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Search Notes" + }, + "search_sessions": { + "items": { + "$ref": "#/components/schemas/SearchReceiptView" + }, + "type": "array", + "title": "Search Sessions" + }, + "exemption_reviews": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Exemption Reviews" + }, + "exemption_decisions": { + "items": { + "$ref": "#/components/schemas/ExemptionDecisionView" + }, + "type": "array", + "title": "Exemption Decisions" + }, + "fee_estimate": { + "type": "string", + "title": "Fee Estimate" + }, + "fee_line_items": { + "items": { + "$ref": "#/components/schemas/FeeLineView" + }, + "type": "array", + "title": "Fee Line Items" + }, + "fee_waiver_reason": { + "type": "string", + "title": "Fee Waiver Reason" + }, + "citations": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Citations" + }, + "response_draft": { + "type": "string", + "title": "Response Draft" + }, + "approval_notes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Approval Notes" + }, + "exports": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Exports" + }, + "documents": { + "items": { + "$ref": "#/components/schemas/RecordsDocumentView" + }, + "type": "array", + "title": "Documents" + }, + "release_packages": { + "items": { + "$ref": "#/components/schemas/ReleasePackageView" + }, + "type": "array", + "title": "Release Packages" + }, + "timeline": { + "items": { + "$ref": "#/components/schemas/TimelineView" + }, + "type": "array", + "title": "Timeline" + }, + "public_status_events": { + "items": { + "$ref": "#/components/schemas/PublicStatusView" + }, + "type": "array", + "title": "Public Status Events" + }, + "messages": { + "items": { + "$ref": "#/components/schemas/MessageView" + }, + "type": "array", + "title": "Messages" + }, + "deadline_reviewed_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Deadline Reviewed At Unix Seconds" + }, + "approved_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Approved At Unix Seconds" + }, + "fulfilled_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Fulfilled At Unix Seconds" + }, + "closed_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Closed At Unix Seconds" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "request_id", + "id", + "public_tracking_number", + "requester", + "requester_contact", + "submitted_via", + "summary", + "deadline", + "deadline_basis", + "status", + "assigned_to", + "clarification_notes", + "search_notes", + "search_sessions", + "exemption_reviews", + "exemption_decisions", + "fee_estimate", + "fee_line_items", + "fee_waiver_reason", + "citations", + "response_draft", + "approval_notes", + "exports", + "timeline", + "public_status_events", + "messages", + "deadline_reviewed_at_unix_seconds", + "approved_at_unix_seconds", + "fulfilled_at_unix_seconds", + "closed_at_unix_seconds", + "created_at_unix_seconds" + ], + "title": "RecordsView" + }, + "ReleasePackageView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "export_path": { + "type": "string", + "title": "Export Path" + }, + "package_hash": { + "type": "string", + "title": "Package Hash" + }, + "document_count": { + "type": "integer", + "title": "Document Count" + }, + "release_artifact_count": { + "type": "integer", + "title": "Release Artifact Count" + }, + "search_session_count": { + "type": "integer", + "title": "Search Session Count" + }, + "release_count": { + "type": "integer", + "title": "Release Count" + }, + "redacted_count": { + "type": "integer", + "title": "Redacted Count" + }, + "exempt_count": { + "type": "integer", + "title": "Exempt Count" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "export_path", + "package_hash", + "document_count", + "release_artifact_count", + "search_session_count", + "release_count", + "redacted_count", + "exempt_count", + "created_at_unix_seconds" + ], + "title": "ReleasePackageView" + }, + "RepeatLookup": { + "properties": { + "property_reference": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Property Reference" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "property_reference" + ], + "title": "RepeatLookup" + }, + "RequestCreate": { + "properties": { + "requester_name": { + "type": "string", + "maxLength": 255, + "title": "Requester Name" + }, + "requester_email": { + "anyOf": [ + { + "type": "string", + "maxLength": 255 + }, + { + "type": "null" + } + ], + "title": "Requester Email" + }, + "requester_phone": { + "anyOf": [ + { + "type": "string", + "maxLength": 50 + }, + { + "type": "null" + } + ], + "title": "Requester Phone" + }, + "requester_type": { + "anyOf": [ + { + "type": "string", + "maxLength": 100 + }, + { + "type": "null" + } + ], + "title": "Requester Type" + }, + "description": { + "type": "string", + "maxLength": 10000, + "title": "Description" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "priority": { + "type": "string", + "title": "Priority", + "default": "normal" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string", + "pattern": "^(narrow|moderate|broad)$" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + } + }, + "type": "object", + "required": [ + "requester_name", + "description" + ], + "title": "RequestCreate" + }, + "RequestDocumentAdd": { + "properties": { + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "relevance_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Relevance Note" + } + }, + "type": "object", + "required": [ + "document_id" + ], + "title": "RequestDocumentAdd" + }, + "RequestDocumentRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "relevance_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Relevance Note" + }, + "exemption_flags": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Exemption Flags" + }, + "inclusion_status": { + "$ref": "#/components/schemas/InclusionStatus" + }, + "attached_at": { + "type": "string", + "format": "date-time", + "title": "Attached At" + }, + "attached_by": { + "type": "string", + "format": "uuid", + "title": "Attached By" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "document_id", + "relevance_note", + "exemption_flags", + "inclusion_status", + "attached_at", + "attached_by" + ], + "title": "RequestDocumentRead" + }, + "RequestRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "requester_name": { + "type": "string", + "title": "Requester Name" + }, + "requester_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Email" + }, + "requester_phone": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Phone" + }, + "requester_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Type" + }, + "date_received": { + "type": "string", + "format": "date-time", + "title": "Date Received" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "description": { + "type": "string", + "title": "Description" + }, + "status": { + "$ref": "#/components/schemas/RequestStatus" + }, + "assigned_to": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "created_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "response_draft": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Response Draft" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + }, + "estimated_fee": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Estimated Fee" + }, + "fee_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Fee Status" + }, + "fee_waiver_requested": { + "type": "boolean", + "title": "Fee Waiver Requested", + "default": false + }, + "priority": { + "type": "string", + "title": "Priority", + "default": "normal" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + }, + "closed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Closed At" + }, + "closure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Closure Reason" + } + }, + "type": "object", + "required": [ + "id", + "requester_name", + "requester_email", + "date_received", + "statutory_deadline", + "description", + "status", + "assigned_to", + "created_by", + "created_at", + "response_draft", + "review_notes" + ], + "title": "RequestRead" + }, + "RequestStats": { + "properties": { + "total_requests": { + "type": "integer", + "title": "Total Requests" + }, + "by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "By Status" + }, + "approaching_deadline": { + "type": "integer", + "title": "Approaching Deadline" + }, + "overdue": { + "type": "integer", + "title": "Overdue" + } + }, + "type": "object", + "required": [ + "total_requests", + "by_status", + "approaching_deadline", + "overdue" + ], + "title": "RequestStats" + }, + "RequestStatus": { + "type": "string", + "enum": [ + "received", + "clarification_needed", + "assigned", + "searching", + "in_review", + "ready_for_release", + "drafted", + "approved", + "fulfilled", + "closed" + ], + "title": "RequestStatus" + }, + "RequestUpdate": { + "properties": { + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "status": { + "anyOf": [ + { + "$ref": "#/components/schemas/RequestStatus" + }, + { + "type": "null" + } + ] + }, + "assigned_to": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "response_draft": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Response Draft" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + } + }, + "type": "object", + "title": "RequestUpdate" + }, + "RequirementBundle": { + "properties": { + "requirement_id": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]{1,100}$", + "title": "Requirement Id" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "project_type": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Project Type" + }, + "source_reference": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Source Reference" + }, + "source_date": { + "type": "string", + "format": "date", + "title": "Source Date" + }, + "effective_on": { + "type": "string", + "format": "date", + "title": "Effective On" + }, + "dataset_kind": { + "type": "string", + "enum": [ + "municipal", + "fictional" + ], + "title": "Dataset Kind" + }, + "filename": { + "type": "string", + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$", + "title": "Filename" + }, + "content_base64": { + "type": "string", + "maxLength": 14000000, + "minLength": 1, + "title": "Content Base64" + }, + "sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Sha256" + }, + "materials": { + "items": { + "$ref": "#/components/schemas/Material" + }, + "type": "array", + "maxItems": 100, + "minItems": 1, + "title": "Materials" + }, + "pathway": { + "items": { + "$ref": "#/components/schemas/PathwayStep" + }, + "type": "array", + "maxItems": 100, + "title": "Pathway" + }, + "fee_link": { + "anyOf": [ + { + "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink" + }, + { + "type": "null" + } + ] + }, + "staff_note": { + "type": "string", + "maxLength": 4000, + "title": "Staff Note", + "default": "" + }, + "change_note": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Change Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requirement_id", + "title", + "jurisdiction", + "project_type", + "source_reference", + "source_date", + "effective_on", + "dataset_kind", + "filename", + "content_base64", + "sha256", + "materials", + "change_note" + ], + "title": "RequirementBundle" + }, + "ResponseLetterCreate": { + "properties": { + "template_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Template Id" + } + }, + "type": "object", + "title": "ResponseLetterCreate" + }, + "ResponseLetterRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "template_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Template Id" + }, + "generated_content": { + "type": "string", + "title": "Generated Content" + }, + "edited_content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Edited Content" + }, + "status": { + "type": "string", + "title": "Status" + }, + "generated_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Generated By" + }, + "approved_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Approved By" + }, + "sent_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Sent At" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "template_id", + "generated_content", + "edited_content", + "status", + "generated_by", + "approved_by", + "sent_at", + "created_at" + ], + "title": "ResponseLetterRead" + }, + "ResponseLetterUpdate": { + "properties": { + "edited_content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Edited Content" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + } + }, + "type": "object", + "title": "ResponseLetterUpdate" + }, + "ReviewInput": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "body": { + "type": "string", + "maxLength": 5000, + "title": "Body", + "default": "" + }, + "hasAltText": { + "type": "boolean", + "title": "Hasalttext", + "default": false + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "en" + } + }, + "additionalProperties": false, + "type": "object", + "title": "ReviewInput" + }, + "Revision": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + }, + "document": { + "$ref": "#/components/schemas/NoticeDraft" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence", + "document" + ], + "title": "Revision" + }, + "RewriteInput": { + "properties": { + "action": { + "type": "string", + "enum": [ + "plain-language", + "language-variant" + ], + "title": "Action" + }, + "text": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Text" + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "text" + ], + "title": "RewriteInput" + }, + "RewriteResult": { + "properties": { + "action": { + "type": "string", + "enum": [ + "plain-language", + "language-variant" + ], + "title": "Action" + }, + "text": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Text" + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "" + }, + "outcome": { + "type": "string", + "enum": [ + "generated", + "unavailable" + ], + "title": "Outcome" + }, + "generated": { + "anyOf": [ + { + "type": "string", + "maxLength": 100000 + }, + { + "type": "null" + } + ], + "title": "Generated" + }, + "model": { + "anyOf": [ + { + "type": "string", + "maxLength": 200 + }, + { + "type": "null" + } + ], + "title": "Model" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "text", + "outcome" + ], + "title": "RewriteResult" + }, + "Rule": { + "properties": { + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "zone_code": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Zone Code" + }, + "key": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Key" + }, + "section_number": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Section Number" + }, + "kind": { + "type": "string", + "enum": [ + "use", + "dimension" + ], + "title": "Kind" + }, + "value": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Value" + }, + "overlay_code": { + "anyOf": [ + { + "type": "string", + "maxLength": 255 + }, + { + "type": "null" + } + ], + "title": "Overlay Code" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "jurisdiction", + "zone_code", + "key", + "section_number", + "kind", + "value" + ], + "title": "Rule" + }, + "RuleTestMatch": { + "properties": { + "matched_text": { + "type": "string", + "title": "Matched Text" + }, + "start": { + "type": "integer", + "title": "Start" + }, + "end": { + "type": "integer", + "title": "End" + } + }, + "type": "object", + "required": [ + "matched_text", + "start", + "end" + ], + "title": "RuleTestMatch" + }, + "RuleTestRequest": { + "properties": { + "sample_text": { + "type": "string", + "title": "Sample Text" + } + }, + "type": "object", + "required": [ + "sample_text" + ], + "title": "RuleTestRequest" + }, + "RuleTestResponse": { + "properties": { + "rule_id": { + "type": "string", + "format": "uuid", + "title": "Rule Id" + }, + "rule_type": { + "type": "string", + "title": "Rule Type" + }, + "matched": { + "type": "boolean", + "title": "Matched" + }, + "matches": { + "items": { + "$ref": "#/components/schemas/RuleTestMatch" + }, + "type": "array", + "title": "Matches" + } + }, + "type": "object", + "required": [ + "rule_id", + "rule_type", + "matched", + "matches" + ], + "title": "RuleTestResponse" + }, + "RuleType": { + "type": "string", + "enum": [ + "regex", + "keyword", + "llm_prompt" + ], + "title": "RuleType" + }, + "SaveReview": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "body": { + "type": "string", + "maxLength": 5000, + "title": "Body", + "default": "" + }, + "hasAltText": { + "type": "boolean", + "title": "Hasalttext", + "default": false + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "en" + }, + "ai_analysis": { + "anyOf": [ + { + "type": "string", + "maxLength": 100000 + }, + { + "type": "null" + } + ], + "title": "Ai Analysis" + }, + "ai_analysis_model": { + "anyOf": [ + { + "type": "string", + "maxLength": 200 + }, + { + "type": "null" + } + ], + "title": "Ai Analysis Model" + }, + "ai_outcome": { + "type": "string", + "enum": [ + "generated", + "unavailable", + "failed" + ], + "title": "Ai Outcome" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "ai_outcome" + ], + "title": "SaveReview" + }, + "SearchFilterOptions": { + "properties": { + "file_types": { + "items": { + "type": "string" + }, + "type": "array", + "title": "File Types" + }, + "source_names": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Source Names" + }, + "departments": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array", + "title": "Departments", + "default": [] + }, + "date_range": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Date Range" + } + }, + "type": "object", + "required": [ + "file_types", + "source_names" + ], + "title": "SearchFilterOptions" + }, + "SearchInput": { + "properties": { + "query": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "SearchInput" + }, + "SearchNoteCommand": { + "properties": { + "action": { + "type": "string", + "const": "record-records-search", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/SearchNotePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "SearchNoteCommand" + }, + "SearchNotePayload": { + "properties": { + "sourceNote": { + "type": "string", + "minLength": 1, + "title": "Sourcenote" + }, + "citation": { + "type": "string", + "title": "Citation", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sourceNote" + ], + "title": "SearchNotePayload" + }, + "SearchReceiptCommand": { + "properties": { + "action": { + "type": "string", + "const": "record-records-search-session", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/SearchReceiptPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "SearchReceiptCommand" + }, + "SearchReceiptPayload": { + "properties": { + "searchQuery": { + "type": "string", + "minLength": 1, + "title": "Searchquery" + }, + "searchLocations": { + "type": "string", + "minLength": 1, + "title": "Searchlocations" + }, + "searchResultTitle": { + "type": "string", + "minLength": 1, + "title": "Searchresulttitle" + }, + "searchResultCitation": { + "type": "string", + "minLength": 1, + "title": "Searchresultcitation" + }, + "searchResultSummary": { + "type": "string", + "minLength": 1, + "title": "Searchresultsummary" + }, + "searchResultStatus": { + "type": "string", + "title": "Searchresultstatus", + "default": "" + }, + "searchReviewer": { + "type": "string", + "title": "Searchreviewer", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "searchQuery", + "searchLocations", + "searchResultTitle", + "searchResultCitation", + "searchResultSummary" + ], + "title": "SearchReceiptPayload" + }, + "SearchReceiptView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "query": { + "type": "string", + "title": "Query" + }, + "locations": { + "type": "string", + "title": "Locations" + }, + "reviewer": { + "type": "string", + "title": "Reviewer" + }, + "results": { + "items": { + "$ref": "#/components/schemas/SearchResultView" + }, + "type": "array", + "title": "Results" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "query", + "locations", + "reviewer", + "results", + "created_at_unix_seconds" + ], + "title": "SearchReceiptView" + }, + "SearchRequest": { + "properties": { + "query": { + "type": "string", + "title": "Query" + }, + "session_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Session Id" + }, + "filters": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Filters" + }, + "limit": { + "type": "integer", + "maximum": 50.0, + "title": "Limit", + "default": 10 + }, + "synthesize": { + "type": "boolean", + "title": "Synthesize", + "default": false + } + }, + "type": "object", + "required": [ + "query" + ], + "title": "SearchRequest" + }, + "SearchResponse": { + "properties": { + "query_id": { + "type": "string", + "format": "uuid", + "title": "Query Id" + }, + "session_id": { + "type": "string", + "format": "uuid", + "title": "Session Id" + }, + "query_text": { + "type": "string", + "title": "Query Text" + }, + "results": { + "items": { + "$ref": "#/components/schemas/SearchResultItem" + }, + "type": "array", + "title": "Results" + }, + "results_count": { + "type": "integer", + "title": "Results Count" + }, + "synthesized_answer": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Synthesized Answer" + }, + "ai_generated": { + "type": "boolean", + "title": "Ai Generated", + "default": false + } + }, + "type": "object", + "required": [ + "query_id", + "session_id", + "query_text", + "results", + "results_count" + ], + "title": "SearchResponse" + }, + "SearchResultItem": { + "properties": { + "chunk_id": { + "type": "string", + "format": "uuid", + "title": "Chunk Id" + }, + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "filename": { + "type": "string", + "title": "Filename" + }, + "file_type": { + "type": "string", + "title": "File Type" + }, + "source_path": { + "type": "string", + "title": "Source Path" + }, + "page_number": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Page Number" + }, + "content_text": { + "type": "string", + "title": "Content Text" + }, + "similarity_score": { + "type": "number", + "title": "Similarity Score" + }, + "rank": { + "type": "integer", + "title": "Rank" + } + }, + "type": "object", + "required": [ + "chunk_id", + "document_id", + "filename", + "file_type", + "source_path", + "page_number", + "content_text", + "similarity_score", + "rank" + ], + "title": "SearchResultItem" + }, + "SearchResultView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "title": { + "type": "string", + "title": "Title" + }, + "citation": { + "type": "string", + "title": "Citation" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "status": { + "type": "string", + "title": "Status" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "title", + "citation", + "summary", + "status" + ], + "title": "SearchResultView" + }, + "SearchSessionRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "user_id": { + "type": "string", + "format": "uuid", + "title": "User Id" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "queries": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array", + "title": "Queries", + "default": [] + } + }, + "type": "object", + "required": [ + "id", + "user_id", + "created_at" + ], + "title": "SearchSessionRead" + }, + "SectionCreate": { + "properties": { + "section_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Section Id" + }, + "chapter_id": { + "type": "string", + "minLength": 1, + "title": "Chapter Id" + }, + "section_number": { + "type": "string", + "minLength": 1, + "title": "Section Number" + }, + "section_heading": { + "type": "string", + "minLength": 1, + "title": "Section Heading" + }, + "parent_section_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parent Section Id" + }, + "sort_order": { + "type": "integer", + "title": "Sort Order", + "default": 0 + }, + "administrative_regulation_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Administrative Regulation Refs" + }, + "resolution_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Resolution Refs" + }, + "policy_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Policy Refs" + }, + "approved_summary_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Approved Summary Refs" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "chapter_id", + "section_number", + "section_heading" + ], + "title": "SectionCreate", + "description": "Request body for creating a code section or subsection." + }, + "SectionVersionCreate": { + "properties": { + "version_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Version Id" + }, + "section_id": { + "type": "string", + "minLength": 1, + "title": "Section Id" + }, + "source_id": { + "type": "string", + "minLength": 1, + "title": "Source Id" + }, + "version_label": { + "type": "string", + "minLength": 1, + "title": "Version Label" + }, + "body": { + "type": "string", + "minLength": 1, + "title": "Body" + }, + "effective_start": { + "type": "string", + "format": "date", + "title": "Effective Start" + }, + "effective_end": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective End" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + }, + "is_current": { + "type": "boolean", + "title": "Is Current", + "default": false + }, + "adoption_event_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Adoption Event Id" + }, + "amendment_event_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Amendment Event Id" + }, + "amendment_summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Amendment Summary" + }, + "prior_version_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Prior Version Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "section_id", + "source_id", + "version_label", + "body", + "effective_start" + ], + "title": "SectionVersionCreate", + "description": "Request body for adding an immutable section version." + }, + "Selection": { + "properties": { + "recording_id": { + "type": "string", + "format": "uuid", + "title": "Recording Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "recording_id", + "expected_sha256" + ], + "title": "Selection" + }, + "SentenceInput": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "citations": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Citations" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text" + ], + "title": "SentenceInput" + }, + "ServiceAccountCreate": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole", + "default": "read_only" + } + }, + "type": "object", + "required": [ + "name" + ], + "title": "ServiceAccountCreate" + }, + "ServiceAccountCreated": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "api_key": { + "type": "string", + "title": "Api Key" + } + }, + "type": "object", + "required": [ + "id", + "name", + "role", + "created_by", + "created_at", + "is_active", + "api_key" + ], + "title": "ServiceAccountCreated", + "description": "Returned only on creation — includes the plaintext API key (shown once)." + }, + "ServiceAccountRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + } + }, + "type": "object", + "required": [ + "id", + "name", + "role", + "created_by", + "created_at", + "is_active" + ], + "title": "ServiceAccountRead" + }, + "ServiceAccountUpdate": { + "properties": { + "role": { + "anyOf": [ + { + "$ref": "#/components/schemas/UserRole" + }, + { + "type": "null" + } + ] + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "ServiceAccountUpdate" + }, + "Snapshot": { + "properties": { + "expected_revision": { + "type": "string", + "format": "uuid", + "title": "Expected Revision" + }, + "visibility": { + "type": "string", + "enum": [ + "staff_only", + "public" + ], + "title": "Visibility" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "expected_revision", + "visibility" + ], + "title": "Snapshot" + }, + "SourceCreate": { + "properties": { + "source_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Id" + }, + "name": { + "type": "string", + "minLength": 1, + "title": "Name" + }, + "publisher": { + "type": "string", + "minLength": 1, + "title": "Publisher" + }, + "source_type": { + "type": "string", + "minLength": 1, + "title": "Source Type" + }, + "source_category": { + "type": "string", + "minLength": 1, + "title": "Source Category" + }, + "source_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Url" + }, + "file_reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "File Reference" + }, + "retrieved_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Retrieved At" + }, + "retrieval_method": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Retrieval Method" + }, + "checksum": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Checksum" + }, + "source_owner": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Owner" + }, + "is_official": { + "type": "boolean", + "title": "Is Official", + "default": true + }, + "official_status_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Official Status Note" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + }, + "staff_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Staff Notes" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "name", + "publisher", + "source_type", + "source_category" + ], + "title": "SourceCreate", + "description": "Request body for registering an official or explicitly labeled source." + }, + "SourceInput": { + "properties": { + "source_id": { + "type": "string", + "minLength": 1, + "title": "Source Id" + }, + "label": { + "type": "string", + "minLength": 1, + "title": "Label" + }, + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "label", + "text" + ], + "title": "SourceInput" + }, + "SourceSnapshot": { + "properties": { + "visibility": { + "type": "string", + "enum": [ + "public", + "staff_only" + ], + "title": "Visibility" + }, + "meeting_event_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "maxItems": 50, + "title": "Meeting Event Ids" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "visibility" + ], + "title": "SourceSnapshot" + }, + "SourceType": { + "type": "string", + "enum": [ + "manual_drop", + "file_system", + "rest_api", + "odbc" + ], + "title": "SourceType" + }, + "StaffRecordsIntake": { + "properties": { + "requester": { + "type": "string", + "minLength": 1, + "title": "Requester" + }, + "summary": { + "type": "string", + "minLength": 1, + "title": "Summary" + }, + "deadline": { + "type": "string", + "title": "Deadline" + }, + "deadlineBasis": { + "type": "string", + "title": "Deadlinebasis", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requester", + "summary", + "deadline" + ], + "title": "StaffRecordsIntake", + "description": "Existing native create-records-request input; no caller-supplied actor." + }, + "StandardsExplanation": { + "properties": { + "question": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Question" + }, + "process_section": { + "type": "string", + "maxLength": 255, + "title": "Process Section", + "default": "" + }, + "zone_code": { + "type": "string", + "maxLength": 40, + "title": "Zone Code", + "default": "" + }, + "rule_types": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 10, + "title": "Rule Types" + }, + "observed": { + "additionalProperties": { + "type": "string" + }, + "type": "object", + "title": "Observed" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "question" + ], + "title": "StandardsExplanation" + }, + "SyncFailureRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "source_id": { + "type": "string", + "format": "uuid", + "title": "Source Id" + }, + "source_path": { + "type": "string", + "title": "Source Path" + }, + "error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Message" + }, + "error_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Class" + }, + "http_status_code": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Http Status Code" + }, + "retry_count": { + "type": "integer", + "title": "Retry Count" + }, + "status": { + "type": "string", + "title": "Status" + }, + "first_failed_at": { + "type": "string", + "format": "date-time", + "title": "First Failed At" + }, + "last_retried_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Retried At" + }, + "dismissed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Dismissed At" + }, + "dismissed_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Dismissed By" + } + }, + "type": "object", + "required": [ + "id", + "source_id", + "source_path", + "error_message", + "error_class", + "http_status_code", + "retry_count", + "status", + "first_failed_at", + "last_retried_at", + "dismissed_at", + "dismissed_by" + ], + "title": "SyncFailureRead" + }, + "SyncRunLogRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "source_id": { + "type": "string", + "format": "uuid", + "title": "Source Id" + }, + "started_at": { + "type": "string", + "format": "date-time", + "title": "Started At" + }, + "finished_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Finished At" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + }, + "records_attempted": { + "type": "integer", + "title": "Records Attempted" + }, + "records_succeeded": { + "type": "integer", + "title": "Records Succeeded" + }, + "records_failed": { + "type": "integer", + "title": "Records Failed" + }, + "error_summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Summary" + } + }, + "type": "object", + "required": [ + "id", + "source_id", + "started_at", + "finished_at", + "status", + "records_attempted", + "records_succeeded", + "records_failed", + "error_summary" + ], + "title": "SyncRunLogRead" + }, + "SystemStatus": { + "properties": { + "version": { + "type": "string", + "title": "Version" + }, + "database": { + "type": "string", + "title": "Database" + }, + "ollama": { + "type": "string", + "title": "Ollama" + }, + "redis": { + "type": "string", + "title": "Redis" + }, + "user_count": { + "type": "integer", + "title": "User Count" + }, + "audit_log_count": { + "type": "integer", + "title": "Audit Log Count" + }, + "suite_session": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Suite Session" + } + }, + "type": "object", + "required": [ + "version", + "database", + "ollama", + "redis", + "user_count", + "audit_log_count" + ], + "title": "SystemStatus" + }, + "TaggedPlan": { + "properties": { + "action": { + "type": "string", + "const": "tagged-pdf", + "title": "Action" + }, + "headingLevels": { + "items": { + "type": "integer", + "maximum": 4294967295.0, + "minimum": 0.0 + }, + "type": "array", + "maxItems": 50, + "title": "Headinglevels" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "TaggedPlan" + }, + "TestConnectionRequest": { + "properties": { + "source_type": { + "type": "string", + "title": "Source Type" + }, + "host": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Host" + }, + "port": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Port" + }, + "path": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Path" + }, + "username": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Username" + }, + "password": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Password" + }, + "rest_api_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Rest Api Config" + }, + "odbc_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Odbc Config" + } + }, + "type": "object", + "required": [ + "source_type" + ], + "title": "TestConnectionRequest", + "description": "Dedicated schema for test-connection. NOT the create schema.\n\nSecurity: credentials in this request body are never persisted, never\nwritten to audit logs, and never returned in the response." + }, + "TestConnectionResponse": { + "properties": { + "success": { + "type": "boolean", + "title": "Success" + }, + "message": { + "type": "string", + "title": "Message" + }, + "latency_ms": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Latency Ms" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + }, + "warning": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Warning" + }, + "differing_keys": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Differing Keys" + } + }, + "type": "object", + "required": [ + "success", + "message" + ], + "title": "TestConnectionResponse" + }, + "TimelineEventCreate": { + "properties": { + "event_type": { + "type": "string", + "title": "Event Type" + }, + "description": { + "type": "string", + "title": "Description" + }, + "internal_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Internal Note" + } + }, + "type": "object", + "required": [ + "event_type", + "description" + ], + "title": "TimelineEventCreate" + }, + "TimelineEventRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "event_type": { + "type": "string", + "title": "Event Type" + }, + "actor_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Actor Id" + }, + "actor_role": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Actor Role" + }, + "description": { + "type": "string", + "title": "Description" + }, + "internal_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Internal Note" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "event_type", + "actor_id", + "actor_role", + "description", + "internal_note", + "created_at" + ], + "title": "TimelineEventRead" + }, + "TimelineView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "action": { + "type": "string", + "title": "Action" + }, + "actor": { + "type": "string", + "title": "Actor" + }, + "note": { + "type": "string", + "title": "Note" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "action", + "actor", + "note", + "created_at_unix_seconds" + ], + "title": "TimelineView" + }, + "TitleCreate": { + "properties": { + "title_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Title Id" + }, + "title_number": { + "type": "string", + "minLength": 1, + "title": "Title Number" + }, + "title_name": { + "type": "string", + "minLength": 1, + "title": "Title Name" + }, + "sort_order": { + "type": "integer", + "title": "Sort Order", + "default": 0 + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title_number", + "title_name" + ], + "title": "TitleCreate", + "description": "Request body for creating a code title." + }, + "TranscriptInput": { + "properties": { + "source_label": { + "type": "string", + "minLength": 1, + "title": "Source Label" + }, + "transcript_text": { + "type": "string", + "minLength": 1, + "title": "Transcript Text" + }, + "correction_of_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Correction Of Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_label", + "transcript_text" + ], + "title": "TranscriptInput" + }, + "UserRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "email": { + "type": "string", + "format": "email", + "title": "Email" + }, + "is_active": { + "type": "boolean", + "title": "Is Active", + "default": true + }, + "is_superuser": { + "type": "boolean", + "title": "Is Superuser", + "default": false + }, + "is_verified": { + "type": "boolean", + "title": "Is Verified", + "default": false + }, + "full_name": { + "type": "string", + "title": "Full Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "last_login": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Login" + }, + "must_change_password": { + "type": "boolean", + "title": "Must Change Password", + "default": false + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + } + }, + "type": "object", + "required": [ + "id", + "email", + "full_name", + "role", + "created_at", + "last_login" + ], + "title": "UserRead" + }, + "UserRole": { + "type": "string", + "enum": [ + "admin", + "staff", + "reviewer", + "read_only", + "liaison", + "public" + ], + "title": "UserRole" + }, + "UserSelfUpdate": { + "properties": { + "password": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Password" + }, + "email": { + "anyOf": [ + { + "type": "string", + "format": "email" + }, + { + "type": "null" + } + ], + "title": "Email" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + }, + "is_superuser": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Superuser" + }, + "is_verified": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Verified" + }, + "full_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Full Name" + } + }, + "type": "object", + "title": "UserSelfUpdate", + "description": "Schema for user self-update via PATCH /users/me.\n\nExcludes role and department_id. Any payload containing those fields is\nrejected at parse time (HTTP 422). Role and department changes require\nadmin privileges via /admin/users/{id}." + }, + "UserUpdateRequest": { + "properties": { + "full_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Full Name" + }, + "role": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Role" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "UserUpdateRequest" + }, + "ValidationError": { + "properties": { + "loc": { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "integer" + } + ] + }, + "type": "array", + "title": "Location" + }, + "msg": { + "type": "string", + "title": "Message" + }, + "type": { + "type": "string", + "title": "Error Type" + }, + "input": { + "title": "Input" + }, + "ctx": { + "type": "object", + "title": "Context" + } + }, + "type": "object", + "required": [ + "loc", + "msg", + "type" + ], + "title": "ValidationError" + }, + "Version": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence" + ], + "title": "Version" + }, + "VoteCorrection": { + "properties": { + "vote": { + "type": "string", + "minLength": 1, + "title": "Vote" + }, + "reason": { + "type": "string", + "minLength": 1, + "title": "Reason" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "vote", + "reason" + ], + "title": "VoteCorrection" + }, + "VoteInput": { + "properties": { + "voter_name": { + "type": "string", + "minLength": 1, + "title": "Voter Name" + }, + "vote": { + "type": "string", + "minLength": 1, + "title": "Vote" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "voter_name", + "vote" + ], + "title": "VoteInput" + }, + "_ParcelLookupIn": { + "properties": { + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "jurisdiction", + "query" + ], + "title": "_ParcelLookupIn" + }, + "townlight_inspections__workflow_models__SourceLink": { + "properties": { + "provider": { + "type": "string", + "const": "code", + "title": "Provider", + "default": "code" + }, + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "SourceLink" + }, + "townlight_permitting__workflow_models__SourceLink": { + "properties": { + "provider": { + "type": "string", + "enum": [ + "code", + "zoning" + ], + "title": "Provider" + }, + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "source_id", + "expected_sha256" + ], + "title": "SourceLink" + }, + "townlight_runtime__inspections_bridge__Search": { + "properties": { + "provider": { + "type": "string", + "const": "code", + "title": "Provider" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "query" + ], + "title": "Search" + }, + "townlight_runtime__notice_bridge__Review": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + }, + "note": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence", + "note" + ], + "title": "Review" + }, + "townlight_runtime__permitting_bridge__Import": { + "properties": { + "bundle": { + "$ref": "#/components/schemas/RequirementBundle" + }, + "expected_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "bundle" + ], + "title": "Import" + }, + "townlight_runtime__permitting_bridge__Search": { + "properties": { + "provider": { + "type": "string", + "enum": [ + "code", + "zoning" + ], + "title": "Provider" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "query" + ], + "title": "Search" + }, + "townlight_runtime__planning_bridge__Import": { + "properties": { + "bundle": { + "additionalProperties": true, + "type": "object", + "title": "Bundle" + }, + "expected_previous_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Expected Previous Revision" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "bundle" + ], + "title": "Import" + }, + "townlight_runtime__planning_bridge__Search": { + "properties": { + "query": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Query" + }, + "plan_type": { + "anyOf": [ + { + "type": "string", + "maxLength": 40 + }, + { + "type": "null" + } + ], + "title": "Plan Type" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "Search" + }, + "townlight_runtime__zoning_bridge__Review": { + "properties": { + "answer": { + "type": "string", + "maxLength": 10000, + "title": "Answer", + "default": "" + }, + "notes": { + "type": "string", + "maxLength": 10000, + "title": "Notes", + "default": "" + }, + "queue_status": { + "type": "string", + "enum": [ + "open", + "in_review", + "resolved", + "closed" + ], + "title": "Queue Status", + "default": "resolved" + } + }, + "additionalProperties": false, + "type": "object", + "title": "Review" + } + }, + "securitySchemes": { + "OAuth2PasswordBearer": { + "type": "oauth2", + "flows": { + "password": { + "scopes": {}, + "tokenUrl": "auth/jwt/login" + } + } + } + } + }, + "x-townlight-component": { + "view": "records", + "identity": "Townlight Records 1.8.0.dev2", + "evidence": "source-schema-only" + } +} diff --git a/docs/beta-1/api/records.html b/docs/beta-1/api/records.html new file mode 100644 index 0000000..5bba24d --- /dev/null +++ b/docs/beta-1/api/records.html @@ -0,0 +1,19623 @@ +Townlight Records API reference
Townlight

Townlight Records API reference

+

Prepared source candidate, November 2, 2026. New signed Windows installed acceptance and publication remain pending.

+

Townlight Records 1.8.0.dev2. The HTTP host is Townlight Records 1.8.0.dev2. Component package versions and the host API version are separate identities.

+

Generated from the actual native inspections-preview composition without application lifespan, migrations or database/network access. It describes route and validation contracts; it does not establish endpoint behavior, individual authorization or installed acceptance. Standalone product applications have separate deployment boundaries.

+

Machine-readable OpenAPI schema · Operating manual and limits

+

HTTP operations

+
GET /admin/coverage-gaps +
{
+  "tags": [
+    "admin"
+  ],
+  "summary": "Get Coverage Gaps",
+  "description": "Identify coverage gaps across jurisdictions, departments, and exemption categories.\n\nReturns:\n- Jurisdictions (state codes) that have no exemption rules\n- Departments with no assigned staff users\n- Exemption categories without any active rules",
+  "operationId": "get_coverage_gaps_admin_coverage_gaps_get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/CoverageGapResponse"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
GET /admin/fee-schedules +
{
+  "tags": [
+    "admin"
+  ],
+  "summary": "List Fee Schedules",
+  "description": "List all fee schedules. Admin only.",
+  "operationId": "list_fee_schedules_admin_fee_schedules_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "jurisdiction",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Jurisdiction"
+      }
+    },
+    {
+      "name": "limit",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "default": 50,
+        "title": "Limit"
+      }
+    },
+    {
+      "name": "offset",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "default": 0,
+        "title": "Offset"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/FeeScheduleRead"
+            },
+            "title": "Response List Fee Schedules Admin Fee Schedules Get"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /admin/fee-schedules +
{
+  "tags": [
+    "admin"
+  ],
+  "summary": "Create Fee Schedule",
+  "description": "Create a new fee schedule. Admin only.",
+  "operationId": "create_fee_schedule_admin_fee_schedules_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/FeeScheduleCreate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/FeeScheduleRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
PATCH /admin/fee-schedules/{schedule_id} +
{
+  "tags": [
+    "admin"
+  ],
+  "summary": "Update Fee Schedule",
+  "description": "Update a fee schedule. Admin only.",
+  "operationId": "update_fee_schedule_admin_fee_schedules__schedule_id__patch",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "schedule_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Schedule Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/FeeScheduleUpdate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/FeeScheduleRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
DELETE /admin/fee-schedules/{schedule_id} +
{
+  "tags": [
+    "admin"
+  ],
+  "summary": "Delete Fee Schedule",
+  "description": "Delete a fee schedule. Admin only.",
+  "operationId": "delete_fee_schedule_admin_fee_schedules__schedule_id__delete",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "schedule_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Schedule Id"
+      }
+    }
+  ],
+  "responses": {
+    "204": {
+      "description": "Successful Response"
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /admin/models +
{
+  "tags": [
+    "admin"
+  ],
+  "summary": "List Models",
+  "operationId": "list_models_admin_models_get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/OllamaStatus"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
GET /admin/models/registry +
{
+  "tags": [
+    "admin"
+  ],
+  "summary": "List Model Registry",
+  "operationId": "list_model_registry_admin_models_registry_get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "items": {
+              "$ref": "#/components/schemas/ModelRegistryRead"
+            },
+            "type": "array",
+            "title": "Response List Model Registry Admin Models Registry Get"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
POST /admin/models/registry +
{
+  "tags": [
+    "admin"
+  ],
+  "summary": "Register Model",
+  "operationId": "register_model_admin_models_registry_post",
+  "requestBody": {
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/ModelRegistryCreate"
+        }
+      }
+    },
+    "required": true
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/ModelRegistryRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
PATCH /admin/models/registry/{model_id} +
{
+  "tags": [
+    "admin"
+  ],
+  "summary": "Update Model Registry",
+  "operationId": "update_model_registry_admin_models_registry__model_id__patch",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "model_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "integer",
+        "title": "Model Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/ModelRegistryUpdate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/ModelRegistryRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
DELETE /admin/models/registry/{model_id} +
{
+  "tags": [
+    "admin"
+  ],
+  "summary": "Delete Model Registry",
+  "operationId": "delete_model_registry_admin_models_registry__model_id__delete",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "model_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "integer",
+        "title": "Model Id"
+      }
+    }
+  ],
+  "responses": {
+    "204": {
+      "description": "Successful Response"
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /admin/status +
{
+  "tags": [
+    "admin"
+  ],
+  "summary": "System Status",
+  "operationId": "system_status_admin_status_get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/SystemStatus"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
GET /admin/users +
{
+  "tags": [
+    "admin"
+  ],
+  "summary": "List Users",
+  "description": "List all users. Admin only.",
+  "operationId": "list_users_admin_users_get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "items": {
+              "$ref": "#/components/schemas/UserRead"
+            },
+            "type": "array",
+            "title": "Response List Users Admin Users Get"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
POST /admin/users +
{
+  "tags": [
+    "admin"
+  ],
+  "summary": "Create User",
+  "description": "Create a new user. Admin only.",
+  "operationId": "create_user_admin_users_post",
+  "requestBody": {
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/AdminUserCreateRequest"
+        }
+      }
+    },
+    "required": true
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/AdminUserCreateResponse"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
PATCH /admin/users/{user_id} +
{
+  "tags": [
+    "admin"
+  ],
+  "summary": "Update User",
+  "description": "Update user fields. Admin only.\n\nGuards against self-demotion: admins cannot change their own role.",
+  "operationId": "update_user_admin_users__user_id__patch",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "user_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "User Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/UserUpdateRequest"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/AdminUserCreateResponse"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /analytics/operational +
{
+  "tags": [
+    "analytics"
+  ],
+  "summary": "Get Operational Metrics",
+  "operationId": "get_operational_metrics_analytics_operational_get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/OperationalMetrics"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
GET /audit/export +
{
+  "tags": [
+    "audit"
+  ],
+  "summary": "Export Audit Logs",
+  "operationId": "export_audit_logs_audit_export_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "format",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "string",
+        "default": "json",
+        "title": "Format"
+      }
+    },
+    {
+      "name": "start_date",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Start Date"
+      }
+    },
+    {
+      "name": "end_date",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "End Date"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /audit/logs +
{
+  "tags": [
+    "audit"
+  ],
+  "summary": "List Audit Logs",
+  "operationId": "list_audit_logs_audit_logs_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "action",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Action"
+      }
+    },
+    {
+      "name": "resource_type",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Resource Type"
+      }
+    },
+    {
+      "name": "user_id",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string",
+            "format": "uuid"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "User Id"
+      }
+    },
+    {
+      "name": "start_date",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string",
+            "format": "date-time"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Start Date"
+      }
+    },
+    {
+      "name": "end_date",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string",
+            "format": "date-time"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "End Date"
+      }
+    },
+    {
+      "name": "limit",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 200,
+        "default": 50,
+        "title": "Limit"
+      }
+    },
+    {
+      "name": "offset",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "default": 0,
+        "title": "Offset"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/AuditLogRead"
+            },
+            "title": "Response List Audit Logs Audit Logs Get"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /audit/verify +
{
+  "tags": [
+    "audit"
+  ],
+  "summary": "Verify Audit Chain",
+  "operationId": "verify_audit_chain_audit_verify_get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/AuditChainVerification"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
POST /auth/jwt/login +
{
+  "tags": [
+    "auth"
+  ],
+  "summary": "Auth:Jwt.Login",
+  "operationId": "auth_jwt_login_auth_jwt_login_post",
+  "requestBody": {
+    "content": {
+      "application/x-www-form-urlencoded": {
+        "schema": {
+          "$ref": "#/components/schemas/Body_auth_jwt_login_auth_jwt_login_post"
+        }
+      }
+    },
+    "required": true
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/BearerResponse"
+          },
+          "example": {
+            "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiOTIyMWZmYzktNjQwZi00MzcyLTg2ZDMtY2U2NDJjYmE1NjAzIiwiYXVkIjoiZmFzdGFwaS11c2VyczphdXRoIiwiZXhwIjoxNTcxNTA0MTkzfQ.M10bjOe45I5Ncu_uXvOmVV8QxnL-nZfcH96U90JaocI",
+            "token_type": "bearer"
+          }
+        }
+      }
+    },
+    "400": {
+      "description": "Bad Request",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/ErrorModel"
+          },
+          "examples": {
+            "LOGIN_BAD_CREDENTIALS": {
+              "summary": "Bad credentials or the user is inactive.",
+              "value": {
+                "detail": "LOGIN_BAD_CREDENTIALS"
+              }
+            },
+            "LOGIN_USER_NOT_VERIFIED": {
+              "summary": "The user is not verified.",
+              "value": {
+                "detail": "LOGIN_USER_NOT_VERIFIED"
+              }
+            }
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /auth/jwt/logout +
{
+  "tags": [
+    "auth"
+  ],
+  "summary": "Auth:Jwt.Logout",
+  "operationId": "auth_jwt_logout_auth_jwt_logout_post",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "401": {
+      "description": "Missing token or inactive user."
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
GET /catalog/connectors +
{
+  "tags": [
+    "catalog"
+  ],
+  "summary": "List Connectors",
+  "operationId": "list_connectors_catalog_connectors_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "domain",
+      "in": "query",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Domain"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /catalog/domains +
{
+  "tags": [
+    "catalog"
+  ],
+  "summary": "List Domains",
+  "operationId": "list_domains_catalog_domains_get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
POST /catalog/load +
{
+  "tags": [
+    "catalog"
+  ],
+  "summary": "Trigger Catalog Load",
+  "operationId": "trigger_catalog_load_catalog_load_post",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
GET /catalog/systems +
{
+  "tags": [
+    "catalog"
+  ],
+  "summary": "List Systems",
+  "operationId": "list_systems_catalog_systems_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "domain",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Domain"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /city-profile +
{
+  "tags": [
+    "city-profile"
+  ],
+  "summary": "Get City Profile",
+  "operationId": "get_city_profile_city_profile_get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "anyOf": [
+              {
+                "$ref": "#/components/schemas/CityProfileRead"
+              },
+              {
+                "type": "null"
+              }
+            ],
+            "title": "Response Get City Profile City Profile Get"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
POST /city-profile +
{
+  "tags": [
+    "city-profile"
+  ],
+  "summary": "Create City Profile",
+  "operationId": "create_city_profile_city_profile_post",
+  "requestBody": {
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/CityProfileCreate"
+        }
+      }
+    },
+    "required": true
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/CityProfileRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
PATCH /city-profile +
{
+  "tags": [
+    "city-profile"
+  ],
+  "summary": "Update City Profile",
+  "operationId": "update_city_profile_city_profile_patch",
+  "requestBody": {
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/CityProfileUpdate"
+        }
+      }
+    },
+    "required": true
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/CityProfileRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
GET /config/portal-mode +
{
+  "tags": [
+    "public"
+  ],
+  "summary": "Get the deployment's current portal posture.",
+  "operationId": "get_portal_mode_config_portal_mode_get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/PortalModeResponse"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /datasources/ +
{
+  "tags": [
+    "datasources"
+  ],
+  "summary": "List Datasources",
+  "operationId": "list_datasources_datasources__get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "items": {
+              "$ref": "#/components/schemas/DataSourceRead"
+            },
+            "type": "array",
+            "title": "Response List Datasources Datasources  Get"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
POST /datasources/ +
{
+  "tags": [
+    "datasources"
+  ],
+  "summary": "Create Datasource",
+  "operationId": "create_datasource_datasources__post",
+  "requestBody": {
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/DataSourceCreate"
+        }
+      }
+    },
+    "required": true
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/DataSourceAdminRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
POST /datasources/documents/{document_id}/re-ingest +
{
+  "tags": [
+    "datasources"
+  ],
+  "summary": "Re Ingest Document",
+  "description": "Re-ingest a failed document. Resets status to pending and queues for processing.",
+  "operationId": "re_ingest_document_datasources_documents__document_id__re_ingest_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "document_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Document Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /datasources/stats +
{
+  "tags": [
+    "datasources"
+  ],
+  "summary": "Ingestion Stats",
+  "operationId": "ingestion_stats_datasources_stats_get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/IngestionStats"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
POST /datasources/test-connection +
{
+  "tags": [
+    "datasources"
+  ],
+  "summary": "Test Connection",
+  "description": "Test connectivity to a data source without persisting anything.\n\nThis endpoint validates the connection parameters and attempts a test\nconnection. Credentials are NOT persisted, NOT logged, and NOT returned.",
+  "operationId": "test_connection_datasources_test_connection_post",
+  "requestBody": {
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/TestConnectionRequest"
+        }
+      }
+    },
+    "required": true
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/TestConnectionResponse"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
POST /datasources/upload +
{
+  "tags": [
+    "datasources"
+  ],
+  "summary": "Upload File",
+  "operationId": "upload_file_datasources_upload_post",
+  "requestBody": {
+    "content": {
+      "multipart/form-data": {
+        "schema": {
+          "$ref": "#/components/schemas/Body_upload_file_datasources_upload_post"
+        }
+      }
+    },
+    "required": true
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
PATCH /datasources/{source_id} +
{
+  "tags": [
+    "datasources"
+  ],
+  "summary": "Update Datasource",
+  "operationId": "update_datasource_datasources__source_id__patch",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "source_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Source Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/DataSourceUpdate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/DataSourceAdminRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /datasources/{source_id}/ingest +
{
+  "tags": [
+    "datasources"
+  ],
+  "summary": "Trigger Ingestion",
+  "operationId": "trigger_ingestion_datasources__source_id__ingest_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "source_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Source Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /datasources/{source_id}/sync-failures +
{
+  "tags": [
+    "sync-failures"
+  ],
+  "summary": "List Sync Failures",
+  "operationId": "list_sync_failures_datasources__source_id__sync_failures_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "source_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Source Id"
+      }
+    },
+    {
+      "name": "status",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "description": "Filter by status",
+        "title": "Status"
+      },
+      "description": "Filter by status"
+    },
+    {
+      "name": "limit",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 500,
+        "minimum": 1,
+        "default": 50,
+        "title": "Limit"
+      }
+    },
+    {
+      "name": "offset",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "minimum": 0,
+        "default": 0,
+        "title": "Offset"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/SyncFailureRead"
+            },
+            "title": "Response List Sync Failures Datasources  Source Id  Sync Failures Get"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /datasources/{source_id}/sync-failures/dismiss-all +
{
+  "tags": [
+    "sync-failures"
+  ],
+  "summary": "Dismiss All Sync Failures",
+  "operationId": "dismiss_all_sync_failures_datasources__source_id__sync_failures_dismiss_all_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "source_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Source Id"
+      }
+    },
+    {
+      "name": "status",
+      "in": "query",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "description": "Status to dismiss — required",
+        "title": "Status"
+      },
+      "description": "Status to dismiss — required"
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /datasources/{source_id}/sync-failures/retry-all +
{
+  "tags": [
+    "sync-failures"
+  ],
+  "summary": "Retry All Sync Failures",
+  "operationId": "retry_all_sync_failures_datasources__source_id__sync_failures_retry_all_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "source_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Source Id"
+      }
+    },
+    {
+      "name": "status",
+      "in": "query",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "description": "Status to reset — required",
+        "title": "Status"
+      },
+      "description": "Status to reset — required"
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /datasources/{source_id}/sync-failures/{failure_id}/dismiss +
{
+  "tags": [
+    "sync-failures"
+  ],
+  "summary": "Dismiss Sync Failure",
+  "operationId": "dismiss_sync_failure_datasources__source_id__sync_failures__failure_id__dismiss_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "source_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Source Id"
+      }
+    },
+    {
+      "name": "failure_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Failure Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /datasources/{source_id}/sync-failures/{failure_id}/retry +
{
+  "tags": [
+    "sync-failures"
+  ],
+  "summary": "Retry Sync Failure",
+  "operationId": "retry_sync_failure_datasources__source_id__sync_failures__failure_id__retry_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "source_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Source Id"
+      }
+    },
+    {
+      "name": "failure_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Failure Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /datasources/{source_id}/sync-run-log +
{
+  "tags": [
+    "sync-failures"
+  ],
+  "summary": "Get Sync Run Log",
+  "operationId": "get_sync_run_log_datasources__source_id__sync_run_log_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "source_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Source Id"
+      }
+    },
+    {
+      "name": "limit",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 100,
+        "minimum": 1,
+        "default": 20,
+        "title": "Limit"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/SyncRunLogRead"
+            },
+            "title": "Response Get Sync Run Log Datasources  Source Id  Sync Run Log Get"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /datasources/{source_id}/unpause +
{
+  "tags": [
+    "sync-failures"
+  ],
+  "summary": "Unpause Source",
+  "operationId": "unpause_source_datasources__source_id__unpause_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "source_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Source Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /departments/ +
{
+  "tags": [
+    "departments"
+  ],
+  "summary": "List Departments",
+  "operationId": "list_departments_departments__get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "items": {
+              "$ref": "#/components/schemas/DepartmentRead"
+            },
+            "type": "array",
+            "title": "Response List Departments Departments  Get"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
POST /departments/ +
{
+  "tags": [
+    "departments"
+  ],
+  "summary": "Create Department",
+  "operationId": "create_department_departments__post",
+  "requestBody": {
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/DepartmentCreate"
+        }
+      }
+    },
+    "required": true
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/DepartmentRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
GET /departments/{dept_id} +
{
+  "tags": [
+    "departments"
+  ],
+  "summary": "Get Department",
+  "operationId": "get_department_departments__dept_id__get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "dept_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Dept Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/DepartmentRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
PATCH /departments/{dept_id} +
{
+  "tags": [
+    "departments"
+  ],
+  "summary": "Update Department",
+  "operationId": "update_department_departments__dept_id__patch",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "dept_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Dept Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/DepartmentUpdate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/DepartmentRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
DELETE /departments/{dept_id} +
{
+  "tags": [
+    "departments"
+  ],
+  "summary": "Delete Department",
+  "operationId": "delete_department_departments__dept_id__delete",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "dept_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Dept Id"
+      }
+    }
+  ],
+  "responses": {
+    "204": {
+      "description": "Successful Response"
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/access/exports/{artifact_id}/complete +
{
+  "tags": [
+    "native-access"
+  ],
+  "summary": "Complete Export",
+  "operationId": "complete_export_desktop_v1_access_exports__artifact_id__complete_post",
+  "parameters": [
+    {
+      "name": "artifact_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Artifact Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/ExportReceipt"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/access/review-context +
{
+  "tags": [
+    "native-access"
+  ],
+  "summary": "Review Context",
+  "operationId": "review_context_desktop_v1_access_review_context_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/ReviewInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/access/reviews +
{
+  "tags": [
+    "native-access"
+  ],
+  "summary": "Save Review",
+  "operationId": "save_review_desktop_v1_access_reviews_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/SaveReview"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/access/reviews/{review_id}/delete +
{
+  "tags": [
+    "native-access"
+  ],
+  "summary": "Delete Review",
+  "operationId": "delete_review_desktop_v1_access_reviews__review_id__delete_post",
+  "parameters": [
+    {
+      "name": "review_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Review Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/access/reviews/{review_id}/export +
{
+  "tags": [
+    "native-access"
+  ],
+  "summary": "Prepare Export",
+  "operationId": "prepare_export_desktop_v1_access_reviews__review_id__export_post",
+  "parameters": [
+    {
+      "name": "review_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Review Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/access/rewrite-context +
{
+  "tags": [
+    "native-access"
+  ],
+  "summary": "Rewrite Context",
+  "operationId": "rewrite_context_desktop_v1_access_rewrite_context_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/RewriteInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/access/rewrite-result +
{
+  "tags": [
+    "native-access"
+  ],
+  "summary": "Rewrite Result",
+  "operationId": "rewrite_result_desktop_v1_access_rewrite_result_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/RewriteResult"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/access/state +
{
+  "tags": [
+    "native-access"
+  ],
+  "summary": "Access State",
+  "operationId": "access_state_desktop_v1_access_state_get",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/access/tools +
{
+  "tags": [
+    "native-access"
+  ],
+  "summary": "Tool",
+  "operationId": "tool_desktop_v1_access_tools_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "oneOf": [
+            {
+              "$ref": "#/components/schemas/FormPlan"
+            },
+            {
+              "$ref": "#/components/schemas/PublishingPlan"
+            },
+            {
+              "$ref": "#/components/schemas/AdaPlan"
+            },
+            {
+              "$ref": "#/components/schemas/TaggedPlan"
+            }
+          ],
+          "discriminator": {
+            "propertyName": "action",
+            "mapping": {
+              "form-plan": "#/components/schemas/FormPlan",
+              "publishing-workflow": "#/components/schemas/PublishingPlan",
+              "ada-title-ii": "#/components/schemas/AdaPlan",
+              "tagged-pdf": "#/components/schemas/TaggedPlan"
+            }
+          },
+          "title": "Data"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/code-sources/search +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Search Code Sources",
+  "operationId": "search_code_sources_desktop_v1_code_sources_search_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/CodeSearch"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/inspections-sources/search +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Search Inspections Sources",
+  "operationId": "search_inspections_sources_desktop_v1_inspections_sources_search_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MeetingsSearch"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings-sources/search +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Search Meetings Sources",
+  "operationId": "search_meetings_sources_desktop_v1_meetings_sources_search_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MeetingsSearch"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/notifications/{notification_id}/sent +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Mark Native Notification Sent",
+  "operationId": "mark_native_notification_sent_desktop_v1_notifications__notification_id__sent_post",
+  "parameters": [
+    {
+      "name": "notification_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Notification Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RecordsStateRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/permitting-sources/search +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Search Permitting Sources",
+  "operationId": "search_permitting_sources_desktop_v1_permitting_sources_search_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MeetingsSearch"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/planning-sources/search +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Search Planning Sources",
+  "operationId": "search_planning_sources_desktop_v1_planning_sources_search_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MeetingsSearch"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/public/lookup +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Public Records Lookup",
+  "operationId": "public_records_lookup_desktop_v1_public_lookup_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Public",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Public"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/PublicLookup"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/public/messages +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Public Records Message",
+  "operationId": "public_records_message_desktop_v1_public_messages_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Public",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Public"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/PublicMessage"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/public/records-state +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Public Records State",
+  "operationId": "public_records_state_desktop_v1_public_records_state_get",
+  "parameters": [
+    {
+      "name": "X-Townlight-Public",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Public"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RecordsStateRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/public/requests +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Public Records Intake",
+  "operationId": "public_records_intake_desktop_v1_public_requests_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Public",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Public"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/PublicIntake"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/records-state +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Get Native Records State",
+  "operationId": "get_native_records_state_desktop_v1_records_state_get",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RecordsStateRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/requests +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Create Native Request",
+  "operationId": "create_native_request_desktop_v1_requests_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/StaffRecordsIntake"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/NativeRequestRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/requests/{request_id} +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Get Native Request",
+  "operationId": "get_native_request_desktop_v1_requests__request_id__get",
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/NativeRequestRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/requests/{request_id}/actions +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Native Request Operation",
+  "operationId": "native_request_operation_desktop_v1_requests__request_id__actions_post",
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "oneOf": [
+            {
+              "$ref": "#/components/schemas/AssignCommand"
+            },
+            {
+              "$ref": "#/components/schemas/DeadlineCommand"
+            },
+            {
+              "$ref": "#/components/schemas/CalculateDeadlineCommand"
+            },
+            {
+              "$ref": "#/components/schemas/ClarificationCommand"
+            },
+            {
+              "$ref": "#/components/schemas/MessageCommand"
+            },
+            {
+              "$ref": "#/components/schemas/SearchNoteCommand"
+            },
+            {
+              "$ref": "#/components/schemas/SearchReceiptCommand"
+            },
+            {
+              "$ref": "#/components/schemas/ExemptionNoteCommand"
+            },
+            {
+              "$ref": "#/components/schemas/ExemptionDecisionCommand"
+            },
+            {
+              "$ref": "#/components/schemas/FeeEstimateCommand"
+            },
+            {
+              "$ref": "#/components/schemas/FeeLineCommand"
+            },
+            {
+              "$ref": "#/components/schemas/FeeWaiverCommand"
+            },
+            {
+              "$ref": "#/components/schemas/DraftCommand"
+            },
+            {
+              "$ref": "#/components/schemas/ApprovalCommand"
+            },
+            {
+              "$ref": "#/components/schemas/FinishCommand"
+            }
+          ],
+          "discriminator": {
+            "propertyName": "action",
+            "mapping": {
+              "assign-records-request": "#/components/schemas/AssignCommand",
+              "set-records-deadline": "#/components/schemas/DeadlineCommand",
+              "calculate-records-deadline": "#/components/schemas/CalculateDeadlineCommand",
+              "request-records-clarification": "#/components/schemas/ClarificationCommand",
+              "add-records-message": "#/components/schemas/MessageCommand",
+              "record-records-search": "#/components/schemas/SearchNoteCommand",
+              "record-records-search-session": "#/components/schemas/SearchReceiptCommand",
+              "add-records-exemption-review": "#/components/schemas/ExemptionNoteCommand",
+              "add-records-exemption-decision": "#/components/schemas/ExemptionDecisionCommand",
+              "estimate-records-fee": "#/components/schemas/FeeEstimateCommand",
+              "add-records-fee-line": "#/components/schemas/FeeLineCommand",
+              "waive-records-fee": "#/components/schemas/FeeWaiverCommand",
+              "draft-records-response": "#/components/schemas/DraftCommand",
+              "approve-records-response": "#/components/schemas/ApprovalCommand",
+              "fulfill-records-request": "#/components/schemas/FinishCommand",
+              "close-records-request": "#/components/schemas/FinishCommand"
+            }
+          },
+          "title": "Command"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RecordsOperationRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/requests/{request_id}/artifacts +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Prepare Native Artifact",
+  "operationId": "prepare_native_artifact_desktop_v1_requests__request_id__artifacts_post",
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/PrepareArtifact"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/ArtifactPlan"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/requests/{request_id}/artifacts/{artifact_id}/complete +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Complete Native Artifact",
+  "operationId": "complete_native_artifact_desktop_v1_requests__request_id__artifacts__artifact_id__complete_post",
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "artifact_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Artifact Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/CompleteArtifact"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RecordsOperationRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/requests/{request_id}/code-sources +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Attach Code Source",
+  "operationId": "attach_code_source_desktop_v1_requests__request_id__code_sources_post",
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/CodeSourceSelection"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RecordsOperationRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/requests/{request_id}/documents +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Attach Native Document",
+  "operationId": "attach_native_document_desktop_v1_requests__request_id__documents_post",
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/AttachDocument"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RecordsOperationRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/requests/{request_id}/documents/{attachment_id}/release-copy +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Attach Native Release Copy",
+  "operationId": "attach_native_release_copy_desktop_v1_requests__request_id__documents__attachment_id__release_copy_post",
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "attachment_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Attachment Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/AttachReleaseCopy"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RecordsOperationRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/requests/{request_id}/draft-context +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Native Draft Context",
+  "operationId": "native_draft_context_desktop_v1_requests__request_id__draft_context_get",
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/requests/{request_id}/generated-draft +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Native Generated Draft",
+  "operationId": "native_generated_draft_desktop_v1_requests__request_id__generated_draft_post",
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/GeneratedDraft"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RecordsOperationRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/requests/{request_id}/inspections-sources +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Attach Inspections Source",
+  "operationId": "attach_inspections_source_desktop_v1_requests__request_id__inspections_sources_post",
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MeetingsSourceSelection"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RecordsOperationRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/requests/{request_id}/meetings-sources +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Attach Meetings Source",
+  "operationId": "attach_meetings_source_desktop_v1_requests__request_id__meetings_sources_post",
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MeetingsSourceSelection"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RecordsOperationRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/requests/{request_id}/permitting-sources +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Attach Permitting Source",
+  "operationId": "attach_permitting_source_desktop_v1_requests__request_id__permitting_sources_post",
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MeetingsSourceSelection"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RecordsOperationRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/requests/{request_id}/planning-sources +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Attach Planning Source",
+  "operationId": "attach_planning_source_desktop_v1_requests__request_id__planning_sources_post",
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MeetingsSourceSelection"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RecordsOperationRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/requests/{request_id}/station-recordings +
{
+  "tags": [
+    "native-desktop",
+    "station-integration"
+  ],
+  "summary": "Attach",
+  "operationId": "attach_desktop_v1_requests__request_id__station_recordings_post",
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/Selection"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RecordsOperationRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/requests/{request_id}/view +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Get Native Request View",
+  "operationId": "get_native_request_view_desktop_v1_requests__request_id__view_get",
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RecordsView"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/requests/{request_id}/zoning-sources +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Attach Zoning Source",
+  "operationId": "attach_zoning_source_desktop_v1_requests__request_id__zoning_sources_post",
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MeetingsSourceSelection"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RecordsOperationRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/station/context +
{
+  "tags": [
+    "native-desktop",
+    "station-integration"
+  ],
+  "summary": "Context",
+  "operationId": "context_desktop_v1_station_context_get",
+  "parameters": [
+    {
+      "name": "capability",
+      "in": "query",
+      "required": true,
+      "schema": {
+        "enum": [
+          "capture",
+          "read"
+        ],
+        "type": "string",
+        "title": "Capability"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/suite/search +
{
+  "tags": [
+    "native-records-snapshot"
+  ],
+  "summary": "Search",
+  "operationId": "search_desktop_v1_suite_search_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/SearchInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/suite/state +
{
+  "tags": [
+    "native-records-snapshot"
+  ],
+  "summary": "Suite State",
+  "operationId": "suite_state_desktop_v1_suite_state_get",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/zoning-sources/search +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Search Zoning Sources",
+  "operationId": "search_zoning_sources_desktop_v1_zoning_sources_search_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MeetingsSearch"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /documents/ +
{
+  "tags": [
+    "documents"
+  ],
+  "summary": "List Documents",
+  "operationId": "list_documents_documents__get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "source_id",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string",
+            "format": "uuid"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Source Id"
+      }
+    },
+    {
+      "name": "status",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "$ref": "#/components/schemas/IngestionStatus"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Status"
+      }
+    },
+    {
+      "name": "limit",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 500,
+        "default": 50,
+        "title": "Limit"
+      }
+    },
+    {
+      "name": "offset",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "default": 0,
+        "title": "Offset"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/DocumentRead"
+            },
+            "title": "Response List Documents Documents  Get"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /documents/{document_id} +
{
+  "tags": [
+    "documents"
+  ],
+  "summary": "Get Document",
+  "operationId": "get_document_documents__document_id__get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "document_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Document Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/DocumentRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /documents/{document_id}/chunks +
{
+  "tags": [
+    "documents"
+  ],
+  "summary": "List Chunks",
+  "operationId": "list_chunks_documents__document_id__chunks_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "document_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Document Id"
+      }
+    },
+    {
+      "name": "limit",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 500,
+        "default": 50,
+        "title": "Limit"
+      }
+    },
+    {
+      "name": "offset",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "default": 0,
+        "title": "Offset"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/DocumentChunkRead"
+            },
+            "title": "Response List Chunks Documents  Document Id  Chunks Get"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /exemptions/dashboard +
{
+  "tags": [
+    "exemptions"
+  ],
+  "summary": "Exemption Dashboard",
+  "operationId": "exemption_dashboard_exemptions_dashboard_get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/ExemptionDashboard"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
GET /exemptions/dashboard/accuracy +
{
+  "tags": [
+    "exemptions"
+  ],
+  "summary": "Exemption Accuracy",
+  "description": "Acceptance/rejection rates by category, optionally filtered by department.",
+  "operationId": "exemption_accuracy_exemptions_dashboard_accuracy_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "department_id",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string",
+            "format": "uuid"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Department Id"
+      }
+    },
+    {
+      "name": "date_from",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string",
+            "format": "date-time"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Date From"
+      }
+    },
+    {
+      "name": "date_to",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string",
+            "format": "date-time"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Date To"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/ExemptionAccuracyReport"
+            },
+            "title": "Response Exemption Accuracy Exemptions Dashboard Accuracy Get"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /exemptions/dashboard/export +
{
+  "tags": [
+    "exemptions"
+  ],
+  "summary": "Export Flag Data",
+  "description": "Export exemption flag data as JSON or CSV.",
+  "operationId": "export_flag_data_exemptions_dashboard_export_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "format",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "string",
+        "default": "json",
+        "title": "Format"
+      }
+    },
+    {
+      "name": "date_from",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string",
+            "format": "date-time"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Date From"
+      }
+    },
+    {
+      "name": "date_to",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string",
+            "format": "date-time"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Date To"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
PATCH /exemptions/flags/{flag_id} +
{
+  "tags": [
+    "exemptions"
+  ],
+  "summary": "Review Flag",
+  "operationId": "review_flag_exemptions_flags__flag_id__patch",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "flag_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Flag Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/ExemptionFlagReview"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/ExemptionFlagRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /exemptions/flags/{request_id} +
{
+  "tags": [
+    "exemptions"
+  ],
+  "summary": "List Flags",
+  "operationId": "list_flags_exemptions_flags__request_id__get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "status",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "$ref": "#/components/schemas/FlagStatus"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Status"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/ExemptionFlagRead"
+            },
+            "title": "Response List Flags Exemptions Flags  Request Id  Get"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /exemptions/rules/ +
{
+  "tags": [
+    "exemptions"
+  ],
+  "summary": "Create Rule",
+  "operationId": "create_rule_exemptions_rules__post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/ExemptionRuleCreate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/ExemptionRuleRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /exemptions/rules/ +
{
+  "tags": [
+    "exemptions"
+  ],
+  "summary": "List Rules",
+  "operationId": "list_rules_exemptions_rules__get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "state_code",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "State Code"
+      }
+    },
+    {
+      "name": "enabled",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "boolean"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Enabled"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/ExemptionRuleRead"
+            },
+            "title": "Response List Rules Exemptions Rules  Get"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
PATCH /exemptions/rules/{rule_id} +
{
+  "tags": [
+    "exemptions"
+  ],
+  "summary": "Update Rule",
+  "operationId": "update_rule_exemptions_rules__rule_id__patch",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "rule_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Rule Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/ExemptionRuleUpdate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/ExemptionRuleRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /exemptions/rules/{rule_id}/history +
{
+  "tags": [
+    "exemptions"
+  ],
+  "summary": "Get Rule History",
+  "description": "Get audit history for an exemption rule.",
+  "operationId": "get_rule_history_exemptions_rules__rule_id__history_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "rule_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Rule Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /exemptions/rules/{rule_id}/test +
{
+  "tags": [
+    "exemptions"
+  ],
+  "summary": "Test Rule",
+  "description": "Test a rule against sample text. Returns match results.\n\nUses the `regex` library with timeout=2s to prevent ReDoS on\nadmin-entered patterns.",
+  "operationId": "test_rule_exemptions_rules__rule_id__test_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "rule_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Rule Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/RuleTestRequest"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RuleTestResponse"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /exemptions/scan/{request_id} +
{
+  "tags": [
+    "exemptions"
+  ],
+  "summary": "Scan For Exemptions",
+  "description": "Scan all documents attached to a request for exemptions.",
+  "operationId": "scan_for_exemptions_exemptions_scan__request_id__post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "state_code",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "string",
+        "pattern": "^[A-Z]{2}$",
+        "default": "CO",
+        "title": "State Code"
+      }
+    },
+    {
+      "name": "use_llm",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "boolean",
+        "default": false,
+        "title": "Use Llm"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /exemptions/templates/ +
{
+  "tags": [
+    "exemptions"
+  ],
+  "summary": "List Templates",
+  "operationId": "list_templates_exemptions_templates__get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "template_type",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Template Type"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/DisclosureTemplateRead"
+            },
+            "title": "Response List Templates Exemptions Templates  Get"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /exemptions/templates/ +
{
+  "tags": [
+    "exemptions"
+  ],
+  "summary": "Create Template",
+  "operationId": "create_template_exemptions_templates__post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/DisclosureTemplateCreate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/DisclosureTemplateRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
PUT /exemptions/templates/{template_id} +
{
+  "tags": [
+    "exemptions"
+  ],
+  "summary": "Update Template",
+  "operationId": "update_template_exemptions_templates__template_id__put",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "template_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Template Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/DisclosureTemplateUpdate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/DisclosureTemplateRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /exemptions/templates/{template_id}/render +
{
+  "tags": [
+    "exemptions"
+  ],
+  "summary": "Render Template",
+  "description": "Render a template with city profile variables substituted.",
+  "operationId": "render_template_exemptions_templates__template_id__render_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "template_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Template Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/DisclosureTemplateRendered"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /health +
{
+  "summary": "Health",
+  "operationId": "health_health_get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    }
+  }
+}
+
GET /notifications/log +
{
+  "tags": [
+    "notifications"
+  ],
+  "summary": "List Notification Log",
+  "description": "List recent notification log entries.",
+  "operationId": "list_notification_log_notifications_log_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "limit",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 200,
+        "default": 50,
+        "title": "Limit"
+      }
+    },
+    {
+      "name": "request_id",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string",
+            "format": "uuid"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Request Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/NotificationLogRead"
+            },
+            "title": "Response List Notification Log Notifications Log Get"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /notifications/templates +
{
+  "tags": [
+    "notifications"
+  ],
+  "summary": "List Templates",
+  "description": "List all notification templates.",
+  "operationId": "list_templates_notifications_templates_get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "items": {
+              "$ref": "#/components/schemas/NotificationTemplateRead"
+            },
+            "type": "array",
+            "title": "Response List Templates Notifications Templates Get"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
POST /notifications/templates +
{
+  "tags": [
+    "notifications"
+  ],
+  "summary": "Create Template",
+  "description": "Create a new notification template (admin only).",
+  "operationId": "create_template_notifications_templates_post",
+  "requestBody": {
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/NotificationTemplateCreate"
+        }
+      }
+    },
+    "required": true
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/NotificationTemplateRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
PATCH /notifications/templates/{template_id} +
{
+  "tags": [
+    "notifications"
+  ],
+  "summary": "Update Template",
+  "description": "Update a notification template (admin only).",
+  "operationId": "update_template_notifications_templates__template_id__patch",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "template_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Template Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/NotificationTemplateUpdate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/NotificationTemplateRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /onboarding/interview +
{
+  "tags": [
+    "onboarding"
+  ],
+  "summary": "Get Next Question",
+  "description": "Generate the next onboarding question and persist the last answer.",
+  "operationId": "get_next_question_onboarding_interview_post",
+  "requestBody": {
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/InterviewRequest"
+        }
+      }
+    },
+    "required": true
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/InterviewResponse"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
POST /requests/ +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Create Request",
+  "operationId": "create_request_requests__post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/RequestCreate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RequestRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /requests/ +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "List Requests",
+  "operationId": "list_requests_requests__get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "status",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "$ref": "#/components/schemas/RequestStatus"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Status"
+      }
+    },
+    {
+      "name": "assigned_to",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string",
+            "format": "uuid"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Assigned To"
+      }
+    },
+    {
+      "name": "limit",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "default": 50,
+        "title": "Limit"
+      }
+    },
+    {
+      "name": "offset",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "default": 0,
+        "title": "Offset"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/RequestRead"
+            },
+            "title": "Response List Requests Requests  Get"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /requests/stats +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Request Stats",
+  "operationId": "request_stats_requests_stats_get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RequestStats"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
GET /requests/{request_id} +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Get Request",
+  "operationId": "get_request_requests__request_id__get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RequestRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
PATCH /requests/{request_id} +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Update Request",
+  "operationId": "update_request_requests__request_id__patch",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/RequestUpdate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RequestRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /requests/{request_id}/approve +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Approve Request",
+  "operationId": "approve_request_requests__request_id__approve_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RequestRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /requests/{request_id}/documents +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Attach Document",
+  "operationId": "attach_document_requests__request_id__documents_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/RequestDocumentAdd"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RequestDocumentRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /requests/{request_id}/documents +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "List Attached Documents",
+  "operationId": "list_attached_documents_requests__request_id__documents_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/RequestDocumentRead"
+            },
+            "title": "Response List Attached Documents Requests  Request Id  Documents Get"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
DELETE /requests/{request_id}/documents/{doc_id} +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Remove Document",
+  "operationId": "remove_document_requests__request_id__documents__doc_id__delete",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "doc_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Doc Id"
+      }
+    }
+  ],
+  "responses": {
+    "204": {
+      "description": "Successful Response"
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /requests/{request_id}/estimate-fees +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Estimate Fees",
+  "description": "Estimate fees based on staff-entered page count and fee schedule.\n\nPage count is a manual staff estimate — not inferred from ingested docs.",
+  "operationId": "estimate_fees_requests__request_id__estimate_fees_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/FeeEstimateRequest"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/FeeEstimateResponse"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /requests/{request_id}/fee-waiver +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Create Fee Waiver",
+  "description": "Request a fee waiver for this records request.",
+  "operationId": "create_fee_waiver_requests__request_id__fee_waiver_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/FeeWaiverCreateRequest"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/FeeWaiverReadResponse"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
PATCH /requests/{request_id}/fee-waiver/{waiver_id} +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Review Fee Waiver",
+  "description": "Approve or deny a fee waiver. Reviewer/Admin only.",
+  "operationId": "review_fee_waiver_requests__request_id__fee_waiver__waiver_id__patch",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "waiver_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Waiver Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/FeeWaiverReviewRequest"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/FeeWaiverReadResponse"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /requests/{request_id}/fees +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Get Fees",
+  "operationId": "get_fees_requests__request_id__fees_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/FeeLineItemRead"
+            },
+            "title": "Response Get Fees Requests  Request Id  Fees Get"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /requests/{request_id}/fees +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Add Fee",
+  "operationId": "add_fee_requests__request_id__fees_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/FeeLineItemCreate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/FeeLineItemRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /requests/{request_id}/messages +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Get Messages",
+  "operationId": "get_messages_requests__request_id__messages_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/MessageRead"
+            },
+            "title": "Response Get Messages Requests  Request Id  Messages Get"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /requests/{request_id}/messages +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Add Message",
+  "operationId": "add_message_requests__request_id__messages_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MessageCreate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/MessageRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /requests/{request_id}/ready-for-release +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Mark Ready For Release",
+  "operationId": "mark_ready_for_release_requests__request_id__ready_for_release_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RequestRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /requests/{request_id}/reject +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Reject Request",
+  "operationId": "reject_request_requests__request_id__reject_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "reason",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "string",
+        "default": "",
+        "title": "Reason"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RequestRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /requests/{request_id}/response-letter +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Generate Response Letter",
+  "description": "Generate a draft response letter for a records request.\n\nAttempts LLM generation via Ollama first; falls back to a structured\ntemplate if the LLM is unavailable.",
+  "operationId": "generate_response_letter_requests__request_id__response_letter_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "content": {
+      "application/json": {
+        "schema": {
+          "anyOf": [
+            {
+              "$ref": "#/components/schemas/ResponseLetterCreate"
+            },
+            {
+              "type": "null"
+            }
+          ],
+          "title": "Data"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/ResponseLetterRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /requests/{request_id}/response-letter +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Get Response Letter",
+  "description": "Get the latest response letter for a request.",
+  "operationId": "get_response_letter_requests__request_id__response_letter_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/ResponseLetterRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
PATCH /requests/{request_id}/response-letter/{letter_id} +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Update Response Letter",
+  "description": "Update a response letter's edited content or status.\n\nStatus changes to 'approved' require REVIEWER role.",
+  "operationId": "update_response_letter_requests__request_id__response_letter__letter_id__patch",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "letter_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Letter Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/ResponseLetterUpdate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/ResponseLetterRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /requests/{request_id}/submit-review +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Submit For Review",
+  "operationId": "submit_for_review_requests__request_id__submit_review_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RequestRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /requests/{request_id}/timeline +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Get Timeline",
+  "operationId": "get_timeline_requests__request_id__timeline_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/TimelineEventRead"
+            },
+            "title": "Response Get Timeline Requests  Request Id  Timeline Get"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /requests/{request_id}/timeline +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Add Timeline Event",
+  "operationId": "add_timeline_event_requests__request_id__timeline_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/TimelineEventCreate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/TimelineEventRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /search/export +
{
+  "tags": [
+    "search"
+  ],
+  "summary": "Export Search Results",
+  "description": "Export search results as CSV. Runs a search and streams the results.",
+  "operationId": "export_search_results_search_export_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "query",
+      "in": "query",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Query"
+      }
+    },
+    {
+      "name": "format",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "string",
+        "default": "csv",
+        "title": "Format"
+      }
+    },
+    {
+      "name": "department_id",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Department Id"
+      }
+    },
+    {
+      "name": "file_type",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "File Type"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /search/filters +
{
+  "tags": [
+    "search"
+  ],
+  "summary": "Get Filter Options",
+  "description": "Get available filter values for search.",
+  "operationId": "get_filter_options_search_filters_get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/SearchFilterOptions"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
POST /search/query +
{
+  "tags": [
+    "search"
+  ],
+  "summary": "Execute Search",
+  "description": "Execute a hybrid search query. Optionally synthesize an LLM answer.",
+  "operationId": "execute_search_search_query_post",
+  "requestBody": {
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/SearchRequest"
+        }
+      }
+    },
+    "required": true
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/SearchResponse"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
GET /search/sessions +
{
+  "tags": [
+    "search"
+  ],
+  "summary": "List Sessions",
+  "description": "List the current user's search sessions.",
+  "operationId": "list_sessions_search_sessions_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "limit",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "default": 20,
+        "title": "Limit"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/SearchSessionRead"
+            },
+            "title": "Response List Sessions Search Sessions Get"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /search/sessions/{session_id} +
{
+  "tags": [
+    "search"
+  ],
+  "summary": "Get Session",
+  "description": "Get a search session with its query history.",
+  "operationId": "get_session_search_sessions__session_id__get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "session_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Session Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/SearchSessionRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /service-accounts/ +
{
+  "tags": [
+    "service-accounts"
+  ],
+  "summary": "List Service Accounts",
+  "operationId": "list_service_accounts_service_accounts__get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "items": {
+              "$ref": "#/components/schemas/ServiceAccountRead"
+            },
+            "type": "array",
+            "title": "Response List Service Accounts Service Accounts  Get"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
POST /service-accounts/ +
{
+  "tags": [
+    "service-accounts"
+  ],
+  "summary": "Create Service Account",
+  "operationId": "create_service_account_service_accounts__post",
+  "requestBody": {
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/ServiceAccountCreate"
+        }
+      }
+    },
+    "required": true
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/ServiceAccountCreated"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
PATCH /service-accounts/{account_id} +
{
+  "tags": [
+    "service-accounts"
+  ],
+  "summary": "Update Service Account",
+  "operationId": "update_service_account_service_accounts__account_id__patch",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "account_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Account Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/ServiceAccountUpdate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/ServiceAccountRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /users/me +
{
+  "tags": [
+    "users"
+  ],
+  "summary": "Users:Current User",
+  "operationId": "users_current_user_users_me_get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/UserRead"
+          }
+        }
+      }
+    },
+    "401": {
+      "description": "Missing token or inactive user."
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
PATCH /users/me +
{
+  "tags": [
+    "users"
+  ],
+  "summary": "Users:Patch Current User",
+  "operationId": "users_patch_current_user_users_me_patch",
+  "requestBody": {
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/UserSelfUpdate"
+        }
+      }
+    },
+    "required": true
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/UserRead"
+          }
+        }
+      }
+    },
+    "401": {
+      "description": "Missing token or inactive user."
+    },
+    "400": {
+      "description": "Bad Request",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/ErrorModel"
+          },
+          "examples": {
+            "UPDATE_USER_EMAIL_ALREADY_EXISTS": {
+              "summary": "A user with this email already exists.",
+              "value": {
+                "detail": "UPDATE_USER_EMAIL_ALREADY_EXISTS"
+              }
+            },
+            "UPDATE_USER_INVALID_PASSWORD": {
+              "summary": "Password validation failed.",
+              "value": {
+                "detail": {
+                  "code": "UPDATE_USER_INVALID_PASSWORD",
+                  "reason": "Password should beat least 3 characters"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
GET /users/{id} +
{
+  "tags": [
+    "users"
+  ],
+  "summary": "Users:User",
+  "operationId": "users_user_users__id__get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/UserRead"
+          }
+        }
+      }
+    },
+    "401": {
+      "description": "Missing token or inactive user."
+    },
+    "403": {
+      "description": "Not a superuser."
+    },
+    "404": {
+      "description": "The user does not exist."
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
PATCH /users/{id} +
{
+  "tags": [
+    "users"
+  ],
+  "summary": "Users:Patch User",
+  "operationId": "users_patch_user_users__id__patch",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/UserSelfUpdate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/UserRead"
+          }
+        }
+      }
+    },
+    "401": {
+      "description": "Missing token or inactive user."
+    },
+    "403": {
+      "description": "Not a superuser."
+    },
+    "404": {
+      "description": "The user does not exist."
+    },
+    "400": {
+      "content": {
+        "application/json": {
+          "examples": {
+            "UPDATE_USER_EMAIL_ALREADY_EXISTS": {
+              "summary": "A user with this email already exists.",
+              "value": {
+                "detail": "UPDATE_USER_EMAIL_ALREADY_EXISTS"
+              }
+            },
+            "UPDATE_USER_INVALID_PASSWORD": {
+              "summary": "Password validation failed.",
+              "value": {
+                "detail": {
+                  "code": "UPDATE_USER_INVALID_PASSWORD",
+                  "reason": "Password should beat least 3 characters"
+                }
+              }
+            }
+          },
+          "schema": {
+            "$ref": "#/components/schemas/ErrorModel"
+          }
+        }
+      },
+      "description": "Bad Request"
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
DELETE /users/{id} +
{
+  "tags": [
+    "users"
+  ],
+  "summary": "Users:Delete User",
+  "operationId": "users_delete_user_users__id__delete",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Id"
+      }
+    }
+  ],
+  "responses": {
+    "204": {
+      "description": "Successful Response"
+    },
+    "401": {
+      "description": "Missing token or inactive user."
+    },
+    "403": {
+      "description": "Not a superuser."
+    },
+    "404": {
+      "description": "The user does not exist."
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+

Request and response data dictionary

+

Each schema includes the actual required fields, types, constraints and descriptions. References resolve against the machine-readable document.

+
ActionItemInput
+{
+  "properties": {
+    "description": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Description"
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "source_motion_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Motion Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "description"
+  ],
+  "title": "ActionItemInput"
+}
+
+
AdaPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "ada-title-ii",
+      "title": "Action"
+    },
+    "serviceArea": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Servicearea"
+    },
+    "hasCoordinatorReview": {
+      "type": "boolean",
+      "title": "Hascoordinatorreview",
+      "default": false
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "serviceArea"
+  ],
+  "title": "AdaPlan"
+}
+
+
AdminUserCreateRequest
+{
+  "properties": {
+    "email": {
+      "type": "string",
+      "title": "Email"
+    },
+    "password": {
+      "type": "string",
+      "title": "Password"
+    },
+    "full_name": {
+      "type": "string",
+      "title": "Full Name",
+      "default": ""
+    },
+    "role": {
+      "type": "string",
+      "title": "Role",
+      "default": "staff"
+    }
+  },
+  "type": "object",
+  "required": [
+    "email",
+    "password"
+  ],
+  "title": "AdminUserCreateRequest"
+}
+
+
AdminUserCreateResponse
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "email": {
+      "type": "string",
+      "title": "Email"
+    },
+    "full_name": {
+      "type": "string",
+      "title": "Full Name"
+    },
+    "role": {
+      "type": "string",
+      "title": "Role"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "email",
+    "full_name",
+    "role",
+    "is_active"
+  ],
+  "title": "AdminUserCreateResponse"
+}
+
+
AgendaAssignment
+{
+  "properties": {
+    "meeting_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Meeting Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "meeting_id"
+  ],
+  "title": "AgendaAssignment"
+}
+
+
AgendaInput
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "department_name": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Department Name"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "department_name"
+  ],
+  "title": "AgendaInput"
+}
+
+
AgendaReviewInput
+{
+  "properties": {
+    "to_status": {
+      "type": "string",
+      "enum": [
+        "DRAFTED",
+        "SUBMITTED",
+        "DEPT_APPROVED",
+        "LEGAL_REVIEWED",
+        "CLERK_ACCEPTED",
+        "ON_AGENDA",
+        "IN_PACKET",
+        "POSTED",
+        "HEARD",
+        "DISPOSED",
+        "ARCHIVED"
+      ],
+      "title": "To Status"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "to_status"
+  ],
+  "title": "AgendaReviewInput"
+}
+
+
AmendmentInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "policy": {
+      "$ref": "#/components/schemas/PolicySelection"
+    },
+    "proposal": {
+      "type": "string",
+      "maxLength": 20000,
+      "minLength": 1,
+      "title": "Proposal"
+    },
+    "responsible_staff": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Responsible Staff"
+    },
+    "status": {
+      "type": "string",
+      "enum": [
+        "draft",
+        "review",
+        "adopted",
+        "withdrawn"
+      ],
+      "title": "Status",
+      "default": "draft"
+    },
+    "review_note": {
+      "type": "string",
+      "maxLength": 5000,
+      "title": "Review Note",
+      "default": ""
+    },
+    "adoption_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Adoption Revision"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "policy",
+    "proposal",
+    "responsible_staff",
+    "note"
+  ],
+  "title": "AmendmentInput"
+}
+
+
AnalysisObservation
+{
+  "properties": {
+    "source": {
+      "type": "string",
+      "maxLength": 64,
+      "minLength": 1,
+      "title": "Source"
+    },
+    "filename": {
+      "type": "string",
+      "maxLength": 160,
+      "title": "Filename",
+      "default": ""
+    },
+    "media_type": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Media Type",
+      "default": ""
+    },
+    "text": {
+      "type": "string",
+      "maxLength": 4000,
+      "minLength": 1,
+      "title": "Text"
+    },
+    "adapter": {
+      "type": "string",
+      "maxLength": 120,
+      "title": "Adapter",
+      "default": ""
+    },
+    "citation_source_ids": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Citation Source Ids"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source",
+    "text"
+  ],
+  "title": "AnalysisObservation",
+  "description": "One draft observation, named with the adapter that actually produced it."
+}
+
+
AnalysisRecord
+{
+  "properties": {
+    "observations": {
+      "items": {
+        "$ref": "#/components/schemas/AnalysisObservation"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Observations"
+    },
+    "cited_sections": {
+      "items": {
+        "$ref": "#/components/schemas/CitedSection"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Cited Sections"
+    },
+    "unavailable": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Unavailable"
+    },
+    "runtime": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Runtime"
+    },
+    "review_required": {
+      "type": "boolean",
+      "title": "Review Required",
+      "default": true
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "AnalysisRecord",
+  "description": "The adapter output that accompanies a saved inspection draft."
+}
+
+
ApprovalCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "approve-records-response",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ApprovalPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "ApprovalCommand"
+}
+
+
ApprovalPayload
+{
+  "properties": {
+    "approvalNote": {
+      "type": "string",
+      "title": "Approvalnote",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "ApprovalPayload"
+}
+
+
ArchiveInput
+{
+  "properties": {
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "public",
+        "closed_session"
+      ],
+      "title": "Visibility"
+    },
+    "packet_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Packet Id"
+    },
+    "minutes_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Minutes Id"
+    },
+    "plain_language_summary": {
+      "type": "string",
+      "title": "Plain Language Summary",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "visibility"
+  ],
+  "title": "ArchiveInput"
+}
+
+
ArtifactPlan
+{
+  "properties": {
+    "artifact_id": {
+      "type": "string",
+      "title": "Artifact Id"
+    },
+    "file_name": {
+      "type": "string",
+      "title": "File Name"
+    },
+    "content": {
+      "type": "string",
+      "title": "Content"
+    },
+    "sha256": {
+      "type": "string",
+      "title": "Sha256"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "artifact_id",
+    "file_name",
+    "content",
+    "sha256",
+    "created_at_unix_seconds"
+  ],
+  "title": "ArtifactPlan"
+}
+
+
AssignCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "assign-records-request",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/AssignmentPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "AssignCommand"
+}
+
+
AssignmentPayload
+{
+  "properties": {
+    "assignedTo": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Assignedto"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "assignedTo"
+  ],
+  "title": "AssignmentPayload"
+}
+
+
AttachDocument
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation",
+      "default": ""
+    },
+    "file": {
+      "$ref": "#/components/schemas/ManagedFileReceipt"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "file"
+  ],
+  "title": "AttachDocument"
+}
+
+
AttachReleaseCopy
+{
+  "properties": {
+    "status": {
+      "type": "string",
+      "enum": [
+        "release-ready copy",
+        "redacted copy"
+      ],
+      "title": "Status"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note",
+      "default": ""
+    },
+    "added_by": {
+      "type": "string",
+      "title": "Added By",
+      "default": ""
+    },
+    "file": {
+      "$ref": "#/components/schemas/ManagedFileReceipt"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "status",
+    "file"
+  ],
+  "title": "AttachReleaseCopy"
+}
+
+
AuditChainVerification
+{
+  "properties": {
+    "is_valid": {
+      "type": "boolean",
+      "title": "Is Valid"
+    },
+    "entries_checked": {
+      "type": "integer",
+      "title": "Entries Checked"
+    },
+    "error_message": {
+      "type": "string",
+      "title": "Error Message"
+    }
+  },
+  "type": "object",
+  "required": [
+    "is_valid",
+    "entries_checked",
+    "error_message"
+  ],
+  "title": "AuditChainVerification"
+}
+
+
AuditLogRead
+{
+  "properties": {
+    "id": {
+      "type": "integer",
+      "title": "Id"
+    },
+    "prev_hash": {
+      "type": "string",
+      "title": "Prev Hash"
+    },
+    "entry_hash": {
+      "type": "string",
+      "title": "Entry Hash"
+    },
+    "timestamp": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Timestamp"
+    },
+    "user_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "User Id"
+    },
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "resource_type": {
+      "type": "string",
+      "title": "Resource Type"
+    },
+    "resource_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Resource Id"
+    },
+    "details": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Details"
+    },
+    "ai_generated": {
+      "type": "boolean",
+      "title": "Ai Generated"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "prev_hash",
+    "entry_hash",
+    "timestamp",
+    "user_id",
+    "action",
+    "resource_type",
+    "resource_id",
+    "details",
+    "ai_generated"
+  ],
+  "title": "AuditLogRead"
+}
+
+
AuditView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "module_id": {
+      "type": "string",
+      "title": "Module Id"
+    },
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    },
+    "previous_hash": {
+      "type": "string",
+      "title": "Previous Hash"
+    },
+    "entry_hash": {
+      "type": "string",
+      "title": "Entry Hash"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "module_id",
+    "action",
+    "summary",
+    "created_at_unix_seconds",
+    "previous_hash",
+    "entry_hash"
+  ],
+  "title": "AuditView"
+}
+
+
BearerResponse
+{
+  "properties": {
+    "access_token": {
+      "type": "string",
+      "title": "Access Token"
+    },
+    "token_type": {
+      "type": "string",
+      "title": "Token Type"
+    }
+  },
+  "type": "object",
+  "required": [
+    "access_token",
+    "token_type"
+  ],
+  "title": "BearerResponse"
+}
+
+
Body_auth_jwt_login_auth_jwt_login_post
+{
+  "properties": {
+    "grant_type": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^password$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Grant Type"
+    },
+    "username": {
+      "type": "string",
+      "title": "Username"
+    },
+    "password": {
+      "type": "string",
+      "format": "password",
+      "title": "Password"
+    },
+    "scope": {
+      "type": "string",
+      "title": "Scope",
+      "default": ""
+    },
+    "client_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Client Id"
+    },
+    "client_secret": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "format": "password",
+      "title": "Client Secret"
+    }
+  },
+  "type": "object",
+  "required": [
+    "username",
+    "password"
+  ],
+  "title": "Body_auth_jwt_login_auth_jwt_login_post"
+}
+
+
Body_upload_file_datasources_upload_post
+{
+  "properties": {
+    "file": {
+      "type": "string",
+      "contentMediaType": "application/octet-stream",
+      "title": "File"
+    }
+  },
+  "type": "object",
+  "required": [
+    "file"
+  ],
+  "title": "Body_upload_file_datasources_upload_post"
+}
+
+
CalculateDeadlineCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "calculate-records-deadline",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/CalculateDeadlinePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "CalculateDeadlineCommand"
+}
+
+
CalculateDeadlinePayload
+{
+  "properties": {
+    "deadlineReceivedDate": {
+      "type": "string",
+      "title": "Deadlinereceiveddate"
+    },
+    "deadlineRuleName": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Deadlinerulename"
+    },
+    "deadlineDayCount": {
+      "type": "string",
+      "title": "Deadlinedaycount"
+    },
+    "deadlineDayType": {
+      "type": "string",
+      "title": "Deadlinedaytype"
+    },
+    "deadlineBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Deadlinebasis"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "deadlineReceivedDate",
+    "deadlineRuleName",
+    "deadlineDayCount",
+    "deadlineDayType",
+    "deadlineBasis"
+  ],
+  "title": "CalculateDeadlinePayload"
+}
+
+
ChapterCreate
+{
+  "properties": {
+    "chapter_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Chapter Id"
+    },
+    "title_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title Id"
+    },
+    "chapter_number": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Chapter Number"
+    },
+    "chapter_name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Chapter Name"
+    },
+    "sort_order": {
+      "type": "integer",
+      "title": "Sort Order",
+      "default": 0
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title_id",
+    "chapter_number",
+    "chapter_name"
+  ],
+  "title": "ChapterCreate",
+  "description": "Request body for creating a code chapter."
+}
+
+
CitedSection
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "citation": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Citation"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "version": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Version",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "citation"
+  ],
+  "title": "CitedSection",
+  "description": "One resolved public Code section; never a caller-supplied quotation."
+}
+
+
CityProfileCreate
+{
+  "properties": {
+    "city_name": {
+      "type": "string",
+      "title": "City Name"
+    },
+    "state": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State"
+    },
+    "county": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "County"
+    },
+    "population_band": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Population Band"
+    },
+    "email_platform": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email Platform"
+    },
+    "has_dedicated_it": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Has Dedicated It"
+    },
+    "monthly_request_volume": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Monthly Request Volume"
+    },
+    "profile_data": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Profile Data",
+      "default": {}
+    },
+    "gap_map": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Gap Map",
+      "default": {}
+    }
+  },
+  "type": "object",
+  "required": [
+    "city_name"
+  ],
+  "title": "CityProfileCreate"
+}
+
+
CityProfileRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "city_name": {
+      "type": "string",
+      "title": "City Name"
+    },
+    "state": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State"
+    },
+    "county": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "County"
+    },
+    "population_band": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Population Band"
+    },
+    "email_platform": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email Platform"
+    },
+    "has_dedicated_it": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Has Dedicated It"
+    },
+    "monthly_request_volume": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Monthly Request Volume"
+    },
+    "onboarding_status": {
+      "type": "string",
+      "title": "Onboarding Status"
+    },
+    "profile_data": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Profile Data"
+    },
+    "gap_map": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Gap Map"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "updated_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "city_name",
+    "state",
+    "county",
+    "population_band",
+    "email_platform",
+    "has_dedicated_it",
+    "monthly_request_volume",
+    "onboarding_status",
+    "profile_data",
+    "gap_map",
+    "created_at",
+    "updated_at"
+  ],
+  "title": "CityProfileRead"
+}
+
+
CityProfileUpdate
+{
+  "properties": {
+    "city_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "City Name"
+    },
+    "state": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State"
+    },
+    "county": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "County"
+    },
+    "population_band": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Population Band"
+    },
+    "email_platform": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email Platform"
+    },
+    "has_dedicated_it": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Has Dedicated It"
+    },
+    "monthly_request_volume": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Monthly Request Volume"
+    },
+    "onboarding_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Onboarding Status"
+    },
+    "profile_data": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Profile Data"
+    },
+    "gap_map": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Gap Map"
+    }
+  },
+  "type": "object",
+  "title": "CityProfileUpdate"
+}
+
+
ClarificationCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "request-records-clarification",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ClarificationPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "ClarificationCommand"
+}
+
+
ClarificationPayload
+{
+  "properties": {
+    "clarificationNote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Clarificationnote"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "clarificationNote"
+  ],
+  "title": "ClarificationPayload"
+}
+
+
Closeout
+{
+  "properties": {
+    "decision_id": {
+      "type": "string",
+      "pattern": "^[A-Za-z0-9_-]{1,64}$",
+      "title": "Decision Id"
+    },
+    "version_id": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Version Id"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "version_label": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Version Label"
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 1000000,
+      "minLength": 1,
+      "title": "Body"
+    },
+    "effective_start": {
+      "type": "string",
+      "format": "date",
+      "title": "Effective Start"
+    },
+    "effective_end": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective End"
+    },
+    "is_current": {
+      "type": "boolean",
+      "title": "Is Current"
+    },
+    "reconciliation_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reconciliation Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "decision_id",
+    "version_id",
+    "source_id",
+    "version_label",
+    "body",
+    "effective_start",
+    "is_current"
+  ],
+  "title": "Closeout"
+}
+
+
CodeContext
+{
+  "properties": {
+    "section_number": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Section Number"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "section_number"
+  ],
+  "title": "CodeContext"
+}
+
+
CodeLink
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "const": "code",
+      "title": "Provider",
+      "default": "code"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "CodeLink"
+}
+
+
CodeSearch
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "CodeSearch"
+}
+
+
CodeSourceSelection
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 200,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "CodeSourceSelection"
+}
+
+
CompleteArtifact
+{
+  "properties": {
+    "export_path": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Export Path"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "export_path"
+  ],
+  "title": "CompleteArtifact"
+}
+
+
ConnectionSearch
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "enum": [
+        "meetings",
+        "zoning"
+      ],
+      "title": "Provider"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "query"
+  ],
+  "title": "ConnectionSearch"
+}
+
+
CoverageGapResponse
+{
+  "properties": {
+    "jurisdictions_without_rules": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Jurisdictions Without Rules"
+    },
+    "departments_without_staff": {
+      "items": {
+        "additionalProperties": true,
+        "type": "object"
+      },
+      "type": "array",
+      "title": "Departments Without Staff"
+    },
+    "uncovered_categories": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Uncovered Categories"
+    },
+    "total_gaps": {
+      "type": "integer",
+      "title": "Total Gaps"
+    }
+  },
+  "type": "object",
+  "required": [
+    "jurisdictions_without_rules",
+    "departments_without_staff",
+    "uncovered_categories",
+    "total_gaps"
+  ],
+  "title": "CoverageGapResponse"
+}
+
+
DataSourceAdminRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "source_type": {
+      "$ref": "#/components/schemas/SourceType"
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "type": "boolean",
+      "title": "Schedule Enabled",
+      "default": true
+    },
+    "next_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Next Sync At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "last_ingestion_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Ingestion At"
+    },
+    "last_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync At"
+    },
+    "last_sync_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync Status"
+    },
+    "last_error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Error Message"
+    },
+    "consecutive_failure_count": {
+      "type": "integer",
+      "title": "Consecutive Failure Count",
+      "default": 0
+    },
+    "sync_paused": {
+      "type": "boolean",
+      "title": "Sync Paused",
+      "default": false
+    },
+    "health_status": {
+      "type": "string",
+      "title": "Health Status",
+      "default": "healthy"
+    },
+    "active_failure_count": {
+      "type": "integer",
+      "title": "Active Failure Count",
+      "default": 0
+    },
+    "connector_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connector Type"
+    },
+    "updated_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Updated At"
+    },
+    "connection_config": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Connection Config"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "source_type",
+    "is_active",
+    "created_by",
+    "created_at",
+    "last_ingestion_at",
+    "connection_config"
+  ],
+  "title": "DataSourceAdminRead",
+  "description": "Full datasource shape including connection_config. Returned only by admin-gated endpoints."
+}
+
+
DataSourceCreate
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "source_type": {
+      "$ref": "#/components/schemas/SourceType"
+    },
+    "connection_config": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Connection Config",
+      "default": {}
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "type": "boolean",
+      "title": "Schedule Enabled",
+      "default": true
+    }
+  },
+  "type": "object",
+  "required": [
+    "name",
+    "source_type"
+  ],
+  "title": "DataSourceCreate"
+}
+
+
DataSourceRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "source_type": {
+      "$ref": "#/components/schemas/SourceType"
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "type": "boolean",
+      "title": "Schedule Enabled",
+      "default": true
+    },
+    "next_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Next Sync At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "last_ingestion_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Ingestion At"
+    },
+    "last_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync At"
+    },
+    "last_sync_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync Status"
+    },
+    "last_error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Error Message"
+    },
+    "consecutive_failure_count": {
+      "type": "integer",
+      "title": "Consecutive Failure Count",
+      "default": 0
+    },
+    "sync_paused": {
+      "type": "boolean",
+      "title": "Sync Paused",
+      "default": false
+    },
+    "health_status": {
+      "type": "string",
+      "title": "Health Status",
+      "default": "healthy"
+    },
+    "active_failure_count": {
+      "type": "integer",
+      "title": "Active Failure Count",
+      "default": 0
+    },
+    "connector_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connector Type"
+    },
+    "updated_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "source_type",
+    "is_active",
+    "created_by",
+    "created_at",
+    "last_ingestion_at"
+  ],
+  "title": "DataSourceRead",
+  "description": "Redacted datasource shape — safe for non-admin roles. connection_config omitted."
+}
+
+
DataSourceUpdate
+{
+  "properties": {
+    "name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Name"
+    },
+    "connection_config": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connection Config"
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Schedule Enabled"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "DataSourceUpdate"
+}
+
+
DeadlineCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "set-records-deadline",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/DeadlinePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "DeadlineCommand"
+}
+
+
DeadlinePayload
+{
+  "properties": {
+    "deadline": {
+      "type": "string",
+      "title": "Deadline"
+    },
+    "deadlineBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Deadlinebasis"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "deadline",
+    "deadlineBasis"
+  ],
+  "title": "DeadlinePayload"
+}
+
+
Decision
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "pattern": "^[A-Za-z0-9_-]{1,64}$",
+      "title": "Id"
+    },
+    "outcome": {
+      "type": "string",
+      "enum": [
+        "adopted",
+        "not_adopted",
+        "deferred",
+        "withdrawn"
+      ],
+      "title": "Outcome"
+    },
+    "decided_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Decided At"
+    },
+    "decision_text": {
+      "type": "string",
+      "maxLength": 1000000,
+      "minLength": 1,
+      "title": "Decision Text"
+    },
+    "supporting_references": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Supporting References"
+    },
+    "supersedes_decision_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^[A-Za-z0-9_-]{1,64}$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supersedes Decision Id"
+    },
+    "reconciliation_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reconciliation Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "outcome",
+    "decision_text"
+  ],
+  "title": "Decision"
+}
+
+
DepartmentCreate
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "code": {
+      "type": "string",
+      "title": "Code"
+    },
+    "contact_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Contact Email"
+    }
+  },
+  "type": "object",
+  "required": [
+    "name",
+    "code"
+  ],
+  "title": "DepartmentCreate"
+}
+
+
DepartmentRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "code": {
+      "type": "string",
+      "title": "Code"
+    },
+    "contact_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Contact Email"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "code",
+    "contact_email",
+    "created_at"
+  ],
+  "title": "DepartmentRead"
+}
+
+
DepartmentUpdate
+{
+  "properties": {
+    "name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Name"
+    },
+    "code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Code"
+    },
+    "contact_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Contact Email"
+    }
+  },
+  "type": "object",
+  "title": "DepartmentUpdate"
+}
+
+
DisclosureTemplateCreate
+{
+  "properties": {
+    "template_type": {
+      "type": "string",
+      "title": "Template Type"
+    },
+    "state_code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State Code"
+    },
+    "content": {
+      "type": "string",
+      "title": "Content"
+    }
+  },
+  "type": "object",
+  "required": [
+    "template_type",
+    "content"
+  ],
+  "title": "DisclosureTemplateCreate"
+}
+
+
DisclosureTemplateRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "template_type": {
+      "type": "string",
+      "title": "Template Type"
+    },
+    "state_code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State Code"
+    },
+    "content": {
+      "type": "string",
+      "title": "Content"
+    },
+    "version": {
+      "type": "integer",
+      "title": "Version"
+    },
+    "updated_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Updated By"
+    },
+    "updated_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "template_type",
+    "state_code",
+    "content",
+    "version",
+    "updated_by",
+    "updated_at"
+  ],
+  "title": "DisclosureTemplateRead"
+}
+
+
DisclosureTemplateRendered
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "template_type": {
+      "type": "string",
+      "title": "Template Type"
+    },
+    "rendered_content": {
+      "type": "string",
+      "title": "Rendered Content"
+    },
+    "has_unresolved_variables": {
+      "type": "boolean",
+      "title": "Has Unresolved Variables"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "template_type",
+    "rendered_content",
+    "has_unresolved_variables"
+  ],
+  "title": "DisclosureTemplateRendered"
+}
+
+
DisclosureTemplateUpdate
+{
+  "properties": {
+    "content": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Content"
+    },
+    "state_code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State Code"
+    }
+  },
+  "type": "object",
+  "title": "DisclosureTemplateUpdate"
+}
+
+
DocumentChunkRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "chunk_index": {
+      "type": "integer",
+      "title": "Chunk Index"
+    },
+    "content_text": {
+      "type": "string",
+      "title": "Content Text"
+    },
+    "token_count": {
+      "type": "integer",
+      "title": "Token Count"
+    },
+    "page_number": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Page Number"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "document_id",
+    "chunk_index",
+    "content_text",
+    "token_count",
+    "page_number"
+  ],
+  "title": "DocumentChunkRead"
+}
+
+
DocumentRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "source_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Source Id"
+    },
+    "source_path": {
+      "type": "string",
+      "title": "Source Path"
+    },
+    "filename": {
+      "type": "string",
+      "title": "Filename"
+    },
+    "file_type": {
+      "type": "string",
+      "title": "File Type"
+    },
+    "file_hash": {
+      "type": "string",
+      "title": "File Hash"
+    },
+    "file_size": {
+      "type": "integer",
+      "title": "File Size"
+    },
+    "ingestion_status": {
+      "$ref": "#/components/schemas/IngestionStatus"
+    },
+    "ingestion_error": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ingestion Error"
+    },
+    "chunk_count": {
+      "type": "integer",
+      "title": "Chunk Count"
+    },
+    "ingested_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ingested At"
+    },
+    "connector_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connector Type"
+    },
+    "updated_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "source_id",
+    "source_path",
+    "filename",
+    "file_type",
+    "file_hash",
+    "file_size",
+    "ingestion_status",
+    "ingestion_error",
+    "chunk_count",
+    "ingested_at"
+  ],
+  "title": "DocumentRead"
+}
+
+
DraftCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "draft-records-response",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/DraftPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "DraftCommand"
+}
+
+
DraftInput
+{
+  "properties": {
+    "source_materials": {
+      "items": {
+        "$ref": "#/components/schemas/SourceInput"
+      },
+      "type": "array",
+      "title": "Source Materials"
+    },
+    "sentences": {
+      "items": {
+        "$ref": "#/components/schemas/SentenceInput"
+      },
+      "type": "array",
+      "minItems": 1,
+      "title": "Sentences"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sentences"
+  ],
+  "title": "DraftInput"
+}
+
+
DraftPayload
+{
+  "properties": {
+    "responseDraft": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Responsedraft"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "responseDraft"
+  ],
+  "title": "DraftPayload"
+}
+
+
ErrorModel
+{
+  "properties": {
+    "detail": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "additionalProperties": {
+            "type": "string"
+          },
+          "type": "object"
+        }
+      ],
+      "title": "Detail"
+    }
+  },
+  "type": "object",
+  "required": [
+    "detail"
+  ],
+  "title": "ErrorModel"
+}
+
+
Evidence
+{
+  "properties": {
+    "filename": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$",
+      "title": "Filename"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Description"
+    },
+    "media_type": {
+      "type": "string",
+      "enum": [
+        "text/plain",
+        "image/jpeg",
+        "image/png",
+        "image/webp",
+        "application/pdf",
+        "audio/webm",
+        "audio/ogg",
+        "audio/wav",
+        "audio/mpeg",
+        "audio/mp4"
+      ],
+      "title": "Media Type"
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 14000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "filename",
+    "description",
+    "media_type",
+    "content_base64",
+    "sha256"
+  ],
+  "title": "Evidence"
+}
+
+
EvidenceItem
+{
+  "properties": {
+    "filename": {
+      "type": "string",
+      "maxLength": 151,
+      "minLength": 1,
+      "title": "Filename"
+    },
+    "media_type": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Media Type"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Description",
+      "default": ""
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 14000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "filename",
+    "media_type",
+    "content_base64",
+    "sha256"
+  ],
+  "title": "EvidenceItem"
+}
+
+
EvidenceItems
+{
+  "properties": {
+    "items": {
+      "items": {
+        "$ref": "#/components/schemas/EvidenceItem"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "minItems": 1,
+      "title": "Items"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "items"
+  ],
+  "title": "EvidenceItems"
+}
+
+
ExemptionAccuracyReport
+{
+  "properties": {
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "total_flags": {
+      "type": "integer",
+      "title": "Total Flags"
+    },
+    "accepted": {
+      "type": "integer",
+      "title": "Accepted"
+    },
+    "rejected": {
+      "type": "integer",
+      "title": "Rejected"
+    },
+    "pending": {
+      "type": "integer",
+      "title": "Pending"
+    },
+    "acceptance_rate": {
+      "type": "number",
+      "title": "Acceptance Rate"
+    }
+  },
+  "type": "object",
+  "required": [
+    "category",
+    "total_flags",
+    "accepted",
+    "rejected",
+    "pending",
+    "acceptance_rate"
+  ],
+  "title": "ExemptionAccuracyReport"
+}
+
+
ExemptionDashboard
+{
+  "properties": {
+    "total_flags": {
+      "type": "integer",
+      "title": "Total Flags"
+    },
+    "by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "By Status"
+    },
+    "by_category": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "By Category"
+    },
+    "acceptance_rate": {
+      "type": "number",
+      "title": "Acceptance Rate"
+    },
+    "total_rules": {
+      "type": "integer",
+      "title": "Total Rules"
+    },
+    "active_rules": {
+      "type": "integer",
+      "title": "Active Rules"
+    }
+  },
+  "type": "object",
+  "required": [
+    "total_flags",
+    "by_status",
+    "by_category",
+    "acceptance_rate",
+    "total_rules",
+    "active_rules"
+  ],
+  "title": "ExemptionDashboard"
+}
+
+
ExemptionDecisionCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-exemption-decision",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ExemptionDecisionPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "ExemptionDecisionCommand"
+}
+
+
ExemptionDecisionPayload
+{
+  "properties": {
+    "exemptionSource": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionsource"
+    },
+    "exemptionKind": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionkind"
+    },
+    "exemptionFinding": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionfinding"
+    },
+    "exemptionDecision": {
+      "type": "string",
+      "enum": [
+        "release",
+        "redact",
+        "exempt"
+      ],
+      "title": "Exemptiondecision"
+    },
+    "exemptionBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionbasis"
+    },
+    "exemptionReviewer": {
+      "type": "string",
+      "title": "Exemptionreviewer",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "exemptionSource",
+    "exemptionKind",
+    "exemptionFinding",
+    "exemptionDecision",
+    "exemptionBasis"
+  ],
+  "title": "ExemptionDecisionPayload"
+}
+
+
ExemptionDecisionView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "source": {
+      "type": "string",
+      "title": "Source"
+    },
+    "kind": {
+      "type": "string",
+      "title": "Kind"
+    },
+    "finding": {
+      "type": "string",
+      "title": "Finding"
+    },
+    "decision": {
+      "type": "string",
+      "enum": [
+        "release",
+        "redact",
+        "exempt"
+      ],
+      "title": "Decision"
+    },
+    "basis": {
+      "type": "string",
+      "title": "Basis"
+    },
+    "reviewer": {
+      "type": "string",
+      "title": "Reviewer"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "source",
+    "kind",
+    "finding",
+    "decision",
+    "basis",
+    "reviewer",
+    "created_at_unix_seconds"
+  ],
+  "title": "ExemptionDecisionView"
+}
+
+
ExemptionFlagRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "chunk_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Chunk Id"
+    },
+    "rule_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Rule Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "matched_text": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Matched Text"
+    },
+    "confidence": {
+      "type": "number",
+      "title": "Confidence"
+    },
+    "status": {
+      "$ref": "#/components/schemas/FlagStatus"
+    },
+    "reviewed_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reviewed By"
+    },
+    "reviewed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reviewed At"
+    },
+    "review_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Reason"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "chunk_id",
+    "rule_id",
+    "request_id",
+    "category",
+    "matched_text",
+    "confidence",
+    "status",
+    "reviewed_by",
+    "reviewed_at",
+    "review_reason",
+    "created_at"
+  ],
+  "title": "ExemptionFlagRead"
+}
+
+
ExemptionFlagReview
+{
+  "properties": {
+    "status": {
+      "$ref": "#/components/schemas/FlagStatus"
+    },
+    "review_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Reason"
+    }
+  },
+  "type": "object",
+  "required": [
+    "status"
+  ],
+  "title": "ExemptionFlagReview"
+}
+
+
ExemptionNoteCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-exemption-review",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ExemptionNotePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "ExemptionNoteCommand"
+}
+
+
ExemptionNotePayload
+{
+  "properties": {
+    "exemptionNote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionnote"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "exemptionNote"
+  ],
+  "title": "ExemptionNotePayload"
+}
+
+
ExemptionRuleCreate
+{
+  "properties": {
+    "state_code": {
+      "type": "string",
+      "title": "State Code"
+    },
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "rule_type": {
+      "$ref": "#/components/schemas/RuleType"
+    },
+    "rule_definition": {
+      "type": "string",
+      "title": "Rule Definition"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "enabled": {
+      "type": "boolean",
+      "title": "Enabled",
+      "default": true
+    }
+  },
+  "type": "object",
+  "required": [
+    "state_code",
+    "category",
+    "rule_type",
+    "rule_definition"
+  ],
+  "title": "ExemptionRuleCreate"
+}
+
+
ExemptionRuleRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "state_code": {
+      "type": "string",
+      "title": "State Code"
+    },
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "rule_type": {
+      "$ref": "#/components/schemas/RuleType"
+    },
+    "rule_definition": {
+      "type": "string",
+      "title": "Rule Definition"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "enabled": {
+      "type": "boolean",
+      "title": "Enabled"
+    },
+    "version": {
+      "type": "integer",
+      "title": "Version",
+      "default": 1
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "state_code",
+    "category",
+    "rule_type",
+    "rule_definition",
+    "description",
+    "enabled",
+    "created_by",
+    "created_at"
+  ],
+  "title": "ExemptionRuleRead"
+}
+
+
ExemptionRuleUpdate
+{
+  "properties": {
+    "rule_definition": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Rule Definition"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "enabled": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Enabled"
+    }
+  },
+  "type": "object",
+  "title": "ExemptionRuleUpdate"
+}
+
+
ExportReceipt
+{
+  "properties": {
+    "export_path": {
+      "type": "string",
+      "maxLength": 32768,
+      "minLength": 1,
+      "title": "Export Path"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "export_path"
+  ],
+  "title": "ExportReceipt"
+}
+
+
FeeEstimateCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "estimate-records-fee",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/FeeEstimatePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "FeeEstimateCommand"
+}
+
+
FeeEstimatePayload
+{
+  "properties": {
+    "feeEstimate": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feeestimate"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "feeEstimate"
+  ],
+  "title": "FeeEstimatePayload"
+}
+
+
FeeEstimateRequest
+{
+  "properties": {
+    "page_count": {
+      "type": "integer",
+      "title": "Page Count"
+    },
+    "fee_schedule_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Fee Schedule Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "page_count",
+    "fee_schedule_id"
+  ],
+  "title": "FeeEstimateRequest"
+}
+
+
FeeEstimateResponse
+{
+  "properties": {
+    "page_count": {
+      "type": "integer",
+      "title": "Page Count"
+    },
+    "unit_price": {
+      "type": "number",
+      "title": "Unit Price"
+    },
+    "total": {
+      "type": "number",
+      "title": "Total"
+    },
+    "fee_type": {
+      "type": "string",
+      "title": "Fee Type"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    }
+  },
+  "type": "object",
+  "required": [
+    "page_count",
+    "unit_price",
+    "total",
+    "fee_type",
+    "description"
+  ],
+  "title": "FeeEstimateResponse"
+}
+
+
FeeLineCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-fee-line",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/FeeLinePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "FeeLineCommand"
+}
+
+
FeeLineItemCreate
+{
+  "properties": {
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "quantity": {
+      "type": "integer",
+      "title": "Quantity",
+      "default": 1
+    },
+    "unit_price": {
+      "type": "number",
+      "title": "Unit Price"
+    },
+    "fee_schedule_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Schedule Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "description",
+    "unit_price"
+  ],
+  "title": "FeeLineItemCreate"
+}
+
+
FeeLineItemRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "fee_schedule_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Schedule Id"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "quantity": {
+      "type": "integer",
+      "title": "Quantity"
+    },
+    "unit_price": {
+      "type": "number",
+      "title": "Unit Price"
+    },
+    "total": {
+      "type": "number",
+      "title": "Total"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "fee_schedule_id",
+    "description",
+    "quantity",
+    "unit_price",
+    "total",
+    "status",
+    "created_at"
+  ],
+  "title": "FeeLineItemRead"
+}
+
+
FeeLinePayload
+{
+  "properties": {
+    "feeLineDescription": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feelinedescription"
+    },
+    "feeScheduleBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feeschedulebasis"
+    },
+    "feeLineAmount": {
+      "type": "string",
+      "title": "Feelineamount"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "feeLineDescription",
+    "feeScheduleBasis",
+    "feeLineAmount"
+  ],
+  "title": "FeeLinePayload"
+}
+
+
FeeLineView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "schedule_basis": {
+      "type": "string",
+      "title": "Schedule Basis"
+    },
+    "amount_cents": {
+      "type": "integer",
+      "title": "Amount Cents"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "description",
+    "schedule_basis",
+    "amount_cents",
+    "created_at_unix_seconds"
+  ],
+  "title": "FeeLineView"
+}
+
+
FeeScheduleCreate
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "title": "Jurisdiction"
+    },
+    "fee_type": {
+      "type": "string",
+      "title": "Fee Type"
+    },
+    "amount": {
+      "type": "number",
+      "title": "Amount"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "effective_date": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective Date"
+    }
+  },
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "fee_type",
+    "amount"
+  ],
+  "title": "FeeScheduleCreate"
+}
+
+
FeeScheduleRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "jurisdiction": {
+      "type": "string",
+      "title": "Jurisdiction"
+    },
+    "fee_type": {
+      "type": "string",
+      "title": "Fee Type"
+    },
+    "amount": {
+      "type": "number",
+      "title": "Amount"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "effective_date": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective Date"
+    },
+    "created_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "jurisdiction",
+    "fee_type",
+    "amount",
+    "description",
+    "effective_date",
+    "created_by",
+    "created_at"
+  ],
+  "title": "FeeScheduleRead"
+}
+
+
FeeScheduleUpdate
+{
+  "properties": {
+    "fee_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Type"
+    },
+    "amount": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Amount"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "effective_date": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective Date"
+    }
+  },
+  "type": "object",
+  "title": "FeeScheduleUpdate"
+}
+
+
FeeWaiverCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "waive-records-fee",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/FeeWaiverPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "FeeWaiverCommand"
+}
+
+
FeeWaiverCreateRequest
+{
+  "properties": {
+    "waiver_type": {
+      "type": "string",
+      "title": "Waiver Type"
+    },
+    "reason": {
+      "type": "string",
+      "title": "Reason"
+    }
+  },
+  "type": "object",
+  "required": [
+    "waiver_type",
+    "reason"
+  ],
+  "title": "FeeWaiverCreateRequest"
+}
+
+
FeeWaiverPayload
+{
+  "properties": {
+    "feeWaiverReason": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feewaiverreason"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "feeWaiverReason"
+  ],
+  "title": "FeeWaiverPayload"
+}
+
+
FeeWaiverReadResponse
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "waiver_type": {
+      "type": "string",
+      "title": "Waiver Type"
+    },
+    "reason": {
+      "type": "string",
+      "title": "Reason"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    },
+    "created_at": {
+      "type": "string",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "waiver_type",
+    "reason",
+    "status",
+    "created_at"
+  ],
+  "title": "FeeWaiverReadResponse"
+}
+
+
FeeWaiverReviewRequest
+{
+  "properties": {
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    }
+  },
+  "type": "object",
+  "required": [
+    "status"
+  ],
+  "title": "FeeWaiverReviewRequest"
+}
+
+
FinishCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "fulfill-records-request",
+        "close-records-request"
+      ],
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/NativePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "FinishCommand"
+}
+
+
FlagStatus
+{
+  "type": "string",
+  "enum": [
+    "flagged",
+    "reviewed",
+    "accepted",
+    "rejected"
+  ],
+  "title": "FlagStatus"
+}
+
+
FormPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "form-plan",
+      "title": "Action"
+    },
+    "formName": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Formname",
+      "default": ""
+    },
+    "fields": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 50,
+      "title": "Fields"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "FormPlan"
+}
+
+
GeneratedDraft
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "model": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Model"
+    },
+    "previous_response_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Previous Response Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text",
+    "model",
+    "previous_response_sha256"
+  ],
+  "title": "GeneratedDraft"
+}
+
+
HTTPValidationError
+{
+  "properties": {
+    "detail": {
+      "items": {
+        "$ref": "#/components/schemas/ValidationError"
+      },
+      "type": "array",
+      "title": "Detail"
+    }
+  },
+  "type": "object",
+  "title": "HTTPValidationError"
+}
+
+
Handoff
+{
+  "properties": {
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "request_id"
+  ],
+  "title": "Handoff"
+}
+
+
ImportBundleCreate
+{
+  "properties": {
+    "job_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Job Id"
+    },
+    "connector_type": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Connector Type"
+    },
+    "source": {
+      "$ref": "#/components/schemas/SourceCreate"
+    },
+    "sources": {
+      "items": {
+        "$ref": "#/components/schemas/SourceCreate"
+      },
+      "type": "array",
+      "title": "Sources"
+    },
+    "titles": {
+      "items": {
+        "$ref": "#/components/schemas/TitleCreate"
+      },
+      "type": "array",
+      "title": "Titles"
+    },
+    "chapters": {
+      "items": {
+        "$ref": "#/components/schemas/ChapterCreate"
+      },
+      "type": "array",
+      "title": "Chapters"
+    },
+    "sections": {
+      "items": {
+        "$ref": "#/components/schemas/SectionCreate"
+      },
+      "type": "array",
+      "title": "Sections"
+    },
+    "versions": {
+      "items": {
+        "$ref": "#/components/schemas/SectionVersionCreate"
+      },
+      "type": "array",
+      "title": "Versions"
+    },
+    "provenance": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Provenance"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "connector_type",
+    "source"
+  ],
+  "title": "ImportBundleCreate",
+  "description": "Request body for local fixture/file-drop import jobs."
+}
+
+
InclusionStatus
+{
+  "type": "string",
+  "enum": [
+    "included",
+    "excluded",
+    "pending"
+  ],
+  "title": "InclusionStatus"
+}
+
+
IngestionStats
+{
+  "properties": {
+    "total_sources": {
+      "type": "integer",
+      "title": "Total Sources"
+    },
+    "active_sources": {
+      "type": "integer",
+      "title": "Active Sources"
+    },
+    "total_documents": {
+      "type": "integer",
+      "title": "Total Documents"
+    },
+    "documents_by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "Documents By Status"
+    },
+    "total_chunks": {
+      "type": "integer",
+      "title": "Total Chunks"
+    }
+  },
+  "type": "object",
+  "required": [
+    "total_sources",
+    "active_sources",
+    "total_documents",
+    "documents_by_status",
+    "total_chunks"
+  ],
+  "title": "IngestionStats"
+}
+
+
IngestionStatus
+{
+  "type": "string",
+  "enum": [
+    "pending",
+    "processing",
+    "completed",
+    "failed"
+  ],
+  "title": "IngestionStatus"
+}
+
+
InitiativeInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "policy": {
+      "$ref": "#/components/schemas/PolicySelection"
+    },
+    "responsible_staff": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Responsible Staff"
+    },
+    "target": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "string"
+        }
+      ],
+      "title": "Target"
+    },
+    "unit": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Unit"
+    },
+    "due_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Due On"
+    },
+    "status": {
+      "type": "string",
+      "enum": [
+        "planned",
+        "active",
+        "completed",
+        "cancelled"
+      ],
+      "title": "Status",
+      "default": "planned"
+    },
+    "milestones": {
+      "items": {
+        "$ref": "#/components/schemas/Milestone"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "title": "Milestones"
+    },
+    "measurements": {
+      "items": {
+        "$ref": "#/components/schemas/Measurement"
+      },
+      "type": "array",
+      "maxItems": 1000,
+      "title": "Measurements"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "policy",
+    "responsible_staff",
+    "target",
+    "unit",
+    "due_on",
+    "note"
+  ],
+  "title": "InitiativeInput"
+}
+
+
InspectionInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "property_reference": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Property Reference"
+    },
+    "inspection_reference": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Inspection Reference"
+    },
+    "dataset_kind": {
+      "type": "string",
+      "enum": [
+        "municipal",
+        "fictional"
+      ],
+      "title": "Dataset Kind"
+    },
+    "inspector_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "minLength": 1,
+      "title": "Inspector Notes"
+    },
+    "photo_observations": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Photo Observations"
+    },
+    "voice_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Voice Notes",
+      "default": ""
+    },
+    "evidence": {
+      "items": {
+        "$ref": "#/components/schemas/Evidence"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "title": "Evidence"
+    },
+    "linked_sources": {
+      "items": {
+        "$ref": "#/components/schemas/townlight_inspections__workflow_models__SourceLink"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Linked Sources"
+    },
+    "assigned_to": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Assigned To",
+      "default": ""
+    },
+    "staff_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Staff Notes",
+      "default": ""
+    },
+    "notice_draft": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Notice Draft",
+      "default": ""
+    },
+    "review_state": {
+      "type": "string",
+      "enum": [
+        "draft",
+        "follow_up",
+        "reviewed"
+      ],
+      "title": "Review State",
+      "default": "draft"
+    },
+    "review_notes": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Review Notes",
+      "default": ""
+    },
+    "public_summary": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Public Summary",
+      "default": ""
+    },
+    "analysis": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/AnalysisRecord"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "property_reference",
+    "inspection_reference",
+    "dataset_kind",
+    "inspector_notes"
+  ],
+  "title": "InspectionInput"
+}
+
+
IntakeInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "project_name": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Project Name"
+    },
+    "project_description": {
+      "type": "string",
+      "maxLength": 10000,
+      "minLength": 1,
+      "title": "Project Description"
+    },
+    "location": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Location"
+    },
+    "applicant_contact": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Applicant Contact",
+      "default": ""
+    },
+    "requirement_revision": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Requirement Revision"
+    },
+    "materials": {
+      "items": {
+        "$ref": "#/components/schemas/MaterialReview"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "minItems": 1,
+      "title": "Materials"
+    },
+    "linked_sources": {
+      "items": {
+        "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Linked Sources"
+    },
+    "staff_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Staff Notes",
+      "default": ""
+    },
+    "assigned_to": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Assigned To",
+      "default": ""
+    },
+    "review_state": {
+      "type": "string",
+      "enum": [
+        "draft",
+        "follow_up",
+        "reviewed"
+      ],
+      "title": "Review State",
+      "default": "draft"
+    },
+    "review_notes": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Review Notes",
+      "default": ""
+    },
+    "public_summary": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Public Summary",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "project_name",
+    "project_description",
+    "location",
+    "requirement_revision",
+    "materials"
+  ],
+  "title": "IntakeInput"
+}
+
+
InterpretationNoteCreate
+{
+  "properties": {
+    "note_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Note Id"
+    },
+    "note_text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Note Text"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "note_text"
+  ],
+  "title": "InterpretationNoteCreate",
+  "description": "Request body for staff-only interpretation notes."
+}
+
+
InterviewRequest
+{
+  "properties": {
+    "last_answer": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Answer"
+    },
+    "last_field": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Field"
+    },
+    "skipped_fields": {
+      "anyOf": [
+        {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Skipped Fields"
+    }
+  },
+  "type": "object",
+  "title": "InterviewRequest"
+}
+
+
InterviewResponse
+{
+  "properties": {
+    "question": {
+      "type": "string",
+      "title": "Question"
+    },
+    "target_field": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Target Field"
+    },
+    "all_complete": {
+      "type": "boolean",
+      "title": "All Complete"
+    },
+    "completed_fields": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Completed Fields"
+    },
+    "onboarding_status": {
+      "type": "string",
+      "title": "Onboarding Status"
+    },
+    "skipped_fields": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Skipped Fields"
+    }
+  },
+  "type": "object",
+  "required": [
+    "question",
+    "target_field",
+    "all_complete",
+    "completed_fields",
+    "onboarding_status",
+    "skipped_fields"
+  ],
+  "title": "InterviewResponse"
+}
+
+
ManagedFileReceipt
+{
+  "properties": {
+    "original_path": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Original Path"
+    },
+    "stored_path": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Stored Path"
+    },
+    "file_name": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "File Name"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Sha256"
+    },
+    "size_bytes": {
+      "type": "integer",
+      "maximum": 2147483647.0,
+      "minimum": 0.0,
+      "title": "Size Bytes"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "original_path",
+    "stored_path",
+    "file_name",
+    "sha256",
+    "size_bytes"
+  ],
+  "title": "ManagedFileReceipt"
+}
+
+
ManagedSource
+{
+  "properties": {
+    "original_path": {
+      "type": "string",
+      "title": "Original Path"
+    },
+    "stored_path": {
+      "type": "string",
+      "title": "Stored Path"
+    },
+    "file_name": {
+      "type": "string",
+      "title": "File Name"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Sha256"
+    },
+    "size_bytes": {
+      "type": "integer",
+      "minimum": 0.0,
+      "title": "Size Bytes"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "original_path",
+    "stored_path",
+    "file_name",
+    "sha256",
+    "size_bytes"
+  ],
+  "title": "ManagedSource"
+}
+
+
Material
+{
+  "properties": {
+    "material_id": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9_-]{1,80}$",
+      "title": "Material Id"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Description"
+    },
+    "citation": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Citation"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "material_id",
+    "description",
+    "citation"
+  ],
+  "title": "Material"
+}
+
+
MaterialReview
+{
+  "properties": {
+    "material_id": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Material Id"
+    },
+    "status": {
+      "type": "string",
+      "enum": [
+        "not_reviewed",
+        "provided",
+        "missing",
+        "unclear"
+      ],
+      "title": "Status",
+      "default": "not_reviewed"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Note",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "material_id"
+  ],
+  "title": "MaterialReview"
+}
+
+
Measurement
+{
+  "properties": {
+    "recorded_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Recorded On"
+    },
+    "value": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "string"
+        }
+      ],
+      "title": "Value"
+    },
+    "evidence": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Evidence"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "recorded_on",
+    "value",
+    "evidence"
+  ],
+  "title": "Measurement"
+}
+
+
MediaAnalysis
+{
+  "properties": {
+    "items": {
+      "items": {
+        "$ref": "#/components/schemas/EvidenceItem"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "minItems": 1,
+      "title": "Items"
+    },
+    "code_links": {
+      "items": {
+        "$ref": "#/components/schemas/CodeLink"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Code Links"
+    },
+    "inspector_supplied_text": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Inspector Supplied Text",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "items"
+  ],
+  "title": "MediaAnalysis"
+}
+
+
MeetingInput
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "scheduled_start": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Scheduled Start"
+    },
+    "location": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Location"
+    },
+    "meeting_type": {
+      "type": "string",
+      "enum": [
+        "regular",
+        "special",
+        "emergency",
+        "closed_session",
+        "executive"
+      ],
+      "title": "Meeting Type",
+      "default": "regular"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "scheduled_start",
+    "location"
+  ],
+  "title": "MeetingInput"
+}
+
+
MeetingLink
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 200,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    },
+    "relation": {
+      "type": "string",
+      "enum": [
+        "hearing",
+        "context",
+        "precedent"
+      ],
+      "title": "Relation"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256",
+    "relation"
+  ],
+  "title": "MeetingLink"
+}
+
+
MeetingSearch
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "MeetingSearch"
+}
+
+
MeetingStageInput
+{
+  "properties": {
+    "to_status": {
+      "type": "string",
+      "enum": [
+        "SCHEDULED",
+        "NOTICED",
+        "PACKET_POSTED",
+        "IN_PROGRESS",
+        "RECESSED",
+        "ADJOURNED",
+        "TRANSCRIPT_READY",
+        "MINUTES_DRAFTED",
+        "MINUTES_POSTED",
+        "MINUTES_ADOPTED",
+        "MINUTES_SIGNED",
+        "ARCHIVED",
+        "CANCELLED"
+      ],
+      "title": "To Status"
+    },
+    "statutory_basis": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Basis"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "to_status"
+  ],
+  "title": "MeetingStageInput"
+}
+
+
MeetingsSearch
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "MeetingsSearch"
+}
+
+
MeetingsSourceSelection
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 200,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "MeetingsSourceSelection"
+}
+
+
MessageCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-message",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/MessagePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "MessageCommand"
+}
+
+
MessageCreate
+{
+  "properties": {
+    "message_text": {
+      "type": "string",
+      "title": "Message Text"
+    },
+    "is_internal": {
+      "type": "boolean",
+      "title": "Is Internal",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "message_text"
+  ],
+  "title": "MessageCreate"
+}
+
+
MessagePayload
+{
+  "properties": {
+    "requestMessageBody": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestmessagebody"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requestMessageBody"
+  ],
+  "title": "MessagePayload"
+}
+
+
MessageRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "sender_type": {
+      "type": "string",
+      "title": "Sender Type"
+    },
+    "sender_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sender Id"
+    },
+    "message_text": {
+      "type": "string",
+      "title": "Message Text"
+    },
+    "is_internal": {
+      "type": "boolean",
+      "title": "Is Internal"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "sender_type",
+    "sender_id",
+    "message_text",
+    "is_internal",
+    "created_at"
+  ],
+  "title": "MessageRead"
+}
+
+
MessageView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "author": {
+      "type": "string",
+      "title": "Author"
+    },
+    "author_role": {
+      "type": "string",
+      "title": "Author Role"
+    },
+    "body": {
+      "type": "string",
+      "title": "Body"
+    },
+    "visibility": {
+      "type": "string",
+      "title": "Visibility"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "author",
+    "author_role",
+    "body",
+    "visibility",
+    "created_at_unix_seconds"
+  ],
+  "title": "MessageView"
+}
+
+
Milestone
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "due_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Due On"
+    },
+    "completed_on": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Completed On"
+    },
+    "evidence": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Evidence",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "due_on"
+  ],
+  "title": "Milestone"
+}
+
+
MinutesDecision
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "post",
+        "adopt",
+        "sign"
+      ],
+      "title": "Action"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "MinutesDecision"
+}
+
+
ModelRegistryCreate
+{
+  "properties": {
+    "model_name": {
+      "type": "string",
+      "title": "Model Name"
+    },
+    "model_version": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Version"
+    },
+    "parameter_count": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parameter Count"
+    },
+    "license": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "License"
+    },
+    "model_card_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Card Url"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active",
+      "default": false
+    },
+    "context_window_size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Context Window Size"
+    },
+    "supports_ner": {
+      "type": "boolean",
+      "title": "Supports Ner",
+      "default": false
+    },
+    "supports_vision": {
+      "type": "boolean",
+      "title": "Supports Vision",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "model_name"
+  ],
+  "title": "ModelRegistryCreate",
+  "description": "Schema for creating a new model_registry record (POST body)."
+}
+
+
ModelRegistryRead
+{
+  "properties": {
+    "id": {
+      "type": "integer",
+      "title": "Id"
+    },
+    "model_name": {
+      "type": "string",
+      "title": "Model Name"
+    },
+    "model_version": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Version"
+    },
+    "parameter_count": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parameter Count"
+    },
+    "license": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "License"
+    },
+    "model_card_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Card Url"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "added_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Added At"
+    },
+    "context_window_size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Context Window Size"
+    },
+    "supports_ner": {
+      "type": "boolean",
+      "title": "Supports Ner"
+    },
+    "supports_vision": {
+      "type": "boolean",
+      "title": "Supports Vision"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "model_name",
+    "is_active",
+    "supports_ner",
+    "supports_vision"
+  ],
+  "title": "ModelRegistryRead",
+  "description": "Schema for returning a model_registry record (GET response).\n\n``from_attributes=True`` allows construction directly from an ORM instance."
+}
+
+
ModelRegistryUpdate
+{
+  "properties": {
+    "model_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Name"
+    },
+    "model_version": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Version"
+    },
+    "parameter_count": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parameter Count"
+    },
+    "license": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "License"
+    },
+    "model_card_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Card Url"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    },
+    "context_window_size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Context Window Size"
+    },
+    "supports_ner": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supports Ner"
+    },
+    "supports_vision": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supports Vision"
+    }
+  },
+  "type": "object",
+  "title": "ModelRegistryUpdate",
+  "description": "Schema for partially updating a model_registry record (PATCH body).\n\nEvery field is optional so callers can send only the fields they want to\nchange."
+}
+
+
MotionCorrection
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "reason": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Reason"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text",
+    "reason"
+  ],
+  "title": "MotionCorrection"
+}
+
+
MotionInput
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "seconded_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "minLength": 1
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Seconded By"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text"
+  ],
+  "title": "MotionInput"
+}
+
+
NativePayload
+{
+  "properties": {},
+  "additionalProperties": false,
+  "type": "object",
+  "title": "NativePayload"
+}
+
+
NativeRequestRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "requester_name": {
+      "type": "string",
+      "title": "Requester Name"
+    },
+    "requester_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Email"
+    },
+    "requester_phone": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Phone"
+    },
+    "requester_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Type"
+    },
+    "date_received": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Date Received"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "status": {
+      "$ref": "#/components/schemas/RequestStatus"
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "created_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "response_draft": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Response Draft"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    },
+    "estimated_fee": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Estimated Fee"
+    },
+    "fee_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Status"
+    },
+    "fee_waiver_requested": {
+      "type": "boolean",
+      "title": "Fee Waiver Requested",
+      "default": false
+    },
+    "priority": {
+      "type": "string",
+      "title": "Priority",
+      "default": "normal"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    },
+    "closed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closed At"
+    },
+    "closure_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closure Reason"
+    },
+    "desktop_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Desktop Id"
+    },
+    "public_tracking_number": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Public Tracking Number"
+    },
+    "submitted_via": {
+      "type": "string",
+      "title": "Submitted Via"
+    },
+    "deadline_label": {
+      "type": "string",
+      "title": "Deadline Label"
+    },
+    "deadline_basis": {
+      "type": "string",
+      "title": "Deadline Basis"
+    },
+    "deadline_reviewed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Deadline Reviewed At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "requester_name",
+    "requester_email",
+    "date_received",
+    "statutory_deadline",
+    "description",
+    "status",
+    "assigned_to",
+    "created_by",
+    "created_at",
+    "response_draft",
+    "review_notes",
+    "desktop_id",
+    "public_tracking_number",
+    "submitted_via",
+    "deadline_label",
+    "deadline_basis",
+    "deadline_reviewed_at"
+  ],
+  "title": "NativeRequestRead"
+}
+
+
NoticeDocumentInput
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text"
+  ],
+  "title": "NoticeDocumentInput"
+}
+
+
NoticeDraft
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 100000,
+      "minLength": 1,
+      "title": "Body"
+    },
+    "notice_type": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Notice Type"
+    },
+    "statutory_basis": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Statutory Basis"
+    },
+    "event_date": {
+      "type": "string",
+      "format": "date",
+      "title": "Event Date"
+    },
+    "lead_days": {
+      "type": "integer",
+      "maximum": 365.0,
+      "minimum": 0.0,
+      "title": "Lead Days"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "body",
+    "notice_type",
+    "statutory_basis",
+    "event_date",
+    "lead_days"
+  ],
+  "title": "NoticeDraft"
+}
+
+
NoticeInput
+{
+  "properties": {
+    "notice_type": {
+      "type": "string",
+      "enum": [
+        "regular",
+        "special",
+        "emergency",
+        "closed_session",
+        "executive"
+      ],
+      "title": "Notice Type"
+    },
+    "posted_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Posted At"
+    },
+    "minimum_notice_hours": {
+      "type": "integer",
+      "minimum": 0.0,
+      "title": "Minimum Notice Hours"
+    },
+    "statutory_basis": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Basis"
+    },
+    "approved_by": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Approved By"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "notice_type",
+    "posted_at",
+    "minimum_notice_hours"
+  ],
+  "title": "NoticeInput"
+}
+
+
NoticeProofInput
+{
+  "properties": {
+    "location": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Location"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note",
+      "default": ""
+    },
+    "document_delivery_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Document Delivery Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "location"
+  ],
+  "title": "NoticeProofInput"
+}
+
+
NotificationLogRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "template_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Template Id"
+    },
+    "recipient_email": {
+      "type": "string",
+      "title": "Recipient Email"
+    },
+    "request_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Request Id"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "sent_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sent At"
+    },
+    "error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Message"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "template_id",
+    "recipient_email",
+    "request_id",
+    "channel",
+    "status",
+    "sent_at",
+    "error_message",
+    "created_at"
+  ],
+  "title": "NotificationLogRead"
+}
+
+
NotificationTemplateCreate
+{
+  "properties": {
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel",
+      "default": "email"
+    },
+    "subject_template": {
+      "type": "string",
+      "title": "Subject Template"
+    },
+    "body_template": {
+      "type": "string",
+      "title": "Body Template"
+    }
+  },
+  "type": "object",
+  "required": [
+    "event_type",
+    "subject_template",
+    "body_template"
+  ],
+  "title": "NotificationTemplateCreate"
+}
+
+
NotificationTemplateRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel"
+    },
+    "subject_template": {
+      "type": "string",
+      "title": "Subject Template"
+    },
+    "body_template": {
+      "type": "string",
+      "title": "Body Template"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "event_type",
+    "channel",
+    "subject_template",
+    "body_template",
+    "is_active",
+    "created_at"
+  ],
+  "title": "NotificationTemplateRead"
+}
+
+
NotificationTemplateUpdate
+{
+  "properties": {
+    "subject_template": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Subject Template"
+    },
+    "body_template": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Body Template"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "NotificationTemplateUpdate"
+}
+
+
NotificationView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "notification_id": {
+      "type": "string",
+      "title": "Notification Id"
+    },
+    "module_id": {
+      "type": "string",
+      "title": "Module Id"
+    },
+    "record_id": {
+      "type": "string",
+      "title": "Record Id"
+    },
+    "audience": {
+      "type": "string",
+      "title": "Audience"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel"
+    },
+    "subject": {
+      "type": "string",
+      "title": "Subject"
+    },
+    "body": {
+      "type": "string",
+      "title": "Body"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    },
+    "sent_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sent At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "notification_id",
+    "module_id",
+    "record_id",
+    "audience",
+    "channel",
+    "subject",
+    "body",
+    "status",
+    "created_at_unix_seconds",
+    "sent_at_unix_seconds"
+  ],
+  "title": "NotificationView"
+}
+
+
OllamaModelInfo
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Size"
+    },
+    "details": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Details"
+    }
+  },
+  "type": "object",
+  "required": [
+    "name"
+  ],
+  "title": "OllamaModelInfo"
+}
+
+
OllamaStatus
+{
+  "properties": {
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "models": {
+      "items": {
+        "$ref": "#/components/schemas/OllamaModelInfo"
+      },
+      "type": "array",
+      "title": "Models"
+    }
+  },
+  "type": "object",
+  "required": [
+    "status",
+    "models"
+  ],
+  "title": "OllamaStatus"
+}
+
+
OperationalMetrics
+{
+  "properties": {
+    "average_response_time_days": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Average Response Time Days"
+    },
+    "median_response_time_days": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Median Response Time Days"
+    },
+    "requests_by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "Requests By Status"
+    },
+    "requests_by_department": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "Requests By Department"
+    },
+    "deadline_compliance_rate": {
+      "type": "number",
+      "title": "Deadline Compliance Rate"
+    },
+    "total_open": {
+      "type": "integer",
+      "title": "Total Open"
+    },
+    "total_closed": {
+      "type": "integer",
+      "title": "Total Closed"
+    },
+    "total_overdue": {
+      "type": "integer",
+      "title": "Total Overdue"
+    },
+    "clarification_frequency": {
+      "type": "number",
+      "title": "Clarification Frequency"
+    },
+    "top_request_topics": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Top Request Topics"
+    }
+  },
+  "type": "object",
+  "required": [
+    "average_response_time_days",
+    "median_response_time_days",
+    "requests_by_status",
+    "requests_by_department",
+    "deadline_compliance_rate",
+    "total_open",
+    "total_closed",
+    "total_overdue",
+    "clarification_frequency",
+    "top_request_topics"
+  ],
+  "title": "OperationalMetrics"
+}
+
+
Outline
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "question_ids": {
+      "items": {
+        "type": "string",
+        "format": "uuid"
+      },
+      "type": "array",
+      "maxItems": 50,
+      "minItems": 1,
+      "title": "Question Ids"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "question_ids"
+  ],
+  "title": "Outline"
+}
+
+
Packet
+{
+  "properties": {
+    "expected_revision": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Expected Revision"
+    },
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "staff_only",
+        "records_copy"
+      ],
+      "title": "Visibility"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "expected_revision",
+    "visibility"
+  ],
+  "title": "Packet"
+}
+
+
PacketInput
+{
+  "properties": {
+    "agenda_item_ids": {
+      "items": {
+        "type": "string",
+        "format": "uuid"
+      },
+      "type": "array",
+      "title": "Agenda Item Ids"
+    },
+    "source_files": {
+      "items": {
+        "$ref": "#/components/schemas/ManagedSource"
+      },
+      "type": "array",
+      "title": "Source Files"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "agenda_item_ids"
+  ],
+  "title": "PacketInput"
+}
+
+
Pathway
+{
+  "properties": {
+    "project_type": {
+      "type": "string",
+      "maxLength": 120,
+      "minLength": 1,
+      "title": "Project Type"
+    },
+    "proposal": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Proposal",
+      "default": ""
+    },
+    "location_context": {
+      "type": "string",
+      "maxLength": 1000,
+      "title": "Location Context",
+      "default": ""
+    },
+    "requirement_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requirement Revision"
+    },
+    "fee_link": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "project_type"
+  ],
+  "title": "Pathway"
+}
+
+
PathwayStep
+{
+  "properties": {
+    "step": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Step"
+    },
+    "citation": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Citation"
+    },
+    "typical_time": {
+      "type": "string",
+      "maxLength": 1000,
+      "title": "Typical Time",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "step",
+    "citation"
+  ],
+  "title": "PathwayStep"
+}
+
+
PlainLanguageSummaryCreate
+{
+  "properties": {
+    "summary_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Summary Id"
+    },
+    "section_version_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Version Id"
+    },
+    "summary_text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Summary Text"
+    },
+    "language_code": {
+      "type": "string",
+      "title": "Language Code",
+      "default": "en"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "section_version_id",
+    "summary_text"
+  ],
+  "title": "PlainLanguageSummaryCreate",
+  "description": "Request body for staff-drafted plain-language summaries."
+}
+
+
PolicySelection
+{
+  "properties": {
+    "plan_id": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Plan Id"
+    },
+    "revision_id": {
+      "type": "string",
+      "maxLength": 36,
+      "minLength": 36,
+      "title": "Revision Id"
+    },
+    "policy_id": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Policy Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "plan_id",
+    "revision_id",
+    "policy_id"
+  ],
+  "title": "PolicySelection"
+}
+
+
PortalModeResponse
+{
+  "properties": {
+    "mode": {
+      "type": "string",
+      "enum": [
+        "public",
+        "private"
+      ],
+      "title": "Mode",
+      "description": "Active portal posture for this deployment. ``public`` = minimal resident surface (landing + authenticated records-request submission + resident registration) reachable without staff auth. ``private`` = staff-only; no public routes, no resident self-registration."
+    }
+  },
+  "type": "object",
+  "required": [
+    "mode"
+  ],
+  "title": "PortalModeResponse",
+  "description": "T5D — schema for ``GET /config/portal-mode``.\n\nExposed to the frontend on boot so it can branch routing without a\nuser-identity lookup. The payload is intentionally the single field\nbelow — no staff config, no user state, no schema version."
+}
+
+
PrepareArtifact
+{
+  "properties": {
+    "kind": {
+      "type": "string",
+      "enum": [
+        "response",
+        "release-package"
+      ],
+      "title": "Kind"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "kind"
+  ],
+  "title": "PrepareArtifact"
+}
+
+
Proof
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    },
+    "filename": {
+      "type": "string",
+      "maxLength": 150,
+      "minLength": 1,
+      "title": "Filename"
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 7000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "location": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Location"
+    },
+    "published_at": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Published At"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence",
+    "filename",
+    "content_base64",
+    "location",
+    "published_at"
+  ],
+  "title": "Proof"
+}
+
+
Proposal
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "pattern": "^[A-Za-z0-9_-]{1,64}$",
+      "title": "Id"
+    },
+    "version_id": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Version Id"
+    },
+    "meeting_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Meeting Id"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "ordinance_number": {
+      "type": "string",
+      "maxLength": 120,
+      "minLength": 1,
+      "title": "Ordinance Number"
+    },
+    "proposed_text": {
+      "type": "string",
+      "maxLength": 1000000,
+      "minLength": 1,
+      "title": "Proposed Text"
+    },
+    "supersedes_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^[A-Za-z0-9_-]{1,64}$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supersedes Id"
+    },
+    "reconciliation_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reconciliation Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "version_id",
+    "meeting_id",
+    "title",
+    "ordinance_number",
+    "proposed_text"
+  ],
+  "title": "Proposal"
+}
+
+
PublicExplore
+{
+  "properties": {
+    "goal": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Goal",
+      "default": ""
+    },
+    "topic": {
+      "type": "string",
+      "maxLength": 160,
+      "title": "Topic",
+      "default": ""
+    },
+    "neighborhood": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Neighborhood",
+      "default": ""
+    },
+    "plan_type": {
+      "type": "string",
+      "maxLength": 120,
+      "title": "Plan Type",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "PublicExplore"
+}
+
+
PublicIntake
+{
+  "properties": {
+    "requester": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requester"
+    },
+    "requesterContact": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestercontact"
+    },
+    "summary": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Summary"
+    },
+    "deadline": {
+      "type": "string",
+      "title": "Deadline",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requester",
+    "requesterContact",
+    "summary"
+  ],
+  "title": "PublicIntake"
+}
+
+
PublicLookup
+{
+  "properties": {
+    "trackingNumber": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Trackingnumber"
+    },
+    "requesterContact": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestercontact"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "trackingNumber",
+    "requesterContact"
+  ],
+  "title": "PublicLookup"
+}
+
+
PublicMessage
+{
+  "properties": {
+    "trackingNumber": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Trackingnumber"
+    },
+    "requesterContact": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestercontact"
+    },
+    "publicRequestMessage": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Publicrequestmessage"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "trackingNumber",
+    "requesterContact",
+    "publicRequestMessage"
+  ],
+  "title": "PublicMessage"
+}
+
+
PublicStatusView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "label": {
+      "type": "string",
+      "title": "Label"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "label",
+    "summary",
+    "status",
+    "created_at_unix_seconds"
+  ],
+  "title": "PublicStatusView"
+}
+
+
PublicationView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "source_module": {
+      "type": "string",
+      "title": "Source Module"
+    },
+    "source_record_id": {
+      "type": "string",
+      "title": "Source Record Id"
+    },
+    "record_type": {
+      "type": "string",
+      "title": "Record Type"
+    },
+    "public_payload": {
+      "type": "string",
+      "title": "Public Payload"
+    },
+    "payload_hash": {
+      "type": "string",
+      "title": "Payload Hash"
+    },
+    "published_at_unix_seconds": {
+      "type": "integer",
+      "title": "Published At Unix Seconds"
+    },
+    "retracted_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Retracted At Unix Seconds"
+    },
+    "retracted_by": {
+      "type": "string",
+      "title": "Retracted By",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "source_module",
+    "source_record_id",
+    "record_type",
+    "public_payload",
+    "payload_hash",
+    "published_at_unix_seconds"
+  ],
+  "title": "PublicationView"
+}
+
+
PublishingPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "publishing-workflow",
+      "title": "Action"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "hasReview": {
+      "type": "boolean",
+      "title": "Hasreview",
+      "default": false
+    },
+    "hasPlainLanguage": {
+      "type": "boolean",
+      "title": "Hasplainlanguage",
+      "default": false
+    },
+    "hasTranslationReview": {
+      "type": "boolean",
+      "title": "Hastranslationreview",
+      "default": false
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "PublishingPlan"
+}
+
+
Question
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    },
+    "question": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Question"
+    },
+    "kind": {
+      "type": "string",
+      "enum": [
+        "use",
+        "dimension"
+      ],
+      "title": "Kind"
+    },
+    "key": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Key"
+    },
+    "audience": {
+      "type": "string",
+      "enum": [
+        "resident",
+        "staff"
+      ],
+      "title": "Audience",
+      "default": "resident"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "query",
+    "question",
+    "kind",
+    "key"
+  ],
+  "title": "Question"
+}
+
+
QuestionAnswerRequest
+{
+  "properties": {
+    "question": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Question"
+    },
+    "section_number": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Section Number"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "question"
+  ],
+  "title": "QuestionAnswerRequest",
+  "description": "Request body for citation-grounded code Q&A."
+}
+
+
RecordsDocumentView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "attachment_id": {
+      "type": "string",
+      "title": "Attachment Id"
+    },
+    "title": {
+      "type": "string",
+      "title": "Title"
+    },
+    "original_path": {
+      "type": "string",
+      "title": "Original Path"
+    },
+    "stored_path": {
+      "type": "string",
+      "title": "Stored Path"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation"
+    },
+    "sha256": {
+      "type": "string",
+      "title": "Sha256"
+    },
+    "size_bytes": {
+      "type": "integer",
+      "title": "Size Bytes"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "added_by": {
+      "type": "string",
+      "title": "Added By"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    },
+    "release_original_path": {
+      "type": "string",
+      "title": "Release Original Path",
+      "default": ""
+    },
+    "release_stored_path": {
+      "type": "string",
+      "title": "Release Stored Path",
+      "default": ""
+    },
+    "release_file_name": {
+      "type": "string",
+      "title": "Release File Name",
+      "default": ""
+    },
+    "release_sha256": {
+      "type": "string",
+      "title": "Release Sha256",
+      "default": ""
+    },
+    "release_size_bytes": {
+      "type": "integer",
+      "title": "Release Size Bytes",
+      "default": 0
+    },
+    "release_status": {
+      "type": "string",
+      "title": "Release Status",
+      "default": ""
+    },
+    "release_note": {
+      "type": "string",
+      "title": "Release Note",
+      "default": ""
+    },
+    "release_added_by": {
+      "type": "string",
+      "title": "Release Added By",
+      "default": ""
+    },
+    "release_added_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Release Added At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "attachment_id",
+    "title",
+    "original_path",
+    "stored_path",
+    "citation",
+    "sha256",
+    "size_bytes",
+    "status",
+    "added_by",
+    "created_at_unix_seconds"
+  ],
+  "title": "RecordsDocumentView"
+}
+
+
RecordsOperationRead
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "message": {
+      "type": "string",
+      "title": "Message"
+    },
+    "request": {
+      "$ref": "#/components/schemas/RecordsView"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "message",
+    "request"
+  ],
+  "title": "RecordsOperationRead"
+}
+
+
RecordsStateRead
+{
+  "properties": {
+    "demo_fixture": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Demo Fixture"
+    },
+    "records_requests": {
+      "items": {
+        "$ref": "#/components/schemas/RecordsView"
+      },
+      "type": "array",
+      "title": "Records Requests"
+    },
+    "notification_events": {
+      "items": {
+        "$ref": "#/components/schemas/NotificationView"
+      },
+      "type": "array",
+      "title": "Notification Events"
+    },
+    "publication_events": {
+      "items": {
+        "$ref": "#/components/schemas/PublicationView"
+      },
+      "type": "array",
+      "title": "Publication Events"
+    },
+    "audit_entries": {
+      "items": {
+        "$ref": "#/components/schemas/AuditView"
+      },
+      "type": "array",
+      "title": "Audit Entries"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "records_requests"
+  ],
+  "title": "RecordsStateRead"
+}
+
+
RecordsView
+{
+  "properties": {
+    "request_id": {
+      "type": "string",
+      "title": "Request Id"
+    },
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "public_tracking_number": {
+      "type": "string",
+      "title": "Public Tracking Number"
+    },
+    "requester": {
+      "type": "string",
+      "title": "Requester"
+    },
+    "requester_contact": {
+      "type": "string",
+      "title": "Requester Contact"
+    },
+    "submitted_via": {
+      "type": "string",
+      "title": "Submitted Via"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "deadline": {
+      "type": "string",
+      "title": "Deadline"
+    },
+    "deadline_basis": {
+      "type": "string",
+      "title": "Deadline Basis"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "assigned_to": {
+      "type": "string",
+      "title": "Assigned To"
+    },
+    "clarification_notes": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Clarification Notes"
+    },
+    "search_notes": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Search Notes"
+    },
+    "search_sessions": {
+      "items": {
+        "$ref": "#/components/schemas/SearchReceiptView"
+      },
+      "type": "array",
+      "title": "Search Sessions"
+    },
+    "exemption_reviews": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Exemption Reviews"
+    },
+    "exemption_decisions": {
+      "items": {
+        "$ref": "#/components/schemas/ExemptionDecisionView"
+      },
+      "type": "array",
+      "title": "Exemption Decisions"
+    },
+    "fee_estimate": {
+      "type": "string",
+      "title": "Fee Estimate"
+    },
+    "fee_line_items": {
+      "items": {
+        "$ref": "#/components/schemas/FeeLineView"
+      },
+      "type": "array",
+      "title": "Fee Line Items"
+    },
+    "fee_waiver_reason": {
+      "type": "string",
+      "title": "Fee Waiver Reason"
+    },
+    "citations": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Citations"
+    },
+    "response_draft": {
+      "type": "string",
+      "title": "Response Draft"
+    },
+    "approval_notes": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Approval Notes"
+    },
+    "exports": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Exports"
+    },
+    "documents": {
+      "items": {
+        "$ref": "#/components/schemas/RecordsDocumentView"
+      },
+      "type": "array",
+      "title": "Documents"
+    },
+    "release_packages": {
+      "items": {
+        "$ref": "#/components/schemas/ReleasePackageView"
+      },
+      "type": "array",
+      "title": "Release Packages"
+    },
+    "timeline": {
+      "items": {
+        "$ref": "#/components/schemas/TimelineView"
+      },
+      "type": "array",
+      "title": "Timeline"
+    },
+    "public_status_events": {
+      "items": {
+        "$ref": "#/components/schemas/PublicStatusView"
+      },
+      "type": "array",
+      "title": "Public Status Events"
+    },
+    "messages": {
+      "items": {
+        "$ref": "#/components/schemas/MessageView"
+      },
+      "type": "array",
+      "title": "Messages"
+    },
+    "deadline_reviewed_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Deadline Reviewed At Unix Seconds"
+    },
+    "approved_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Approved At Unix Seconds"
+    },
+    "fulfilled_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fulfilled At Unix Seconds"
+    },
+    "closed_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closed At Unix Seconds"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "request_id",
+    "id",
+    "public_tracking_number",
+    "requester",
+    "requester_contact",
+    "submitted_via",
+    "summary",
+    "deadline",
+    "deadline_basis",
+    "status",
+    "assigned_to",
+    "clarification_notes",
+    "search_notes",
+    "search_sessions",
+    "exemption_reviews",
+    "exemption_decisions",
+    "fee_estimate",
+    "fee_line_items",
+    "fee_waiver_reason",
+    "citations",
+    "response_draft",
+    "approval_notes",
+    "exports",
+    "timeline",
+    "public_status_events",
+    "messages",
+    "deadline_reviewed_at_unix_seconds",
+    "approved_at_unix_seconds",
+    "fulfilled_at_unix_seconds",
+    "closed_at_unix_seconds",
+    "created_at_unix_seconds"
+  ],
+  "title": "RecordsView"
+}
+
+
ReleasePackageView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "export_path": {
+      "type": "string",
+      "title": "Export Path"
+    },
+    "package_hash": {
+      "type": "string",
+      "title": "Package Hash"
+    },
+    "document_count": {
+      "type": "integer",
+      "title": "Document Count"
+    },
+    "release_artifact_count": {
+      "type": "integer",
+      "title": "Release Artifact Count"
+    },
+    "search_session_count": {
+      "type": "integer",
+      "title": "Search Session Count"
+    },
+    "release_count": {
+      "type": "integer",
+      "title": "Release Count"
+    },
+    "redacted_count": {
+      "type": "integer",
+      "title": "Redacted Count"
+    },
+    "exempt_count": {
+      "type": "integer",
+      "title": "Exempt Count"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "export_path",
+    "package_hash",
+    "document_count",
+    "release_artifact_count",
+    "search_session_count",
+    "release_count",
+    "redacted_count",
+    "exempt_count",
+    "created_at_unix_seconds"
+  ],
+  "title": "ReleasePackageView"
+}
+
+
RepeatLookup
+{
+  "properties": {
+    "property_reference": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Property Reference"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "property_reference"
+  ],
+  "title": "RepeatLookup"
+}
+
+
RequestCreate
+{
+  "properties": {
+    "requester_name": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Requester Name"
+    },
+    "requester_email": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 255
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Email"
+    },
+    "requester_phone": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 50
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Phone"
+    },
+    "requester_type": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 100
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Type"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Description"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "priority": {
+      "type": "string",
+      "title": "Priority",
+      "default": "normal"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^(narrow|moderate|broad)$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "requester_name",
+    "description"
+  ],
+  "title": "RequestCreate"
+}
+
+
RequestDocumentAdd
+{
+  "properties": {
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "relevance_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Relevance Note"
+    }
+  },
+  "type": "object",
+  "required": [
+    "document_id"
+  ],
+  "title": "RequestDocumentAdd"
+}
+
+
RequestDocumentRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "relevance_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Relevance Note"
+    },
+    "exemption_flags": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Exemption Flags"
+    },
+    "inclusion_status": {
+      "$ref": "#/components/schemas/InclusionStatus"
+    },
+    "attached_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Attached At"
+    },
+    "attached_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Attached By"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "document_id",
+    "relevance_note",
+    "exemption_flags",
+    "inclusion_status",
+    "attached_at",
+    "attached_by"
+  ],
+  "title": "RequestDocumentRead"
+}
+
+
RequestRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "requester_name": {
+      "type": "string",
+      "title": "Requester Name"
+    },
+    "requester_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Email"
+    },
+    "requester_phone": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Phone"
+    },
+    "requester_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Type"
+    },
+    "date_received": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Date Received"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "status": {
+      "$ref": "#/components/schemas/RequestStatus"
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "created_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "response_draft": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Response Draft"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    },
+    "estimated_fee": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Estimated Fee"
+    },
+    "fee_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Status"
+    },
+    "fee_waiver_requested": {
+      "type": "boolean",
+      "title": "Fee Waiver Requested",
+      "default": false
+    },
+    "priority": {
+      "type": "string",
+      "title": "Priority",
+      "default": "normal"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    },
+    "closed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closed At"
+    },
+    "closure_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closure Reason"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "requester_name",
+    "requester_email",
+    "date_received",
+    "statutory_deadline",
+    "description",
+    "status",
+    "assigned_to",
+    "created_by",
+    "created_at",
+    "response_draft",
+    "review_notes"
+  ],
+  "title": "RequestRead"
+}
+
+
RequestStats
+{
+  "properties": {
+    "total_requests": {
+      "type": "integer",
+      "title": "Total Requests"
+    },
+    "by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "By Status"
+    },
+    "approaching_deadline": {
+      "type": "integer",
+      "title": "Approaching Deadline"
+    },
+    "overdue": {
+      "type": "integer",
+      "title": "Overdue"
+    }
+  },
+  "type": "object",
+  "required": [
+    "total_requests",
+    "by_status",
+    "approaching_deadline",
+    "overdue"
+  ],
+  "title": "RequestStats"
+}
+
+
RequestStatus
+{
+  "type": "string",
+  "enum": [
+    "received",
+    "clarification_needed",
+    "assigned",
+    "searching",
+    "in_review",
+    "ready_for_release",
+    "drafted",
+    "approved",
+    "fulfilled",
+    "closed"
+  ],
+  "title": "RequestStatus"
+}
+
+
RequestUpdate
+{
+  "properties": {
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/RequestStatus"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "response_draft": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Response Draft"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    }
+  },
+  "type": "object",
+  "title": "RequestUpdate"
+}
+
+
RequirementBundle
+{
+  "properties": {
+    "requirement_id": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9_-]{1,100}$",
+      "title": "Requirement Id"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "project_type": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Project Type"
+    },
+    "source_reference": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Source Reference"
+    },
+    "source_date": {
+      "type": "string",
+      "format": "date",
+      "title": "Source Date"
+    },
+    "effective_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Effective On"
+    },
+    "dataset_kind": {
+      "type": "string",
+      "enum": [
+        "municipal",
+        "fictional"
+      ],
+      "title": "Dataset Kind"
+    },
+    "filename": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$",
+      "title": "Filename"
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 14000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Sha256"
+    },
+    "materials": {
+      "items": {
+        "$ref": "#/components/schemas/Material"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "minItems": 1,
+      "title": "Materials"
+    },
+    "pathway": {
+      "items": {
+        "$ref": "#/components/schemas/PathwayStep"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "title": "Pathway"
+    },
+    "fee_link": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    },
+    "staff_note": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Staff Note",
+      "default": ""
+    },
+    "change_note": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Change Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requirement_id",
+    "title",
+    "jurisdiction",
+    "project_type",
+    "source_reference",
+    "source_date",
+    "effective_on",
+    "dataset_kind",
+    "filename",
+    "content_base64",
+    "sha256",
+    "materials",
+    "change_note"
+  ],
+  "title": "RequirementBundle"
+}
+
+
ResponseLetterCreate
+{
+  "properties": {
+    "template_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Template Id"
+    }
+  },
+  "type": "object",
+  "title": "ResponseLetterCreate"
+}
+
+
ResponseLetterRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "template_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Template Id"
+    },
+    "generated_content": {
+      "type": "string",
+      "title": "Generated Content"
+    },
+    "edited_content": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Edited Content"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "generated_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Generated By"
+    },
+    "approved_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Approved By"
+    },
+    "sent_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sent At"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "template_id",
+    "generated_content",
+    "edited_content",
+    "status",
+    "generated_by",
+    "approved_by",
+    "sent_at",
+    "created_at"
+  ],
+  "title": "ResponseLetterRead"
+}
+
+
ResponseLetterUpdate
+{
+  "properties": {
+    "edited_content": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Edited Content"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Status"
+    }
+  },
+  "type": "object",
+  "title": "ResponseLetterUpdate"
+}
+
+
ReviewInput
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 5000,
+      "title": "Body",
+      "default": ""
+    },
+    "hasAltText": {
+      "type": "boolean",
+      "title": "Hasalttext",
+      "default": false
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": "en"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "ReviewInput"
+}
+
+
Revision
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    },
+    "document": {
+      "$ref": "#/components/schemas/NoticeDraft"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence",
+    "document"
+  ],
+  "title": "Revision"
+}
+
+
RewriteInput
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "plain-language",
+        "language-variant"
+      ],
+      "title": "Action"
+    },
+    "text": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Text"
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "text"
+  ],
+  "title": "RewriteInput"
+}
+
+
RewriteResult
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "plain-language",
+        "language-variant"
+      ],
+      "title": "Action"
+    },
+    "text": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Text"
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": ""
+    },
+    "outcome": {
+      "type": "string",
+      "enum": [
+        "generated",
+        "unavailable"
+      ],
+      "title": "Outcome"
+    },
+    "generated": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 100000
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Generated"
+    },
+    "model": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 200
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "text",
+    "outcome"
+  ],
+  "title": "RewriteResult"
+}
+
+
Rule
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "zone_code": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Zone Code"
+    },
+    "key": {
+      "type": "string",
+      "maxLength": 120,
+      "minLength": 1,
+      "title": "Key"
+    },
+    "section_number": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Section Number"
+    },
+    "kind": {
+      "type": "string",
+      "enum": [
+        "use",
+        "dimension"
+      ],
+      "title": "Kind"
+    },
+    "value": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Value"
+    },
+    "overlay_code": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 255
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Overlay Code"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "zone_code",
+    "key",
+    "section_number",
+    "kind",
+    "value"
+  ],
+  "title": "Rule"
+}
+
+
RuleTestMatch
+{
+  "properties": {
+    "matched_text": {
+      "type": "string",
+      "title": "Matched Text"
+    },
+    "start": {
+      "type": "integer",
+      "title": "Start"
+    },
+    "end": {
+      "type": "integer",
+      "title": "End"
+    }
+  },
+  "type": "object",
+  "required": [
+    "matched_text",
+    "start",
+    "end"
+  ],
+  "title": "RuleTestMatch"
+}
+
+
RuleTestRequest
+{
+  "properties": {
+    "sample_text": {
+      "type": "string",
+      "title": "Sample Text"
+    }
+  },
+  "type": "object",
+  "required": [
+    "sample_text"
+  ],
+  "title": "RuleTestRequest"
+}
+
+
RuleTestResponse
+{
+  "properties": {
+    "rule_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Rule Id"
+    },
+    "rule_type": {
+      "type": "string",
+      "title": "Rule Type"
+    },
+    "matched": {
+      "type": "boolean",
+      "title": "Matched"
+    },
+    "matches": {
+      "items": {
+        "$ref": "#/components/schemas/RuleTestMatch"
+      },
+      "type": "array",
+      "title": "Matches"
+    }
+  },
+  "type": "object",
+  "required": [
+    "rule_id",
+    "rule_type",
+    "matched",
+    "matches"
+  ],
+  "title": "RuleTestResponse"
+}
+
+
RuleType
+{
+  "type": "string",
+  "enum": [
+    "regex",
+    "keyword",
+    "llm_prompt"
+  ],
+  "title": "RuleType"
+}
+
+
SaveReview
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 5000,
+      "title": "Body",
+      "default": ""
+    },
+    "hasAltText": {
+      "type": "boolean",
+      "title": "Hasalttext",
+      "default": false
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": "en"
+    },
+    "ai_analysis": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 100000
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ai Analysis"
+    },
+    "ai_analysis_model": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 200
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ai Analysis Model"
+    },
+    "ai_outcome": {
+      "type": "string",
+      "enum": [
+        "generated",
+        "unavailable",
+        "failed"
+      ],
+      "title": "Ai Outcome"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "ai_outcome"
+  ],
+  "title": "SaveReview"
+}
+
+
SearchFilterOptions
+{
+  "properties": {
+    "file_types": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "File Types"
+    },
+    "source_names": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Source Names"
+    },
+    "departments": {
+      "items": {
+        "additionalProperties": true,
+        "type": "object"
+      },
+      "type": "array",
+      "title": "Departments",
+      "default": []
+    },
+    "date_range": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Date Range"
+    }
+  },
+  "type": "object",
+  "required": [
+    "file_types",
+    "source_names"
+  ],
+  "title": "SearchFilterOptions"
+}
+
+
SearchInput
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "SearchInput"
+}
+
+
SearchNoteCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "record-records-search",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/SearchNotePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "SearchNoteCommand"
+}
+
+
SearchNotePayload
+{
+  "properties": {
+    "sourceNote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Sourcenote"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sourceNote"
+  ],
+  "title": "SearchNotePayload"
+}
+
+
SearchReceiptCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "record-records-search-session",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/SearchReceiptPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "SearchReceiptCommand"
+}
+
+
SearchReceiptPayload
+{
+  "properties": {
+    "searchQuery": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchquery"
+    },
+    "searchLocations": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchlocations"
+    },
+    "searchResultTitle": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchresulttitle"
+    },
+    "searchResultCitation": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchresultcitation"
+    },
+    "searchResultSummary": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchresultsummary"
+    },
+    "searchResultStatus": {
+      "type": "string",
+      "title": "Searchresultstatus",
+      "default": ""
+    },
+    "searchReviewer": {
+      "type": "string",
+      "title": "Searchreviewer",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "searchQuery",
+    "searchLocations",
+    "searchResultTitle",
+    "searchResultCitation",
+    "searchResultSummary"
+  ],
+  "title": "SearchReceiptPayload"
+}
+
+
SearchReceiptView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "query": {
+      "type": "string",
+      "title": "Query"
+    },
+    "locations": {
+      "type": "string",
+      "title": "Locations"
+    },
+    "reviewer": {
+      "type": "string",
+      "title": "Reviewer"
+    },
+    "results": {
+      "items": {
+        "$ref": "#/components/schemas/SearchResultView"
+      },
+      "type": "array",
+      "title": "Results"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "query",
+    "locations",
+    "reviewer",
+    "results",
+    "created_at_unix_seconds"
+  ],
+  "title": "SearchReceiptView"
+}
+
+
SearchRequest
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "title": "Query"
+    },
+    "session_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Session Id"
+    },
+    "filters": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Filters"
+    },
+    "limit": {
+      "type": "integer",
+      "maximum": 50.0,
+      "title": "Limit",
+      "default": 10
+    },
+    "synthesize": {
+      "type": "boolean",
+      "title": "Synthesize",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "SearchRequest"
+}
+
+
SearchResponse
+{
+  "properties": {
+    "query_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Query Id"
+    },
+    "session_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Session Id"
+    },
+    "query_text": {
+      "type": "string",
+      "title": "Query Text"
+    },
+    "results": {
+      "items": {
+        "$ref": "#/components/schemas/SearchResultItem"
+      },
+      "type": "array",
+      "title": "Results"
+    },
+    "results_count": {
+      "type": "integer",
+      "title": "Results Count"
+    },
+    "synthesized_answer": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Synthesized Answer"
+    },
+    "ai_generated": {
+      "type": "boolean",
+      "title": "Ai Generated",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "query_id",
+    "session_id",
+    "query_text",
+    "results",
+    "results_count"
+  ],
+  "title": "SearchResponse"
+}
+
+
SearchResultItem
+{
+  "properties": {
+    "chunk_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Chunk Id"
+    },
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "filename": {
+      "type": "string",
+      "title": "Filename"
+    },
+    "file_type": {
+      "type": "string",
+      "title": "File Type"
+    },
+    "source_path": {
+      "type": "string",
+      "title": "Source Path"
+    },
+    "page_number": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Page Number"
+    },
+    "content_text": {
+      "type": "string",
+      "title": "Content Text"
+    },
+    "similarity_score": {
+      "type": "number",
+      "title": "Similarity Score"
+    },
+    "rank": {
+      "type": "integer",
+      "title": "Rank"
+    }
+  },
+  "type": "object",
+  "required": [
+    "chunk_id",
+    "document_id",
+    "filename",
+    "file_type",
+    "source_path",
+    "page_number",
+    "content_text",
+    "similarity_score",
+    "rank"
+  ],
+  "title": "SearchResultItem"
+}
+
+
SearchResultView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "title": {
+      "type": "string",
+      "title": "Title"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "title",
+    "citation",
+    "summary",
+    "status"
+  ],
+  "title": "SearchResultView"
+}
+
+
SearchSessionRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "user_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "User Id"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "queries": {
+      "items": {
+        "additionalProperties": true,
+        "type": "object"
+      },
+      "type": "array",
+      "title": "Queries",
+      "default": []
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "user_id",
+    "created_at"
+  ],
+  "title": "SearchSessionRead"
+}
+
+
SectionCreate
+{
+  "properties": {
+    "section_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Section Id"
+    },
+    "chapter_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Chapter Id"
+    },
+    "section_number": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Number"
+    },
+    "section_heading": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Heading"
+    },
+    "parent_section_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parent Section Id"
+    },
+    "sort_order": {
+      "type": "integer",
+      "title": "Sort Order",
+      "default": 0
+    },
+    "administrative_regulation_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Administrative Regulation Refs"
+    },
+    "resolution_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Resolution Refs"
+    },
+    "policy_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Policy Refs"
+    },
+    "approved_summary_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Approved Summary Refs"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "chapter_id",
+    "section_number",
+    "section_heading"
+  ],
+  "title": "SectionCreate",
+  "description": "Request body for creating a code section or subsection."
+}
+
+
SectionVersionCreate
+{
+  "properties": {
+    "version_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Version Id"
+    },
+    "section_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Id"
+    },
+    "source_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "version_label": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Version Label"
+    },
+    "body": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Body"
+    },
+    "effective_start": {
+      "type": "string",
+      "format": "date",
+      "title": "Effective Start"
+    },
+    "effective_end": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective End"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    },
+    "is_current": {
+      "type": "boolean",
+      "title": "Is Current",
+      "default": false
+    },
+    "adoption_event_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Adoption Event Id"
+    },
+    "amendment_event_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Amendment Event Id"
+    },
+    "amendment_summary": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Amendment Summary"
+    },
+    "prior_version_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Prior Version Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "section_id",
+    "source_id",
+    "version_label",
+    "body",
+    "effective_start"
+  ],
+  "title": "SectionVersionCreate",
+  "description": "Request body for adding an immutable section version."
+}
+
+
Selection
+{
+  "properties": {
+    "recording_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Recording Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "recording_id",
+    "expected_sha256"
+  ],
+  "title": "Selection"
+}
+
+
SentenceInput
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "citations": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Citations"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text"
+  ],
+  "title": "SentenceInput"
+}
+
+
ServiceAccountCreate
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole",
+      "default": "read_only"
+    }
+  },
+  "type": "object",
+  "required": [
+    "name"
+  ],
+  "title": "ServiceAccountCreate"
+}
+
+
ServiceAccountCreated
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "api_key": {
+      "type": "string",
+      "title": "Api Key"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "role",
+    "created_by",
+    "created_at",
+    "is_active",
+    "api_key"
+  ],
+  "title": "ServiceAccountCreated",
+  "description": "Returned only on creation — includes the plaintext API key (shown once)."
+}
+
+
ServiceAccountRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "role",
+    "created_by",
+    "created_at",
+    "is_active"
+  ],
+  "title": "ServiceAccountRead"
+}
+
+
ServiceAccountUpdate
+{
+  "properties": {
+    "role": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/UserRole"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "ServiceAccountUpdate"
+}
+
+
Snapshot
+{
+  "properties": {
+    "expected_revision": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Expected Revision"
+    },
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "staff_only",
+        "public"
+      ],
+      "title": "Visibility"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "expected_revision",
+    "visibility"
+  ],
+  "title": "Snapshot"
+}
+
+
SourceCreate
+{
+  "properties": {
+    "source_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Id"
+    },
+    "name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Name"
+    },
+    "publisher": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Publisher"
+    },
+    "source_type": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Type"
+    },
+    "source_category": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Category"
+    },
+    "source_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Url"
+    },
+    "file_reference": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "File Reference"
+    },
+    "retrieved_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Retrieved At"
+    },
+    "retrieval_method": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Retrieval Method"
+    },
+    "checksum": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Checksum"
+    },
+    "source_owner": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Owner"
+    },
+    "is_official": {
+      "type": "boolean",
+      "title": "Is Official",
+      "default": true
+    },
+    "official_status_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Official Status Note"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    },
+    "staff_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Staff Notes"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "name",
+    "publisher",
+    "source_type",
+    "source_category"
+  ],
+  "title": "SourceCreate",
+  "description": "Request body for registering an official or explicitly labeled source."
+}
+
+
SourceInput
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "label": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Label"
+    },
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "label",
+    "text"
+  ],
+  "title": "SourceInput"
+}
+
+
SourceSnapshot
+{
+  "properties": {
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "public",
+        "staff_only"
+      ],
+      "title": "Visibility"
+    },
+    "meeting_event_ids": {
+      "items": {
+        "type": "string",
+        "format": "uuid"
+      },
+      "type": "array",
+      "maxItems": 50,
+      "title": "Meeting Event Ids"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "visibility"
+  ],
+  "title": "SourceSnapshot"
+}
+
+
SourceType
+{
+  "type": "string",
+  "enum": [
+    "manual_drop",
+    "file_system",
+    "rest_api",
+    "odbc"
+  ],
+  "title": "SourceType"
+}
+
+
StaffRecordsIntake
+{
+  "properties": {
+    "requester": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requester"
+    },
+    "summary": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Summary"
+    },
+    "deadline": {
+      "type": "string",
+      "title": "Deadline"
+    },
+    "deadlineBasis": {
+      "type": "string",
+      "title": "Deadlinebasis",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requester",
+    "summary",
+    "deadline"
+  ],
+  "title": "StaffRecordsIntake",
+  "description": "Existing native create-records-request input; no caller-supplied actor."
+}
+
+
StandardsExplanation
+{
+  "properties": {
+    "question": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Question"
+    },
+    "process_section": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Process Section",
+      "default": ""
+    },
+    "zone_code": {
+      "type": "string",
+      "maxLength": 40,
+      "title": "Zone Code",
+      "default": ""
+    },
+    "rule_types": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "title": "Rule Types"
+    },
+    "observed": {
+      "additionalProperties": {
+        "type": "string"
+      },
+      "type": "object",
+      "title": "Observed"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "question"
+  ],
+  "title": "StandardsExplanation"
+}
+
+
SyncFailureRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "source_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Source Id"
+    },
+    "source_path": {
+      "type": "string",
+      "title": "Source Path"
+    },
+    "error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Message"
+    },
+    "error_class": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Class"
+    },
+    "http_status_code": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Http Status Code"
+    },
+    "retry_count": {
+      "type": "integer",
+      "title": "Retry Count"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "first_failed_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "First Failed At"
+    },
+    "last_retried_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Retried At"
+    },
+    "dismissed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Dismissed At"
+    },
+    "dismissed_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Dismissed By"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "source_id",
+    "source_path",
+    "error_message",
+    "error_class",
+    "http_status_code",
+    "retry_count",
+    "status",
+    "first_failed_at",
+    "last_retried_at",
+    "dismissed_at",
+    "dismissed_by"
+  ],
+  "title": "SyncFailureRead"
+}
+
+
SyncRunLogRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "source_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Source Id"
+    },
+    "started_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Started At"
+    },
+    "finished_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Finished At"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Status"
+    },
+    "records_attempted": {
+      "type": "integer",
+      "title": "Records Attempted"
+    },
+    "records_succeeded": {
+      "type": "integer",
+      "title": "Records Succeeded"
+    },
+    "records_failed": {
+      "type": "integer",
+      "title": "Records Failed"
+    },
+    "error_summary": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Summary"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "source_id",
+    "started_at",
+    "finished_at",
+    "status",
+    "records_attempted",
+    "records_succeeded",
+    "records_failed",
+    "error_summary"
+  ],
+  "title": "SyncRunLogRead"
+}
+
+
SystemStatus
+{
+  "properties": {
+    "version": {
+      "type": "string",
+      "title": "Version"
+    },
+    "database": {
+      "type": "string",
+      "title": "Database"
+    },
+    "ollama": {
+      "type": "string",
+      "title": "Ollama"
+    },
+    "redis": {
+      "type": "string",
+      "title": "Redis"
+    },
+    "user_count": {
+      "type": "integer",
+      "title": "User Count"
+    },
+    "audit_log_count": {
+      "type": "integer",
+      "title": "Audit Log Count"
+    },
+    "suite_session": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Suite Session"
+    }
+  },
+  "type": "object",
+  "required": [
+    "version",
+    "database",
+    "ollama",
+    "redis",
+    "user_count",
+    "audit_log_count"
+  ],
+  "title": "SystemStatus"
+}
+
+
TaggedPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "tagged-pdf",
+      "title": "Action"
+    },
+    "headingLevels": {
+      "items": {
+        "type": "integer",
+        "maximum": 4294967295.0,
+        "minimum": 0.0
+      },
+      "type": "array",
+      "maxItems": 50,
+      "title": "Headinglevels"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "TaggedPlan"
+}
+
+
TestConnectionRequest
+{
+  "properties": {
+    "source_type": {
+      "type": "string",
+      "title": "Source Type"
+    },
+    "host": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Host"
+    },
+    "port": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Port"
+    },
+    "path": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Path"
+    },
+    "username": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Username"
+    },
+    "password": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Password"
+    },
+    "rest_api_config": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Rest Api Config"
+    },
+    "odbc_config": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Odbc Config"
+    }
+  },
+  "type": "object",
+  "required": [
+    "source_type"
+  ],
+  "title": "TestConnectionRequest",
+  "description": "Dedicated schema for test-connection. NOT the create schema.\n\nSecurity: credentials in this request body are never persisted, never\nwritten to audit logs, and never returned in the response."
+}
+
+
TestConnectionResponse
+{
+  "properties": {
+    "success": {
+      "type": "boolean",
+      "title": "Success"
+    },
+    "message": {
+      "type": "string",
+      "title": "Message"
+    },
+    "latency_ms": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Latency Ms"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Status"
+    },
+    "warning": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Warning"
+    },
+    "differing_keys": {
+      "anyOf": [
+        {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Differing Keys"
+    }
+  },
+  "type": "object",
+  "required": [
+    "success",
+    "message"
+  ],
+  "title": "TestConnectionResponse"
+}
+
+
TimelineEventCreate
+{
+  "properties": {
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "internal_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Internal Note"
+    }
+  },
+  "type": "object",
+  "required": [
+    "event_type",
+    "description"
+  ],
+  "title": "TimelineEventCreate"
+}
+
+
TimelineEventRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "actor_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Actor Id"
+    },
+    "actor_role": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Actor Role"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "internal_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Internal Note"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "event_type",
+    "actor_id",
+    "actor_role",
+    "description",
+    "internal_note",
+    "created_at"
+  ],
+  "title": "TimelineEventRead"
+}
+
+
TimelineView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "actor": {
+      "type": "string",
+      "title": "Actor"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "action",
+    "actor",
+    "note",
+    "created_at_unix_seconds"
+  ],
+  "title": "TimelineView"
+}
+
+
TitleCreate
+{
+  "properties": {
+    "title_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Title Id"
+    },
+    "title_number": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title Number"
+    },
+    "title_name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title Name"
+    },
+    "sort_order": {
+      "type": "integer",
+      "title": "Sort Order",
+      "default": 0
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title_number",
+    "title_name"
+  ],
+  "title": "TitleCreate",
+  "description": "Request body for creating a code title."
+}
+
+
TranscriptInput
+{
+  "properties": {
+    "source_label": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Label"
+    },
+    "transcript_text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Transcript Text"
+    },
+    "correction_of_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Correction Of Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_label",
+    "transcript_text"
+  ],
+  "title": "TranscriptInput"
+}
+
+
UserRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "email": {
+      "type": "string",
+      "format": "email",
+      "title": "Email"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active",
+      "default": true
+    },
+    "is_superuser": {
+      "type": "boolean",
+      "title": "Is Superuser",
+      "default": false
+    },
+    "is_verified": {
+      "type": "boolean",
+      "title": "Is Verified",
+      "default": false
+    },
+    "full_name": {
+      "type": "string",
+      "title": "Full Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "last_login": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Login"
+    },
+    "must_change_password": {
+      "type": "boolean",
+      "title": "Must Change Password",
+      "default": false
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "email",
+    "full_name",
+    "role",
+    "created_at",
+    "last_login"
+  ],
+  "title": "UserRead"
+}
+
+
UserRole
+{
+  "type": "string",
+  "enum": [
+    "admin",
+    "staff",
+    "reviewer",
+    "read_only",
+    "liaison",
+    "public"
+  ],
+  "title": "UserRole"
+}
+
+
UserSelfUpdate
+{
+  "properties": {
+    "password": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Password"
+    },
+    "email": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "email"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    },
+    "is_superuser": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Superuser"
+    },
+    "is_verified": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Verified"
+    },
+    "full_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Full Name"
+    }
+  },
+  "type": "object",
+  "title": "UserSelfUpdate",
+  "description": "Schema for user self-update via PATCH /users/me.\n\nExcludes role and department_id. Any payload containing those fields is\nrejected at parse time (HTTP 422). Role and department changes require\nadmin privileges via /admin/users/{id}."
+}
+
+
UserUpdateRequest
+{
+  "properties": {
+    "full_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Full Name"
+    },
+    "role": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Role"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "UserUpdateRequest"
+}
+
+
ValidationError
+{
+  "properties": {
+    "loc": {
+      "items": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "integer"
+          }
+        ]
+      },
+      "type": "array",
+      "title": "Location"
+    },
+    "msg": {
+      "type": "string",
+      "title": "Message"
+    },
+    "type": {
+      "type": "string",
+      "title": "Error Type"
+    },
+    "input": {
+      "title": "Input"
+    },
+    "ctx": {
+      "type": "object",
+      "title": "Context"
+    }
+  },
+  "type": "object",
+  "required": [
+    "loc",
+    "msg",
+    "type"
+  ],
+  "title": "ValidationError"
+}
+
+
Version
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence"
+  ],
+  "title": "Version"
+}
+
+
VoteCorrection
+{
+  "properties": {
+    "vote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Vote"
+    },
+    "reason": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Reason"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "vote",
+    "reason"
+  ],
+  "title": "VoteCorrection"
+}
+
+
VoteInput
+{
+  "properties": {
+    "voter_name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Voter Name"
+    },
+    "vote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Vote"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "voter_name",
+    "vote"
+  ],
+  "title": "VoteInput"
+}
+
+
_ParcelLookupIn
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "query"
+  ],
+  "title": "_ParcelLookupIn"
+}
+
+
townlight_inspections__workflow_models__SourceLink
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "const": "code",
+      "title": "Provider",
+      "default": "code"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "SourceLink"
+}
+
+
townlight_permitting__workflow_models__SourceLink
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "enum": [
+        "code",
+        "zoning"
+      ],
+      "title": "Provider"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "SourceLink"
+}
+
+
townlight_runtime__inspections_bridge__Search
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "const": "code",
+      "title": "Provider"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "query"
+  ],
+  "title": "Search"
+}
+
+
townlight_runtime__notice_bridge__Review
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence",
+    "note"
+  ],
+  "title": "Review"
+}
+
+
townlight_runtime__permitting_bridge__Import
+{
+  "properties": {
+    "bundle": {
+      "$ref": "#/components/schemas/RequirementBundle"
+    },
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "bundle"
+  ],
+  "title": "Import"
+}
+
+
townlight_runtime__permitting_bridge__Search
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "enum": [
+        "code",
+        "zoning"
+      ],
+      "title": "Provider"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "query"
+  ],
+  "title": "Search"
+}
+
+
townlight_runtime__planning_bridge__Import
+{
+  "properties": {
+    "bundle": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Bundle"
+    },
+    "expected_previous_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Previous Revision"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "bundle"
+  ],
+  "title": "Import"
+}
+
+
townlight_runtime__planning_bridge__Search
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Query"
+    },
+    "plan_type": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 40
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Plan Type"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "Search"
+}
+
+
townlight_runtime__zoning_bridge__Review
+{
+  "properties": {
+    "answer": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Answer",
+      "default": ""
+    },
+    "notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Notes",
+      "default": ""
+    },
+    "queue_status": {
+      "type": "string",
+      "enum": [
+        "open",
+        "in_review",
+        "resolved",
+        "closed"
+      ],
+      "title": "Queue Status",
+      "default": "resolved"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "Review"
+}
+
Townlight · AGPL-3.0-only · Source schema evidence only
\ No newline at end of file diff --git a/docs/beta-1/api/station-openapi.json b/docs/beta-1/api/station-openapi.json new file mode 100644 index 0000000..7b72341 --- /dev/null +++ b/docs/beta-1/api/station-openapi.json @@ -0,0 +1,11180 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "Townlight Records", + "description": "Prepared source schema for the actual native composition; installed acceptance remains pending. Exported without lifespan, migrations or database/network access.", + "version": "1.8.0.dev2" + }, + "paths": { + "/desktop/v1/station/context": { + "get": { + "tags": [ + "native-desktop", + "station-integration" + ], + "summary": "Context", + "operationId": "context_desktop_v1_station_context_get", + "parameters": [ + { + "name": "capability", + "in": "query", + "required": true, + "schema": { + "enum": [ + "capture", + "read" + ], + "type": "string", + "title": "Capability" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/requests/{request_id}/station-recordings": { + "post": { + "tags": [ + "native-desktop", + "station-integration" + ], + "summary": "Attach", + "operationId": "attach_desktop_v1_requests__request_id__station_recordings_post", + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Selection" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordsOperationRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/station/catalog": { + "get": { + "tags": [ + "native-meetings" + ], + "summary": "Station Catalog", + "description": "Authorized name-based operator selection from canonical Meetings data.", + "operationId": "station_catalog_desktop_v1_meetings_station_catalog_get", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "ActionItemInput": { + "properties": { + "description": { + "type": "string", + "minLength": 1, + "title": "Description" + }, + "assigned_to": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "source_motion_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Source Motion Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "description" + ], + "title": "ActionItemInput" + }, + "AdaPlan": { + "properties": { + "action": { + "type": "string", + "const": "ada-title-ii", + "title": "Action" + }, + "serviceArea": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Servicearea" + }, + "hasCoordinatorReview": { + "type": "boolean", + "title": "Hascoordinatorreview", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "serviceArea" + ], + "title": "AdaPlan" + }, + "AdminUserCreateRequest": { + "properties": { + "email": { + "type": "string", + "title": "Email" + }, + "password": { + "type": "string", + "title": "Password" + }, + "full_name": { + "type": "string", + "title": "Full Name", + "default": "" + }, + "role": { + "type": "string", + "title": "Role", + "default": "staff" + } + }, + "type": "object", + "required": [ + "email", + "password" + ], + "title": "AdminUserCreateRequest" + }, + "AdminUserCreateResponse": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "email": { + "type": "string", + "title": "Email" + }, + "full_name": { + "type": "string", + "title": "Full Name" + }, + "role": { + "type": "string", + "title": "Role" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + } + }, + "type": "object", + "required": [ + "id", + "email", + "full_name", + "role", + "is_active" + ], + "title": "AdminUserCreateResponse" + }, + "AgendaAssignment": { + "properties": { + "meeting_id": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "meeting_id" + ], + "title": "AgendaAssignment" + }, + "AgendaInput": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "department_name": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Department Name" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "department_name" + ], + "title": "AgendaInput" + }, + "AgendaReviewInput": { + "properties": { + "to_status": { + "type": "string", + "enum": [ + "DRAFTED", + "SUBMITTED", + "DEPT_APPROVED", + "LEGAL_REVIEWED", + "CLERK_ACCEPTED", + "ON_AGENDA", + "IN_PACKET", + "POSTED", + "HEARD", + "DISPOSED", + "ARCHIVED" + ], + "title": "To Status" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "to_status" + ], + "title": "AgendaReviewInput" + }, + "AmendmentInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "policy": { + "$ref": "#/components/schemas/PolicySelection" + }, + "proposal": { + "type": "string", + "maxLength": 20000, + "minLength": 1, + "title": "Proposal" + }, + "responsible_staff": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Responsible Staff" + }, + "status": { + "type": "string", + "enum": [ + "draft", + "review", + "adopted", + "withdrawn" + ], + "title": "Status", + "default": "draft" + }, + "review_note": { + "type": "string", + "maxLength": 5000, + "title": "Review Note", + "default": "" + }, + "adoption_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Adoption Revision" + }, + "note": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "policy", + "proposal", + "responsible_staff", + "note" + ], + "title": "AmendmentInput" + }, + "AnalysisObservation": { + "properties": { + "source": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "title": "Source" + }, + "filename": { + "type": "string", + "maxLength": 160, + "title": "Filename", + "default": "" + }, + "media_type": { + "type": "string", + "maxLength": 80, + "title": "Media Type", + "default": "" + }, + "text": { + "type": "string", + "maxLength": 4000, + "minLength": 1, + "title": "Text" + }, + "adapter": { + "type": "string", + "maxLength": 120, + "title": "Adapter", + "default": "" + }, + "citation_source_ids": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 30, + "title": "Citation Source Ids" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source", + "text" + ], + "title": "AnalysisObservation", + "description": "One draft observation, named with the adapter that actually produced it." + }, + "AnalysisRecord": { + "properties": { + "observations": { + "items": { + "$ref": "#/components/schemas/AnalysisObservation" + }, + "type": "array", + "maxItems": 30, + "title": "Observations" + }, + "cited_sections": { + "items": { + "$ref": "#/components/schemas/CitedSection" + }, + "type": "array", + "maxItems": 30, + "title": "Cited Sections" + }, + "unavailable": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 30, + "title": "Unavailable" + }, + "runtime": { + "additionalProperties": true, + "type": "object", + "title": "Runtime" + }, + "review_required": { + "type": "boolean", + "title": "Review Required", + "default": true + } + }, + "additionalProperties": false, + "type": "object", + "title": "AnalysisRecord", + "description": "The adapter output that accompanies a saved inspection draft." + }, + "ApprovalCommand": { + "properties": { + "action": { + "type": "string", + "const": "approve-records-response", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ApprovalPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "ApprovalCommand" + }, + "ApprovalPayload": { + "properties": { + "approvalNote": { + "type": "string", + "title": "Approvalnote", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "title": "ApprovalPayload" + }, + "ArchiveInput": { + "properties": { + "visibility": { + "type": "string", + "enum": [ + "public", + "closed_session" + ], + "title": "Visibility" + }, + "packet_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Packet Id" + }, + "minutes_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Minutes Id" + }, + "plain_language_summary": { + "type": "string", + "title": "Plain Language Summary", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "visibility" + ], + "title": "ArchiveInput" + }, + "ArtifactPlan": { + "properties": { + "artifact_id": { + "type": "string", + "title": "Artifact Id" + }, + "file_name": { + "type": "string", + "title": "File Name" + }, + "content": { + "type": "string", + "title": "Content" + }, + "sha256": { + "type": "string", + "title": "Sha256" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "artifact_id", + "file_name", + "content", + "sha256", + "created_at_unix_seconds" + ], + "title": "ArtifactPlan" + }, + "AssignCommand": { + "properties": { + "action": { + "type": "string", + "const": "assign-records-request", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/AssignmentPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "AssignCommand" + }, + "AssignmentPayload": { + "properties": { + "assignedTo": { + "type": "string", + "minLength": 1, + "title": "Assignedto" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "assignedTo" + ], + "title": "AssignmentPayload" + }, + "AttachDocument": { + "properties": { + "title": { + "type": "string", + "minLength": 1, + "title": "Title" + }, + "citation": { + "type": "string", + "title": "Citation", + "default": "" + }, + "file": { + "$ref": "#/components/schemas/ManagedFileReceipt" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "file" + ], + "title": "AttachDocument" + }, + "AttachReleaseCopy": { + "properties": { + "status": { + "type": "string", + "enum": [ + "release-ready copy", + "redacted copy" + ], + "title": "Status" + }, + "note": { + "type": "string", + "title": "Note", + "default": "" + }, + "added_by": { + "type": "string", + "title": "Added By", + "default": "" + }, + "file": { + "$ref": "#/components/schemas/ManagedFileReceipt" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "status", + "file" + ], + "title": "AttachReleaseCopy" + }, + "AuditChainVerification": { + "properties": { + "is_valid": { + "type": "boolean", + "title": "Is Valid" + }, + "entries_checked": { + "type": "integer", + "title": "Entries Checked" + }, + "error_message": { + "type": "string", + "title": "Error Message" + } + }, + "type": "object", + "required": [ + "is_valid", + "entries_checked", + "error_message" + ], + "title": "AuditChainVerification" + }, + "AuditLogRead": { + "properties": { + "id": { + "type": "integer", + "title": "Id" + }, + "prev_hash": { + "type": "string", + "title": "Prev Hash" + }, + "entry_hash": { + "type": "string", + "title": "Entry Hash" + }, + "timestamp": { + "type": "string", + "format": "date-time", + "title": "Timestamp" + }, + "user_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "User Id" + }, + "action": { + "type": "string", + "title": "Action" + }, + "resource_type": { + "type": "string", + "title": "Resource Type" + }, + "resource_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Resource Id" + }, + "details": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Details" + }, + "ai_generated": { + "type": "boolean", + "title": "Ai Generated" + } + }, + "type": "object", + "required": [ + "id", + "prev_hash", + "entry_hash", + "timestamp", + "user_id", + "action", + "resource_type", + "resource_id", + "details", + "ai_generated" + ], + "title": "AuditLogRead" + }, + "AuditView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "module_id": { + "type": "string", + "title": "Module Id" + }, + "action": { + "type": "string", + "title": "Action" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + }, + "previous_hash": { + "type": "string", + "title": "Previous Hash" + }, + "entry_hash": { + "type": "string", + "title": "Entry Hash" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "module_id", + "action", + "summary", + "created_at_unix_seconds", + "previous_hash", + "entry_hash" + ], + "title": "AuditView" + }, + "BearerResponse": { + "properties": { + "access_token": { + "type": "string", + "title": "Access Token" + }, + "token_type": { + "type": "string", + "title": "Token Type" + } + }, + "type": "object", + "required": [ + "access_token", + "token_type" + ], + "title": "BearerResponse" + }, + "Body_auth_jwt_login_auth_jwt_login_post": { + "properties": { + "grant_type": { + "anyOf": [ + { + "type": "string", + "pattern": "^password$" + }, + { + "type": "null" + } + ], + "title": "Grant Type" + }, + "username": { + "type": "string", + "title": "Username" + }, + "password": { + "type": "string", + "format": "password", + "title": "Password" + }, + "scope": { + "type": "string", + "title": "Scope", + "default": "" + }, + "client_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Client Id" + }, + "client_secret": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "format": "password", + "title": "Client Secret" + } + }, + "type": "object", + "required": [ + "username", + "password" + ], + "title": "Body_auth_jwt_login_auth_jwt_login_post" + }, + "Body_upload_file_datasources_upload_post": { + "properties": { + "file": { + "type": "string", + "contentMediaType": "application/octet-stream", + "title": "File" + } + }, + "type": "object", + "required": [ + "file" + ], + "title": "Body_upload_file_datasources_upload_post" + }, + "CalculateDeadlineCommand": { + "properties": { + "action": { + "type": "string", + "const": "calculate-records-deadline", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/CalculateDeadlinePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "CalculateDeadlineCommand" + }, + "CalculateDeadlinePayload": { + "properties": { + "deadlineReceivedDate": { + "type": "string", + "title": "Deadlinereceiveddate" + }, + "deadlineRuleName": { + "type": "string", + "minLength": 1, + "title": "Deadlinerulename" + }, + "deadlineDayCount": { + "type": "string", + "title": "Deadlinedaycount" + }, + "deadlineDayType": { + "type": "string", + "title": "Deadlinedaytype" + }, + "deadlineBasis": { + "type": "string", + "minLength": 1, + "title": "Deadlinebasis" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "deadlineReceivedDate", + "deadlineRuleName", + "deadlineDayCount", + "deadlineDayType", + "deadlineBasis" + ], + "title": "CalculateDeadlinePayload" + }, + "ChapterCreate": { + "properties": { + "chapter_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Chapter Id" + }, + "title_id": { + "type": "string", + "minLength": 1, + "title": "Title Id" + }, + "chapter_number": { + "type": "string", + "minLength": 1, + "title": "Chapter Number" + }, + "chapter_name": { + "type": "string", + "minLength": 1, + "title": "Chapter Name" + }, + "sort_order": { + "type": "integer", + "title": "Sort Order", + "default": 0 + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title_id", + "chapter_number", + "chapter_name" + ], + "title": "ChapterCreate", + "description": "Request body for creating a code chapter." + }, + "CitedSection": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "citation": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Citation" + }, + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "version": { + "type": "string", + "maxLength": 80, + "title": "Version", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "citation" + ], + "title": "CitedSection", + "description": "One resolved public Code section; never a caller-supplied quotation." + }, + "CityProfileCreate": { + "properties": { + "city_name": { + "type": "string", + "title": "City Name" + }, + "state": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State" + }, + "county": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "County" + }, + "population_band": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Population Band" + }, + "email_platform": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Email Platform" + }, + "has_dedicated_it": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Has Dedicated It" + }, + "monthly_request_volume": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Monthly Request Volume" + }, + "profile_data": { + "additionalProperties": true, + "type": "object", + "title": "Profile Data", + "default": {} + }, + "gap_map": { + "additionalProperties": true, + "type": "object", + "title": "Gap Map", + "default": {} + } + }, + "type": "object", + "required": [ + "city_name" + ], + "title": "CityProfileCreate" + }, + "CityProfileRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "city_name": { + "type": "string", + "title": "City Name" + }, + "state": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State" + }, + "county": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "County" + }, + "population_band": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Population Band" + }, + "email_platform": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Email Platform" + }, + "has_dedicated_it": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Has Dedicated It" + }, + "monthly_request_volume": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Monthly Request Volume" + }, + "onboarding_status": { + "type": "string", + "title": "Onboarding Status" + }, + "profile_data": { + "additionalProperties": true, + "type": "object", + "title": "Profile Data" + }, + "gap_map": { + "additionalProperties": true, + "type": "object", + "title": "Gap Map" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "city_name", + "state", + "county", + "population_band", + "email_platform", + "has_dedicated_it", + "monthly_request_volume", + "onboarding_status", + "profile_data", + "gap_map", + "created_at", + "updated_at" + ], + "title": "CityProfileRead" + }, + "CityProfileUpdate": { + "properties": { + "city_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "City Name" + }, + "state": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State" + }, + "county": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "County" + }, + "population_band": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Population Band" + }, + "email_platform": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Email Platform" + }, + "has_dedicated_it": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Has Dedicated It" + }, + "monthly_request_volume": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Monthly Request Volume" + }, + "onboarding_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Onboarding Status" + }, + "profile_data": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Profile Data" + }, + "gap_map": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Gap Map" + } + }, + "type": "object", + "title": "CityProfileUpdate" + }, + "ClarificationCommand": { + "properties": { + "action": { + "type": "string", + "const": "request-records-clarification", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ClarificationPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "ClarificationCommand" + }, + "ClarificationPayload": { + "properties": { + "clarificationNote": { + "type": "string", + "minLength": 1, + "title": "Clarificationnote" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "clarificationNote" + ], + "title": "ClarificationPayload" + }, + "Closeout": { + "properties": { + "decision_id": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Decision Id" + }, + "version_id": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Version Id" + }, + "source_id": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Source Id" + }, + "version_label": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Version Label" + }, + "body": { + "type": "string", + "maxLength": 1000000, + "minLength": 1, + "title": "Body" + }, + "effective_start": { + "type": "string", + "format": "date", + "title": "Effective Start" + }, + "effective_end": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective End" + }, + "is_current": { + "type": "boolean", + "title": "Is Current" + }, + "reconciliation_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reconciliation Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "decision_id", + "version_id", + "source_id", + "version_label", + "body", + "effective_start", + "is_current" + ], + "title": "Closeout" + }, + "CodeContext": { + "properties": { + "section_number": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Section Number" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "section_number" + ], + "title": "CodeContext" + }, + "CodeLink": { + "properties": { + "provider": { + "type": "string", + "const": "code", + "title": "Provider", + "default": "code" + }, + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "CodeLink" + }, + "CodeSearch": { + "properties": { + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "CodeSearch" + }, + "CodeSourceSelection": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "CodeSourceSelection" + }, + "CompleteArtifact": { + "properties": { + "export_path": { + "type": "string", + "minLength": 1, + "title": "Export Path" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "export_path" + ], + "title": "CompleteArtifact" + }, + "ConnectionSearch": { + "properties": { + "provider": { + "type": "string", + "enum": [ + "meetings", + "zoning" + ], + "title": "Provider" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "query" + ], + "title": "ConnectionSearch" + }, + "CoverageGapResponse": { + "properties": { + "jurisdictions_without_rules": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Jurisdictions Without Rules" + }, + "departments_without_staff": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array", + "title": "Departments Without Staff" + }, + "uncovered_categories": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Uncovered Categories" + }, + "total_gaps": { + "type": "integer", + "title": "Total Gaps" + } + }, + "type": "object", + "required": [ + "jurisdictions_without_rules", + "departments_without_staff", + "uncovered_categories", + "total_gaps" + ], + "title": "CoverageGapResponse" + }, + "DataSourceAdminRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "source_type": { + "$ref": "#/components/schemas/SourceType" + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "type": "boolean", + "title": "Schedule Enabled", + "default": true + }, + "next_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Next Sync At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "last_ingestion_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Ingestion At" + }, + "last_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Sync At" + }, + "last_sync_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Sync Status" + }, + "last_error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Error Message" + }, + "consecutive_failure_count": { + "type": "integer", + "title": "Consecutive Failure Count", + "default": 0 + }, + "sync_paused": { + "type": "boolean", + "title": "Sync Paused", + "default": false + }, + "health_status": { + "type": "string", + "title": "Health Status", + "default": "healthy" + }, + "active_failure_count": { + "type": "integer", + "title": "Active Failure Count", + "default": 0 + }, + "connector_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Connector Type" + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At" + }, + "connection_config": { + "additionalProperties": true, + "type": "object", + "title": "Connection Config" + } + }, + "type": "object", + "required": [ + "id", + "name", + "source_type", + "is_active", + "created_by", + "created_at", + "last_ingestion_at", + "connection_config" + ], + "title": "DataSourceAdminRead", + "description": "Full datasource shape including connection_config. Returned only by admin-gated endpoints." + }, + "DataSourceCreate": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "source_type": { + "$ref": "#/components/schemas/SourceType" + }, + "connection_config": { + "additionalProperties": true, + "type": "object", + "title": "Connection Config", + "default": {} + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "type": "boolean", + "title": "Schedule Enabled", + "default": true + } + }, + "type": "object", + "required": [ + "name", + "source_type" + ], + "title": "DataSourceCreate" + }, + "DataSourceRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "source_type": { + "$ref": "#/components/schemas/SourceType" + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "type": "boolean", + "title": "Schedule Enabled", + "default": true + }, + "next_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Next Sync At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "last_ingestion_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Ingestion At" + }, + "last_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Sync At" + }, + "last_sync_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Sync Status" + }, + "last_error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Error Message" + }, + "consecutive_failure_count": { + "type": "integer", + "title": "Consecutive Failure Count", + "default": 0 + }, + "sync_paused": { + "type": "boolean", + "title": "Sync Paused", + "default": false + }, + "health_status": { + "type": "string", + "title": "Health Status", + "default": "healthy" + }, + "active_failure_count": { + "type": "integer", + "title": "Active Failure Count", + "default": 0 + }, + "connector_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Connector Type" + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "name", + "source_type", + "is_active", + "created_by", + "created_at", + "last_ingestion_at" + ], + "title": "DataSourceRead", + "description": "Redacted datasource shape — safe for non-admin roles. connection_config omitted." + }, + "DataSourceUpdate": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "connection_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Connection Config" + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Schedule Enabled" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "DataSourceUpdate" + }, + "DeadlineCommand": { + "properties": { + "action": { + "type": "string", + "const": "set-records-deadline", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/DeadlinePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "DeadlineCommand" + }, + "DeadlinePayload": { + "properties": { + "deadline": { + "type": "string", + "title": "Deadline" + }, + "deadlineBasis": { + "type": "string", + "minLength": 1, + "title": "Deadlinebasis" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "deadline", + "deadlineBasis" + ], + "title": "DeadlinePayload" + }, + "Decision": { + "properties": { + "id": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Id" + }, + "outcome": { + "type": "string", + "enum": [ + "adopted", + "not_adopted", + "deferred", + "withdrawn" + ], + "title": "Outcome" + }, + "decided_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Decided At" + }, + "decision_text": { + "type": "string", + "maxLength": 1000000, + "minLength": 1, + "title": "Decision Text" + }, + "supporting_references": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Supporting References" + }, + "supersedes_decision_id": { + "anyOf": [ + { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$" + }, + { + "type": "null" + } + ], + "title": "Supersedes Decision Id" + }, + "reconciliation_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reconciliation Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "outcome", + "decision_text" + ], + "title": "Decision" + }, + "DepartmentCreate": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "code": { + "type": "string", + "title": "Code" + }, + "contact_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Contact Email" + } + }, + "type": "object", + "required": [ + "name", + "code" + ], + "title": "DepartmentCreate" + }, + "DepartmentRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "code": { + "type": "string", + "title": "Code" + }, + "contact_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Contact Email" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "name", + "code", + "contact_email", + "created_at" + ], + "title": "DepartmentRead" + }, + "DepartmentUpdate": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Code" + }, + "contact_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Contact Email" + } + }, + "type": "object", + "title": "DepartmentUpdate" + }, + "DisclosureTemplateCreate": { + "properties": { + "template_type": { + "type": "string", + "title": "Template Type" + }, + "state_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State Code" + }, + "content": { + "type": "string", + "title": "Content" + } + }, + "type": "object", + "required": [ + "template_type", + "content" + ], + "title": "DisclosureTemplateCreate" + }, + "DisclosureTemplateRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "template_type": { + "type": "string", + "title": "Template Type" + }, + "state_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State Code" + }, + "content": { + "type": "string", + "title": "Content" + }, + "version": { + "type": "integer", + "title": "Version" + }, + "updated_by": { + "type": "string", + "format": "uuid", + "title": "Updated By" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "template_type", + "state_code", + "content", + "version", + "updated_by", + "updated_at" + ], + "title": "DisclosureTemplateRead" + }, + "DisclosureTemplateRendered": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "template_type": { + "type": "string", + "title": "Template Type" + }, + "rendered_content": { + "type": "string", + "title": "Rendered Content" + }, + "has_unresolved_variables": { + "type": "boolean", + "title": "Has Unresolved Variables" + } + }, + "type": "object", + "required": [ + "id", + "template_type", + "rendered_content", + "has_unresolved_variables" + ], + "title": "DisclosureTemplateRendered" + }, + "DisclosureTemplateUpdate": { + "properties": { + "content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Content" + }, + "state_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State Code" + } + }, + "type": "object", + "title": "DisclosureTemplateUpdate" + }, + "DocumentChunkRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "chunk_index": { + "type": "integer", + "title": "Chunk Index" + }, + "content_text": { + "type": "string", + "title": "Content Text" + }, + "token_count": { + "type": "integer", + "title": "Token Count" + }, + "page_number": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Page Number" + } + }, + "type": "object", + "required": [ + "id", + "document_id", + "chunk_index", + "content_text", + "token_count", + "page_number" + ], + "title": "DocumentChunkRead" + }, + "DocumentRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "source_id": { + "type": "string", + "format": "uuid", + "title": "Source Id" + }, + "source_path": { + "type": "string", + "title": "Source Path" + }, + "filename": { + "type": "string", + "title": "Filename" + }, + "file_type": { + "type": "string", + "title": "File Type" + }, + "file_hash": { + "type": "string", + "title": "File Hash" + }, + "file_size": { + "type": "integer", + "title": "File Size" + }, + "ingestion_status": { + "$ref": "#/components/schemas/IngestionStatus" + }, + "ingestion_error": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Ingestion Error" + }, + "chunk_count": { + "type": "integer", + "title": "Chunk Count" + }, + "ingested_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Ingested At" + }, + "connector_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Connector Type" + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "source_id", + "source_path", + "filename", + "file_type", + "file_hash", + "file_size", + "ingestion_status", + "ingestion_error", + "chunk_count", + "ingested_at" + ], + "title": "DocumentRead" + }, + "DraftCommand": { + "properties": { + "action": { + "type": "string", + "const": "draft-records-response", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/DraftPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "DraftCommand" + }, + "DraftInput": { + "properties": { + "source_materials": { + "items": { + "$ref": "#/components/schemas/SourceInput" + }, + "type": "array", + "title": "Source Materials" + }, + "sentences": { + "items": { + "$ref": "#/components/schemas/SentenceInput" + }, + "type": "array", + "minItems": 1, + "title": "Sentences" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sentences" + ], + "title": "DraftInput" + }, + "DraftPayload": { + "properties": { + "responseDraft": { + "type": "string", + "minLength": 1, + "title": "Responsedraft" + }, + "citation": { + "type": "string", + "title": "Citation", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "responseDraft" + ], + "title": "DraftPayload" + }, + "ErrorModel": { + "properties": { + "detail": { + "anyOf": [ + { + "type": "string" + }, + { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + ], + "title": "Detail" + } + }, + "type": "object", + "required": [ + "detail" + ], + "title": "ErrorModel" + }, + "Evidence": { + "properties": { + "filename": { + "type": "string", + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$", + "title": "Filename" + }, + "description": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Description" + }, + "media_type": { + "type": "string", + "enum": [ + "text/plain", + "image/jpeg", + "image/png", + "image/webp", + "application/pdf", + "audio/webm", + "audio/ogg", + "audio/wav", + "audio/mpeg", + "audio/mp4" + ], + "title": "Media Type" + }, + "content_base64": { + "type": "string", + "maxLength": 14000000, + "minLength": 1, + "title": "Content Base64" + }, + "sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "filename", + "description", + "media_type", + "content_base64", + "sha256" + ], + "title": "Evidence" + }, + "EvidenceItem": { + "properties": { + "filename": { + "type": "string", + "maxLength": 151, + "minLength": 1, + "title": "Filename" + }, + "media_type": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Media Type" + }, + "description": { + "type": "string", + "maxLength": 2000, + "title": "Description", + "default": "" + }, + "content_base64": { + "type": "string", + "maxLength": 14000000, + "minLength": 1, + "title": "Content Base64" + }, + "sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "filename", + "media_type", + "content_base64", + "sha256" + ], + "title": "EvidenceItem" + }, + "EvidenceItems": { + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/EvidenceItem" + }, + "type": "array", + "maxItems": 10, + "minItems": 1, + "title": "Items" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "items" + ], + "title": "EvidenceItems" + }, + "ExemptionAccuracyReport": { + "properties": { + "category": { + "type": "string", + "title": "Category" + }, + "total_flags": { + "type": "integer", + "title": "Total Flags" + }, + "accepted": { + "type": "integer", + "title": "Accepted" + }, + "rejected": { + "type": "integer", + "title": "Rejected" + }, + "pending": { + "type": "integer", + "title": "Pending" + }, + "acceptance_rate": { + "type": "number", + "title": "Acceptance Rate" + } + }, + "type": "object", + "required": [ + "category", + "total_flags", + "accepted", + "rejected", + "pending", + "acceptance_rate" + ], + "title": "ExemptionAccuracyReport" + }, + "ExemptionDashboard": { + "properties": { + "total_flags": { + "type": "integer", + "title": "Total Flags" + }, + "by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "By Status" + }, + "by_category": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "By Category" + }, + "acceptance_rate": { + "type": "number", + "title": "Acceptance Rate" + }, + "total_rules": { + "type": "integer", + "title": "Total Rules" + }, + "active_rules": { + "type": "integer", + "title": "Active Rules" + } + }, + "type": "object", + "required": [ + "total_flags", + "by_status", + "by_category", + "acceptance_rate", + "total_rules", + "active_rules" + ], + "title": "ExemptionDashboard" + }, + "ExemptionDecisionCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-exemption-decision", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ExemptionDecisionPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "ExemptionDecisionCommand" + }, + "ExemptionDecisionPayload": { + "properties": { + "exemptionSource": { + "type": "string", + "minLength": 1, + "title": "Exemptionsource" + }, + "exemptionKind": { + "type": "string", + "minLength": 1, + "title": "Exemptionkind" + }, + "exemptionFinding": { + "type": "string", + "minLength": 1, + "title": "Exemptionfinding" + }, + "exemptionDecision": { + "type": "string", + "enum": [ + "release", + "redact", + "exempt" + ], + "title": "Exemptiondecision" + }, + "exemptionBasis": { + "type": "string", + "minLength": 1, + "title": "Exemptionbasis" + }, + "exemptionReviewer": { + "type": "string", + "title": "Exemptionreviewer", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "exemptionSource", + "exemptionKind", + "exemptionFinding", + "exemptionDecision", + "exemptionBasis" + ], + "title": "ExemptionDecisionPayload" + }, + "ExemptionDecisionView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "source": { + "type": "string", + "title": "Source" + }, + "kind": { + "type": "string", + "title": "Kind" + }, + "finding": { + "type": "string", + "title": "Finding" + }, + "decision": { + "type": "string", + "enum": [ + "release", + "redact", + "exempt" + ], + "title": "Decision" + }, + "basis": { + "type": "string", + "title": "Basis" + }, + "reviewer": { + "type": "string", + "title": "Reviewer" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "source", + "kind", + "finding", + "decision", + "basis", + "reviewer", + "created_at_unix_seconds" + ], + "title": "ExemptionDecisionView" + }, + "ExemptionFlagRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "chunk_id": { + "type": "string", + "format": "uuid", + "title": "Chunk Id" + }, + "rule_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Rule Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "category": { + "type": "string", + "title": "Category" + }, + "matched_text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Matched Text" + }, + "confidence": { + "type": "number", + "title": "Confidence" + }, + "status": { + "$ref": "#/components/schemas/FlagStatus" + }, + "reviewed_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Reviewed By" + }, + "reviewed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Reviewed At" + }, + "review_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Reason" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "chunk_id", + "rule_id", + "request_id", + "category", + "matched_text", + "confidence", + "status", + "reviewed_by", + "reviewed_at", + "review_reason", + "created_at" + ], + "title": "ExemptionFlagRead" + }, + "ExemptionFlagReview": { + "properties": { + "status": { + "$ref": "#/components/schemas/FlagStatus" + }, + "review_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Reason" + } + }, + "type": "object", + "required": [ + "status" + ], + "title": "ExemptionFlagReview" + }, + "ExemptionNoteCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-exemption-review", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ExemptionNotePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "ExemptionNoteCommand" + }, + "ExemptionNotePayload": { + "properties": { + "exemptionNote": { + "type": "string", + "minLength": 1, + "title": "Exemptionnote" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "exemptionNote" + ], + "title": "ExemptionNotePayload" + }, + "ExemptionRuleCreate": { + "properties": { + "state_code": { + "type": "string", + "title": "State Code" + }, + "category": { + "type": "string", + "title": "Category" + }, + "rule_type": { + "$ref": "#/components/schemas/RuleType" + }, + "rule_definition": { + "type": "string", + "title": "Rule Definition" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "enabled": { + "type": "boolean", + "title": "Enabled", + "default": true + } + }, + "type": "object", + "required": [ + "state_code", + "category", + "rule_type", + "rule_definition" + ], + "title": "ExemptionRuleCreate" + }, + "ExemptionRuleRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "state_code": { + "type": "string", + "title": "State Code" + }, + "category": { + "type": "string", + "title": "Category" + }, + "rule_type": { + "$ref": "#/components/schemas/RuleType" + }, + "rule_definition": { + "type": "string", + "title": "Rule Definition" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "enabled": { + "type": "boolean", + "title": "Enabled" + }, + "version": { + "type": "integer", + "title": "Version", + "default": 1 + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "state_code", + "category", + "rule_type", + "rule_definition", + "description", + "enabled", + "created_by", + "created_at" + ], + "title": "ExemptionRuleRead" + }, + "ExemptionRuleUpdate": { + "properties": { + "rule_definition": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Rule Definition" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "enabled": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Enabled" + } + }, + "type": "object", + "title": "ExemptionRuleUpdate" + }, + "ExportReceipt": { + "properties": { + "export_path": { + "type": "string", + "maxLength": 32768, + "minLength": 1, + "title": "Export Path" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "export_path" + ], + "title": "ExportReceipt" + }, + "FeeEstimateCommand": { + "properties": { + "action": { + "type": "string", + "const": "estimate-records-fee", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/FeeEstimatePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "FeeEstimateCommand" + }, + "FeeEstimatePayload": { + "properties": { + "feeEstimate": { + "type": "string", + "minLength": 1, + "title": "Feeestimate" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "feeEstimate" + ], + "title": "FeeEstimatePayload" + }, + "FeeEstimateRequest": { + "properties": { + "page_count": { + "type": "integer", + "title": "Page Count" + }, + "fee_schedule_id": { + "type": "string", + "format": "uuid", + "title": "Fee Schedule Id" + } + }, + "type": "object", + "required": [ + "page_count", + "fee_schedule_id" + ], + "title": "FeeEstimateRequest" + }, + "FeeEstimateResponse": { + "properties": { + "page_count": { + "type": "integer", + "title": "Page Count" + }, + "unit_price": { + "type": "number", + "title": "Unit Price" + }, + "total": { + "type": "number", + "title": "Total" + }, + "fee_type": { + "type": "string", + "title": "Fee Type" + }, + "description": { + "type": "string", + "title": "Description" + } + }, + "type": "object", + "required": [ + "page_count", + "unit_price", + "total", + "fee_type", + "description" + ], + "title": "FeeEstimateResponse" + }, + "FeeLineCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-fee-line", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/FeeLinePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "FeeLineCommand" + }, + "FeeLineItemCreate": { + "properties": { + "description": { + "type": "string", + "title": "Description" + }, + "quantity": { + "type": "integer", + "title": "Quantity", + "default": 1 + }, + "unit_price": { + "type": "number", + "title": "Unit Price" + }, + "fee_schedule_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Fee Schedule Id" + } + }, + "type": "object", + "required": [ + "description", + "unit_price" + ], + "title": "FeeLineItemCreate" + }, + "FeeLineItemRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "fee_schedule_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Fee Schedule Id" + }, + "description": { + "type": "string", + "title": "Description" + }, + "quantity": { + "type": "integer", + "title": "Quantity" + }, + "unit_price": { + "type": "number", + "title": "Unit Price" + }, + "total": { + "type": "number", + "title": "Total" + }, + "status": { + "type": "string", + "title": "Status" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "fee_schedule_id", + "description", + "quantity", + "unit_price", + "total", + "status", + "created_at" + ], + "title": "FeeLineItemRead" + }, + "FeeLinePayload": { + "properties": { + "feeLineDescription": { + "type": "string", + "minLength": 1, + "title": "Feelinedescription" + }, + "feeScheduleBasis": { + "type": "string", + "minLength": 1, + "title": "Feeschedulebasis" + }, + "feeLineAmount": { + "type": "string", + "title": "Feelineamount" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "feeLineDescription", + "feeScheduleBasis", + "feeLineAmount" + ], + "title": "FeeLinePayload" + }, + "FeeLineView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "description": { + "type": "string", + "title": "Description" + }, + "schedule_basis": { + "type": "string", + "title": "Schedule Basis" + }, + "amount_cents": { + "type": "integer", + "title": "Amount Cents" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "description", + "schedule_basis", + "amount_cents", + "created_at_unix_seconds" + ], + "title": "FeeLineView" + }, + "FeeScheduleCreate": { + "properties": { + "jurisdiction": { + "type": "string", + "title": "Jurisdiction" + }, + "fee_type": { + "type": "string", + "title": "Fee Type" + }, + "amount": { + "type": "number", + "title": "Amount" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "effective_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective Date" + } + }, + "type": "object", + "required": [ + "jurisdiction", + "fee_type", + "amount" + ], + "title": "FeeScheduleCreate" + }, + "FeeScheduleRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "jurisdiction": { + "type": "string", + "title": "Jurisdiction" + }, + "fee_type": { + "type": "string", + "title": "Fee Type" + }, + "amount": { + "type": "number", + "title": "Amount" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "effective_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective Date" + }, + "created_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "jurisdiction", + "fee_type", + "amount", + "description", + "effective_date", + "created_by", + "created_at" + ], + "title": "FeeScheduleRead" + }, + "FeeScheduleUpdate": { + "properties": { + "fee_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Fee Type" + }, + "amount": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Amount" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "effective_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective Date" + } + }, + "type": "object", + "title": "FeeScheduleUpdate" + }, + "FeeWaiverCommand": { + "properties": { + "action": { + "type": "string", + "const": "waive-records-fee", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/FeeWaiverPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "FeeWaiverCommand" + }, + "FeeWaiverCreateRequest": { + "properties": { + "waiver_type": { + "type": "string", + "title": "Waiver Type" + }, + "reason": { + "type": "string", + "title": "Reason" + } + }, + "type": "object", + "required": [ + "waiver_type", + "reason" + ], + "title": "FeeWaiverCreateRequest" + }, + "FeeWaiverPayload": { + "properties": { + "feeWaiverReason": { + "type": "string", + "minLength": 1, + "title": "Feewaiverreason" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "feeWaiverReason" + ], + "title": "FeeWaiverPayload" + }, + "FeeWaiverReadResponse": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "waiver_type": { + "type": "string", + "title": "Waiver Type" + }, + "reason": { + "type": "string", + "title": "Reason" + }, + "status": { + "type": "string", + "title": "Status" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + }, + "created_at": { + "type": "string", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "waiver_type", + "reason", + "status", + "created_at" + ], + "title": "FeeWaiverReadResponse" + }, + "FeeWaiverReviewRequest": { + "properties": { + "status": { + "type": "string", + "title": "Status" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + } + }, + "type": "object", + "required": [ + "status" + ], + "title": "FeeWaiverReviewRequest" + }, + "FinishCommand": { + "properties": { + "action": { + "type": "string", + "enum": [ + "fulfill-records-request", + "close-records-request" + ], + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/NativePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "FinishCommand" + }, + "FlagStatus": { + "type": "string", + "enum": [ + "flagged", + "reviewed", + "accepted", + "rejected" + ], + "title": "FlagStatus" + }, + "FormPlan": { + "properties": { + "action": { + "type": "string", + "const": "form-plan", + "title": "Action" + }, + "formName": { + "type": "string", + "maxLength": 500, + "title": "Formname", + "default": "" + }, + "fields": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 50, + "title": "Fields" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "FormPlan" + }, + "GeneratedDraft": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "model": { + "type": "string", + "minLength": 1, + "title": "Model" + }, + "previous_response_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Previous Response Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text", + "model", + "previous_response_sha256" + ], + "title": "GeneratedDraft" + }, + "HTTPValidationError": { + "properties": { + "detail": { + "items": { + "$ref": "#/components/schemas/ValidationError" + }, + "type": "array", + "title": "Detail" + } + }, + "type": "object", + "title": "HTTPValidationError" + }, + "Handoff": { + "properties": { + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "request_id" + ], + "title": "Handoff" + }, + "ImportBundleCreate": { + "properties": { + "job_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Job Id" + }, + "connector_type": { + "type": "string", + "minLength": 1, + "title": "Connector Type" + }, + "source": { + "$ref": "#/components/schemas/SourceCreate" + }, + "sources": { + "items": { + "$ref": "#/components/schemas/SourceCreate" + }, + "type": "array", + "title": "Sources" + }, + "titles": { + "items": { + "$ref": "#/components/schemas/TitleCreate" + }, + "type": "array", + "title": "Titles" + }, + "chapters": { + "items": { + "$ref": "#/components/schemas/ChapterCreate" + }, + "type": "array", + "title": "Chapters" + }, + "sections": { + "items": { + "$ref": "#/components/schemas/SectionCreate" + }, + "type": "array", + "title": "Sections" + }, + "versions": { + "items": { + "$ref": "#/components/schemas/SectionVersionCreate" + }, + "type": "array", + "title": "Versions" + }, + "provenance": { + "additionalProperties": true, + "type": "object", + "title": "Provenance" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "connector_type", + "source" + ], + "title": "ImportBundleCreate", + "description": "Request body for local fixture/file-drop import jobs." + }, + "InclusionStatus": { + "type": "string", + "enum": [ + "included", + "excluded", + "pending" + ], + "title": "InclusionStatus" + }, + "IngestionStats": { + "properties": { + "total_sources": { + "type": "integer", + "title": "Total Sources" + }, + "active_sources": { + "type": "integer", + "title": "Active Sources" + }, + "total_documents": { + "type": "integer", + "title": "Total Documents" + }, + "documents_by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Documents By Status" + }, + "total_chunks": { + "type": "integer", + "title": "Total Chunks" + } + }, + "type": "object", + "required": [ + "total_sources", + "active_sources", + "total_documents", + "documents_by_status", + "total_chunks" + ], + "title": "IngestionStats" + }, + "IngestionStatus": { + "type": "string", + "enum": [ + "pending", + "processing", + "completed", + "failed" + ], + "title": "IngestionStatus" + }, + "InitiativeInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "policy": { + "$ref": "#/components/schemas/PolicySelection" + }, + "responsible_staff": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Responsible Staff" + }, + "target": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "title": "Target" + }, + "unit": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Unit" + }, + "due_on": { + "type": "string", + "format": "date", + "title": "Due On" + }, + "status": { + "type": "string", + "enum": [ + "planned", + "active", + "completed", + "cancelled" + ], + "title": "Status", + "default": "planned" + }, + "milestones": { + "items": { + "$ref": "#/components/schemas/Milestone" + }, + "type": "array", + "maxItems": 100, + "title": "Milestones" + }, + "measurements": { + "items": { + "$ref": "#/components/schemas/Measurement" + }, + "type": "array", + "maxItems": 1000, + "title": "Measurements" + }, + "note": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "policy", + "responsible_staff", + "target", + "unit", + "due_on", + "note" + ], + "title": "InitiativeInput" + }, + "InspectionInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "property_reference": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Property Reference" + }, + "inspection_reference": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Inspection Reference" + }, + "dataset_kind": { + "type": "string", + "enum": [ + "municipal", + "fictional" + ], + "title": "Dataset Kind" + }, + "inspector_notes": { + "type": "string", + "maxLength": 10000, + "minLength": 1, + "title": "Inspector Notes" + }, + "photo_observations": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 30, + "title": "Photo Observations" + }, + "voice_notes": { + "type": "string", + "maxLength": 10000, + "title": "Voice Notes", + "default": "" + }, + "evidence": { + "items": { + "$ref": "#/components/schemas/Evidence" + }, + "type": "array", + "maxItems": 10, + "title": "Evidence" + }, + "linked_sources": { + "items": { + "$ref": "#/components/schemas/townlight_inspections__workflow_models__SourceLink" + }, + "type": "array", + "maxItems": 30, + "title": "Linked Sources" + }, + "assigned_to": { + "type": "string", + "maxLength": 255, + "title": "Assigned To", + "default": "" + }, + "staff_notes": { + "type": "string", + "maxLength": 10000, + "title": "Staff Notes", + "default": "" + }, + "notice_draft": { + "type": "string", + "maxLength": 10000, + "title": "Notice Draft", + "default": "" + }, + "review_state": { + "type": "string", + "enum": [ + "draft", + "follow_up", + "reviewed" + ], + "title": "Review State", + "default": "draft" + }, + "review_notes": { + "type": "string", + "maxLength": 4000, + "title": "Review Notes", + "default": "" + }, + "public_summary": { + "type": "string", + "maxLength": 10000, + "title": "Public Summary", + "default": "" + }, + "analysis": { + "anyOf": [ + { + "$ref": "#/components/schemas/AnalysisRecord" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "property_reference", + "inspection_reference", + "dataset_kind", + "inspector_notes" + ], + "title": "InspectionInput" + }, + "IntakeInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "project_name": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Project Name" + }, + "project_description": { + "type": "string", + "maxLength": 10000, + "minLength": 1, + "title": "Project Description" + }, + "location": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Location" + }, + "applicant_contact": { + "type": "string", + "maxLength": 2000, + "title": "Applicant Contact", + "default": "" + }, + "requirement_revision": { + "type": "string", + "format": "uuid", + "title": "Requirement Revision" + }, + "materials": { + "items": { + "$ref": "#/components/schemas/MaterialReview" + }, + "type": "array", + "maxItems": 100, + "minItems": 1, + "title": "Materials" + }, + "linked_sources": { + "items": { + "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink" + }, + "type": "array", + "maxItems": 30, + "title": "Linked Sources" + }, + "staff_notes": { + "type": "string", + "maxLength": 10000, + "title": "Staff Notes", + "default": "" + }, + "assigned_to": { + "type": "string", + "maxLength": 255, + "title": "Assigned To", + "default": "" + }, + "review_state": { + "type": "string", + "enum": [ + "draft", + "follow_up", + "reviewed" + ], + "title": "Review State", + "default": "draft" + }, + "review_notes": { + "type": "string", + "maxLength": 4000, + "title": "Review Notes", + "default": "" + }, + "public_summary": { + "type": "string", + "maxLength": 10000, + "title": "Public Summary", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "project_name", + "project_description", + "location", + "requirement_revision", + "materials" + ], + "title": "IntakeInput" + }, + "InterpretationNoteCreate": { + "properties": { + "note_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Note Id" + }, + "note_text": { + "type": "string", + "minLength": 1, + "title": "Note Text" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "note_text" + ], + "title": "InterpretationNoteCreate", + "description": "Request body for staff-only interpretation notes." + }, + "InterviewRequest": { + "properties": { + "last_answer": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Answer" + }, + "last_field": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Field" + }, + "skipped_fields": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Skipped Fields" + } + }, + "type": "object", + "title": "InterviewRequest" + }, + "InterviewResponse": { + "properties": { + "question": { + "type": "string", + "title": "Question" + }, + "target_field": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Target Field" + }, + "all_complete": { + "type": "boolean", + "title": "All Complete" + }, + "completed_fields": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Completed Fields" + }, + "onboarding_status": { + "type": "string", + "title": "Onboarding Status" + }, + "skipped_fields": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Skipped Fields" + } + }, + "type": "object", + "required": [ + "question", + "target_field", + "all_complete", + "completed_fields", + "onboarding_status", + "skipped_fields" + ], + "title": "InterviewResponse" + }, + "ManagedFileReceipt": { + "properties": { + "original_path": { + "type": "string", + "minLength": 1, + "title": "Original Path" + }, + "stored_path": { + "type": "string", + "minLength": 1, + "title": "Stored Path" + }, + "file_name": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "File Name" + }, + "sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Sha256" + }, + "size_bytes": { + "type": "integer", + "maximum": 2147483647.0, + "minimum": 0.0, + "title": "Size Bytes" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "original_path", + "stored_path", + "file_name", + "sha256", + "size_bytes" + ], + "title": "ManagedFileReceipt" + }, + "ManagedSource": { + "properties": { + "original_path": { + "type": "string", + "title": "Original Path" + }, + "stored_path": { + "type": "string", + "title": "Stored Path" + }, + "file_name": { + "type": "string", + "title": "File Name" + }, + "sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Sha256" + }, + "size_bytes": { + "type": "integer", + "minimum": 0.0, + "title": "Size Bytes" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "original_path", + "stored_path", + "file_name", + "sha256", + "size_bytes" + ], + "title": "ManagedSource" + }, + "Material": { + "properties": { + "material_id": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]{1,80}$", + "title": "Material Id" + }, + "description": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Description" + }, + "citation": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Citation" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "material_id", + "description", + "citation" + ], + "title": "Material" + }, + "MaterialReview": { + "properties": { + "material_id": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Material Id" + }, + "status": { + "type": "string", + "enum": [ + "not_reviewed", + "provided", + "missing", + "unclear" + ], + "title": "Status", + "default": "not_reviewed" + }, + "note": { + "type": "string", + "maxLength": 2000, + "title": "Note", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "material_id" + ], + "title": "MaterialReview" + }, + "Measurement": { + "properties": { + "recorded_on": { + "type": "string", + "format": "date", + "title": "Recorded On" + }, + "value": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "title": "Value" + }, + "evidence": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Evidence" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "recorded_on", + "value", + "evidence" + ], + "title": "Measurement" + }, + "MediaAnalysis": { + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/EvidenceItem" + }, + "type": "array", + "maxItems": 10, + "minItems": 1, + "title": "Items" + }, + "code_links": { + "items": { + "$ref": "#/components/schemas/CodeLink" + }, + "type": "array", + "maxItems": 30, + "title": "Code Links" + }, + "inspector_supplied_text": { + "type": "string", + "maxLength": 10000, + "title": "Inspector Supplied Text", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "items" + ], + "title": "MediaAnalysis" + }, + "MeetingInput": { + "properties": { + "title": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Title" + }, + "scheduled_start": { + "type": "string", + "format": "date-time", + "title": "Scheduled Start" + }, + "location": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Location" + }, + "meeting_type": { + "type": "string", + "enum": [ + "regular", + "special", + "emergency", + "closed_session", + "executive" + ], + "title": "Meeting Type", + "default": "regular" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "scheduled_start", + "location" + ], + "title": "MeetingInput" + }, + "MeetingLink": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + }, + "relation": { + "type": "string", + "enum": [ + "hearing", + "context", + "precedent" + ], + "title": "Relation" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256", + "relation" + ], + "title": "MeetingLink" + }, + "MeetingSearch": { + "properties": { + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "MeetingSearch" + }, + "MeetingStageInput": { + "properties": { + "to_status": { + "type": "string", + "enum": [ + "SCHEDULED", + "NOTICED", + "PACKET_POSTED", + "IN_PROGRESS", + "RECESSED", + "ADJOURNED", + "TRANSCRIPT_READY", + "MINUTES_DRAFTED", + "MINUTES_POSTED", + "MINUTES_ADOPTED", + "MINUTES_SIGNED", + "ARCHIVED", + "CANCELLED" + ], + "title": "To Status" + }, + "statutory_basis": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Statutory Basis" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "to_status" + ], + "title": "MeetingStageInput" + }, + "MeetingsSearch": { + "properties": { + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "MeetingsSearch" + }, + "MeetingsSourceSelection": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "MeetingsSourceSelection" + }, + "MessageCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-message", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/MessagePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "MessageCommand" + }, + "MessageCreate": { + "properties": { + "message_text": { + "type": "string", + "title": "Message Text" + }, + "is_internal": { + "type": "boolean", + "title": "Is Internal", + "default": false + } + }, + "type": "object", + "required": [ + "message_text" + ], + "title": "MessageCreate" + }, + "MessagePayload": { + "properties": { + "requestMessageBody": { + "type": "string", + "minLength": 1, + "title": "Requestmessagebody" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requestMessageBody" + ], + "title": "MessagePayload" + }, + "MessageRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "sender_type": { + "type": "string", + "title": "Sender Type" + }, + "sender_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Sender Id" + }, + "message_text": { + "type": "string", + "title": "Message Text" + }, + "is_internal": { + "type": "boolean", + "title": "Is Internal" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "sender_type", + "sender_id", + "message_text", + "is_internal", + "created_at" + ], + "title": "MessageRead" + }, + "MessageView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "author": { + "type": "string", + "title": "Author" + }, + "author_role": { + "type": "string", + "title": "Author Role" + }, + "body": { + "type": "string", + "title": "Body" + }, + "visibility": { + "type": "string", + "title": "Visibility" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "author", + "author_role", + "body", + "visibility", + "created_at_unix_seconds" + ], + "title": "MessageView" + }, + "Milestone": { + "properties": { + "title": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Title" + }, + "due_on": { + "type": "string", + "format": "date", + "title": "Due On" + }, + "completed_on": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Completed On" + }, + "evidence": { + "type": "string", + "maxLength": 2000, + "title": "Evidence", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "due_on" + ], + "title": "Milestone" + }, + "MinutesDecision": { + "properties": { + "action": { + "type": "string", + "enum": [ + "post", + "adopt", + "sign" + ], + "title": "Action" + }, + "note": { + "type": "string", + "title": "Note", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "MinutesDecision" + }, + "ModelRegistryCreate": { + "properties": { + "model_name": { + "type": "string", + "title": "Model Name" + }, + "model_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Version" + }, + "parameter_count": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parameter Count" + }, + "license": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License" + }, + "model_card_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Card Url" + }, + "is_active": { + "type": "boolean", + "title": "Is Active", + "default": false + }, + "context_window_size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Context Window Size" + }, + "supports_ner": { + "type": "boolean", + "title": "Supports Ner", + "default": false + }, + "supports_vision": { + "type": "boolean", + "title": "Supports Vision", + "default": false + } + }, + "type": "object", + "required": [ + "model_name" + ], + "title": "ModelRegistryCreate", + "description": "Schema for creating a new model_registry record (POST body)." + }, + "ModelRegistryRead": { + "properties": { + "id": { + "type": "integer", + "title": "Id" + }, + "model_name": { + "type": "string", + "title": "Model Name" + }, + "model_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Version" + }, + "parameter_count": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parameter Count" + }, + "license": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License" + }, + "model_card_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Card Url" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "added_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Added At" + }, + "context_window_size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Context Window Size" + }, + "supports_ner": { + "type": "boolean", + "title": "Supports Ner" + }, + "supports_vision": { + "type": "boolean", + "title": "Supports Vision" + } + }, + "type": "object", + "required": [ + "id", + "model_name", + "is_active", + "supports_ner", + "supports_vision" + ], + "title": "ModelRegistryRead", + "description": "Schema for returning a model_registry record (GET response).\n\n``from_attributes=True`` allows construction directly from an ORM instance." + }, + "ModelRegistryUpdate": { + "properties": { + "model_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Name" + }, + "model_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Version" + }, + "parameter_count": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parameter Count" + }, + "license": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License" + }, + "model_card_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Card Url" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + }, + "context_window_size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Context Window Size" + }, + "supports_ner": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Supports Ner" + }, + "supports_vision": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Supports Vision" + } + }, + "type": "object", + "title": "ModelRegistryUpdate", + "description": "Schema for partially updating a model_registry record (PATCH body).\n\nEvery field is optional so callers can send only the fields they want to\nchange." + }, + "MotionCorrection": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "reason": { + "type": "string", + "minLength": 1, + "title": "Reason" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text", + "reason" + ], + "title": "MotionCorrection" + }, + "MotionInput": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "seconded_by": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Seconded By" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text" + ], + "title": "MotionInput" + }, + "NativePayload": { + "properties": {}, + "additionalProperties": false, + "type": "object", + "title": "NativePayload" + }, + "NativeRequestRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "requester_name": { + "type": "string", + "title": "Requester Name" + }, + "requester_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Email" + }, + "requester_phone": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Phone" + }, + "requester_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Type" + }, + "date_received": { + "type": "string", + "format": "date-time", + "title": "Date Received" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "description": { + "type": "string", + "title": "Description" + }, + "status": { + "$ref": "#/components/schemas/RequestStatus" + }, + "assigned_to": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "created_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "response_draft": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Response Draft" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + }, + "estimated_fee": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Estimated Fee" + }, + "fee_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Fee Status" + }, + "fee_waiver_requested": { + "type": "boolean", + "title": "Fee Waiver Requested", + "default": false + }, + "priority": { + "type": "string", + "title": "Priority", + "default": "normal" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + }, + "closed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Closed At" + }, + "closure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Closure Reason" + }, + "desktop_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Desktop Id" + }, + "public_tracking_number": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Public Tracking Number" + }, + "submitted_via": { + "type": "string", + "title": "Submitted Via" + }, + "deadline_label": { + "type": "string", + "title": "Deadline Label" + }, + "deadline_basis": { + "type": "string", + "title": "Deadline Basis" + }, + "deadline_reviewed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Deadline Reviewed At" + } + }, + "type": "object", + "required": [ + "id", + "requester_name", + "requester_email", + "date_received", + "statutory_deadline", + "description", + "status", + "assigned_to", + "created_by", + "created_at", + "response_draft", + "review_notes", + "desktop_id", + "public_tracking_number", + "submitted_via", + "deadline_label", + "deadline_basis", + "deadline_reviewed_at" + ], + "title": "NativeRequestRead" + }, + "NoticeDocumentInput": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text" + ], + "title": "NoticeDocumentInput" + }, + "NoticeDraft": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "body": { + "type": "string", + "maxLength": 100000, + "minLength": 1, + "title": "Body" + }, + "notice_type": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Notice Type" + }, + "statutory_basis": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Statutory Basis" + }, + "event_date": { + "type": "string", + "format": "date", + "title": "Event Date" + }, + "lead_days": { + "type": "integer", + "maximum": 365.0, + "minimum": 0.0, + "title": "Lead Days" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "body", + "notice_type", + "statutory_basis", + "event_date", + "lead_days" + ], + "title": "NoticeDraft" + }, + "NoticeInput": { + "properties": { + "notice_type": { + "type": "string", + "enum": [ + "regular", + "special", + "emergency", + "closed_session", + "executive" + ], + "title": "Notice Type" + }, + "posted_at": { + "type": "string", + "format": "date-time", + "title": "Posted At" + }, + "minimum_notice_hours": { + "type": "integer", + "minimum": 0.0, + "title": "Minimum Notice Hours" + }, + "statutory_basis": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Statutory Basis" + }, + "approved_by": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Approved By" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "notice_type", + "posted_at", + "minimum_notice_hours" + ], + "title": "NoticeInput" + }, + "NoticeProofInput": { + "properties": { + "location": { + "type": "string", + "minLength": 1, + "title": "Location" + }, + "note": { + "type": "string", + "title": "Note", + "default": "" + }, + "document_delivery_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Document Delivery Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "location" + ], + "title": "NoticeProofInput" + }, + "NotificationLogRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "template_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Template Id" + }, + "recipient_email": { + "type": "string", + "title": "Recipient Email" + }, + "request_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Request Id" + }, + "channel": { + "type": "string", + "title": "Channel" + }, + "status": { + "type": "string", + "title": "Status" + }, + "sent_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Sent At" + }, + "error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Message" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "template_id", + "recipient_email", + "request_id", + "channel", + "status", + "sent_at", + "error_message", + "created_at" + ], + "title": "NotificationLogRead" + }, + "NotificationTemplateCreate": { + "properties": { + "event_type": { + "type": "string", + "title": "Event Type" + }, + "channel": { + "type": "string", + "title": "Channel", + "default": "email" + }, + "subject_template": { + "type": "string", + "title": "Subject Template" + }, + "body_template": { + "type": "string", + "title": "Body Template" + } + }, + "type": "object", + "required": [ + "event_type", + "subject_template", + "body_template" + ], + "title": "NotificationTemplateCreate" + }, + "NotificationTemplateRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "event_type": { + "type": "string", + "title": "Event Type" + }, + "channel": { + "type": "string", + "title": "Channel" + }, + "subject_template": { + "type": "string", + "title": "Subject Template" + }, + "body_template": { + "type": "string", + "title": "Body Template" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "event_type", + "channel", + "subject_template", + "body_template", + "is_active", + "created_at" + ], + "title": "NotificationTemplateRead" + }, + "NotificationTemplateUpdate": { + "properties": { + "subject_template": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Subject Template" + }, + "body_template": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Body Template" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "NotificationTemplateUpdate" + }, + "NotificationView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "notification_id": { + "type": "string", + "title": "Notification Id" + }, + "module_id": { + "type": "string", + "title": "Module Id" + }, + "record_id": { + "type": "string", + "title": "Record Id" + }, + "audience": { + "type": "string", + "title": "Audience" + }, + "channel": { + "type": "string", + "title": "Channel" + }, + "subject": { + "type": "string", + "title": "Subject" + }, + "body": { + "type": "string", + "title": "Body" + }, + "status": { + "type": "string", + "title": "Status" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + }, + "sent_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Sent At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "notification_id", + "module_id", + "record_id", + "audience", + "channel", + "subject", + "body", + "status", + "created_at_unix_seconds", + "sent_at_unix_seconds" + ], + "title": "NotificationView" + }, + "OllamaModelInfo": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Size" + }, + "details": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Details" + } + }, + "type": "object", + "required": [ + "name" + ], + "title": "OllamaModelInfo" + }, + "OllamaStatus": { + "properties": { + "status": { + "type": "string", + "title": "Status" + }, + "models": { + "items": { + "$ref": "#/components/schemas/OllamaModelInfo" + }, + "type": "array", + "title": "Models" + } + }, + "type": "object", + "required": [ + "status", + "models" + ], + "title": "OllamaStatus" + }, + "OperationalMetrics": { + "properties": { + "average_response_time_days": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Average Response Time Days" + }, + "median_response_time_days": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Median Response Time Days" + }, + "requests_by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Requests By Status" + }, + "requests_by_department": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Requests By Department" + }, + "deadline_compliance_rate": { + "type": "number", + "title": "Deadline Compliance Rate" + }, + "total_open": { + "type": "integer", + "title": "Total Open" + }, + "total_closed": { + "type": "integer", + "title": "Total Closed" + }, + "total_overdue": { + "type": "integer", + "title": "Total Overdue" + }, + "clarification_frequency": { + "type": "number", + "title": "Clarification Frequency" + }, + "top_request_topics": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Top Request Topics" + } + }, + "type": "object", + "required": [ + "average_response_time_days", + "median_response_time_days", + "requests_by_status", + "requests_by_department", + "deadline_compliance_rate", + "total_open", + "total_closed", + "total_overdue", + "clarification_frequency", + "top_request_topics" + ], + "title": "OperationalMetrics" + }, + "Outline": { + "properties": { + "title": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Title" + }, + "question_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "maxItems": 50, + "minItems": 1, + "title": "Question Ids" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "question_ids" + ], + "title": "Outline" + }, + "Packet": { + "properties": { + "expected_revision": { + "type": "string", + "format": "uuid", + "title": "Expected Revision" + }, + "visibility": { + "type": "string", + "enum": [ + "staff_only", + "records_copy" + ], + "title": "Visibility" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "expected_revision", + "visibility" + ], + "title": "Packet" + }, + "PacketInput": { + "properties": { + "agenda_item_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "title": "Agenda Item Ids" + }, + "source_files": { + "items": { + "$ref": "#/components/schemas/ManagedSource" + }, + "type": "array", + "title": "Source Files" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "agenda_item_ids" + ], + "title": "PacketInput" + }, + "Pathway": { + "properties": { + "project_type": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Project Type" + }, + "proposal": { + "type": "string", + "maxLength": 4000, + "title": "Proposal", + "default": "" + }, + "location_context": { + "type": "string", + "maxLength": 1000, + "title": "Location Context", + "default": "" + }, + "requirement_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Requirement Revision" + }, + "fee_link": { + "anyOf": [ + { + "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "project_type" + ], + "title": "Pathway" + }, + "PathwayStep": { + "properties": { + "step": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Step" + }, + "citation": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Citation" + }, + "typical_time": { + "type": "string", + "maxLength": 1000, + "title": "Typical Time", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "step", + "citation" + ], + "title": "PathwayStep" + }, + "PlainLanguageSummaryCreate": { + "properties": { + "summary_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Summary Id" + }, + "section_version_id": { + "type": "string", + "minLength": 1, + "title": "Section Version Id" + }, + "summary_text": { + "type": "string", + "minLength": 1, + "title": "Summary Text" + }, + "language_code": { + "type": "string", + "title": "Language Code", + "default": "en" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "section_version_id", + "summary_text" + ], + "title": "PlainLanguageSummaryCreate", + "description": "Request body for staff-drafted plain-language summaries." + }, + "PolicySelection": { + "properties": { + "plan_id": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Plan Id" + }, + "revision_id": { + "type": "string", + "maxLength": 36, + "minLength": 36, + "title": "Revision Id" + }, + "policy_id": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Policy Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "plan_id", + "revision_id", + "policy_id" + ], + "title": "PolicySelection" + }, + "PortalModeResponse": { + "properties": { + "mode": { + "type": "string", + "enum": [ + "public", + "private" + ], + "title": "Mode", + "description": "Active portal posture for this deployment. ``public`` = minimal resident surface (landing + authenticated records-request submission + resident registration) reachable without staff auth. ``private`` = staff-only; no public routes, no resident self-registration." + } + }, + "type": "object", + "required": [ + "mode" + ], + "title": "PortalModeResponse", + "description": "T5D — schema for ``GET /config/portal-mode``.\n\nExposed to the frontend on boot so it can branch routing without a\nuser-identity lookup. The payload is intentionally the single field\nbelow — no staff config, no user state, no schema version." + }, + "PrepareArtifact": { + "properties": { + "kind": { + "type": "string", + "enum": [ + "response", + "release-package" + ], + "title": "Kind" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "kind" + ], + "title": "PrepareArtifact" + }, + "Proof": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + }, + "filename": { + "type": "string", + "maxLength": 150, + "minLength": 1, + "title": "Filename" + }, + "content_base64": { + "type": "string", + "maxLength": 7000000, + "minLength": 1, + "title": "Content Base64" + }, + "location": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Location" + }, + "published_at": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Published At" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence", + "filename", + "content_base64", + "location", + "published_at" + ], + "title": "Proof" + }, + "Proposal": { + "properties": { + "id": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Id" + }, + "version_id": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Version Id" + }, + "meeting_id": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "ordinance_number": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Ordinance Number" + }, + "proposed_text": { + "type": "string", + "maxLength": 1000000, + "minLength": 1, + "title": "Proposed Text" + }, + "supersedes_id": { + "anyOf": [ + { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$" + }, + { + "type": "null" + } + ], + "title": "Supersedes Id" + }, + "reconciliation_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reconciliation Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "version_id", + "meeting_id", + "title", + "ordinance_number", + "proposed_text" + ], + "title": "Proposal" + }, + "PublicExplore": { + "properties": { + "goal": { + "type": "string", + "maxLength": 500, + "title": "Goal", + "default": "" + }, + "topic": { + "type": "string", + "maxLength": 160, + "title": "Topic", + "default": "" + }, + "neighborhood": { + "type": "string", + "maxLength": 255, + "title": "Neighborhood", + "default": "" + }, + "plan_type": { + "type": "string", + "maxLength": 120, + "title": "Plan Type", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "title": "PublicExplore" + }, + "PublicIntake": { + "properties": { + "requester": { + "type": "string", + "minLength": 1, + "title": "Requester" + }, + "requesterContact": { + "type": "string", + "minLength": 1, + "title": "Requestercontact" + }, + "summary": { + "type": "string", + "minLength": 1, + "title": "Summary" + }, + "deadline": { + "type": "string", + "title": "Deadline", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requester", + "requesterContact", + "summary" + ], + "title": "PublicIntake" + }, + "PublicLookup": { + "properties": { + "trackingNumber": { + "type": "string", + "minLength": 1, + "title": "Trackingnumber" + }, + "requesterContact": { + "type": "string", + "minLength": 1, + "title": "Requestercontact" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "trackingNumber", + "requesterContact" + ], + "title": "PublicLookup" + }, + "PublicMessage": { + "properties": { + "trackingNumber": { + "type": "string", + "minLength": 1, + "title": "Trackingnumber" + }, + "requesterContact": { + "type": "string", + "minLength": 1, + "title": "Requestercontact" + }, + "publicRequestMessage": { + "type": "string", + "minLength": 1, + "title": "Publicrequestmessage" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "trackingNumber", + "requesterContact", + "publicRequestMessage" + ], + "title": "PublicMessage" + }, + "PublicStatusView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "label": { + "type": "string", + "title": "Label" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "status": { + "type": "string", + "title": "Status" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "label", + "summary", + "status", + "created_at_unix_seconds" + ], + "title": "PublicStatusView" + }, + "PublicationView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "source_module": { + "type": "string", + "title": "Source Module" + }, + "source_record_id": { + "type": "string", + "title": "Source Record Id" + }, + "record_type": { + "type": "string", + "title": "Record Type" + }, + "public_payload": { + "type": "string", + "title": "Public Payload" + }, + "payload_hash": { + "type": "string", + "title": "Payload Hash" + }, + "published_at_unix_seconds": { + "type": "integer", + "title": "Published At Unix Seconds" + }, + "retracted_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Retracted At Unix Seconds" + }, + "retracted_by": { + "type": "string", + "title": "Retracted By", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "source_module", + "source_record_id", + "record_type", + "public_payload", + "payload_hash", + "published_at_unix_seconds" + ], + "title": "PublicationView" + }, + "PublishingPlan": { + "properties": { + "action": { + "type": "string", + "const": "publishing-workflow", + "title": "Action" + }, + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "hasReview": { + "type": "boolean", + "title": "Hasreview", + "default": false + }, + "hasPlainLanguage": { + "type": "boolean", + "title": "Hasplainlanguage", + "default": false + }, + "hasTranslationReview": { + "type": "boolean", + "title": "Hastranslationreview", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "PublishingPlan" + }, + "Question": { + "properties": { + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + }, + "question": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Question" + }, + "kind": { + "type": "string", + "enum": [ + "use", + "dimension" + ], + "title": "Kind" + }, + "key": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Key" + }, + "audience": { + "type": "string", + "enum": [ + "resident", + "staff" + ], + "title": "Audience", + "default": "resident" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "jurisdiction", + "query", + "question", + "kind", + "key" + ], + "title": "Question" + }, + "QuestionAnswerRequest": { + "properties": { + "question": { + "type": "string", + "minLength": 1, + "title": "Question" + }, + "section_number": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Section Number" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "question" + ], + "title": "QuestionAnswerRequest", + "description": "Request body for citation-grounded code Q&A." + }, + "RecordsDocumentView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "attachment_id": { + "type": "string", + "title": "Attachment Id" + }, + "title": { + "type": "string", + "title": "Title" + }, + "original_path": { + "type": "string", + "title": "Original Path" + }, + "stored_path": { + "type": "string", + "title": "Stored Path" + }, + "citation": { + "type": "string", + "title": "Citation" + }, + "sha256": { + "type": "string", + "title": "Sha256" + }, + "size_bytes": { + "type": "integer", + "title": "Size Bytes" + }, + "status": { + "type": "string", + "title": "Status" + }, + "added_by": { + "type": "string", + "title": "Added By" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + }, + "release_original_path": { + "type": "string", + "title": "Release Original Path", + "default": "" + }, + "release_stored_path": { + "type": "string", + "title": "Release Stored Path", + "default": "" + }, + "release_file_name": { + "type": "string", + "title": "Release File Name", + "default": "" + }, + "release_sha256": { + "type": "string", + "title": "Release Sha256", + "default": "" + }, + "release_size_bytes": { + "type": "integer", + "title": "Release Size Bytes", + "default": 0 + }, + "release_status": { + "type": "string", + "title": "Release Status", + "default": "" + }, + "release_note": { + "type": "string", + "title": "Release Note", + "default": "" + }, + "release_added_by": { + "type": "string", + "title": "Release Added By", + "default": "" + }, + "release_added_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Release Added At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "attachment_id", + "title", + "original_path", + "stored_path", + "citation", + "sha256", + "size_bytes", + "status", + "added_by", + "created_at_unix_seconds" + ], + "title": "RecordsDocumentView" + }, + "RecordsOperationRead": { + "properties": { + "action": { + "type": "string", + "title": "Action" + }, + "message": { + "type": "string", + "title": "Message" + }, + "request": { + "$ref": "#/components/schemas/RecordsView" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "message", + "request" + ], + "title": "RecordsOperationRead" + }, + "RecordsStateRead": { + "properties": { + "demo_fixture": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Demo Fixture" + }, + "records_requests": { + "items": { + "$ref": "#/components/schemas/RecordsView" + }, + "type": "array", + "title": "Records Requests" + }, + "notification_events": { + "items": { + "$ref": "#/components/schemas/NotificationView" + }, + "type": "array", + "title": "Notification Events" + }, + "publication_events": { + "items": { + "$ref": "#/components/schemas/PublicationView" + }, + "type": "array", + "title": "Publication Events" + }, + "audit_entries": { + "items": { + "$ref": "#/components/schemas/AuditView" + }, + "type": "array", + "title": "Audit Entries" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "records_requests" + ], + "title": "RecordsStateRead" + }, + "RecordsView": { + "properties": { + "request_id": { + "type": "string", + "title": "Request Id" + }, + "id": { + "type": "string", + "title": "Id" + }, + "public_tracking_number": { + "type": "string", + "title": "Public Tracking Number" + }, + "requester": { + "type": "string", + "title": "Requester" + }, + "requester_contact": { + "type": "string", + "title": "Requester Contact" + }, + "submitted_via": { + "type": "string", + "title": "Submitted Via" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "deadline": { + "type": "string", + "title": "Deadline" + }, + "deadline_basis": { + "type": "string", + "title": "Deadline Basis" + }, + "status": { + "type": "string", + "title": "Status" + }, + "assigned_to": { + "type": "string", + "title": "Assigned To" + }, + "clarification_notes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Clarification Notes" + }, + "search_notes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Search Notes" + }, + "search_sessions": { + "items": { + "$ref": "#/components/schemas/SearchReceiptView" + }, + "type": "array", + "title": "Search Sessions" + }, + "exemption_reviews": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Exemption Reviews" + }, + "exemption_decisions": { + "items": { + "$ref": "#/components/schemas/ExemptionDecisionView" + }, + "type": "array", + "title": "Exemption Decisions" + }, + "fee_estimate": { + "type": "string", + "title": "Fee Estimate" + }, + "fee_line_items": { + "items": { + "$ref": "#/components/schemas/FeeLineView" + }, + "type": "array", + "title": "Fee Line Items" + }, + "fee_waiver_reason": { + "type": "string", + "title": "Fee Waiver Reason" + }, + "citations": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Citations" + }, + "response_draft": { + "type": "string", + "title": "Response Draft" + }, + "approval_notes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Approval Notes" + }, + "exports": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Exports" + }, + "documents": { + "items": { + "$ref": "#/components/schemas/RecordsDocumentView" + }, + "type": "array", + "title": "Documents" + }, + "release_packages": { + "items": { + "$ref": "#/components/schemas/ReleasePackageView" + }, + "type": "array", + "title": "Release Packages" + }, + "timeline": { + "items": { + "$ref": "#/components/schemas/TimelineView" + }, + "type": "array", + "title": "Timeline" + }, + "public_status_events": { + "items": { + "$ref": "#/components/schemas/PublicStatusView" + }, + "type": "array", + "title": "Public Status Events" + }, + "messages": { + "items": { + "$ref": "#/components/schemas/MessageView" + }, + "type": "array", + "title": "Messages" + }, + "deadline_reviewed_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Deadline Reviewed At Unix Seconds" + }, + "approved_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Approved At Unix Seconds" + }, + "fulfilled_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Fulfilled At Unix Seconds" + }, + "closed_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Closed At Unix Seconds" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "request_id", + "id", + "public_tracking_number", + "requester", + "requester_contact", + "submitted_via", + "summary", + "deadline", + "deadline_basis", + "status", + "assigned_to", + "clarification_notes", + "search_notes", + "search_sessions", + "exemption_reviews", + "exemption_decisions", + "fee_estimate", + "fee_line_items", + "fee_waiver_reason", + "citations", + "response_draft", + "approval_notes", + "exports", + "timeline", + "public_status_events", + "messages", + "deadline_reviewed_at_unix_seconds", + "approved_at_unix_seconds", + "fulfilled_at_unix_seconds", + "closed_at_unix_seconds", + "created_at_unix_seconds" + ], + "title": "RecordsView" + }, + "ReleasePackageView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "export_path": { + "type": "string", + "title": "Export Path" + }, + "package_hash": { + "type": "string", + "title": "Package Hash" + }, + "document_count": { + "type": "integer", + "title": "Document Count" + }, + "release_artifact_count": { + "type": "integer", + "title": "Release Artifact Count" + }, + "search_session_count": { + "type": "integer", + "title": "Search Session Count" + }, + "release_count": { + "type": "integer", + "title": "Release Count" + }, + "redacted_count": { + "type": "integer", + "title": "Redacted Count" + }, + "exempt_count": { + "type": "integer", + "title": "Exempt Count" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "export_path", + "package_hash", + "document_count", + "release_artifact_count", + "search_session_count", + "release_count", + "redacted_count", + "exempt_count", + "created_at_unix_seconds" + ], + "title": "ReleasePackageView" + }, + "RepeatLookup": { + "properties": { + "property_reference": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Property Reference" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "property_reference" + ], + "title": "RepeatLookup" + }, + "RequestCreate": { + "properties": { + "requester_name": { + "type": "string", + "maxLength": 255, + "title": "Requester Name" + }, + "requester_email": { + "anyOf": [ + { + "type": "string", + "maxLength": 255 + }, + { + "type": "null" + } + ], + "title": "Requester Email" + }, + "requester_phone": { + "anyOf": [ + { + "type": "string", + "maxLength": 50 + }, + { + "type": "null" + } + ], + "title": "Requester Phone" + }, + "requester_type": { + "anyOf": [ + { + "type": "string", + "maxLength": 100 + }, + { + "type": "null" + } + ], + "title": "Requester Type" + }, + "description": { + "type": "string", + "maxLength": 10000, + "title": "Description" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "priority": { + "type": "string", + "title": "Priority", + "default": "normal" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string", + "pattern": "^(narrow|moderate|broad)$" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + } + }, + "type": "object", + "required": [ + "requester_name", + "description" + ], + "title": "RequestCreate" + }, + "RequestDocumentAdd": { + "properties": { + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "relevance_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Relevance Note" + } + }, + "type": "object", + "required": [ + "document_id" + ], + "title": "RequestDocumentAdd" + }, + "RequestDocumentRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "relevance_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Relevance Note" + }, + "exemption_flags": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Exemption Flags" + }, + "inclusion_status": { + "$ref": "#/components/schemas/InclusionStatus" + }, + "attached_at": { + "type": "string", + "format": "date-time", + "title": "Attached At" + }, + "attached_by": { + "type": "string", + "format": "uuid", + "title": "Attached By" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "document_id", + "relevance_note", + "exemption_flags", + "inclusion_status", + "attached_at", + "attached_by" + ], + "title": "RequestDocumentRead" + }, + "RequestRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "requester_name": { + "type": "string", + "title": "Requester Name" + }, + "requester_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Email" + }, + "requester_phone": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Phone" + }, + "requester_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Type" + }, + "date_received": { + "type": "string", + "format": "date-time", + "title": "Date Received" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "description": { + "type": "string", + "title": "Description" + }, + "status": { + "$ref": "#/components/schemas/RequestStatus" + }, + "assigned_to": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "created_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "response_draft": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Response Draft" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + }, + "estimated_fee": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Estimated Fee" + }, + "fee_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Fee Status" + }, + "fee_waiver_requested": { + "type": "boolean", + "title": "Fee Waiver Requested", + "default": false + }, + "priority": { + "type": "string", + "title": "Priority", + "default": "normal" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + }, + "closed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Closed At" + }, + "closure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Closure Reason" + } + }, + "type": "object", + "required": [ + "id", + "requester_name", + "requester_email", + "date_received", + "statutory_deadline", + "description", + "status", + "assigned_to", + "created_by", + "created_at", + "response_draft", + "review_notes" + ], + "title": "RequestRead" + }, + "RequestStats": { + "properties": { + "total_requests": { + "type": "integer", + "title": "Total Requests" + }, + "by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "By Status" + }, + "approaching_deadline": { + "type": "integer", + "title": "Approaching Deadline" + }, + "overdue": { + "type": "integer", + "title": "Overdue" + } + }, + "type": "object", + "required": [ + "total_requests", + "by_status", + "approaching_deadline", + "overdue" + ], + "title": "RequestStats" + }, + "RequestStatus": { + "type": "string", + "enum": [ + "received", + "clarification_needed", + "assigned", + "searching", + "in_review", + "ready_for_release", + "drafted", + "approved", + "fulfilled", + "closed" + ], + "title": "RequestStatus" + }, + "RequestUpdate": { + "properties": { + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "status": { + "anyOf": [ + { + "$ref": "#/components/schemas/RequestStatus" + }, + { + "type": "null" + } + ] + }, + "assigned_to": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "response_draft": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Response Draft" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + } + }, + "type": "object", + "title": "RequestUpdate" + }, + "RequirementBundle": { + "properties": { + "requirement_id": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]{1,100}$", + "title": "Requirement Id" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "project_type": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Project Type" + }, + "source_reference": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Source Reference" + }, + "source_date": { + "type": "string", + "format": "date", + "title": "Source Date" + }, + "effective_on": { + "type": "string", + "format": "date", + "title": "Effective On" + }, + "dataset_kind": { + "type": "string", + "enum": [ + "municipal", + "fictional" + ], + "title": "Dataset Kind" + }, + "filename": { + "type": "string", + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$", + "title": "Filename" + }, + "content_base64": { + "type": "string", + "maxLength": 14000000, + "minLength": 1, + "title": "Content Base64" + }, + "sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Sha256" + }, + "materials": { + "items": { + "$ref": "#/components/schemas/Material" + }, + "type": "array", + "maxItems": 100, + "minItems": 1, + "title": "Materials" + }, + "pathway": { + "items": { + "$ref": "#/components/schemas/PathwayStep" + }, + "type": "array", + "maxItems": 100, + "title": "Pathway" + }, + "fee_link": { + "anyOf": [ + { + "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink" + }, + { + "type": "null" + } + ] + }, + "staff_note": { + "type": "string", + "maxLength": 4000, + "title": "Staff Note", + "default": "" + }, + "change_note": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Change Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requirement_id", + "title", + "jurisdiction", + "project_type", + "source_reference", + "source_date", + "effective_on", + "dataset_kind", + "filename", + "content_base64", + "sha256", + "materials", + "change_note" + ], + "title": "RequirementBundle" + }, + "ResponseLetterCreate": { + "properties": { + "template_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Template Id" + } + }, + "type": "object", + "title": "ResponseLetterCreate" + }, + "ResponseLetterRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "template_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Template Id" + }, + "generated_content": { + "type": "string", + "title": "Generated Content" + }, + "edited_content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Edited Content" + }, + "status": { + "type": "string", + "title": "Status" + }, + "generated_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Generated By" + }, + "approved_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Approved By" + }, + "sent_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Sent At" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "template_id", + "generated_content", + "edited_content", + "status", + "generated_by", + "approved_by", + "sent_at", + "created_at" + ], + "title": "ResponseLetterRead" + }, + "ResponseLetterUpdate": { + "properties": { + "edited_content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Edited Content" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + } + }, + "type": "object", + "title": "ResponseLetterUpdate" + }, + "ReviewInput": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "body": { + "type": "string", + "maxLength": 5000, + "title": "Body", + "default": "" + }, + "hasAltText": { + "type": "boolean", + "title": "Hasalttext", + "default": false + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "en" + } + }, + "additionalProperties": false, + "type": "object", + "title": "ReviewInput" + }, + "Revision": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + }, + "document": { + "$ref": "#/components/schemas/NoticeDraft" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence", + "document" + ], + "title": "Revision" + }, + "RewriteInput": { + "properties": { + "action": { + "type": "string", + "enum": [ + "plain-language", + "language-variant" + ], + "title": "Action" + }, + "text": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Text" + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "text" + ], + "title": "RewriteInput" + }, + "RewriteResult": { + "properties": { + "action": { + "type": "string", + "enum": [ + "plain-language", + "language-variant" + ], + "title": "Action" + }, + "text": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Text" + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "" + }, + "outcome": { + "type": "string", + "enum": [ + "generated", + "unavailable" + ], + "title": "Outcome" + }, + "generated": { + "anyOf": [ + { + "type": "string", + "maxLength": 100000 + }, + { + "type": "null" + } + ], + "title": "Generated" + }, + "model": { + "anyOf": [ + { + "type": "string", + "maxLength": 200 + }, + { + "type": "null" + } + ], + "title": "Model" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "text", + "outcome" + ], + "title": "RewriteResult" + }, + "Rule": { + "properties": { + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "zone_code": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Zone Code" + }, + "key": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Key" + }, + "section_number": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Section Number" + }, + "kind": { + "type": "string", + "enum": [ + "use", + "dimension" + ], + "title": "Kind" + }, + "value": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Value" + }, + "overlay_code": { + "anyOf": [ + { + "type": "string", + "maxLength": 255 + }, + { + "type": "null" + } + ], + "title": "Overlay Code" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "jurisdiction", + "zone_code", + "key", + "section_number", + "kind", + "value" + ], + "title": "Rule" + }, + "RuleTestMatch": { + "properties": { + "matched_text": { + "type": "string", + "title": "Matched Text" + }, + "start": { + "type": "integer", + "title": "Start" + }, + "end": { + "type": "integer", + "title": "End" + } + }, + "type": "object", + "required": [ + "matched_text", + "start", + "end" + ], + "title": "RuleTestMatch" + }, + "RuleTestRequest": { + "properties": { + "sample_text": { + "type": "string", + "title": "Sample Text" + } + }, + "type": "object", + "required": [ + "sample_text" + ], + "title": "RuleTestRequest" + }, + "RuleTestResponse": { + "properties": { + "rule_id": { + "type": "string", + "format": "uuid", + "title": "Rule Id" + }, + "rule_type": { + "type": "string", + "title": "Rule Type" + }, + "matched": { + "type": "boolean", + "title": "Matched" + }, + "matches": { + "items": { + "$ref": "#/components/schemas/RuleTestMatch" + }, + "type": "array", + "title": "Matches" + } + }, + "type": "object", + "required": [ + "rule_id", + "rule_type", + "matched", + "matches" + ], + "title": "RuleTestResponse" + }, + "RuleType": { + "type": "string", + "enum": [ + "regex", + "keyword", + "llm_prompt" + ], + "title": "RuleType" + }, + "SaveReview": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "body": { + "type": "string", + "maxLength": 5000, + "title": "Body", + "default": "" + }, + "hasAltText": { + "type": "boolean", + "title": "Hasalttext", + "default": false + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "en" + }, + "ai_analysis": { + "anyOf": [ + { + "type": "string", + "maxLength": 100000 + }, + { + "type": "null" + } + ], + "title": "Ai Analysis" + }, + "ai_analysis_model": { + "anyOf": [ + { + "type": "string", + "maxLength": 200 + }, + { + "type": "null" + } + ], + "title": "Ai Analysis Model" + }, + "ai_outcome": { + "type": "string", + "enum": [ + "generated", + "unavailable", + "failed" + ], + "title": "Ai Outcome" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "ai_outcome" + ], + "title": "SaveReview" + }, + "SearchFilterOptions": { + "properties": { + "file_types": { + "items": { + "type": "string" + }, + "type": "array", + "title": "File Types" + }, + "source_names": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Source Names" + }, + "departments": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array", + "title": "Departments", + "default": [] + }, + "date_range": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Date Range" + } + }, + "type": "object", + "required": [ + "file_types", + "source_names" + ], + "title": "SearchFilterOptions" + }, + "SearchInput": { + "properties": { + "query": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "SearchInput" + }, + "SearchNoteCommand": { + "properties": { + "action": { + "type": "string", + "const": "record-records-search", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/SearchNotePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "SearchNoteCommand" + }, + "SearchNotePayload": { + "properties": { + "sourceNote": { + "type": "string", + "minLength": 1, + "title": "Sourcenote" + }, + "citation": { + "type": "string", + "title": "Citation", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sourceNote" + ], + "title": "SearchNotePayload" + }, + "SearchReceiptCommand": { + "properties": { + "action": { + "type": "string", + "const": "record-records-search-session", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/SearchReceiptPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "SearchReceiptCommand" + }, + "SearchReceiptPayload": { + "properties": { + "searchQuery": { + "type": "string", + "minLength": 1, + "title": "Searchquery" + }, + "searchLocations": { + "type": "string", + "minLength": 1, + "title": "Searchlocations" + }, + "searchResultTitle": { + "type": "string", + "minLength": 1, + "title": "Searchresulttitle" + }, + "searchResultCitation": { + "type": "string", + "minLength": 1, + "title": "Searchresultcitation" + }, + "searchResultSummary": { + "type": "string", + "minLength": 1, + "title": "Searchresultsummary" + }, + "searchResultStatus": { + "type": "string", + "title": "Searchresultstatus", + "default": "" + }, + "searchReviewer": { + "type": "string", + "title": "Searchreviewer", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "searchQuery", + "searchLocations", + "searchResultTitle", + "searchResultCitation", + "searchResultSummary" + ], + "title": "SearchReceiptPayload" + }, + "SearchReceiptView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "query": { + "type": "string", + "title": "Query" + }, + "locations": { + "type": "string", + "title": "Locations" + }, + "reviewer": { + "type": "string", + "title": "Reviewer" + }, + "results": { + "items": { + "$ref": "#/components/schemas/SearchResultView" + }, + "type": "array", + "title": "Results" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "query", + "locations", + "reviewer", + "results", + "created_at_unix_seconds" + ], + "title": "SearchReceiptView" + }, + "SearchRequest": { + "properties": { + "query": { + "type": "string", + "title": "Query" + }, + "session_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Session Id" + }, + "filters": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Filters" + }, + "limit": { + "type": "integer", + "maximum": 50.0, + "title": "Limit", + "default": 10 + }, + "synthesize": { + "type": "boolean", + "title": "Synthesize", + "default": false + } + }, + "type": "object", + "required": [ + "query" + ], + "title": "SearchRequest" + }, + "SearchResponse": { + "properties": { + "query_id": { + "type": "string", + "format": "uuid", + "title": "Query Id" + }, + "session_id": { + "type": "string", + "format": "uuid", + "title": "Session Id" + }, + "query_text": { + "type": "string", + "title": "Query Text" + }, + "results": { + "items": { + "$ref": "#/components/schemas/SearchResultItem" + }, + "type": "array", + "title": "Results" + }, + "results_count": { + "type": "integer", + "title": "Results Count" + }, + "synthesized_answer": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Synthesized Answer" + }, + "ai_generated": { + "type": "boolean", + "title": "Ai Generated", + "default": false + } + }, + "type": "object", + "required": [ + "query_id", + "session_id", + "query_text", + "results", + "results_count" + ], + "title": "SearchResponse" + }, + "SearchResultItem": { + "properties": { + "chunk_id": { + "type": "string", + "format": "uuid", + "title": "Chunk Id" + }, + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "filename": { + "type": "string", + "title": "Filename" + }, + "file_type": { + "type": "string", + "title": "File Type" + }, + "source_path": { + "type": "string", + "title": "Source Path" + }, + "page_number": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Page Number" + }, + "content_text": { + "type": "string", + "title": "Content Text" + }, + "similarity_score": { + "type": "number", + "title": "Similarity Score" + }, + "rank": { + "type": "integer", + "title": "Rank" + } + }, + "type": "object", + "required": [ + "chunk_id", + "document_id", + "filename", + "file_type", + "source_path", + "page_number", + "content_text", + "similarity_score", + "rank" + ], + "title": "SearchResultItem" + }, + "SearchResultView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "title": { + "type": "string", + "title": "Title" + }, + "citation": { + "type": "string", + "title": "Citation" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "status": { + "type": "string", + "title": "Status" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "title", + "citation", + "summary", + "status" + ], + "title": "SearchResultView" + }, + "SearchSessionRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "user_id": { + "type": "string", + "format": "uuid", + "title": "User Id" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "queries": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array", + "title": "Queries", + "default": [] + } + }, + "type": "object", + "required": [ + "id", + "user_id", + "created_at" + ], + "title": "SearchSessionRead" + }, + "SectionCreate": { + "properties": { + "section_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Section Id" + }, + "chapter_id": { + "type": "string", + "minLength": 1, + "title": "Chapter Id" + }, + "section_number": { + "type": "string", + "minLength": 1, + "title": "Section Number" + }, + "section_heading": { + "type": "string", + "minLength": 1, + "title": "Section Heading" + }, + "parent_section_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parent Section Id" + }, + "sort_order": { + "type": "integer", + "title": "Sort Order", + "default": 0 + }, + "administrative_regulation_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Administrative Regulation Refs" + }, + "resolution_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Resolution Refs" + }, + "policy_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Policy Refs" + }, + "approved_summary_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Approved Summary Refs" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "chapter_id", + "section_number", + "section_heading" + ], + "title": "SectionCreate", + "description": "Request body for creating a code section or subsection." + }, + "SectionVersionCreate": { + "properties": { + "version_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Version Id" + }, + "section_id": { + "type": "string", + "minLength": 1, + "title": "Section Id" + }, + "source_id": { + "type": "string", + "minLength": 1, + "title": "Source Id" + }, + "version_label": { + "type": "string", + "minLength": 1, + "title": "Version Label" + }, + "body": { + "type": "string", + "minLength": 1, + "title": "Body" + }, + "effective_start": { + "type": "string", + "format": "date", + "title": "Effective Start" + }, + "effective_end": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective End" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + }, + "is_current": { + "type": "boolean", + "title": "Is Current", + "default": false + }, + "adoption_event_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Adoption Event Id" + }, + "amendment_event_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Amendment Event Id" + }, + "amendment_summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Amendment Summary" + }, + "prior_version_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Prior Version Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "section_id", + "source_id", + "version_label", + "body", + "effective_start" + ], + "title": "SectionVersionCreate", + "description": "Request body for adding an immutable section version." + }, + "Selection": { + "properties": { + "recording_id": { + "type": "string", + "format": "uuid", + "title": "Recording Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "recording_id", + "expected_sha256" + ], + "title": "Selection" + }, + "SentenceInput": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "citations": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Citations" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text" + ], + "title": "SentenceInput" + }, + "ServiceAccountCreate": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole", + "default": "read_only" + } + }, + "type": "object", + "required": [ + "name" + ], + "title": "ServiceAccountCreate" + }, + "ServiceAccountCreated": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "api_key": { + "type": "string", + "title": "Api Key" + } + }, + "type": "object", + "required": [ + "id", + "name", + "role", + "created_by", + "created_at", + "is_active", + "api_key" + ], + "title": "ServiceAccountCreated", + "description": "Returned only on creation — includes the plaintext API key (shown once)." + }, + "ServiceAccountRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + } + }, + "type": "object", + "required": [ + "id", + "name", + "role", + "created_by", + "created_at", + "is_active" + ], + "title": "ServiceAccountRead" + }, + "ServiceAccountUpdate": { + "properties": { + "role": { + "anyOf": [ + { + "$ref": "#/components/schemas/UserRole" + }, + { + "type": "null" + } + ] + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "ServiceAccountUpdate" + }, + "Snapshot": { + "properties": { + "expected_revision": { + "type": "string", + "format": "uuid", + "title": "Expected Revision" + }, + "visibility": { + "type": "string", + "enum": [ + "staff_only", + "public" + ], + "title": "Visibility" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "expected_revision", + "visibility" + ], + "title": "Snapshot" + }, + "SourceCreate": { + "properties": { + "source_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Id" + }, + "name": { + "type": "string", + "minLength": 1, + "title": "Name" + }, + "publisher": { + "type": "string", + "minLength": 1, + "title": "Publisher" + }, + "source_type": { + "type": "string", + "minLength": 1, + "title": "Source Type" + }, + "source_category": { + "type": "string", + "minLength": 1, + "title": "Source Category" + }, + "source_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Url" + }, + "file_reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "File Reference" + }, + "retrieved_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Retrieved At" + }, + "retrieval_method": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Retrieval Method" + }, + "checksum": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Checksum" + }, + "source_owner": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Owner" + }, + "is_official": { + "type": "boolean", + "title": "Is Official", + "default": true + }, + "official_status_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Official Status Note" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + }, + "staff_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Staff Notes" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "name", + "publisher", + "source_type", + "source_category" + ], + "title": "SourceCreate", + "description": "Request body for registering an official or explicitly labeled source." + }, + "SourceInput": { + "properties": { + "source_id": { + "type": "string", + "minLength": 1, + "title": "Source Id" + }, + "label": { + "type": "string", + "minLength": 1, + "title": "Label" + }, + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "label", + "text" + ], + "title": "SourceInput" + }, + "SourceSnapshot": { + "properties": { + "visibility": { + "type": "string", + "enum": [ + "public", + "staff_only" + ], + "title": "Visibility" + }, + "meeting_event_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "maxItems": 50, + "title": "Meeting Event Ids" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "visibility" + ], + "title": "SourceSnapshot" + }, + "SourceType": { + "type": "string", + "enum": [ + "manual_drop", + "file_system", + "rest_api", + "odbc" + ], + "title": "SourceType" + }, + "StaffRecordsIntake": { + "properties": { + "requester": { + "type": "string", + "minLength": 1, + "title": "Requester" + }, + "summary": { + "type": "string", + "minLength": 1, + "title": "Summary" + }, + "deadline": { + "type": "string", + "title": "Deadline" + }, + "deadlineBasis": { + "type": "string", + "title": "Deadlinebasis", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requester", + "summary", + "deadline" + ], + "title": "StaffRecordsIntake", + "description": "Existing native create-records-request input; no caller-supplied actor." + }, + "StandardsExplanation": { + "properties": { + "question": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Question" + }, + "process_section": { + "type": "string", + "maxLength": 255, + "title": "Process Section", + "default": "" + }, + "zone_code": { + "type": "string", + "maxLength": 40, + "title": "Zone Code", + "default": "" + }, + "rule_types": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 10, + "title": "Rule Types" + }, + "observed": { + "additionalProperties": { + "type": "string" + }, + "type": "object", + "title": "Observed" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "question" + ], + "title": "StandardsExplanation" + }, + "SyncFailureRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "source_id": { + "type": "string", + "format": "uuid", + "title": "Source Id" + }, + "source_path": { + "type": "string", + "title": "Source Path" + }, + "error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Message" + }, + "error_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Class" + }, + "http_status_code": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Http Status Code" + }, + "retry_count": { + "type": "integer", + "title": "Retry Count" + }, + "status": { + "type": "string", + "title": "Status" + }, + "first_failed_at": { + "type": "string", + "format": "date-time", + "title": "First Failed At" + }, + "last_retried_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Retried At" + }, + "dismissed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Dismissed At" + }, + "dismissed_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Dismissed By" + } + }, + "type": "object", + "required": [ + "id", + "source_id", + "source_path", + "error_message", + "error_class", + "http_status_code", + "retry_count", + "status", + "first_failed_at", + "last_retried_at", + "dismissed_at", + "dismissed_by" + ], + "title": "SyncFailureRead" + }, + "SyncRunLogRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "source_id": { + "type": "string", + "format": "uuid", + "title": "Source Id" + }, + "started_at": { + "type": "string", + "format": "date-time", + "title": "Started At" + }, + "finished_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Finished At" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + }, + "records_attempted": { + "type": "integer", + "title": "Records Attempted" + }, + "records_succeeded": { + "type": "integer", + "title": "Records Succeeded" + }, + "records_failed": { + "type": "integer", + "title": "Records Failed" + }, + "error_summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Summary" + } + }, + "type": "object", + "required": [ + "id", + "source_id", + "started_at", + "finished_at", + "status", + "records_attempted", + "records_succeeded", + "records_failed", + "error_summary" + ], + "title": "SyncRunLogRead" + }, + "SystemStatus": { + "properties": { + "version": { + "type": "string", + "title": "Version" + }, + "database": { + "type": "string", + "title": "Database" + }, + "ollama": { + "type": "string", + "title": "Ollama" + }, + "redis": { + "type": "string", + "title": "Redis" + }, + "user_count": { + "type": "integer", + "title": "User Count" + }, + "audit_log_count": { + "type": "integer", + "title": "Audit Log Count" + }, + "suite_session": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Suite Session" + } + }, + "type": "object", + "required": [ + "version", + "database", + "ollama", + "redis", + "user_count", + "audit_log_count" + ], + "title": "SystemStatus" + }, + "TaggedPlan": { + "properties": { + "action": { + "type": "string", + "const": "tagged-pdf", + "title": "Action" + }, + "headingLevels": { + "items": { + "type": "integer", + "maximum": 4294967295.0, + "minimum": 0.0 + }, + "type": "array", + "maxItems": 50, + "title": "Headinglevels" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "TaggedPlan" + }, + "TestConnectionRequest": { + "properties": { + "source_type": { + "type": "string", + "title": "Source Type" + }, + "host": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Host" + }, + "port": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Port" + }, + "path": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Path" + }, + "username": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Username" + }, + "password": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Password" + }, + "rest_api_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Rest Api Config" + }, + "odbc_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Odbc Config" + } + }, + "type": "object", + "required": [ + "source_type" + ], + "title": "TestConnectionRequest", + "description": "Dedicated schema for test-connection. NOT the create schema.\n\nSecurity: credentials in this request body are never persisted, never\nwritten to audit logs, and never returned in the response." + }, + "TestConnectionResponse": { + "properties": { + "success": { + "type": "boolean", + "title": "Success" + }, + "message": { + "type": "string", + "title": "Message" + }, + "latency_ms": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Latency Ms" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + }, + "warning": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Warning" + }, + "differing_keys": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Differing Keys" + } + }, + "type": "object", + "required": [ + "success", + "message" + ], + "title": "TestConnectionResponse" + }, + "TimelineEventCreate": { + "properties": { + "event_type": { + "type": "string", + "title": "Event Type" + }, + "description": { + "type": "string", + "title": "Description" + }, + "internal_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Internal Note" + } + }, + "type": "object", + "required": [ + "event_type", + "description" + ], + "title": "TimelineEventCreate" + }, + "TimelineEventRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "event_type": { + "type": "string", + "title": "Event Type" + }, + "actor_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Actor Id" + }, + "actor_role": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Actor Role" + }, + "description": { + "type": "string", + "title": "Description" + }, + "internal_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Internal Note" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "event_type", + "actor_id", + "actor_role", + "description", + "internal_note", + "created_at" + ], + "title": "TimelineEventRead" + }, + "TimelineView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "action": { + "type": "string", + "title": "Action" + }, + "actor": { + "type": "string", + "title": "Actor" + }, + "note": { + "type": "string", + "title": "Note" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "action", + "actor", + "note", + "created_at_unix_seconds" + ], + "title": "TimelineView" + }, + "TitleCreate": { + "properties": { + "title_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Title Id" + }, + "title_number": { + "type": "string", + "minLength": 1, + "title": "Title Number" + }, + "title_name": { + "type": "string", + "minLength": 1, + "title": "Title Name" + }, + "sort_order": { + "type": "integer", + "title": "Sort Order", + "default": 0 + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title_number", + "title_name" + ], + "title": "TitleCreate", + "description": "Request body for creating a code title." + }, + "TranscriptInput": { + "properties": { + "source_label": { + "type": "string", + "minLength": 1, + "title": "Source Label" + }, + "transcript_text": { + "type": "string", + "minLength": 1, + "title": "Transcript Text" + }, + "correction_of_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Correction Of Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_label", + "transcript_text" + ], + "title": "TranscriptInput" + }, + "UserRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "email": { + "type": "string", + "format": "email", + "title": "Email" + }, + "is_active": { + "type": "boolean", + "title": "Is Active", + "default": true + }, + "is_superuser": { + "type": "boolean", + "title": "Is Superuser", + "default": false + }, + "is_verified": { + "type": "boolean", + "title": "Is Verified", + "default": false + }, + "full_name": { + "type": "string", + "title": "Full Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "last_login": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Login" + }, + "must_change_password": { + "type": "boolean", + "title": "Must Change Password", + "default": false + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + } + }, + "type": "object", + "required": [ + "id", + "email", + "full_name", + "role", + "created_at", + "last_login" + ], + "title": "UserRead" + }, + "UserRole": { + "type": "string", + "enum": [ + "admin", + "staff", + "reviewer", + "read_only", + "liaison", + "public" + ], + "title": "UserRole" + }, + "UserSelfUpdate": { + "properties": { + "password": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Password" + }, + "email": { + "anyOf": [ + { + "type": "string", + "format": "email" + }, + { + "type": "null" + } + ], + "title": "Email" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + }, + "is_superuser": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Superuser" + }, + "is_verified": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Verified" + }, + "full_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Full Name" + } + }, + "type": "object", + "title": "UserSelfUpdate", + "description": "Schema for user self-update via PATCH /users/me.\n\nExcludes role and department_id. Any payload containing those fields is\nrejected at parse time (HTTP 422). Role and department changes require\nadmin privileges via /admin/users/{id}." + }, + "UserUpdateRequest": { + "properties": { + "full_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Full Name" + }, + "role": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Role" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "UserUpdateRequest" + }, + "ValidationError": { + "properties": { + "loc": { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "integer" + } + ] + }, + "type": "array", + "title": "Location" + }, + "msg": { + "type": "string", + "title": "Message" + }, + "type": { + "type": "string", + "title": "Error Type" + }, + "input": { + "title": "Input" + }, + "ctx": { + "type": "object", + "title": "Context" + } + }, + "type": "object", + "required": [ + "loc", + "msg", + "type" + ], + "title": "ValidationError" + }, + "Version": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence" + ], + "title": "Version" + }, + "VoteCorrection": { + "properties": { + "vote": { + "type": "string", + "minLength": 1, + "title": "Vote" + }, + "reason": { + "type": "string", + "minLength": 1, + "title": "Reason" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "vote", + "reason" + ], + "title": "VoteCorrection" + }, + "VoteInput": { + "properties": { + "voter_name": { + "type": "string", + "minLength": 1, + "title": "Voter Name" + }, + "vote": { + "type": "string", + "minLength": 1, + "title": "Vote" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "voter_name", + "vote" + ], + "title": "VoteInput" + }, + "_ParcelLookupIn": { + "properties": { + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "jurisdiction", + "query" + ], + "title": "_ParcelLookupIn" + }, + "townlight_inspections__workflow_models__SourceLink": { + "properties": { + "provider": { + "type": "string", + "const": "code", + "title": "Provider", + "default": "code" + }, + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "SourceLink" + }, + "townlight_permitting__workflow_models__SourceLink": { + "properties": { + "provider": { + "type": "string", + "enum": [ + "code", + "zoning" + ], + "title": "Provider" + }, + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "source_id", + "expected_sha256" + ], + "title": "SourceLink" + }, + "townlight_runtime__inspections_bridge__Search": { + "properties": { + "provider": { + "type": "string", + "const": "code", + "title": "Provider" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "query" + ], + "title": "Search" + }, + "townlight_runtime__notice_bridge__Review": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + }, + "note": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence", + "note" + ], + "title": "Review" + }, + "townlight_runtime__permitting_bridge__Import": { + "properties": { + "bundle": { + "$ref": "#/components/schemas/RequirementBundle" + }, + "expected_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "bundle" + ], + "title": "Import" + }, + "townlight_runtime__permitting_bridge__Search": { + "properties": { + "provider": { + "type": "string", + "enum": [ + "code", + "zoning" + ], + "title": "Provider" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "query" + ], + "title": "Search" + }, + "townlight_runtime__planning_bridge__Import": { + "properties": { + "bundle": { + "additionalProperties": true, + "type": "object", + "title": "Bundle" + }, + "expected_previous_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Expected Previous Revision" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "bundle" + ], + "title": "Import" + }, + "townlight_runtime__planning_bridge__Search": { + "properties": { + "query": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Query" + }, + "plan_type": { + "anyOf": [ + { + "type": "string", + "maxLength": 40 + }, + { + "type": "null" + } + ], + "title": "Plan Type" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "Search" + }, + "townlight_runtime__zoning_bridge__Review": { + "properties": { + "answer": { + "type": "string", + "maxLength": 10000, + "title": "Answer", + "default": "" + }, + "notes": { + "type": "string", + "maxLength": 10000, + "title": "Notes", + "default": "" + }, + "queue_status": { + "type": "string", + "enum": [ + "open", + "in_review", + "resolved", + "closed" + ], + "title": "Queue Status", + "default": "resolved" + } + }, + "additionalProperties": false, + "type": "object", + "title": "Review" + } + }, + "securitySchemes": { + "OAuth2PasswordBearer": { + "type": "oauth2", + "flows": { + "password": { + "scopes": {}, + "tokenUrl": "auth/jwt/login" + } + } + } + } + }, + "x-townlight-component": { + "view": "station", + "identity": "Townlight Station 0.3.0", + "evidence": "source-schema-only" + } +} diff --git a/docs/beta-1/api/station.html b/docs/beta-1/api/station.html new file mode 100644 index 0000000..1d46cc3 --- /dev/null +++ b/docs/beta-1/api/station.html @@ -0,0 +1,11667 @@ +Townlight Station API reference
Townlight

Townlight Station API reference

+

Prepared source candidate, November 2, 2026. New signed Windows installed acceptance and publication remain pending.

+

Townlight Station 0.3.0. The HTTP host is Townlight Records 1.8.0.dev2. Component package versions and the host API version are separate identities.

+

Generated from the actual native inspections-preview composition without application lifespan, migrations or database/network access. It describes route and validation contracts; it does not establish endpoint behavior, individual authorization or installed acceptance. Standalone product applications have separate deployment boundaries.

+

Machine-readable OpenAPI schema · Operating manual and limits

+

HTTP operations

+
GET /desktop/v1/meetings/station/catalog +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Station Catalog",
+  "description": "Authorized name-based operator selection from canonical Meetings data.",
+  "operationId": "station_catalog_desktop_v1_meetings_station_catalog_get",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/requests/{request_id}/station-recordings +
{
+  "tags": [
+    "native-desktop",
+    "station-integration"
+  ],
+  "summary": "Attach",
+  "operationId": "attach_desktop_v1_requests__request_id__station_recordings_post",
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/Selection"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RecordsOperationRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/station/context +
{
+  "tags": [
+    "native-desktop",
+    "station-integration"
+  ],
+  "summary": "Context",
+  "operationId": "context_desktop_v1_station_context_get",
+  "parameters": [
+    {
+      "name": "capability",
+      "in": "query",
+      "required": true,
+      "schema": {
+        "enum": [
+          "capture",
+          "read"
+        ],
+        "type": "string",
+        "title": "Capability"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+

Request and response data dictionary

+

Each schema includes the actual required fields, types, constraints and descriptions. References resolve against the machine-readable document.

+
ActionItemInput
+{
+  "properties": {
+    "description": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Description"
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "source_motion_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Motion Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "description"
+  ],
+  "title": "ActionItemInput"
+}
+
+
AdaPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "ada-title-ii",
+      "title": "Action"
+    },
+    "serviceArea": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Servicearea"
+    },
+    "hasCoordinatorReview": {
+      "type": "boolean",
+      "title": "Hascoordinatorreview",
+      "default": false
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "serviceArea"
+  ],
+  "title": "AdaPlan"
+}
+
+
AdminUserCreateRequest
+{
+  "properties": {
+    "email": {
+      "type": "string",
+      "title": "Email"
+    },
+    "password": {
+      "type": "string",
+      "title": "Password"
+    },
+    "full_name": {
+      "type": "string",
+      "title": "Full Name",
+      "default": ""
+    },
+    "role": {
+      "type": "string",
+      "title": "Role",
+      "default": "staff"
+    }
+  },
+  "type": "object",
+  "required": [
+    "email",
+    "password"
+  ],
+  "title": "AdminUserCreateRequest"
+}
+
+
AdminUserCreateResponse
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "email": {
+      "type": "string",
+      "title": "Email"
+    },
+    "full_name": {
+      "type": "string",
+      "title": "Full Name"
+    },
+    "role": {
+      "type": "string",
+      "title": "Role"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "email",
+    "full_name",
+    "role",
+    "is_active"
+  ],
+  "title": "AdminUserCreateResponse"
+}
+
+
AgendaAssignment
+{
+  "properties": {
+    "meeting_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Meeting Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "meeting_id"
+  ],
+  "title": "AgendaAssignment"
+}
+
+
AgendaInput
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "department_name": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Department Name"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "department_name"
+  ],
+  "title": "AgendaInput"
+}
+
+
AgendaReviewInput
+{
+  "properties": {
+    "to_status": {
+      "type": "string",
+      "enum": [
+        "DRAFTED",
+        "SUBMITTED",
+        "DEPT_APPROVED",
+        "LEGAL_REVIEWED",
+        "CLERK_ACCEPTED",
+        "ON_AGENDA",
+        "IN_PACKET",
+        "POSTED",
+        "HEARD",
+        "DISPOSED",
+        "ARCHIVED"
+      ],
+      "title": "To Status"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "to_status"
+  ],
+  "title": "AgendaReviewInput"
+}
+
+
AmendmentInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "policy": {
+      "$ref": "#/components/schemas/PolicySelection"
+    },
+    "proposal": {
+      "type": "string",
+      "maxLength": 20000,
+      "minLength": 1,
+      "title": "Proposal"
+    },
+    "responsible_staff": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Responsible Staff"
+    },
+    "status": {
+      "type": "string",
+      "enum": [
+        "draft",
+        "review",
+        "adopted",
+        "withdrawn"
+      ],
+      "title": "Status",
+      "default": "draft"
+    },
+    "review_note": {
+      "type": "string",
+      "maxLength": 5000,
+      "title": "Review Note",
+      "default": ""
+    },
+    "adoption_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Adoption Revision"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "policy",
+    "proposal",
+    "responsible_staff",
+    "note"
+  ],
+  "title": "AmendmentInput"
+}
+
+
AnalysisObservation
+{
+  "properties": {
+    "source": {
+      "type": "string",
+      "maxLength": 64,
+      "minLength": 1,
+      "title": "Source"
+    },
+    "filename": {
+      "type": "string",
+      "maxLength": 160,
+      "title": "Filename",
+      "default": ""
+    },
+    "media_type": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Media Type",
+      "default": ""
+    },
+    "text": {
+      "type": "string",
+      "maxLength": 4000,
+      "minLength": 1,
+      "title": "Text"
+    },
+    "adapter": {
+      "type": "string",
+      "maxLength": 120,
+      "title": "Adapter",
+      "default": ""
+    },
+    "citation_source_ids": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Citation Source Ids"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source",
+    "text"
+  ],
+  "title": "AnalysisObservation",
+  "description": "One draft observation, named with the adapter that actually produced it."
+}
+
+
AnalysisRecord
+{
+  "properties": {
+    "observations": {
+      "items": {
+        "$ref": "#/components/schemas/AnalysisObservation"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Observations"
+    },
+    "cited_sections": {
+      "items": {
+        "$ref": "#/components/schemas/CitedSection"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Cited Sections"
+    },
+    "unavailable": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Unavailable"
+    },
+    "runtime": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Runtime"
+    },
+    "review_required": {
+      "type": "boolean",
+      "title": "Review Required",
+      "default": true
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "AnalysisRecord",
+  "description": "The adapter output that accompanies a saved inspection draft."
+}
+
+
ApprovalCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "approve-records-response",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ApprovalPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "ApprovalCommand"
+}
+
+
ApprovalPayload
+{
+  "properties": {
+    "approvalNote": {
+      "type": "string",
+      "title": "Approvalnote",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "ApprovalPayload"
+}
+
+
ArchiveInput
+{
+  "properties": {
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "public",
+        "closed_session"
+      ],
+      "title": "Visibility"
+    },
+    "packet_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Packet Id"
+    },
+    "minutes_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Minutes Id"
+    },
+    "plain_language_summary": {
+      "type": "string",
+      "title": "Plain Language Summary",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "visibility"
+  ],
+  "title": "ArchiveInput"
+}
+
+
ArtifactPlan
+{
+  "properties": {
+    "artifact_id": {
+      "type": "string",
+      "title": "Artifact Id"
+    },
+    "file_name": {
+      "type": "string",
+      "title": "File Name"
+    },
+    "content": {
+      "type": "string",
+      "title": "Content"
+    },
+    "sha256": {
+      "type": "string",
+      "title": "Sha256"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "artifact_id",
+    "file_name",
+    "content",
+    "sha256",
+    "created_at_unix_seconds"
+  ],
+  "title": "ArtifactPlan"
+}
+
+
AssignCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "assign-records-request",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/AssignmentPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "AssignCommand"
+}
+
+
AssignmentPayload
+{
+  "properties": {
+    "assignedTo": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Assignedto"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "assignedTo"
+  ],
+  "title": "AssignmentPayload"
+}
+
+
AttachDocument
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation",
+      "default": ""
+    },
+    "file": {
+      "$ref": "#/components/schemas/ManagedFileReceipt"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "file"
+  ],
+  "title": "AttachDocument"
+}
+
+
AttachReleaseCopy
+{
+  "properties": {
+    "status": {
+      "type": "string",
+      "enum": [
+        "release-ready copy",
+        "redacted copy"
+      ],
+      "title": "Status"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note",
+      "default": ""
+    },
+    "added_by": {
+      "type": "string",
+      "title": "Added By",
+      "default": ""
+    },
+    "file": {
+      "$ref": "#/components/schemas/ManagedFileReceipt"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "status",
+    "file"
+  ],
+  "title": "AttachReleaseCopy"
+}
+
+
AuditChainVerification
+{
+  "properties": {
+    "is_valid": {
+      "type": "boolean",
+      "title": "Is Valid"
+    },
+    "entries_checked": {
+      "type": "integer",
+      "title": "Entries Checked"
+    },
+    "error_message": {
+      "type": "string",
+      "title": "Error Message"
+    }
+  },
+  "type": "object",
+  "required": [
+    "is_valid",
+    "entries_checked",
+    "error_message"
+  ],
+  "title": "AuditChainVerification"
+}
+
+
AuditLogRead
+{
+  "properties": {
+    "id": {
+      "type": "integer",
+      "title": "Id"
+    },
+    "prev_hash": {
+      "type": "string",
+      "title": "Prev Hash"
+    },
+    "entry_hash": {
+      "type": "string",
+      "title": "Entry Hash"
+    },
+    "timestamp": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Timestamp"
+    },
+    "user_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "User Id"
+    },
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "resource_type": {
+      "type": "string",
+      "title": "Resource Type"
+    },
+    "resource_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Resource Id"
+    },
+    "details": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Details"
+    },
+    "ai_generated": {
+      "type": "boolean",
+      "title": "Ai Generated"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "prev_hash",
+    "entry_hash",
+    "timestamp",
+    "user_id",
+    "action",
+    "resource_type",
+    "resource_id",
+    "details",
+    "ai_generated"
+  ],
+  "title": "AuditLogRead"
+}
+
+
AuditView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "module_id": {
+      "type": "string",
+      "title": "Module Id"
+    },
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    },
+    "previous_hash": {
+      "type": "string",
+      "title": "Previous Hash"
+    },
+    "entry_hash": {
+      "type": "string",
+      "title": "Entry Hash"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "module_id",
+    "action",
+    "summary",
+    "created_at_unix_seconds",
+    "previous_hash",
+    "entry_hash"
+  ],
+  "title": "AuditView"
+}
+
+
BearerResponse
+{
+  "properties": {
+    "access_token": {
+      "type": "string",
+      "title": "Access Token"
+    },
+    "token_type": {
+      "type": "string",
+      "title": "Token Type"
+    }
+  },
+  "type": "object",
+  "required": [
+    "access_token",
+    "token_type"
+  ],
+  "title": "BearerResponse"
+}
+
+
Body_auth_jwt_login_auth_jwt_login_post
+{
+  "properties": {
+    "grant_type": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^password$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Grant Type"
+    },
+    "username": {
+      "type": "string",
+      "title": "Username"
+    },
+    "password": {
+      "type": "string",
+      "format": "password",
+      "title": "Password"
+    },
+    "scope": {
+      "type": "string",
+      "title": "Scope",
+      "default": ""
+    },
+    "client_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Client Id"
+    },
+    "client_secret": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "format": "password",
+      "title": "Client Secret"
+    }
+  },
+  "type": "object",
+  "required": [
+    "username",
+    "password"
+  ],
+  "title": "Body_auth_jwt_login_auth_jwt_login_post"
+}
+
+
Body_upload_file_datasources_upload_post
+{
+  "properties": {
+    "file": {
+      "type": "string",
+      "contentMediaType": "application/octet-stream",
+      "title": "File"
+    }
+  },
+  "type": "object",
+  "required": [
+    "file"
+  ],
+  "title": "Body_upload_file_datasources_upload_post"
+}
+
+
CalculateDeadlineCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "calculate-records-deadline",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/CalculateDeadlinePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "CalculateDeadlineCommand"
+}
+
+
CalculateDeadlinePayload
+{
+  "properties": {
+    "deadlineReceivedDate": {
+      "type": "string",
+      "title": "Deadlinereceiveddate"
+    },
+    "deadlineRuleName": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Deadlinerulename"
+    },
+    "deadlineDayCount": {
+      "type": "string",
+      "title": "Deadlinedaycount"
+    },
+    "deadlineDayType": {
+      "type": "string",
+      "title": "Deadlinedaytype"
+    },
+    "deadlineBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Deadlinebasis"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "deadlineReceivedDate",
+    "deadlineRuleName",
+    "deadlineDayCount",
+    "deadlineDayType",
+    "deadlineBasis"
+  ],
+  "title": "CalculateDeadlinePayload"
+}
+
+
ChapterCreate
+{
+  "properties": {
+    "chapter_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Chapter Id"
+    },
+    "title_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title Id"
+    },
+    "chapter_number": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Chapter Number"
+    },
+    "chapter_name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Chapter Name"
+    },
+    "sort_order": {
+      "type": "integer",
+      "title": "Sort Order",
+      "default": 0
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title_id",
+    "chapter_number",
+    "chapter_name"
+  ],
+  "title": "ChapterCreate",
+  "description": "Request body for creating a code chapter."
+}
+
+
CitedSection
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "citation": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Citation"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "version": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Version",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "citation"
+  ],
+  "title": "CitedSection",
+  "description": "One resolved public Code section; never a caller-supplied quotation."
+}
+
+
CityProfileCreate
+{
+  "properties": {
+    "city_name": {
+      "type": "string",
+      "title": "City Name"
+    },
+    "state": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State"
+    },
+    "county": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "County"
+    },
+    "population_band": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Population Band"
+    },
+    "email_platform": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email Platform"
+    },
+    "has_dedicated_it": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Has Dedicated It"
+    },
+    "monthly_request_volume": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Monthly Request Volume"
+    },
+    "profile_data": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Profile Data",
+      "default": {}
+    },
+    "gap_map": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Gap Map",
+      "default": {}
+    }
+  },
+  "type": "object",
+  "required": [
+    "city_name"
+  ],
+  "title": "CityProfileCreate"
+}
+
+
CityProfileRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "city_name": {
+      "type": "string",
+      "title": "City Name"
+    },
+    "state": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State"
+    },
+    "county": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "County"
+    },
+    "population_band": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Population Band"
+    },
+    "email_platform": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email Platform"
+    },
+    "has_dedicated_it": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Has Dedicated It"
+    },
+    "monthly_request_volume": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Monthly Request Volume"
+    },
+    "onboarding_status": {
+      "type": "string",
+      "title": "Onboarding Status"
+    },
+    "profile_data": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Profile Data"
+    },
+    "gap_map": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Gap Map"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "updated_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "city_name",
+    "state",
+    "county",
+    "population_band",
+    "email_platform",
+    "has_dedicated_it",
+    "monthly_request_volume",
+    "onboarding_status",
+    "profile_data",
+    "gap_map",
+    "created_at",
+    "updated_at"
+  ],
+  "title": "CityProfileRead"
+}
+
+
CityProfileUpdate
+{
+  "properties": {
+    "city_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "City Name"
+    },
+    "state": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State"
+    },
+    "county": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "County"
+    },
+    "population_band": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Population Band"
+    },
+    "email_platform": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email Platform"
+    },
+    "has_dedicated_it": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Has Dedicated It"
+    },
+    "monthly_request_volume": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Monthly Request Volume"
+    },
+    "onboarding_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Onboarding Status"
+    },
+    "profile_data": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Profile Data"
+    },
+    "gap_map": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Gap Map"
+    }
+  },
+  "type": "object",
+  "title": "CityProfileUpdate"
+}
+
+
ClarificationCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "request-records-clarification",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ClarificationPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "ClarificationCommand"
+}
+
+
ClarificationPayload
+{
+  "properties": {
+    "clarificationNote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Clarificationnote"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "clarificationNote"
+  ],
+  "title": "ClarificationPayload"
+}
+
+
Closeout
+{
+  "properties": {
+    "decision_id": {
+      "type": "string",
+      "pattern": "^[A-Za-z0-9_-]{1,64}$",
+      "title": "Decision Id"
+    },
+    "version_id": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Version Id"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "version_label": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Version Label"
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 1000000,
+      "minLength": 1,
+      "title": "Body"
+    },
+    "effective_start": {
+      "type": "string",
+      "format": "date",
+      "title": "Effective Start"
+    },
+    "effective_end": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective End"
+    },
+    "is_current": {
+      "type": "boolean",
+      "title": "Is Current"
+    },
+    "reconciliation_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reconciliation Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "decision_id",
+    "version_id",
+    "source_id",
+    "version_label",
+    "body",
+    "effective_start",
+    "is_current"
+  ],
+  "title": "Closeout"
+}
+
+
CodeContext
+{
+  "properties": {
+    "section_number": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Section Number"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "section_number"
+  ],
+  "title": "CodeContext"
+}
+
+
CodeLink
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "const": "code",
+      "title": "Provider",
+      "default": "code"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "CodeLink"
+}
+
+
CodeSearch
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "CodeSearch"
+}
+
+
CodeSourceSelection
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 200,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "CodeSourceSelection"
+}
+
+
CompleteArtifact
+{
+  "properties": {
+    "export_path": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Export Path"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "export_path"
+  ],
+  "title": "CompleteArtifact"
+}
+
+
ConnectionSearch
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "enum": [
+        "meetings",
+        "zoning"
+      ],
+      "title": "Provider"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "query"
+  ],
+  "title": "ConnectionSearch"
+}
+
+
CoverageGapResponse
+{
+  "properties": {
+    "jurisdictions_without_rules": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Jurisdictions Without Rules"
+    },
+    "departments_without_staff": {
+      "items": {
+        "additionalProperties": true,
+        "type": "object"
+      },
+      "type": "array",
+      "title": "Departments Without Staff"
+    },
+    "uncovered_categories": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Uncovered Categories"
+    },
+    "total_gaps": {
+      "type": "integer",
+      "title": "Total Gaps"
+    }
+  },
+  "type": "object",
+  "required": [
+    "jurisdictions_without_rules",
+    "departments_without_staff",
+    "uncovered_categories",
+    "total_gaps"
+  ],
+  "title": "CoverageGapResponse"
+}
+
+
DataSourceAdminRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "source_type": {
+      "$ref": "#/components/schemas/SourceType"
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "type": "boolean",
+      "title": "Schedule Enabled",
+      "default": true
+    },
+    "next_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Next Sync At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "last_ingestion_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Ingestion At"
+    },
+    "last_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync At"
+    },
+    "last_sync_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync Status"
+    },
+    "last_error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Error Message"
+    },
+    "consecutive_failure_count": {
+      "type": "integer",
+      "title": "Consecutive Failure Count",
+      "default": 0
+    },
+    "sync_paused": {
+      "type": "boolean",
+      "title": "Sync Paused",
+      "default": false
+    },
+    "health_status": {
+      "type": "string",
+      "title": "Health Status",
+      "default": "healthy"
+    },
+    "active_failure_count": {
+      "type": "integer",
+      "title": "Active Failure Count",
+      "default": 0
+    },
+    "connector_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connector Type"
+    },
+    "updated_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Updated At"
+    },
+    "connection_config": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Connection Config"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "source_type",
+    "is_active",
+    "created_by",
+    "created_at",
+    "last_ingestion_at",
+    "connection_config"
+  ],
+  "title": "DataSourceAdminRead",
+  "description": "Full datasource shape including connection_config. Returned only by admin-gated endpoints."
+}
+
+
DataSourceCreate
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "source_type": {
+      "$ref": "#/components/schemas/SourceType"
+    },
+    "connection_config": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Connection Config",
+      "default": {}
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "type": "boolean",
+      "title": "Schedule Enabled",
+      "default": true
+    }
+  },
+  "type": "object",
+  "required": [
+    "name",
+    "source_type"
+  ],
+  "title": "DataSourceCreate"
+}
+
+
DataSourceRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "source_type": {
+      "$ref": "#/components/schemas/SourceType"
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "type": "boolean",
+      "title": "Schedule Enabled",
+      "default": true
+    },
+    "next_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Next Sync At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "last_ingestion_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Ingestion At"
+    },
+    "last_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync At"
+    },
+    "last_sync_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync Status"
+    },
+    "last_error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Error Message"
+    },
+    "consecutive_failure_count": {
+      "type": "integer",
+      "title": "Consecutive Failure Count",
+      "default": 0
+    },
+    "sync_paused": {
+      "type": "boolean",
+      "title": "Sync Paused",
+      "default": false
+    },
+    "health_status": {
+      "type": "string",
+      "title": "Health Status",
+      "default": "healthy"
+    },
+    "active_failure_count": {
+      "type": "integer",
+      "title": "Active Failure Count",
+      "default": 0
+    },
+    "connector_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connector Type"
+    },
+    "updated_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "source_type",
+    "is_active",
+    "created_by",
+    "created_at",
+    "last_ingestion_at"
+  ],
+  "title": "DataSourceRead",
+  "description": "Redacted datasource shape — safe for non-admin roles. connection_config omitted."
+}
+
+
DataSourceUpdate
+{
+  "properties": {
+    "name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Name"
+    },
+    "connection_config": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connection Config"
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Schedule Enabled"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "DataSourceUpdate"
+}
+
+
DeadlineCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "set-records-deadline",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/DeadlinePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "DeadlineCommand"
+}
+
+
DeadlinePayload
+{
+  "properties": {
+    "deadline": {
+      "type": "string",
+      "title": "Deadline"
+    },
+    "deadlineBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Deadlinebasis"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "deadline",
+    "deadlineBasis"
+  ],
+  "title": "DeadlinePayload"
+}
+
+
Decision
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "pattern": "^[A-Za-z0-9_-]{1,64}$",
+      "title": "Id"
+    },
+    "outcome": {
+      "type": "string",
+      "enum": [
+        "adopted",
+        "not_adopted",
+        "deferred",
+        "withdrawn"
+      ],
+      "title": "Outcome"
+    },
+    "decided_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Decided At"
+    },
+    "decision_text": {
+      "type": "string",
+      "maxLength": 1000000,
+      "minLength": 1,
+      "title": "Decision Text"
+    },
+    "supporting_references": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Supporting References"
+    },
+    "supersedes_decision_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^[A-Za-z0-9_-]{1,64}$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supersedes Decision Id"
+    },
+    "reconciliation_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reconciliation Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "outcome",
+    "decision_text"
+  ],
+  "title": "Decision"
+}
+
+
DepartmentCreate
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "code": {
+      "type": "string",
+      "title": "Code"
+    },
+    "contact_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Contact Email"
+    }
+  },
+  "type": "object",
+  "required": [
+    "name",
+    "code"
+  ],
+  "title": "DepartmentCreate"
+}
+
+
DepartmentRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "code": {
+      "type": "string",
+      "title": "Code"
+    },
+    "contact_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Contact Email"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "code",
+    "contact_email",
+    "created_at"
+  ],
+  "title": "DepartmentRead"
+}
+
+
DepartmentUpdate
+{
+  "properties": {
+    "name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Name"
+    },
+    "code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Code"
+    },
+    "contact_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Contact Email"
+    }
+  },
+  "type": "object",
+  "title": "DepartmentUpdate"
+}
+
+
DisclosureTemplateCreate
+{
+  "properties": {
+    "template_type": {
+      "type": "string",
+      "title": "Template Type"
+    },
+    "state_code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State Code"
+    },
+    "content": {
+      "type": "string",
+      "title": "Content"
+    }
+  },
+  "type": "object",
+  "required": [
+    "template_type",
+    "content"
+  ],
+  "title": "DisclosureTemplateCreate"
+}
+
+
DisclosureTemplateRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "template_type": {
+      "type": "string",
+      "title": "Template Type"
+    },
+    "state_code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State Code"
+    },
+    "content": {
+      "type": "string",
+      "title": "Content"
+    },
+    "version": {
+      "type": "integer",
+      "title": "Version"
+    },
+    "updated_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Updated By"
+    },
+    "updated_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "template_type",
+    "state_code",
+    "content",
+    "version",
+    "updated_by",
+    "updated_at"
+  ],
+  "title": "DisclosureTemplateRead"
+}
+
+
DisclosureTemplateRendered
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "template_type": {
+      "type": "string",
+      "title": "Template Type"
+    },
+    "rendered_content": {
+      "type": "string",
+      "title": "Rendered Content"
+    },
+    "has_unresolved_variables": {
+      "type": "boolean",
+      "title": "Has Unresolved Variables"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "template_type",
+    "rendered_content",
+    "has_unresolved_variables"
+  ],
+  "title": "DisclosureTemplateRendered"
+}
+
+
DisclosureTemplateUpdate
+{
+  "properties": {
+    "content": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Content"
+    },
+    "state_code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State Code"
+    }
+  },
+  "type": "object",
+  "title": "DisclosureTemplateUpdate"
+}
+
+
DocumentChunkRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "chunk_index": {
+      "type": "integer",
+      "title": "Chunk Index"
+    },
+    "content_text": {
+      "type": "string",
+      "title": "Content Text"
+    },
+    "token_count": {
+      "type": "integer",
+      "title": "Token Count"
+    },
+    "page_number": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Page Number"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "document_id",
+    "chunk_index",
+    "content_text",
+    "token_count",
+    "page_number"
+  ],
+  "title": "DocumentChunkRead"
+}
+
+
DocumentRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "source_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Source Id"
+    },
+    "source_path": {
+      "type": "string",
+      "title": "Source Path"
+    },
+    "filename": {
+      "type": "string",
+      "title": "Filename"
+    },
+    "file_type": {
+      "type": "string",
+      "title": "File Type"
+    },
+    "file_hash": {
+      "type": "string",
+      "title": "File Hash"
+    },
+    "file_size": {
+      "type": "integer",
+      "title": "File Size"
+    },
+    "ingestion_status": {
+      "$ref": "#/components/schemas/IngestionStatus"
+    },
+    "ingestion_error": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ingestion Error"
+    },
+    "chunk_count": {
+      "type": "integer",
+      "title": "Chunk Count"
+    },
+    "ingested_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ingested At"
+    },
+    "connector_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connector Type"
+    },
+    "updated_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "source_id",
+    "source_path",
+    "filename",
+    "file_type",
+    "file_hash",
+    "file_size",
+    "ingestion_status",
+    "ingestion_error",
+    "chunk_count",
+    "ingested_at"
+  ],
+  "title": "DocumentRead"
+}
+
+
DraftCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "draft-records-response",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/DraftPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "DraftCommand"
+}
+
+
DraftInput
+{
+  "properties": {
+    "source_materials": {
+      "items": {
+        "$ref": "#/components/schemas/SourceInput"
+      },
+      "type": "array",
+      "title": "Source Materials"
+    },
+    "sentences": {
+      "items": {
+        "$ref": "#/components/schemas/SentenceInput"
+      },
+      "type": "array",
+      "minItems": 1,
+      "title": "Sentences"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sentences"
+  ],
+  "title": "DraftInput"
+}
+
+
DraftPayload
+{
+  "properties": {
+    "responseDraft": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Responsedraft"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "responseDraft"
+  ],
+  "title": "DraftPayload"
+}
+
+
ErrorModel
+{
+  "properties": {
+    "detail": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "additionalProperties": {
+            "type": "string"
+          },
+          "type": "object"
+        }
+      ],
+      "title": "Detail"
+    }
+  },
+  "type": "object",
+  "required": [
+    "detail"
+  ],
+  "title": "ErrorModel"
+}
+
+
Evidence
+{
+  "properties": {
+    "filename": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$",
+      "title": "Filename"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Description"
+    },
+    "media_type": {
+      "type": "string",
+      "enum": [
+        "text/plain",
+        "image/jpeg",
+        "image/png",
+        "image/webp",
+        "application/pdf",
+        "audio/webm",
+        "audio/ogg",
+        "audio/wav",
+        "audio/mpeg",
+        "audio/mp4"
+      ],
+      "title": "Media Type"
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 14000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "filename",
+    "description",
+    "media_type",
+    "content_base64",
+    "sha256"
+  ],
+  "title": "Evidence"
+}
+
+
EvidenceItem
+{
+  "properties": {
+    "filename": {
+      "type": "string",
+      "maxLength": 151,
+      "minLength": 1,
+      "title": "Filename"
+    },
+    "media_type": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Media Type"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Description",
+      "default": ""
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 14000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "filename",
+    "media_type",
+    "content_base64",
+    "sha256"
+  ],
+  "title": "EvidenceItem"
+}
+
+
EvidenceItems
+{
+  "properties": {
+    "items": {
+      "items": {
+        "$ref": "#/components/schemas/EvidenceItem"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "minItems": 1,
+      "title": "Items"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "items"
+  ],
+  "title": "EvidenceItems"
+}
+
+
ExemptionAccuracyReport
+{
+  "properties": {
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "total_flags": {
+      "type": "integer",
+      "title": "Total Flags"
+    },
+    "accepted": {
+      "type": "integer",
+      "title": "Accepted"
+    },
+    "rejected": {
+      "type": "integer",
+      "title": "Rejected"
+    },
+    "pending": {
+      "type": "integer",
+      "title": "Pending"
+    },
+    "acceptance_rate": {
+      "type": "number",
+      "title": "Acceptance Rate"
+    }
+  },
+  "type": "object",
+  "required": [
+    "category",
+    "total_flags",
+    "accepted",
+    "rejected",
+    "pending",
+    "acceptance_rate"
+  ],
+  "title": "ExemptionAccuracyReport"
+}
+
+
ExemptionDashboard
+{
+  "properties": {
+    "total_flags": {
+      "type": "integer",
+      "title": "Total Flags"
+    },
+    "by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "By Status"
+    },
+    "by_category": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "By Category"
+    },
+    "acceptance_rate": {
+      "type": "number",
+      "title": "Acceptance Rate"
+    },
+    "total_rules": {
+      "type": "integer",
+      "title": "Total Rules"
+    },
+    "active_rules": {
+      "type": "integer",
+      "title": "Active Rules"
+    }
+  },
+  "type": "object",
+  "required": [
+    "total_flags",
+    "by_status",
+    "by_category",
+    "acceptance_rate",
+    "total_rules",
+    "active_rules"
+  ],
+  "title": "ExemptionDashboard"
+}
+
+
ExemptionDecisionCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-exemption-decision",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ExemptionDecisionPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "ExemptionDecisionCommand"
+}
+
+
ExemptionDecisionPayload
+{
+  "properties": {
+    "exemptionSource": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionsource"
+    },
+    "exemptionKind": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionkind"
+    },
+    "exemptionFinding": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionfinding"
+    },
+    "exemptionDecision": {
+      "type": "string",
+      "enum": [
+        "release",
+        "redact",
+        "exempt"
+      ],
+      "title": "Exemptiondecision"
+    },
+    "exemptionBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionbasis"
+    },
+    "exemptionReviewer": {
+      "type": "string",
+      "title": "Exemptionreviewer",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "exemptionSource",
+    "exemptionKind",
+    "exemptionFinding",
+    "exemptionDecision",
+    "exemptionBasis"
+  ],
+  "title": "ExemptionDecisionPayload"
+}
+
+
ExemptionDecisionView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "source": {
+      "type": "string",
+      "title": "Source"
+    },
+    "kind": {
+      "type": "string",
+      "title": "Kind"
+    },
+    "finding": {
+      "type": "string",
+      "title": "Finding"
+    },
+    "decision": {
+      "type": "string",
+      "enum": [
+        "release",
+        "redact",
+        "exempt"
+      ],
+      "title": "Decision"
+    },
+    "basis": {
+      "type": "string",
+      "title": "Basis"
+    },
+    "reviewer": {
+      "type": "string",
+      "title": "Reviewer"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "source",
+    "kind",
+    "finding",
+    "decision",
+    "basis",
+    "reviewer",
+    "created_at_unix_seconds"
+  ],
+  "title": "ExemptionDecisionView"
+}
+
+
ExemptionFlagRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "chunk_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Chunk Id"
+    },
+    "rule_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Rule Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "matched_text": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Matched Text"
+    },
+    "confidence": {
+      "type": "number",
+      "title": "Confidence"
+    },
+    "status": {
+      "$ref": "#/components/schemas/FlagStatus"
+    },
+    "reviewed_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reviewed By"
+    },
+    "reviewed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reviewed At"
+    },
+    "review_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Reason"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "chunk_id",
+    "rule_id",
+    "request_id",
+    "category",
+    "matched_text",
+    "confidence",
+    "status",
+    "reviewed_by",
+    "reviewed_at",
+    "review_reason",
+    "created_at"
+  ],
+  "title": "ExemptionFlagRead"
+}
+
+
ExemptionFlagReview
+{
+  "properties": {
+    "status": {
+      "$ref": "#/components/schemas/FlagStatus"
+    },
+    "review_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Reason"
+    }
+  },
+  "type": "object",
+  "required": [
+    "status"
+  ],
+  "title": "ExemptionFlagReview"
+}
+
+
ExemptionNoteCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-exemption-review",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ExemptionNotePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "ExemptionNoteCommand"
+}
+
+
ExemptionNotePayload
+{
+  "properties": {
+    "exemptionNote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionnote"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "exemptionNote"
+  ],
+  "title": "ExemptionNotePayload"
+}
+
+
ExemptionRuleCreate
+{
+  "properties": {
+    "state_code": {
+      "type": "string",
+      "title": "State Code"
+    },
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "rule_type": {
+      "$ref": "#/components/schemas/RuleType"
+    },
+    "rule_definition": {
+      "type": "string",
+      "title": "Rule Definition"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "enabled": {
+      "type": "boolean",
+      "title": "Enabled",
+      "default": true
+    }
+  },
+  "type": "object",
+  "required": [
+    "state_code",
+    "category",
+    "rule_type",
+    "rule_definition"
+  ],
+  "title": "ExemptionRuleCreate"
+}
+
+
ExemptionRuleRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "state_code": {
+      "type": "string",
+      "title": "State Code"
+    },
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "rule_type": {
+      "$ref": "#/components/schemas/RuleType"
+    },
+    "rule_definition": {
+      "type": "string",
+      "title": "Rule Definition"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "enabled": {
+      "type": "boolean",
+      "title": "Enabled"
+    },
+    "version": {
+      "type": "integer",
+      "title": "Version",
+      "default": 1
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "state_code",
+    "category",
+    "rule_type",
+    "rule_definition",
+    "description",
+    "enabled",
+    "created_by",
+    "created_at"
+  ],
+  "title": "ExemptionRuleRead"
+}
+
+
ExemptionRuleUpdate
+{
+  "properties": {
+    "rule_definition": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Rule Definition"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "enabled": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Enabled"
+    }
+  },
+  "type": "object",
+  "title": "ExemptionRuleUpdate"
+}
+
+
ExportReceipt
+{
+  "properties": {
+    "export_path": {
+      "type": "string",
+      "maxLength": 32768,
+      "minLength": 1,
+      "title": "Export Path"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "export_path"
+  ],
+  "title": "ExportReceipt"
+}
+
+
FeeEstimateCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "estimate-records-fee",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/FeeEstimatePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "FeeEstimateCommand"
+}
+
+
FeeEstimatePayload
+{
+  "properties": {
+    "feeEstimate": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feeestimate"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "feeEstimate"
+  ],
+  "title": "FeeEstimatePayload"
+}
+
+
FeeEstimateRequest
+{
+  "properties": {
+    "page_count": {
+      "type": "integer",
+      "title": "Page Count"
+    },
+    "fee_schedule_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Fee Schedule Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "page_count",
+    "fee_schedule_id"
+  ],
+  "title": "FeeEstimateRequest"
+}
+
+
FeeEstimateResponse
+{
+  "properties": {
+    "page_count": {
+      "type": "integer",
+      "title": "Page Count"
+    },
+    "unit_price": {
+      "type": "number",
+      "title": "Unit Price"
+    },
+    "total": {
+      "type": "number",
+      "title": "Total"
+    },
+    "fee_type": {
+      "type": "string",
+      "title": "Fee Type"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    }
+  },
+  "type": "object",
+  "required": [
+    "page_count",
+    "unit_price",
+    "total",
+    "fee_type",
+    "description"
+  ],
+  "title": "FeeEstimateResponse"
+}
+
+
FeeLineCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-fee-line",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/FeeLinePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "FeeLineCommand"
+}
+
+
FeeLineItemCreate
+{
+  "properties": {
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "quantity": {
+      "type": "integer",
+      "title": "Quantity",
+      "default": 1
+    },
+    "unit_price": {
+      "type": "number",
+      "title": "Unit Price"
+    },
+    "fee_schedule_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Schedule Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "description",
+    "unit_price"
+  ],
+  "title": "FeeLineItemCreate"
+}
+
+
FeeLineItemRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "fee_schedule_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Schedule Id"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "quantity": {
+      "type": "integer",
+      "title": "Quantity"
+    },
+    "unit_price": {
+      "type": "number",
+      "title": "Unit Price"
+    },
+    "total": {
+      "type": "number",
+      "title": "Total"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "fee_schedule_id",
+    "description",
+    "quantity",
+    "unit_price",
+    "total",
+    "status",
+    "created_at"
+  ],
+  "title": "FeeLineItemRead"
+}
+
+
FeeLinePayload
+{
+  "properties": {
+    "feeLineDescription": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feelinedescription"
+    },
+    "feeScheduleBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feeschedulebasis"
+    },
+    "feeLineAmount": {
+      "type": "string",
+      "title": "Feelineamount"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "feeLineDescription",
+    "feeScheduleBasis",
+    "feeLineAmount"
+  ],
+  "title": "FeeLinePayload"
+}
+
+
FeeLineView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "schedule_basis": {
+      "type": "string",
+      "title": "Schedule Basis"
+    },
+    "amount_cents": {
+      "type": "integer",
+      "title": "Amount Cents"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "description",
+    "schedule_basis",
+    "amount_cents",
+    "created_at_unix_seconds"
+  ],
+  "title": "FeeLineView"
+}
+
+
FeeScheduleCreate
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "title": "Jurisdiction"
+    },
+    "fee_type": {
+      "type": "string",
+      "title": "Fee Type"
+    },
+    "amount": {
+      "type": "number",
+      "title": "Amount"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "effective_date": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective Date"
+    }
+  },
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "fee_type",
+    "amount"
+  ],
+  "title": "FeeScheduleCreate"
+}
+
+
FeeScheduleRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "jurisdiction": {
+      "type": "string",
+      "title": "Jurisdiction"
+    },
+    "fee_type": {
+      "type": "string",
+      "title": "Fee Type"
+    },
+    "amount": {
+      "type": "number",
+      "title": "Amount"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "effective_date": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective Date"
+    },
+    "created_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "jurisdiction",
+    "fee_type",
+    "amount",
+    "description",
+    "effective_date",
+    "created_by",
+    "created_at"
+  ],
+  "title": "FeeScheduleRead"
+}
+
+
FeeScheduleUpdate
+{
+  "properties": {
+    "fee_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Type"
+    },
+    "amount": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Amount"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "effective_date": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective Date"
+    }
+  },
+  "type": "object",
+  "title": "FeeScheduleUpdate"
+}
+
+
FeeWaiverCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "waive-records-fee",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/FeeWaiverPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "FeeWaiverCommand"
+}
+
+
FeeWaiverCreateRequest
+{
+  "properties": {
+    "waiver_type": {
+      "type": "string",
+      "title": "Waiver Type"
+    },
+    "reason": {
+      "type": "string",
+      "title": "Reason"
+    }
+  },
+  "type": "object",
+  "required": [
+    "waiver_type",
+    "reason"
+  ],
+  "title": "FeeWaiverCreateRequest"
+}
+
+
FeeWaiverPayload
+{
+  "properties": {
+    "feeWaiverReason": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feewaiverreason"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "feeWaiverReason"
+  ],
+  "title": "FeeWaiverPayload"
+}
+
+
FeeWaiverReadResponse
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "waiver_type": {
+      "type": "string",
+      "title": "Waiver Type"
+    },
+    "reason": {
+      "type": "string",
+      "title": "Reason"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    },
+    "created_at": {
+      "type": "string",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "waiver_type",
+    "reason",
+    "status",
+    "created_at"
+  ],
+  "title": "FeeWaiverReadResponse"
+}
+
+
FeeWaiverReviewRequest
+{
+  "properties": {
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    }
+  },
+  "type": "object",
+  "required": [
+    "status"
+  ],
+  "title": "FeeWaiverReviewRequest"
+}
+
+
FinishCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "fulfill-records-request",
+        "close-records-request"
+      ],
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/NativePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "FinishCommand"
+}
+
+
FlagStatus
+{
+  "type": "string",
+  "enum": [
+    "flagged",
+    "reviewed",
+    "accepted",
+    "rejected"
+  ],
+  "title": "FlagStatus"
+}
+
+
FormPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "form-plan",
+      "title": "Action"
+    },
+    "formName": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Formname",
+      "default": ""
+    },
+    "fields": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 50,
+      "title": "Fields"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "FormPlan"
+}
+
+
GeneratedDraft
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "model": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Model"
+    },
+    "previous_response_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Previous Response Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text",
+    "model",
+    "previous_response_sha256"
+  ],
+  "title": "GeneratedDraft"
+}
+
+
HTTPValidationError
+{
+  "properties": {
+    "detail": {
+      "items": {
+        "$ref": "#/components/schemas/ValidationError"
+      },
+      "type": "array",
+      "title": "Detail"
+    }
+  },
+  "type": "object",
+  "title": "HTTPValidationError"
+}
+
+
Handoff
+{
+  "properties": {
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "request_id"
+  ],
+  "title": "Handoff"
+}
+
+
ImportBundleCreate
+{
+  "properties": {
+    "job_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Job Id"
+    },
+    "connector_type": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Connector Type"
+    },
+    "source": {
+      "$ref": "#/components/schemas/SourceCreate"
+    },
+    "sources": {
+      "items": {
+        "$ref": "#/components/schemas/SourceCreate"
+      },
+      "type": "array",
+      "title": "Sources"
+    },
+    "titles": {
+      "items": {
+        "$ref": "#/components/schemas/TitleCreate"
+      },
+      "type": "array",
+      "title": "Titles"
+    },
+    "chapters": {
+      "items": {
+        "$ref": "#/components/schemas/ChapterCreate"
+      },
+      "type": "array",
+      "title": "Chapters"
+    },
+    "sections": {
+      "items": {
+        "$ref": "#/components/schemas/SectionCreate"
+      },
+      "type": "array",
+      "title": "Sections"
+    },
+    "versions": {
+      "items": {
+        "$ref": "#/components/schemas/SectionVersionCreate"
+      },
+      "type": "array",
+      "title": "Versions"
+    },
+    "provenance": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Provenance"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "connector_type",
+    "source"
+  ],
+  "title": "ImportBundleCreate",
+  "description": "Request body for local fixture/file-drop import jobs."
+}
+
+
InclusionStatus
+{
+  "type": "string",
+  "enum": [
+    "included",
+    "excluded",
+    "pending"
+  ],
+  "title": "InclusionStatus"
+}
+
+
IngestionStats
+{
+  "properties": {
+    "total_sources": {
+      "type": "integer",
+      "title": "Total Sources"
+    },
+    "active_sources": {
+      "type": "integer",
+      "title": "Active Sources"
+    },
+    "total_documents": {
+      "type": "integer",
+      "title": "Total Documents"
+    },
+    "documents_by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "Documents By Status"
+    },
+    "total_chunks": {
+      "type": "integer",
+      "title": "Total Chunks"
+    }
+  },
+  "type": "object",
+  "required": [
+    "total_sources",
+    "active_sources",
+    "total_documents",
+    "documents_by_status",
+    "total_chunks"
+  ],
+  "title": "IngestionStats"
+}
+
+
IngestionStatus
+{
+  "type": "string",
+  "enum": [
+    "pending",
+    "processing",
+    "completed",
+    "failed"
+  ],
+  "title": "IngestionStatus"
+}
+
+
InitiativeInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "policy": {
+      "$ref": "#/components/schemas/PolicySelection"
+    },
+    "responsible_staff": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Responsible Staff"
+    },
+    "target": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "string"
+        }
+      ],
+      "title": "Target"
+    },
+    "unit": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Unit"
+    },
+    "due_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Due On"
+    },
+    "status": {
+      "type": "string",
+      "enum": [
+        "planned",
+        "active",
+        "completed",
+        "cancelled"
+      ],
+      "title": "Status",
+      "default": "planned"
+    },
+    "milestones": {
+      "items": {
+        "$ref": "#/components/schemas/Milestone"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "title": "Milestones"
+    },
+    "measurements": {
+      "items": {
+        "$ref": "#/components/schemas/Measurement"
+      },
+      "type": "array",
+      "maxItems": 1000,
+      "title": "Measurements"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "policy",
+    "responsible_staff",
+    "target",
+    "unit",
+    "due_on",
+    "note"
+  ],
+  "title": "InitiativeInput"
+}
+
+
InspectionInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "property_reference": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Property Reference"
+    },
+    "inspection_reference": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Inspection Reference"
+    },
+    "dataset_kind": {
+      "type": "string",
+      "enum": [
+        "municipal",
+        "fictional"
+      ],
+      "title": "Dataset Kind"
+    },
+    "inspector_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "minLength": 1,
+      "title": "Inspector Notes"
+    },
+    "photo_observations": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Photo Observations"
+    },
+    "voice_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Voice Notes",
+      "default": ""
+    },
+    "evidence": {
+      "items": {
+        "$ref": "#/components/schemas/Evidence"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "title": "Evidence"
+    },
+    "linked_sources": {
+      "items": {
+        "$ref": "#/components/schemas/townlight_inspections__workflow_models__SourceLink"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Linked Sources"
+    },
+    "assigned_to": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Assigned To",
+      "default": ""
+    },
+    "staff_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Staff Notes",
+      "default": ""
+    },
+    "notice_draft": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Notice Draft",
+      "default": ""
+    },
+    "review_state": {
+      "type": "string",
+      "enum": [
+        "draft",
+        "follow_up",
+        "reviewed"
+      ],
+      "title": "Review State",
+      "default": "draft"
+    },
+    "review_notes": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Review Notes",
+      "default": ""
+    },
+    "public_summary": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Public Summary",
+      "default": ""
+    },
+    "analysis": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/AnalysisRecord"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "property_reference",
+    "inspection_reference",
+    "dataset_kind",
+    "inspector_notes"
+  ],
+  "title": "InspectionInput"
+}
+
+
IntakeInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "project_name": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Project Name"
+    },
+    "project_description": {
+      "type": "string",
+      "maxLength": 10000,
+      "minLength": 1,
+      "title": "Project Description"
+    },
+    "location": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Location"
+    },
+    "applicant_contact": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Applicant Contact",
+      "default": ""
+    },
+    "requirement_revision": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Requirement Revision"
+    },
+    "materials": {
+      "items": {
+        "$ref": "#/components/schemas/MaterialReview"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "minItems": 1,
+      "title": "Materials"
+    },
+    "linked_sources": {
+      "items": {
+        "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Linked Sources"
+    },
+    "staff_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Staff Notes",
+      "default": ""
+    },
+    "assigned_to": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Assigned To",
+      "default": ""
+    },
+    "review_state": {
+      "type": "string",
+      "enum": [
+        "draft",
+        "follow_up",
+        "reviewed"
+      ],
+      "title": "Review State",
+      "default": "draft"
+    },
+    "review_notes": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Review Notes",
+      "default": ""
+    },
+    "public_summary": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Public Summary",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "project_name",
+    "project_description",
+    "location",
+    "requirement_revision",
+    "materials"
+  ],
+  "title": "IntakeInput"
+}
+
+
InterpretationNoteCreate
+{
+  "properties": {
+    "note_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Note Id"
+    },
+    "note_text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Note Text"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "note_text"
+  ],
+  "title": "InterpretationNoteCreate",
+  "description": "Request body for staff-only interpretation notes."
+}
+
+
InterviewRequest
+{
+  "properties": {
+    "last_answer": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Answer"
+    },
+    "last_field": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Field"
+    },
+    "skipped_fields": {
+      "anyOf": [
+        {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Skipped Fields"
+    }
+  },
+  "type": "object",
+  "title": "InterviewRequest"
+}
+
+
InterviewResponse
+{
+  "properties": {
+    "question": {
+      "type": "string",
+      "title": "Question"
+    },
+    "target_field": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Target Field"
+    },
+    "all_complete": {
+      "type": "boolean",
+      "title": "All Complete"
+    },
+    "completed_fields": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Completed Fields"
+    },
+    "onboarding_status": {
+      "type": "string",
+      "title": "Onboarding Status"
+    },
+    "skipped_fields": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Skipped Fields"
+    }
+  },
+  "type": "object",
+  "required": [
+    "question",
+    "target_field",
+    "all_complete",
+    "completed_fields",
+    "onboarding_status",
+    "skipped_fields"
+  ],
+  "title": "InterviewResponse"
+}
+
+
ManagedFileReceipt
+{
+  "properties": {
+    "original_path": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Original Path"
+    },
+    "stored_path": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Stored Path"
+    },
+    "file_name": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "File Name"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Sha256"
+    },
+    "size_bytes": {
+      "type": "integer",
+      "maximum": 2147483647.0,
+      "minimum": 0.0,
+      "title": "Size Bytes"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "original_path",
+    "stored_path",
+    "file_name",
+    "sha256",
+    "size_bytes"
+  ],
+  "title": "ManagedFileReceipt"
+}
+
+
ManagedSource
+{
+  "properties": {
+    "original_path": {
+      "type": "string",
+      "title": "Original Path"
+    },
+    "stored_path": {
+      "type": "string",
+      "title": "Stored Path"
+    },
+    "file_name": {
+      "type": "string",
+      "title": "File Name"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Sha256"
+    },
+    "size_bytes": {
+      "type": "integer",
+      "minimum": 0.0,
+      "title": "Size Bytes"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "original_path",
+    "stored_path",
+    "file_name",
+    "sha256",
+    "size_bytes"
+  ],
+  "title": "ManagedSource"
+}
+
+
Material
+{
+  "properties": {
+    "material_id": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9_-]{1,80}$",
+      "title": "Material Id"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Description"
+    },
+    "citation": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Citation"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "material_id",
+    "description",
+    "citation"
+  ],
+  "title": "Material"
+}
+
+
MaterialReview
+{
+  "properties": {
+    "material_id": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Material Id"
+    },
+    "status": {
+      "type": "string",
+      "enum": [
+        "not_reviewed",
+        "provided",
+        "missing",
+        "unclear"
+      ],
+      "title": "Status",
+      "default": "not_reviewed"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Note",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "material_id"
+  ],
+  "title": "MaterialReview"
+}
+
+
Measurement
+{
+  "properties": {
+    "recorded_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Recorded On"
+    },
+    "value": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "string"
+        }
+      ],
+      "title": "Value"
+    },
+    "evidence": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Evidence"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "recorded_on",
+    "value",
+    "evidence"
+  ],
+  "title": "Measurement"
+}
+
+
MediaAnalysis
+{
+  "properties": {
+    "items": {
+      "items": {
+        "$ref": "#/components/schemas/EvidenceItem"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "minItems": 1,
+      "title": "Items"
+    },
+    "code_links": {
+      "items": {
+        "$ref": "#/components/schemas/CodeLink"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Code Links"
+    },
+    "inspector_supplied_text": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Inspector Supplied Text",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "items"
+  ],
+  "title": "MediaAnalysis"
+}
+
+
MeetingInput
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "scheduled_start": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Scheduled Start"
+    },
+    "location": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Location"
+    },
+    "meeting_type": {
+      "type": "string",
+      "enum": [
+        "regular",
+        "special",
+        "emergency",
+        "closed_session",
+        "executive"
+      ],
+      "title": "Meeting Type",
+      "default": "regular"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "scheduled_start",
+    "location"
+  ],
+  "title": "MeetingInput"
+}
+
+
MeetingLink
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 200,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    },
+    "relation": {
+      "type": "string",
+      "enum": [
+        "hearing",
+        "context",
+        "precedent"
+      ],
+      "title": "Relation"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256",
+    "relation"
+  ],
+  "title": "MeetingLink"
+}
+
+
MeetingSearch
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "MeetingSearch"
+}
+
+
MeetingStageInput
+{
+  "properties": {
+    "to_status": {
+      "type": "string",
+      "enum": [
+        "SCHEDULED",
+        "NOTICED",
+        "PACKET_POSTED",
+        "IN_PROGRESS",
+        "RECESSED",
+        "ADJOURNED",
+        "TRANSCRIPT_READY",
+        "MINUTES_DRAFTED",
+        "MINUTES_POSTED",
+        "MINUTES_ADOPTED",
+        "MINUTES_SIGNED",
+        "ARCHIVED",
+        "CANCELLED"
+      ],
+      "title": "To Status"
+    },
+    "statutory_basis": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Basis"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "to_status"
+  ],
+  "title": "MeetingStageInput"
+}
+
+
MeetingsSearch
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "MeetingsSearch"
+}
+
+
MeetingsSourceSelection
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 200,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "MeetingsSourceSelection"
+}
+
+
MessageCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-message",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/MessagePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "MessageCommand"
+}
+
+
MessageCreate
+{
+  "properties": {
+    "message_text": {
+      "type": "string",
+      "title": "Message Text"
+    },
+    "is_internal": {
+      "type": "boolean",
+      "title": "Is Internal",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "message_text"
+  ],
+  "title": "MessageCreate"
+}
+
+
MessagePayload
+{
+  "properties": {
+    "requestMessageBody": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestmessagebody"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requestMessageBody"
+  ],
+  "title": "MessagePayload"
+}
+
+
MessageRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "sender_type": {
+      "type": "string",
+      "title": "Sender Type"
+    },
+    "sender_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sender Id"
+    },
+    "message_text": {
+      "type": "string",
+      "title": "Message Text"
+    },
+    "is_internal": {
+      "type": "boolean",
+      "title": "Is Internal"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "sender_type",
+    "sender_id",
+    "message_text",
+    "is_internal",
+    "created_at"
+  ],
+  "title": "MessageRead"
+}
+
+
MessageView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "author": {
+      "type": "string",
+      "title": "Author"
+    },
+    "author_role": {
+      "type": "string",
+      "title": "Author Role"
+    },
+    "body": {
+      "type": "string",
+      "title": "Body"
+    },
+    "visibility": {
+      "type": "string",
+      "title": "Visibility"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "author",
+    "author_role",
+    "body",
+    "visibility",
+    "created_at_unix_seconds"
+  ],
+  "title": "MessageView"
+}
+
+
Milestone
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "due_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Due On"
+    },
+    "completed_on": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Completed On"
+    },
+    "evidence": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Evidence",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "due_on"
+  ],
+  "title": "Milestone"
+}
+
+
MinutesDecision
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "post",
+        "adopt",
+        "sign"
+      ],
+      "title": "Action"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "MinutesDecision"
+}
+
+
ModelRegistryCreate
+{
+  "properties": {
+    "model_name": {
+      "type": "string",
+      "title": "Model Name"
+    },
+    "model_version": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Version"
+    },
+    "parameter_count": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parameter Count"
+    },
+    "license": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "License"
+    },
+    "model_card_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Card Url"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active",
+      "default": false
+    },
+    "context_window_size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Context Window Size"
+    },
+    "supports_ner": {
+      "type": "boolean",
+      "title": "Supports Ner",
+      "default": false
+    },
+    "supports_vision": {
+      "type": "boolean",
+      "title": "Supports Vision",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "model_name"
+  ],
+  "title": "ModelRegistryCreate",
+  "description": "Schema for creating a new model_registry record (POST body)."
+}
+
+
ModelRegistryRead
+{
+  "properties": {
+    "id": {
+      "type": "integer",
+      "title": "Id"
+    },
+    "model_name": {
+      "type": "string",
+      "title": "Model Name"
+    },
+    "model_version": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Version"
+    },
+    "parameter_count": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parameter Count"
+    },
+    "license": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "License"
+    },
+    "model_card_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Card Url"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "added_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Added At"
+    },
+    "context_window_size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Context Window Size"
+    },
+    "supports_ner": {
+      "type": "boolean",
+      "title": "Supports Ner"
+    },
+    "supports_vision": {
+      "type": "boolean",
+      "title": "Supports Vision"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "model_name",
+    "is_active",
+    "supports_ner",
+    "supports_vision"
+  ],
+  "title": "ModelRegistryRead",
+  "description": "Schema for returning a model_registry record (GET response).\n\n``from_attributes=True`` allows construction directly from an ORM instance."
+}
+
+
ModelRegistryUpdate
+{
+  "properties": {
+    "model_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Name"
+    },
+    "model_version": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Version"
+    },
+    "parameter_count": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parameter Count"
+    },
+    "license": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "License"
+    },
+    "model_card_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Card Url"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    },
+    "context_window_size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Context Window Size"
+    },
+    "supports_ner": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supports Ner"
+    },
+    "supports_vision": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supports Vision"
+    }
+  },
+  "type": "object",
+  "title": "ModelRegistryUpdate",
+  "description": "Schema for partially updating a model_registry record (PATCH body).\n\nEvery field is optional so callers can send only the fields they want to\nchange."
+}
+
+
MotionCorrection
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "reason": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Reason"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text",
+    "reason"
+  ],
+  "title": "MotionCorrection"
+}
+
+
MotionInput
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "seconded_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "minLength": 1
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Seconded By"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text"
+  ],
+  "title": "MotionInput"
+}
+
+
NativePayload
+{
+  "properties": {},
+  "additionalProperties": false,
+  "type": "object",
+  "title": "NativePayload"
+}
+
+
NativeRequestRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "requester_name": {
+      "type": "string",
+      "title": "Requester Name"
+    },
+    "requester_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Email"
+    },
+    "requester_phone": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Phone"
+    },
+    "requester_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Type"
+    },
+    "date_received": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Date Received"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "status": {
+      "$ref": "#/components/schemas/RequestStatus"
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "created_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "response_draft": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Response Draft"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    },
+    "estimated_fee": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Estimated Fee"
+    },
+    "fee_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Status"
+    },
+    "fee_waiver_requested": {
+      "type": "boolean",
+      "title": "Fee Waiver Requested",
+      "default": false
+    },
+    "priority": {
+      "type": "string",
+      "title": "Priority",
+      "default": "normal"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    },
+    "closed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closed At"
+    },
+    "closure_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closure Reason"
+    },
+    "desktop_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Desktop Id"
+    },
+    "public_tracking_number": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Public Tracking Number"
+    },
+    "submitted_via": {
+      "type": "string",
+      "title": "Submitted Via"
+    },
+    "deadline_label": {
+      "type": "string",
+      "title": "Deadline Label"
+    },
+    "deadline_basis": {
+      "type": "string",
+      "title": "Deadline Basis"
+    },
+    "deadline_reviewed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Deadline Reviewed At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "requester_name",
+    "requester_email",
+    "date_received",
+    "statutory_deadline",
+    "description",
+    "status",
+    "assigned_to",
+    "created_by",
+    "created_at",
+    "response_draft",
+    "review_notes",
+    "desktop_id",
+    "public_tracking_number",
+    "submitted_via",
+    "deadline_label",
+    "deadline_basis",
+    "deadline_reviewed_at"
+  ],
+  "title": "NativeRequestRead"
+}
+
+
NoticeDocumentInput
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text"
+  ],
+  "title": "NoticeDocumentInput"
+}
+
+
NoticeDraft
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 100000,
+      "minLength": 1,
+      "title": "Body"
+    },
+    "notice_type": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Notice Type"
+    },
+    "statutory_basis": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Statutory Basis"
+    },
+    "event_date": {
+      "type": "string",
+      "format": "date",
+      "title": "Event Date"
+    },
+    "lead_days": {
+      "type": "integer",
+      "maximum": 365.0,
+      "minimum": 0.0,
+      "title": "Lead Days"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "body",
+    "notice_type",
+    "statutory_basis",
+    "event_date",
+    "lead_days"
+  ],
+  "title": "NoticeDraft"
+}
+
+
NoticeInput
+{
+  "properties": {
+    "notice_type": {
+      "type": "string",
+      "enum": [
+        "regular",
+        "special",
+        "emergency",
+        "closed_session",
+        "executive"
+      ],
+      "title": "Notice Type"
+    },
+    "posted_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Posted At"
+    },
+    "minimum_notice_hours": {
+      "type": "integer",
+      "minimum": 0.0,
+      "title": "Minimum Notice Hours"
+    },
+    "statutory_basis": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Basis"
+    },
+    "approved_by": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Approved By"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "notice_type",
+    "posted_at",
+    "minimum_notice_hours"
+  ],
+  "title": "NoticeInput"
+}
+
+
NoticeProofInput
+{
+  "properties": {
+    "location": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Location"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note",
+      "default": ""
+    },
+    "document_delivery_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Document Delivery Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "location"
+  ],
+  "title": "NoticeProofInput"
+}
+
+
NotificationLogRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "template_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Template Id"
+    },
+    "recipient_email": {
+      "type": "string",
+      "title": "Recipient Email"
+    },
+    "request_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Request Id"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "sent_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sent At"
+    },
+    "error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Message"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "template_id",
+    "recipient_email",
+    "request_id",
+    "channel",
+    "status",
+    "sent_at",
+    "error_message",
+    "created_at"
+  ],
+  "title": "NotificationLogRead"
+}
+
+
NotificationTemplateCreate
+{
+  "properties": {
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel",
+      "default": "email"
+    },
+    "subject_template": {
+      "type": "string",
+      "title": "Subject Template"
+    },
+    "body_template": {
+      "type": "string",
+      "title": "Body Template"
+    }
+  },
+  "type": "object",
+  "required": [
+    "event_type",
+    "subject_template",
+    "body_template"
+  ],
+  "title": "NotificationTemplateCreate"
+}
+
+
NotificationTemplateRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel"
+    },
+    "subject_template": {
+      "type": "string",
+      "title": "Subject Template"
+    },
+    "body_template": {
+      "type": "string",
+      "title": "Body Template"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "event_type",
+    "channel",
+    "subject_template",
+    "body_template",
+    "is_active",
+    "created_at"
+  ],
+  "title": "NotificationTemplateRead"
+}
+
+
NotificationTemplateUpdate
+{
+  "properties": {
+    "subject_template": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Subject Template"
+    },
+    "body_template": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Body Template"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "NotificationTemplateUpdate"
+}
+
+
NotificationView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "notification_id": {
+      "type": "string",
+      "title": "Notification Id"
+    },
+    "module_id": {
+      "type": "string",
+      "title": "Module Id"
+    },
+    "record_id": {
+      "type": "string",
+      "title": "Record Id"
+    },
+    "audience": {
+      "type": "string",
+      "title": "Audience"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel"
+    },
+    "subject": {
+      "type": "string",
+      "title": "Subject"
+    },
+    "body": {
+      "type": "string",
+      "title": "Body"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    },
+    "sent_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sent At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "notification_id",
+    "module_id",
+    "record_id",
+    "audience",
+    "channel",
+    "subject",
+    "body",
+    "status",
+    "created_at_unix_seconds",
+    "sent_at_unix_seconds"
+  ],
+  "title": "NotificationView"
+}
+
+
OllamaModelInfo
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Size"
+    },
+    "details": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Details"
+    }
+  },
+  "type": "object",
+  "required": [
+    "name"
+  ],
+  "title": "OllamaModelInfo"
+}
+
+
OllamaStatus
+{
+  "properties": {
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "models": {
+      "items": {
+        "$ref": "#/components/schemas/OllamaModelInfo"
+      },
+      "type": "array",
+      "title": "Models"
+    }
+  },
+  "type": "object",
+  "required": [
+    "status",
+    "models"
+  ],
+  "title": "OllamaStatus"
+}
+
+
OperationalMetrics
+{
+  "properties": {
+    "average_response_time_days": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Average Response Time Days"
+    },
+    "median_response_time_days": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Median Response Time Days"
+    },
+    "requests_by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "Requests By Status"
+    },
+    "requests_by_department": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "Requests By Department"
+    },
+    "deadline_compliance_rate": {
+      "type": "number",
+      "title": "Deadline Compliance Rate"
+    },
+    "total_open": {
+      "type": "integer",
+      "title": "Total Open"
+    },
+    "total_closed": {
+      "type": "integer",
+      "title": "Total Closed"
+    },
+    "total_overdue": {
+      "type": "integer",
+      "title": "Total Overdue"
+    },
+    "clarification_frequency": {
+      "type": "number",
+      "title": "Clarification Frequency"
+    },
+    "top_request_topics": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Top Request Topics"
+    }
+  },
+  "type": "object",
+  "required": [
+    "average_response_time_days",
+    "median_response_time_days",
+    "requests_by_status",
+    "requests_by_department",
+    "deadline_compliance_rate",
+    "total_open",
+    "total_closed",
+    "total_overdue",
+    "clarification_frequency",
+    "top_request_topics"
+  ],
+  "title": "OperationalMetrics"
+}
+
+
Outline
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "question_ids": {
+      "items": {
+        "type": "string",
+        "format": "uuid"
+      },
+      "type": "array",
+      "maxItems": 50,
+      "minItems": 1,
+      "title": "Question Ids"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "question_ids"
+  ],
+  "title": "Outline"
+}
+
+
Packet
+{
+  "properties": {
+    "expected_revision": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Expected Revision"
+    },
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "staff_only",
+        "records_copy"
+      ],
+      "title": "Visibility"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "expected_revision",
+    "visibility"
+  ],
+  "title": "Packet"
+}
+
+
PacketInput
+{
+  "properties": {
+    "agenda_item_ids": {
+      "items": {
+        "type": "string",
+        "format": "uuid"
+      },
+      "type": "array",
+      "title": "Agenda Item Ids"
+    },
+    "source_files": {
+      "items": {
+        "$ref": "#/components/schemas/ManagedSource"
+      },
+      "type": "array",
+      "title": "Source Files"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "agenda_item_ids"
+  ],
+  "title": "PacketInput"
+}
+
+
Pathway
+{
+  "properties": {
+    "project_type": {
+      "type": "string",
+      "maxLength": 120,
+      "minLength": 1,
+      "title": "Project Type"
+    },
+    "proposal": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Proposal",
+      "default": ""
+    },
+    "location_context": {
+      "type": "string",
+      "maxLength": 1000,
+      "title": "Location Context",
+      "default": ""
+    },
+    "requirement_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requirement Revision"
+    },
+    "fee_link": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "project_type"
+  ],
+  "title": "Pathway"
+}
+
+
PathwayStep
+{
+  "properties": {
+    "step": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Step"
+    },
+    "citation": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Citation"
+    },
+    "typical_time": {
+      "type": "string",
+      "maxLength": 1000,
+      "title": "Typical Time",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "step",
+    "citation"
+  ],
+  "title": "PathwayStep"
+}
+
+
PlainLanguageSummaryCreate
+{
+  "properties": {
+    "summary_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Summary Id"
+    },
+    "section_version_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Version Id"
+    },
+    "summary_text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Summary Text"
+    },
+    "language_code": {
+      "type": "string",
+      "title": "Language Code",
+      "default": "en"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "section_version_id",
+    "summary_text"
+  ],
+  "title": "PlainLanguageSummaryCreate",
+  "description": "Request body for staff-drafted plain-language summaries."
+}
+
+
PolicySelection
+{
+  "properties": {
+    "plan_id": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Plan Id"
+    },
+    "revision_id": {
+      "type": "string",
+      "maxLength": 36,
+      "minLength": 36,
+      "title": "Revision Id"
+    },
+    "policy_id": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Policy Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "plan_id",
+    "revision_id",
+    "policy_id"
+  ],
+  "title": "PolicySelection"
+}
+
+
PortalModeResponse
+{
+  "properties": {
+    "mode": {
+      "type": "string",
+      "enum": [
+        "public",
+        "private"
+      ],
+      "title": "Mode",
+      "description": "Active portal posture for this deployment. ``public`` = minimal resident surface (landing + authenticated records-request submission + resident registration) reachable without staff auth. ``private`` = staff-only; no public routes, no resident self-registration."
+    }
+  },
+  "type": "object",
+  "required": [
+    "mode"
+  ],
+  "title": "PortalModeResponse",
+  "description": "T5D — schema for ``GET /config/portal-mode``.\n\nExposed to the frontend on boot so it can branch routing without a\nuser-identity lookup. The payload is intentionally the single field\nbelow — no staff config, no user state, no schema version."
+}
+
+
PrepareArtifact
+{
+  "properties": {
+    "kind": {
+      "type": "string",
+      "enum": [
+        "response",
+        "release-package"
+      ],
+      "title": "Kind"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "kind"
+  ],
+  "title": "PrepareArtifact"
+}
+
+
Proof
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    },
+    "filename": {
+      "type": "string",
+      "maxLength": 150,
+      "minLength": 1,
+      "title": "Filename"
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 7000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "location": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Location"
+    },
+    "published_at": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Published At"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence",
+    "filename",
+    "content_base64",
+    "location",
+    "published_at"
+  ],
+  "title": "Proof"
+}
+
+
Proposal
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "pattern": "^[A-Za-z0-9_-]{1,64}$",
+      "title": "Id"
+    },
+    "version_id": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Version Id"
+    },
+    "meeting_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Meeting Id"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "ordinance_number": {
+      "type": "string",
+      "maxLength": 120,
+      "minLength": 1,
+      "title": "Ordinance Number"
+    },
+    "proposed_text": {
+      "type": "string",
+      "maxLength": 1000000,
+      "minLength": 1,
+      "title": "Proposed Text"
+    },
+    "supersedes_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^[A-Za-z0-9_-]{1,64}$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supersedes Id"
+    },
+    "reconciliation_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reconciliation Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "version_id",
+    "meeting_id",
+    "title",
+    "ordinance_number",
+    "proposed_text"
+  ],
+  "title": "Proposal"
+}
+
+
PublicExplore
+{
+  "properties": {
+    "goal": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Goal",
+      "default": ""
+    },
+    "topic": {
+      "type": "string",
+      "maxLength": 160,
+      "title": "Topic",
+      "default": ""
+    },
+    "neighborhood": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Neighborhood",
+      "default": ""
+    },
+    "plan_type": {
+      "type": "string",
+      "maxLength": 120,
+      "title": "Plan Type",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "PublicExplore"
+}
+
+
PublicIntake
+{
+  "properties": {
+    "requester": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requester"
+    },
+    "requesterContact": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestercontact"
+    },
+    "summary": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Summary"
+    },
+    "deadline": {
+      "type": "string",
+      "title": "Deadline",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requester",
+    "requesterContact",
+    "summary"
+  ],
+  "title": "PublicIntake"
+}
+
+
PublicLookup
+{
+  "properties": {
+    "trackingNumber": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Trackingnumber"
+    },
+    "requesterContact": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestercontact"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "trackingNumber",
+    "requesterContact"
+  ],
+  "title": "PublicLookup"
+}
+
+
PublicMessage
+{
+  "properties": {
+    "trackingNumber": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Trackingnumber"
+    },
+    "requesterContact": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestercontact"
+    },
+    "publicRequestMessage": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Publicrequestmessage"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "trackingNumber",
+    "requesterContact",
+    "publicRequestMessage"
+  ],
+  "title": "PublicMessage"
+}
+
+
PublicStatusView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "label": {
+      "type": "string",
+      "title": "Label"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "label",
+    "summary",
+    "status",
+    "created_at_unix_seconds"
+  ],
+  "title": "PublicStatusView"
+}
+
+
PublicationView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "source_module": {
+      "type": "string",
+      "title": "Source Module"
+    },
+    "source_record_id": {
+      "type": "string",
+      "title": "Source Record Id"
+    },
+    "record_type": {
+      "type": "string",
+      "title": "Record Type"
+    },
+    "public_payload": {
+      "type": "string",
+      "title": "Public Payload"
+    },
+    "payload_hash": {
+      "type": "string",
+      "title": "Payload Hash"
+    },
+    "published_at_unix_seconds": {
+      "type": "integer",
+      "title": "Published At Unix Seconds"
+    },
+    "retracted_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Retracted At Unix Seconds"
+    },
+    "retracted_by": {
+      "type": "string",
+      "title": "Retracted By",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "source_module",
+    "source_record_id",
+    "record_type",
+    "public_payload",
+    "payload_hash",
+    "published_at_unix_seconds"
+  ],
+  "title": "PublicationView"
+}
+
+
PublishingPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "publishing-workflow",
+      "title": "Action"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "hasReview": {
+      "type": "boolean",
+      "title": "Hasreview",
+      "default": false
+    },
+    "hasPlainLanguage": {
+      "type": "boolean",
+      "title": "Hasplainlanguage",
+      "default": false
+    },
+    "hasTranslationReview": {
+      "type": "boolean",
+      "title": "Hastranslationreview",
+      "default": false
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "PublishingPlan"
+}
+
+
Question
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    },
+    "question": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Question"
+    },
+    "kind": {
+      "type": "string",
+      "enum": [
+        "use",
+        "dimension"
+      ],
+      "title": "Kind"
+    },
+    "key": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Key"
+    },
+    "audience": {
+      "type": "string",
+      "enum": [
+        "resident",
+        "staff"
+      ],
+      "title": "Audience",
+      "default": "resident"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "query",
+    "question",
+    "kind",
+    "key"
+  ],
+  "title": "Question"
+}
+
+
QuestionAnswerRequest
+{
+  "properties": {
+    "question": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Question"
+    },
+    "section_number": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Section Number"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "question"
+  ],
+  "title": "QuestionAnswerRequest",
+  "description": "Request body for citation-grounded code Q&A."
+}
+
+
RecordsDocumentView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "attachment_id": {
+      "type": "string",
+      "title": "Attachment Id"
+    },
+    "title": {
+      "type": "string",
+      "title": "Title"
+    },
+    "original_path": {
+      "type": "string",
+      "title": "Original Path"
+    },
+    "stored_path": {
+      "type": "string",
+      "title": "Stored Path"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation"
+    },
+    "sha256": {
+      "type": "string",
+      "title": "Sha256"
+    },
+    "size_bytes": {
+      "type": "integer",
+      "title": "Size Bytes"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "added_by": {
+      "type": "string",
+      "title": "Added By"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    },
+    "release_original_path": {
+      "type": "string",
+      "title": "Release Original Path",
+      "default": ""
+    },
+    "release_stored_path": {
+      "type": "string",
+      "title": "Release Stored Path",
+      "default": ""
+    },
+    "release_file_name": {
+      "type": "string",
+      "title": "Release File Name",
+      "default": ""
+    },
+    "release_sha256": {
+      "type": "string",
+      "title": "Release Sha256",
+      "default": ""
+    },
+    "release_size_bytes": {
+      "type": "integer",
+      "title": "Release Size Bytes",
+      "default": 0
+    },
+    "release_status": {
+      "type": "string",
+      "title": "Release Status",
+      "default": ""
+    },
+    "release_note": {
+      "type": "string",
+      "title": "Release Note",
+      "default": ""
+    },
+    "release_added_by": {
+      "type": "string",
+      "title": "Release Added By",
+      "default": ""
+    },
+    "release_added_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Release Added At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "attachment_id",
+    "title",
+    "original_path",
+    "stored_path",
+    "citation",
+    "sha256",
+    "size_bytes",
+    "status",
+    "added_by",
+    "created_at_unix_seconds"
+  ],
+  "title": "RecordsDocumentView"
+}
+
+
RecordsOperationRead
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "message": {
+      "type": "string",
+      "title": "Message"
+    },
+    "request": {
+      "$ref": "#/components/schemas/RecordsView"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "message",
+    "request"
+  ],
+  "title": "RecordsOperationRead"
+}
+
+
RecordsStateRead
+{
+  "properties": {
+    "demo_fixture": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Demo Fixture"
+    },
+    "records_requests": {
+      "items": {
+        "$ref": "#/components/schemas/RecordsView"
+      },
+      "type": "array",
+      "title": "Records Requests"
+    },
+    "notification_events": {
+      "items": {
+        "$ref": "#/components/schemas/NotificationView"
+      },
+      "type": "array",
+      "title": "Notification Events"
+    },
+    "publication_events": {
+      "items": {
+        "$ref": "#/components/schemas/PublicationView"
+      },
+      "type": "array",
+      "title": "Publication Events"
+    },
+    "audit_entries": {
+      "items": {
+        "$ref": "#/components/schemas/AuditView"
+      },
+      "type": "array",
+      "title": "Audit Entries"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "records_requests"
+  ],
+  "title": "RecordsStateRead"
+}
+
+
RecordsView
+{
+  "properties": {
+    "request_id": {
+      "type": "string",
+      "title": "Request Id"
+    },
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "public_tracking_number": {
+      "type": "string",
+      "title": "Public Tracking Number"
+    },
+    "requester": {
+      "type": "string",
+      "title": "Requester"
+    },
+    "requester_contact": {
+      "type": "string",
+      "title": "Requester Contact"
+    },
+    "submitted_via": {
+      "type": "string",
+      "title": "Submitted Via"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "deadline": {
+      "type": "string",
+      "title": "Deadline"
+    },
+    "deadline_basis": {
+      "type": "string",
+      "title": "Deadline Basis"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "assigned_to": {
+      "type": "string",
+      "title": "Assigned To"
+    },
+    "clarification_notes": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Clarification Notes"
+    },
+    "search_notes": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Search Notes"
+    },
+    "search_sessions": {
+      "items": {
+        "$ref": "#/components/schemas/SearchReceiptView"
+      },
+      "type": "array",
+      "title": "Search Sessions"
+    },
+    "exemption_reviews": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Exemption Reviews"
+    },
+    "exemption_decisions": {
+      "items": {
+        "$ref": "#/components/schemas/ExemptionDecisionView"
+      },
+      "type": "array",
+      "title": "Exemption Decisions"
+    },
+    "fee_estimate": {
+      "type": "string",
+      "title": "Fee Estimate"
+    },
+    "fee_line_items": {
+      "items": {
+        "$ref": "#/components/schemas/FeeLineView"
+      },
+      "type": "array",
+      "title": "Fee Line Items"
+    },
+    "fee_waiver_reason": {
+      "type": "string",
+      "title": "Fee Waiver Reason"
+    },
+    "citations": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Citations"
+    },
+    "response_draft": {
+      "type": "string",
+      "title": "Response Draft"
+    },
+    "approval_notes": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Approval Notes"
+    },
+    "exports": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Exports"
+    },
+    "documents": {
+      "items": {
+        "$ref": "#/components/schemas/RecordsDocumentView"
+      },
+      "type": "array",
+      "title": "Documents"
+    },
+    "release_packages": {
+      "items": {
+        "$ref": "#/components/schemas/ReleasePackageView"
+      },
+      "type": "array",
+      "title": "Release Packages"
+    },
+    "timeline": {
+      "items": {
+        "$ref": "#/components/schemas/TimelineView"
+      },
+      "type": "array",
+      "title": "Timeline"
+    },
+    "public_status_events": {
+      "items": {
+        "$ref": "#/components/schemas/PublicStatusView"
+      },
+      "type": "array",
+      "title": "Public Status Events"
+    },
+    "messages": {
+      "items": {
+        "$ref": "#/components/schemas/MessageView"
+      },
+      "type": "array",
+      "title": "Messages"
+    },
+    "deadline_reviewed_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Deadline Reviewed At Unix Seconds"
+    },
+    "approved_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Approved At Unix Seconds"
+    },
+    "fulfilled_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fulfilled At Unix Seconds"
+    },
+    "closed_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closed At Unix Seconds"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "request_id",
+    "id",
+    "public_tracking_number",
+    "requester",
+    "requester_contact",
+    "submitted_via",
+    "summary",
+    "deadline",
+    "deadline_basis",
+    "status",
+    "assigned_to",
+    "clarification_notes",
+    "search_notes",
+    "search_sessions",
+    "exemption_reviews",
+    "exemption_decisions",
+    "fee_estimate",
+    "fee_line_items",
+    "fee_waiver_reason",
+    "citations",
+    "response_draft",
+    "approval_notes",
+    "exports",
+    "timeline",
+    "public_status_events",
+    "messages",
+    "deadline_reviewed_at_unix_seconds",
+    "approved_at_unix_seconds",
+    "fulfilled_at_unix_seconds",
+    "closed_at_unix_seconds",
+    "created_at_unix_seconds"
+  ],
+  "title": "RecordsView"
+}
+
+
ReleasePackageView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "export_path": {
+      "type": "string",
+      "title": "Export Path"
+    },
+    "package_hash": {
+      "type": "string",
+      "title": "Package Hash"
+    },
+    "document_count": {
+      "type": "integer",
+      "title": "Document Count"
+    },
+    "release_artifact_count": {
+      "type": "integer",
+      "title": "Release Artifact Count"
+    },
+    "search_session_count": {
+      "type": "integer",
+      "title": "Search Session Count"
+    },
+    "release_count": {
+      "type": "integer",
+      "title": "Release Count"
+    },
+    "redacted_count": {
+      "type": "integer",
+      "title": "Redacted Count"
+    },
+    "exempt_count": {
+      "type": "integer",
+      "title": "Exempt Count"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "export_path",
+    "package_hash",
+    "document_count",
+    "release_artifact_count",
+    "search_session_count",
+    "release_count",
+    "redacted_count",
+    "exempt_count",
+    "created_at_unix_seconds"
+  ],
+  "title": "ReleasePackageView"
+}
+
+
RepeatLookup
+{
+  "properties": {
+    "property_reference": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Property Reference"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "property_reference"
+  ],
+  "title": "RepeatLookup"
+}
+
+
RequestCreate
+{
+  "properties": {
+    "requester_name": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Requester Name"
+    },
+    "requester_email": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 255
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Email"
+    },
+    "requester_phone": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 50
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Phone"
+    },
+    "requester_type": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 100
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Type"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Description"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "priority": {
+      "type": "string",
+      "title": "Priority",
+      "default": "normal"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^(narrow|moderate|broad)$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "requester_name",
+    "description"
+  ],
+  "title": "RequestCreate"
+}
+
+
RequestDocumentAdd
+{
+  "properties": {
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "relevance_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Relevance Note"
+    }
+  },
+  "type": "object",
+  "required": [
+    "document_id"
+  ],
+  "title": "RequestDocumentAdd"
+}
+
+
RequestDocumentRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "relevance_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Relevance Note"
+    },
+    "exemption_flags": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Exemption Flags"
+    },
+    "inclusion_status": {
+      "$ref": "#/components/schemas/InclusionStatus"
+    },
+    "attached_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Attached At"
+    },
+    "attached_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Attached By"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "document_id",
+    "relevance_note",
+    "exemption_flags",
+    "inclusion_status",
+    "attached_at",
+    "attached_by"
+  ],
+  "title": "RequestDocumentRead"
+}
+
+
RequestRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "requester_name": {
+      "type": "string",
+      "title": "Requester Name"
+    },
+    "requester_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Email"
+    },
+    "requester_phone": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Phone"
+    },
+    "requester_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Type"
+    },
+    "date_received": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Date Received"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "status": {
+      "$ref": "#/components/schemas/RequestStatus"
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "created_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "response_draft": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Response Draft"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    },
+    "estimated_fee": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Estimated Fee"
+    },
+    "fee_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Status"
+    },
+    "fee_waiver_requested": {
+      "type": "boolean",
+      "title": "Fee Waiver Requested",
+      "default": false
+    },
+    "priority": {
+      "type": "string",
+      "title": "Priority",
+      "default": "normal"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    },
+    "closed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closed At"
+    },
+    "closure_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closure Reason"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "requester_name",
+    "requester_email",
+    "date_received",
+    "statutory_deadline",
+    "description",
+    "status",
+    "assigned_to",
+    "created_by",
+    "created_at",
+    "response_draft",
+    "review_notes"
+  ],
+  "title": "RequestRead"
+}
+
+
RequestStats
+{
+  "properties": {
+    "total_requests": {
+      "type": "integer",
+      "title": "Total Requests"
+    },
+    "by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "By Status"
+    },
+    "approaching_deadline": {
+      "type": "integer",
+      "title": "Approaching Deadline"
+    },
+    "overdue": {
+      "type": "integer",
+      "title": "Overdue"
+    }
+  },
+  "type": "object",
+  "required": [
+    "total_requests",
+    "by_status",
+    "approaching_deadline",
+    "overdue"
+  ],
+  "title": "RequestStats"
+}
+
+
RequestStatus
+{
+  "type": "string",
+  "enum": [
+    "received",
+    "clarification_needed",
+    "assigned",
+    "searching",
+    "in_review",
+    "ready_for_release",
+    "drafted",
+    "approved",
+    "fulfilled",
+    "closed"
+  ],
+  "title": "RequestStatus"
+}
+
+
RequestUpdate
+{
+  "properties": {
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/RequestStatus"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "response_draft": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Response Draft"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    }
+  },
+  "type": "object",
+  "title": "RequestUpdate"
+}
+
+
RequirementBundle
+{
+  "properties": {
+    "requirement_id": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9_-]{1,100}$",
+      "title": "Requirement Id"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "project_type": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Project Type"
+    },
+    "source_reference": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Source Reference"
+    },
+    "source_date": {
+      "type": "string",
+      "format": "date",
+      "title": "Source Date"
+    },
+    "effective_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Effective On"
+    },
+    "dataset_kind": {
+      "type": "string",
+      "enum": [
+        "municipal",
+        "fictional"
+      ],
+      "title": "Dataset Kind"
+    },
+    "filename": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$",
+      "title": "Filename"
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 14000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Sha256"
+    },
+    "materials": {
+      "items": {
+        "$ref": "#/components/schemas/Material"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "minItems": 1,
+      "title": "Materials"
+    },
+    "pathway": {
+      "items": {
+        "$ref": "#/components/schemas/PathwayStep"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "title": "Pathway"
+    },
+    "fee_link": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    },
+    "staff_note": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Staff Note",
+      "default": ""
+    },
+    "change_note": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Change Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requirement_id",
+    "title",
+    "jurisdiction",
+    "project_type",
+    "source_reference",
+    "source_date",
+    "effective_on",
+    "dataset_kind",
+    "filename",
+    "content_base64",
+    "sha256",
+    "materials",
+    "change_note"
+  ],
+  "title": "RequirementBundle"
+}
+
+
ResponseLetterCreate
+{
+  "properties": {
+    "template_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Template Id"
+    }
+  },
+  "type": "object",
+  "title": "ResponseLetterCreate"
+}
+
+
ResponseLetterRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "template_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Template Id"
+    },
+    "generated_content": {
+      "type": "string",
+      "title": "Generated Content"
+    },
+    "edited_content": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Edited Content"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "generated_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Generated By"
+    },
+    "approved_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Approved By"
+    },
+    "sent_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sent At"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "template_id",
+    "generated_content",
+    "edited_content",
+    "status",
+    "generated_by",
+    "approved_by",
+    "sent_at",
+    "created_at"
+  ],
+  "title": "ResponseLetterRead"
+}
+
+
ResponseLetterUpdate
+{
+  "properties": {
+    "edited_content": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Edited Content"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Status"
+    }
+  },
+  "type": "object",
+  "title": "ResponseLetterUpdate"
+}
+
+
ReviewInput
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 5000,
+      "title": "Body",
+      "default": ""
+    },
+    "hasAltText": {
+      "type": "boolean",
+      "title": "Hasalttext",
+      "default": false
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": "en"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "ReviewInput"
+}
+
+
Revision
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    },
+    "document": {
+      "$ref": "#/components/schemas/NoticeDraft"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence",
+    "document"
+  ],
+  "title": "Revision"
+}
+
+
RewriteInput
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "plain-language",
+        "language-variant"
+      ],
+      "title": "Action"
+    },
+    "text": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Text"
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "text"
+  ],
+  "title": "RewriteInput"
+}
+
+
RewriteResult
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "plain-language",
+        "language-variant"
+      ],
+      "title": "Action"
+    },
+    "text": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Text"
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": ""
+    },
+    "outcome": {
+      "type": "string",
+      "enum": [
+        "generated",
+        "unavailable"
+      ],
+      "title": "Outcome"
+    },
+    "generated": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 100000
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Generated"
+    },
+    "model": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 200
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "text",
+    "outcome"
+  ],
+  "title": "RewriteResult"
+}
+
+
Rule
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "zone_code": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Zone Code"
+    },
+    "key": {
+      "type": "string",
+      "maxLength": 120,
+      "minLength": 1,
+      "title": "Key"
+    },
+    "section_number": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Section Number"
+    },
+    "kind": {
+      "type": "string",
+      "enum": [
+        "use",
+        "dimension"
+      ],
+      "title": "Kind"
+    },
+    "value": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Value"
+    },
+    "overlay_code": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 255
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Overlay Code"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "zone_code",
+    "key",
+    "section_number",
+    "kind",
+    "value"
+  ],
+  "title": "Rule"
+}
+
+
RuleTestMatch
+{
+  "properties": {
+    "matched_text": {
+      "type": "string",
+      "title": "Matched Text"
+    },
+    "start": {
+      "type": "integer",
+      "title": "Start"
+    },
+    "end": {
+      "type": "integer",
+      "title": "End"
+    }
+  },
+  "type": "object",
+  "required": [
+    "matched_text",
+    "start",
+    "end"
+  ],
+  "title": "RuleTestMatch"
+}
+
+
RuleTestRequest
+{
+  "properties": {
+    "sample_text": {
+      "type": "string",
+      "title": "Sample Text"
+    }
+  },
+  "type": "object",
+  "required": [
+    "sample_text"
+  ],
+  "title": "RuleTestRequest"
+}
+
+
RuleTestResponse
+{
+  "properties": {
+    "rule_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Rule Id"
+    },
+    "rule_type": {
+      "type": "string",
+      "title": "Rule Type"
+    },
+    "matched": {
+      "type": "boolean",
+      "title": "Matched"
+    },
+    "matches": {
+      "items": {
+        "$ref": "#/components/schemas/RuleTestMatch"
+      },
+      "type": "array",
+      "title": "Matches"
+    }
+  },
+  "type": "object",
+  "required": [
+    "rule_id",
+    "rule_type",
+    "matched",
+    "matches"
+  ],
+  "title": "RuleTestResponse"
+}
+
+
RuleType
+{
+  "type": "string",
+  "enum": [
+    "regex",
+    "keyword",
+    "llm_prompt"
+  ],
+  "title": "RuleType"
+}
+
+
SaveReview
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 5000,
+      "title": "Body",
+      "default": ""
+    },
+    "hasAltText": {
+      "type": "boolean",
+      "title": "Hasalttext",
+      "default": false
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": "en"
+    },
+    "ai_analysis": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 100000
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ai Analysis"
+    },
+    "ai_analysis_model": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 200
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ai Analysis Model"
+    },
+    "ai_outcome": {
+      "type": "string",
+      "enum": [
+        "generated",
+        "unavailable",
+        "failed"
+      ],
+      "title": "Ai Outcome"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "ai_outcome"
+  ],
+  "title": "SaveReview"
+}
+
+
SearchFilterOptions
+{
+  "properties": {
+    "file_types": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "File Types"
+    },
+    "source_names": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Source Names"
+    },
+    "departments": {
+      "items": {
+        "additionalProperties": true,
+        "type": "object"
+      },
+      "type": "array",
+      "title": "Departments",
+      "default": []
+    },
+    "date_range": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Date Range"
+    }
+  },
+  "type": "object",
+  "required": [
+    "file_types",
+    "source_names"
+  ],
+  "title": "SearchFilterOptions"
+}
+
+
SearchInput
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "SearchInput"
+}
+
+
SearchNoteCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "record-records-search",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/SearchNotePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "SearchNoteCommand"
+}
+
+
SearchNotePayload
+{
+  "properties": {
+    "sourceNote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Sourcenote"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sourceNote"
+  ],
+  "title": "SearchNotePayload"
+}
+
+
SearchReceiptCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "record-records-search-session",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/SearchReceiptPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "SearchReceiptCommand"
+}
+
+
SearchReceiptPayload
+{
+  "properties": {
+    "searchQuery": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchquery"
+    },
+    "searchLocations": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchlocations"
+    },
+    "searchResultTitle": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchresulttitle"
+    },
+    "searchResultCitation": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchresultcitation"
+    },
+    "searchResultSummary": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchresultsummary"
+    },
+    "searchResultStatus": {
+      "type": "string",
+      "title": "Searchresultstatus",
+      "default": ""
+    },
+    "searchReviewer": {
+      "type": "string",
+      "title": "Searchreviewer",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "searchQuery",
+    "searchLocations",
+    "searchResultTitle",
+    "searchResultCitation",
+    "searchResultSummary"
+  ],
+  "title": "SearchReceiptPayload"
+}
+
+
SearchReceiptView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "query": {
+      "type": "string",
+      "title": "Query"
+    },
+    "locations": {
+      "type": "string",
+      "title": "Locations"
+    },
+    "reviewer": {
+      "type": "string",
+      "title": "Reviewer"
+    },
+    "results": {
+      "items": {
+        "$ref": "#/components/schemas/SearchResultView"
+      },
+      "type": "array",
+      "title": "Results"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "query",
+    "locations",
+    "reviewer",
+    "results",
+    "created_at_unix_seconds"
+  ],
+  "title": "SearchReceiptView"
+}
+
+
SearchRequest
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "title": "Query"
+    },
+    "session_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Session Id"
+    },
+    "filters": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Filters"
+    },
+    "limit": {
+      "type": "integer",
+      "maximum": 50.0,
+      "title": "Limit",
+      "default": 10
+    },
+    "synthesize": {
+      "type": "boolean",
+      "title": "Synthesize",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "SearchRequest"
+}
+
+
SearchResponse
+{
+  "properties": {
+    "query_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Query Id"
+    },
+    "session_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Session Id"
+    },
+    "query_text": {
+      "type": "string",
+      "title": "Query Text"
+    },
+    "results": {
+      "items": {
+        "$ref": "#/components/schemas/SearchResultItem"
+      },
+      "type": "array",
+      "title": "Results"
+    },
+    "results_count": {
+      "type": "integer",
+      "title": "Results Count"
+    },
+    "synthesized_answer": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Synthesized Answer"
+    },
+    "ai_generated": {
+      "type": "boolean",
+      "title": "Ai Generated",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "query_id",
+    "session_id",
+    "query_text",
+    "results",
+    "results_count"
+  ],
+  "title": "SearchResponse"
+}
+
+
SearchResultItem
+{
+  "properties": {
+    "chunk_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Chunk Id"
+    },
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "filename": {
+      "type": "string",
+      "title": "Filename"
+    },
+    "file_type": {
+      "type": "string",
+      "title": "File Type"
+    },
+    "source_path": {
+      "type": "string",
+      "title": "Source Path"
+    },
+    "page_number": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Page Number"
+    },
+    "content_text": {
+      "type": "string",
+      "title": "Content Text"
+    },
+    "similarity_score": {
+      "type": "number",
+      "title": "Similarity Score"
+    },
+    "rank": {
+      "type": "integer",
+      "title": "Rank"
+    }
+  },
+  "type": "object",
+  "required": [
+    "chunk_id",
+    "document_id",
+    "filename",
+    "file_type",
+    "source_path",
+    "page_number",
+    "content_text",
+    "similarity_score",
+    "rank"
+  ],
+  "title": "SearchResultItem"
+}
+
+
SearchResultView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "title": {
+      "type": "string",
+      "title": "Title"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "title",
+    "citation",
+    "summary",
+    "status"
+  ],
+  "title": "SearchResultView"
+}
+
+
SearchSessionRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "user_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "User Id"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "queries": {
+      "items": {
+        "additionalProperties": true,
+        "type": "object"
+      },
+      "type": "array",
+      "title": "Queries",
+      "default": []
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "user_id",
+    "created_at"
+  ],
+  "title": "SearchSessionRead"
+}
+
+
SectionCreate
+{
+  "properties": {
+    "section_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Section Id"
+    },
+    "chapter_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Chapter Id"
+    },
+    "section_number": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Number"
+    },
+    "section_heading": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Heading"
+    },
+    "parent_section_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parent Section Id"
+    },
+    "sort_order": {
+      "type": "integer",
+      "title": "Sort Order",
+      "default": 0
+    },
+    "administrative_regulation_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Administrative Regulation Refs"
+    },
+    "resolution_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Resolution Refs"
+    },
+    "policy_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Policy Refs"
+    },
+    "approved_summary_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Approved Summary Refs"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "chapter_id",
+    "section_number",
+    "section_heading"
+  ],
+  "title": "SectionCreate",
+  "description": "Request body for creating a code section or subsection."
+}
+
+
SectionVersionCreate
+{
+  "properties": {
+    "version_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Version Id"
+    },
+    "section_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Id"
+    },
+    "source_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "version_label": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Version Label"
+    },
+    "body": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Body"
+    },
+    "effective_start": {
+      "type": "string",
+      "format": "date",
+      "title": "Effective Start"
+    },
+    "effective_end": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective End"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    },
+    "is_current": {
+      "type": "boolean",
+      "title": "Is Current",
+      "default": false
+    },
+    "adoption_event_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Adoption Event Id"
+    },
+    "amendment_event_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Amendment Event Id"
+    },
+    "amendment_summary": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Amendment Summary"
+    },
+    "prior_version_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Prior Version Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "section_id",
+    "source_id",
+    "version_label",
+    "body",
+    "effective_start"
+  ],
+  "title": "SectionVersionCreate",
+  "description": "Request body for adding an immutable section version."
+}
+
+
Selection
+{
+  "properties": {
+    "recording_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Recording Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "recording_id",
+    "expected_sha256"
+  ],
+  "title": "Selection"
+}
+
+
SentenceInput
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "citations": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Citations"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text"
+  ],
+  "title": "SentenceInput"
+}
+
+
ServiceAccountCreate
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole",
+      "default": "read_only"
+    }
+  },
+  "type": "object",
+  "required": [
+    "name"
+  ],
+  "title": "ServiceAccountCreate"
+}
+
+
ServiceAccountCreated
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "api_key": {
+      "type": "string",
+      "title": "Api Key"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "role",
+    "created_by",
+    "created_at",
+    "is_active",
+    "api_key"
+  ],
+  "title": "ServiceAccountCreated",
+  "description": "Returned only on creation — includes the plaintext API key (shown once)."
+}
+
+
ServiceAccountRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "role",
+    "created_by",
+    "created_at",
+    "is_active"
+  ],
+  "title": "ServiceAccountRead"
+}
+
+
ServiceAccountUpdate
+{
+  "properties": {
+    "role": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/UserRole"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "ServiceAccountUpdate"
+}
+
+
Snapshot
+{
+  "properties": {
+    "expected_revision": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Expected Revision"
+    },
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "staff_only",
+        "public"
+      ],
+      "title": "Visibility"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "expected_revision",
+    "visibility"
+  ],
+  "title": "Snapshot"
+}
+
+
SourceCreate
+{
+  "properties": {
+    "source_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Id"
+    },
+    "name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Name"
+    },
+    "publisher": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Publisher"
+    },
+    "source_type": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Type"
+    },
+    "source_category": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Category"
+    },
+    "source_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Url"
+    },
+    "file_reference": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "File Reference"
+    },
+    "retrieved_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Retrieved At"
+    },
+    "retrieval_method": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Retrieval Method"
+    },
+    "checksum": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Checksum"
+    },
+    "source_owner": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Owner"
+    },
+    "is_official": {
+      "type": "boolean",
+      "title": "Is Official",
+      "default": true
+    },
+    "official_status_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Official Status Note"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    },
+    "staff_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Staff Notes"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "name",
+    "publisher",
+    "source_type",
+    "source_category"
+  ],
+  "title": "SourceCreate",
+  "description": "Request body for registering an official or explicitly labeled source."
+}
+
+
SourceInput
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "label": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Label"
+    },
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "label",
+    "text"
+  ],
+  "title": "SourceInput"
+}
+
+
SourceSnapshot
+{
+  "properties": {
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "public",
+        "staff_only"
+      ],
+      "title": "Visibility"
+    },
+    "meeting_event_ids": {
+      "items": {
+        "type": "string",
+        "format": "uuid"
+      },
+      "type": "array",
+      "maxItems": 50,
+      "title": "Meeting Event Ids"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "visibility"
+  ],
+  "title": "SourceSnapshot"
+}
+
+
SourceType
+{
+  "type": "string",
+  "enum": [
+    "manual_drop",
+    "file_system",
+    "rest_api",
+    "odbc"
+  ],
+  "title": "SourceType"
+}
+
+
StaffRecordsIntake
+{
+  "properties": {
+    "requester": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requester"
+    },
+    "summary": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Summary"
+    },
+    "deadline": {
+      "type": "string",
+      "title": "Deadline"
+    },
+    "deadlineBasis": {
+      "type": "string",
+      "title": "Deadlinebasis",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requester",
+    "summary",
+    "deadline"
+  ],
+  "title": "StaffRecordsIntake",
+  "description": "Existing native create-records-request input; no caller-supplied actor."
+}
+
+
StandardsExplanation
+{
+  "properties": {
+    "question": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Question"
+    },
+    "process_section": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Process Section",
+      "default": ""
+    },
+    "zone_code": {
+      "type": "string",
+      "maxLength": 40,
+      "title": "Zone Code",
+      "default": ""
+    },
+    "rule_types": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "title": "Rule Types"
+    },
+    "observed": {
+      "additionalProperties": {
+        "type": "string"
+      },
+      "type": "object",
+      "title": "Observed"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "question"
+  ],
+  "title": "StandardsExplanation"
+}
+
+
SyncFailureRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "source_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Source Id"
+    },
+    "source_path": {
+      "type": "string",
+      "title": "Source Path"
+    },
+    "error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Message"
+    },
+    "error_class": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Class"
+    },
+    "http_status_code": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Http Status Code"
+    },
+    "retry_count": {
+      "type": "integer",
+      "title": "Retry Count"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "first_failed_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "First Failed At"
+    },
+    "last_retried_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Retried At"
+    },
+    "dismissed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Dismissed At"
+    },
+    "dismissed_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Dismissed By"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "source_id",
+    "source_path",
+    "error_message",
+    "error_class",
+    "http_status_code",
+    "retry_count",
+    "status",
+    "first_failed_at",
+    "last_retried_at",
+    "dismissed_at",
+    "dismissed_by"
+  ],
+  "title": "SyncFailureRead"
+}
+
+
SyncRunLogRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "source_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Source Id"
+    },
+    "started_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Started At"
+    },
+    "finished_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Finished At"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Status"
+    },
+    "records_attempted": {
+      "type": "integer",
+      "title": "Records Attempted"
+    },
+    "records_succeeded": {
+      "type": "integer",
+      "title": "Records Succeeded"
+    },
+    "records_failed": {
+      "type": "integer",
+      "title": "Records Failed"
+    },
+    "error_summary": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Summary"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "source_id",
+    "started_at",
+    "finished_at",
+    "status",
+    "records_attempted",
+    "records_succeeded",
+    "records_failed",
+    "error_summary"
+  ],
+  "title": "SyncRunLogRead"
+}
+
+
SystemStatus
+{
+  "properties": {
+    "version": {
+      "type": "string",
+      "title": "Version"
+    },
+    "database": {
+      "type": "string",
+      "title": "Database"
+    },
+    "ollama": {
+      "type": "string",
+      "title": "Ollama"
+    },
+    "redis": {
+      "type": "string",
+      "title": "Redis"
+    },
+    "user_count": {
+      "type": "integer",
+      "title": "User Count"
+    },
+    "audit_log_count": {
+      "type": "integer",
+      "title": "Audit Log Count"
+    },
+    "suite_session": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Suite Session"
+    }
+  },
+  "type": "object",
+  "required": [
+    "version",
+    "database",
+    "ollama",
+    "redis",
+    "user_count",
+    "audit_log_count"
+  ],
+  "title": "SystemStatus"
+}
+
+
TaggedPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "tagged-pdf",
+      "title": "Action"
+    },
+    "headingLevels": {
+      "items": {
+        "type": "integer",
+        "maximum": 4294967295.0,
+        "minimum": 0.0
+      },
+      "type": "array",
+      "maxItems": 50,
+      "title": "Headinglevels"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "TaggedPlan"
+}
+
+
TestConnectionRequest
+{
+  "properties": {
+    "source_type": {
+      "type": "string",
+      "title": "Source Type"
+    },
+    "host": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Host"
+    },
+    "port": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Port"
+    },
+    "path": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Path"
+    },
+    "username": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Username"
+    },
+    "password": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Password"
+    },
+    "rest_api_config": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Rest Api Config"
+    },
+    "odbc_config": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Odbc Config"
+    }
+  },
+  "type": "object",
+  "required": [
+    "source_type"
+  ],
+  "title": "TestConnectionRequest",
+  "description": "Dedicated schema for test-connection. NOT the create schema.\n\nSecurity: credentials in this request body are never persisted, never\nwritten to audit logs, and never returned in the response."
+}
+
+
TestConnectionResponse
+{
+  "properties": {
+    "success": {
+      "type": "boolean",
+      "title": "Success"
+    },
+    "message": {
+      "type": "string",
+      "title": "Message"
+    },
+    "latency_ms": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Latency Ms"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Status"
+    },
+    "warning": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Warning"
+    },
+    "differing_keys": {
+      "anyOf": [
+        {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Differing Keys"
+    }
+  },
+  "type": "object",
+  "required": [
+    "success",
+    "message"
+  ],
+  "title": "TestConnectionResponse"
+}
+
+
TimelineEventCreate
+{
+  "properties": {
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "internal_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Internal Note"
+    }
+  },
+  "type": "object",
+  "required": [
+    "event_type",
+    "description"
+  ],
+  "title": "TimelineEventCreate"
+}
+
+
TimelineEventRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "actor_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Actor Id"
+    },
+    "actor_role": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Actor Role"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "internal_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Internal Note"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "event_type",
+    "actor_id",
+    "actor_role",
+    "description",
+    "internal_note",
+    "created_at"
+  ],
+  "title": "TimelineEventRead"
+}
+
+
TimelineView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "actor": {
+      "type": "string",
+      "title": "Actor"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "action",
+    "actor",
+    "note",
+    "created_at_unix_seconds"
+  ],
+  "title": "TimelineView"
+}
+
+
TitleCreate
+{
+  "properties": {
+    "title_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Title Id"
+    },
+    "title_number": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title Number"
+    },
+    "title_name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title Name"
+    },
+    "sort_order": {
+      "type": "integer",
+      "title": "Sort Order",
+      "default": 0
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title_number",
+    "title_name"
+  ],
+  "title": "TitleCreate",
+  "description": "Request body for creating a code title."
+}
+
+
TranscriptInput
+{
+  "properties": {
+    "source_label": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Label"
+    },
+    "transcript_text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Transcript Text"
+    },
+    "correction_of_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Correction Of Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_label",
+    "transcript_text"
+  ],
+  "title": "TranscriptInput"
+}
+
+
UserRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "email": {
+      "type": "string",
+      "format": "email",
+      "title": "Email"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active",
+      "default": true
+    },
+    "is_superuser": {
+      "type": "boolean",
+      "title": "Is Superuser",
+      "default": false
+    },
+    "is_verified": {
+      "type": "boolean",
+      "title": "Is Verified",
+      "default": false
+    },
+    "full_name": {
+      "type": "string",
+      "title": "Full Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "last_login": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Login"
+    },
+    "must_change_password": {
+      "type": "boolean",
+      "title": "Must Change Password",
+      "default": false
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "email",
+    "full_name",
+    "role",
+    "created_at",
+    "last_login"
+  ],
+  "title": "UserRead"
+}
+
+
UserRole
+{
+  "type": "string",
+  "enum": [
+    "admin",
+    "staff",
+    "reviewer",
+    "read_only",
+    "liaison",
+    "public"
+  ],
+  "title": "UserRole"
+}
+
+
UserSelfUpdate
+{
+  "properties": {
+    "password": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Password"
+    },
+    "email": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "email"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    },
+    "is_superuser": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Superuser"
+    },
+    "is_verified": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Verified"
+    },
+    "full_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Full Name"
+    }
+  },
+  "type": "object",
+  "title": "UserSelfUpdate",
+  "description": "Schema for user self-update via PATCH /users/me.\n\nExcludes role and department_id. Any payload containing those fields is\nrejected at parse time (HTTP 422). Role and department changes require\nadmin privileges via /admin/users/{id}."
+}
+
+
UserUpdateRequest
+{
+  "properties": {
+    "full_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Full Name"
+    },
+    "role": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Role"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "UserUpdateRequest"
+}
+
+
ValidationError
+{
+  "properties": {
+    "loc": {
+      "items": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "integer"
+          }
+        ]
+      },
+      "type": "array",
+      "title": "Location"
+    },
+    "msg": {
+      "type": "string",
+      "title": "Message"
+    },
+    "type": {
+      "type": "string",
+      "title": "Error Type"
+    },
+    "input": {
+      "title": "Input"
+    },
+    "ctx": {
+      "type": "object",
+      "title": "Context"
+    }
+  },
+  "type": "object",
+  "required": [
+    "loc",
+    "msg",
+    "type"
+  ],
+  "title": "ValidationError"
+}
+
+
Version
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence"
+  ],
+  "title": "Version"
+}
+
+
VoteCorrection
+{
+  "properties": {
+    "vote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Vote"
+    },
+    "reason": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Reason"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "vote",
+    "reason"
+  ],
+  "title": "VoteCorrection"
+}
+
+
VoteInput
+{
+  "properties": {
+    "voter_name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Voter Name"
+    },
+    "vote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Vote"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "voter_name",
+    "vote"
+  ],
+  "title": "VoteInput"
+}
+
+
_ParcelLookupIn
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "query"
+  ],
+  "title": "_ParcelLookupIn"
+}
+
+
townlight_inspections__workflow_models__SourceLink
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "const": "code",
+      "title": "Provider",
+      "default": "code"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "SourceLink"
+}
+
+
townlight_permitting__workflow_models__SourceLink
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "enum": [
+        "code",
+        "zoning"
+      ],
+      "title": "Provider"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "SourceLink"
+}
+
+
townlight_runtime__inspections_bridge__Search
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "const": "code",
+      "title": "Provider"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "query"
+  ],
+  "title": "Search"
+}
+
+
townlight_runtime__notice_bridge__Review
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence",
+    "note"
+  ],
+  "title": "Review"
+}
+
+
townlight_runtime__permitting_bridge__Import
+{
+  "properties": {
+    "bundle": {
+      "$ref": "#/components/schemas/RequirementBundle"
+    },
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "bundle"
+  ],
+  "title": "Import"
+}
+
+
townlight_runtime__permitting_bridge__Search
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "enum": [
+        "code",
+        "zoning"
+      ],
+      "title": "Provider"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "query"
+  ],
+  "title": "Search"
+}
+
+
townlight_runtime__planning_bridge__Import
+{
+  "properties": {
+    "bundle": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Bundle"
+    },
+    "expected_previous_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Previous Revision"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "bundle"
+  ],
+  "title": "Import"
+}
+
+
townlight_runtime__planning_bridge__Search
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Query"
+    },
+    "plan_type": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 40
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Plan Type"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "Search"
+}
+
+
townlight_runtime__zoning_bridge__Review
+{
+  "properties": {
+    "answer": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Answer",
+      "default": ""
+    },
+    "notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Notes",
+      "default": ""
+    },
+    "queue_status": {
+      "type": "string",
+      "enum": [
+        "open",
+        "in_review",
+        "resolved",
+        "closed"
+      ],
+      "title": "Queue Status",
+      "default": "resolved"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "Review"
+}
+
+

Separate Station service

The native operations above are the suite authority boundary. Station runs its own service and database. Its unchanged 0.3.0 service contract is available in the separate Station service schema. Schema reuse does not establish the changed suite candidate’s installed handoff acceptance.

Townlight · AGPL-3.0-only · Source schema evidence only
\ No newline at end of file diff --git a/docs/beta-1/api/suite-openapi.json b/docs/beta-1/api/suite-openapi.json new file mode 100644 index 0000000..b7ebbe2 --- /dev/null +++ b/docs/beta-1/api/suite-openapi.json @@ -0,0 +1,27254 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "Townlight Records", + "description": "Prepared source schema for the actual native composition; installed acceptance remains pending. Exported without lifespan, migrations or database/network access.", + "version": "1.8.0.dev2" + }, + "paths": { + "/auth/jwt/login": { + "post": { + "tags": [ + "auth" + ], + "summary": "Auth:Jwt.Login", + "operationId": "auth_jwt_login_auth_jwt_login_post", + "requestBody": { + "content": { + "application/x-www-form-urlencoded": { + "schema": { + "$ref": "#/components/schemas/Body_auth_jwt_login_auth_jwt_login_post" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BearerResponse" + }, + "example": { + "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiOTIyMWZmYzktNjQwZi00MzcyLTg2ZDMtY2U2NDJjYmE1NjAzIiwiYXVkIjoiZmFzdGFwaS11c2VyczphdXRoIiwiZXhwIjoxNTcxNTA0MTkzfQ.M10bjOe45I5Ncu_uXvOmVV8QxnL-nZfcH96U90JaocI", + "token_type": "bearer" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorModel" + }, + "examples": { + "LOGIN_BAD_CREDENTIALS": { + "summary": "Bad credentials or the user is inactive.", + "value": { + "detail": "LOGIN_BAD_CREDENTIALS" + } + }, + "LOGIN_USER_NOT_VERIFIED": { + "summary": "The user is not verified.", + "value": { + "detail": "LOGIN_USER_NOT_VERIFIED" + } + } + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/auth/jwt/logout": { + "post": { + "tags": [ + "auth" + ], + "summary": "Auth:Jwt.Logout", + "operationId": "auth_jwt_logout_auth_jwt_logout_post", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "401": { + "description": "Missing token or inactive user." + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/users/me": { + "get": { + "tags": [ + "users" + ], + "summary": "Users:Current User", + "operationId": "users_current_user_users_me_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserRead" + } + } + } + }, + "401": { + "description": "Missing token or inactive user." + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + }, + "patch": { + "tags": [ + "users" + ], + "summary": "Users:Patch Current User", + "operationId": "users_patch_current_user_users_me_patch", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserSelfUpdate" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserRead" + } + } + } + }, + "401": { + "description": "Missing token or inactive user." + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorModel" + }, + "examples": { + "UPDATE_USER_EMAIL_ALREADY_EXISTS": { + "summary": "A user with this email already exists.", + "value": { + "detail": "UPDATE_USER_EMAIL_ALREADY_EXISTS" + } + }, + "UPDATE_USER_INVALID_PASSWORD": { + "summary": "Password validation failed.", + "value": { + "detail": { + "code": "UPDATE_USER_INVALID_PASSWORD", + "reason": "Password should beat least 3 characters" + } + } + } + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/users/{id}": { + "get": { + "tags": [ + "users" + ], + "summary": "Users:User", + "operationId": "users_user_users__id__get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserRead" + } + } + } + }, + "401": { + "description": "Missing token or inactive user." + }, + "403": { + "description": "Not a superuser." + }, + "404": { + "description": "The user does not exist." + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "patch": { + "tags": [ + "users" + ], + "summary": "Users:Patch User", + "operationId": "users_patch_user_users__id__patch", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserSelfUpdate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserRead" + } + } + } + }, + "401": { + "description": "Missing token or inactive user." + }, + "403": { + "description": "Not a superuser." + }, + "404": { + "description": "The user does not exist." + }, + "400": { + "content": { + "application/json": { + "examples": { + "UPDATE_USER_EMAIL_ALREADY_EXISTS": { + "summary": "A user with this email already exists.", + "value": { + "detail": "UPDATE_USER_EMAIL_ALREADY_EXISTS" + } + }, + "UPDATE_USER_INVALID_PASSWORD": { + "summary": "Password validation failed.", + "value": { + "detail": { + "code": "UPDATE_USER_INVALID_PASSWORD", + "reason": "Password should beat least 3 characters" + } + } + } + }, + "schema": { + "$ref": "#/components/schemas/ErrorModel" + } + } + }, + "description": "Bad Request" + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "delete": { + "tags": [ + "users" + ], + "summary": "Users:Delete User", + "operationId": "users_delete_user_users__id__delete", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Id" + } + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "401": { + "description": "Missing token or inactive user." + }, + "403": { + "description": "Not a superuser." + }, + "404": { + "description": "The user does not exist." + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/config/portal-mode": { + "get": { + "tags": [ + "public" + ], + "summary": "Get the deployment's current portal posture.", + "operationId": "get_portal_mode_config_portal_mode_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PortalModeResponse" + } + } + } + } + } + } + }, + "/audit/logs": { + "get": { + "tags": [ + "audit" + ], + "summary": "List Audit Logs", + "operationId": "list_audit_logs_audit_logs_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "action", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Action" + } + }, + { + "name": "resource_type", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Resource Type" + } + }, + { + "name": "user_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "User Id" + } + }, + { + "name": "start_date", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Start Date" + } + }, + { + "name": "end_date", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "End Date" + } + }, + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 200, + "default": 50, + "title": "Limit" + } + }, + { + "name": "offset", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "default": 0, + "title": "Offset" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AuditLogRead" + }, + "title": "Response List Audit Logs Audit Logs Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/audit/verify": { + "get": { + "tags": [ + "audit" + ], + "summary": "Verify Audit Chain", + "operationId": "verify_audit_chain_audit_verify_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuditChainVerification" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/audit/export": { + "get": { + "tags": [ + "audit" + ], + "summary": "Export Audit Logs", + "operationId": "export_audit_logs_audit_export_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "format", + "in": "query", + "required": false, + "schema": { + "type": "string", + "default": "json", + "title": "Format" + } + }, + { + "name": "start_date", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Start Date" + } + }, + { + "name": "end_date", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "End Date" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/service-accounts/": { + "get": { + "tags": [ + "service-accounts" + ], + "summary": "List Service Accounts", + "operationId": "list_service_accounts_service_accounts__get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/ServiceAccountRead" + }, + "type": "array", + "title": "Response List Service Accounts Service Accounts Get" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + }, + "post": { + "tags": [ + "service-accounts" + ], + "summary": "Create Service Account", + "operationId": "create_service_account_service_accounts__post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceAccountCreate" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceAccountCreated" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/service-accounts/{account_id}": { + "patch": { + "tags": [ + "service-accounts" + ], + "summary": "Update Service Account", + "operationId": "update_service_account_service_accounts__account_id__patch", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "account_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Account Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceAccountUpdate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceAccountRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/admin/status": { + "get": { + "tags": [ + "admin" + ], + "summary": "System Status", + "operationId": "system_status_admin_status_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SystemStatus" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/admin/users": { + "get": { + "tags": [ + "admin" + ], + "summary": "List Users", + "description": "List all users. Admin only.", + "operationId": "list_users_admin_users_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/UserRead" + }, + "type": "array", + "title": "Response List Users Admin Users Get" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + }, + "post": { + "tags": [ + "admin" + ], + "summary": "Create User", + "description": "Create a new user. Admin only.", + "operationId": "create_user_admin_users_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AdminUserCreateRequest" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AdminUserCreateResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/admin/users/{user_id}": { + "patch": { + "tags": [ + "admin" + ], + "summary": "Update User", + "description": "Update user fields. Admin only.\n\nGuards against self-demotion: admins cannot change their own role.", + "operationId": "update_user_admin_users__user_id__patch", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "user_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "User Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserUpdateRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AdminUserCreateResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/admin/models": { + "get": { + "tags": [ + "admin" + ], + "summary": "List Models", + "operationId": "list_models_admin_models_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OllamaStatus" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/admin/models/registry": { + "get": { + "tags": [ + "admin" + ], + "summary": "List Model Registry", + "operationId": "list_model_registry_admin_models_registry_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/ModelRegistryRead" + }, + "type": "array", + "title": "Response List Model Registry Admin Models Registry Get" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + }, + "post": { + "tags": [ + "admin" + ], + "summary": "Register Model", + "operationId": "register_model_admin_models_registry_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ModelRegistryCreate" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ModelRegistryRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/admin/models/registry/{model_id}": { + "patch": { + "tags": [ + "admin" + ], + "summary": "Update Model Registry", + "operationId": "update_model_registry_admin_models_registry__model_id__patch", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "model_id", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "title": "Model Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ModelRegistryUpdate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ModelRegistryRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "delete": { + "tags": [ + "admin" + ], + "summary": "Delete Model Registry", + "operationId": "delete_model_registry_admin_models_registry__model_id__delete", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "model_id", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "title": "Model Id" + } + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/admin/fee-schedules": { + "get": { + "tags": [ + "admin" + ], + "summary": "List Fee Schedules", + "description": "List all fee schedules. Admin only.", + "operationId": "list_fee_schedules_admin_fee_schedules_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "jurisdiction", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Jurisdiction" + } + }, + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "default": 50, + "title": "Limit" + } + }, + { + "name": "offset", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "default": 0, + "title": "Offset" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FeeScheduleRead" + }, + "title": "Response List Fee Schedules Admin Fee Schedules Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "tags": [ + "admin" + ], + "summary": "Create Fee Schedule", + "description": "Create a new fee schedule. Admin only.", + "operationId": "create_fee_schedule_admin_fee_schedules_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FeeScheduleCreate" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FeeScheduleRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/admin/fee-schedules/{schedule_id}": { + "patch": { + "tags": [ + "admin" + ], + "summary": "Update Fee Schedule", + "description": "Update a fee schedule. Admin only.", + "operationId": "update_fee_schedule_admin_fee_schedules__schedule_id__patch", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "schedule_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Schedule Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FeeScheduleUpdate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FeeScheduleRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "delete": { + "tags": [ + "admin" + ], + "summary": "Delete Fee Schedule", + "description": "Delete a fee schedule. Admin only.", + "operationId": "delete_fee_schedule_admin_fee_schedules__schedule_id__delete", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "schedule_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Schedule Id" + } + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/admin/coverage-gaps": { + "get": { + "tags": [ + "admin" + ], + "summary": "Get Coverage Gaps", + "description": "Identify coverage gaps across jurisdictions, departments, and exemption categories.\n\nReturns:\n- Jurisdictions (state codes) that have no exemption rules\n- Departments with no assigned staff users\n- Exemption categories without any active rules", + "operationId": "get_coverage_gaps_admin_coverage_gaps_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CoverageGapResponse" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/datasources/": { + "get": { + "tags": [ + "datasources" + ], + "summary": "List Datasources", + "operationId": "list_datasources_datasources__get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/DataSourceRead" + }, + "type": "array", + "title": "Response List Datasources Datasources Get" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + }, + "post": { + "tags": [ + "datasources" + ], + "summary": "Create Datasource", + "operationId": "create_datasource_datasources__post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataSourceCreate" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataSourceAdminRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/datasources/{source_id}": { + "patch": { + "tags": [ + "datasources" + ], + "summary": "Update Datasource", + "operationId": "update_datasource_datasources__source_id__patch", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "source_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Source Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataSourceUpdate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DataSourceAdminRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/datasources/{source_id}/ingest": { + "post": { + "tags": [ + "datasources" + ], + "summary": "Trigger Ingestion", + "operationId": "trigger_ingestion_datasources__source_id__ingest_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "source_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Source Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/datasources/upload": { + "post": { + "tags": [ + "datasources" + ], + "summary": "Upload File", + "operationId": "upload_file_datasources_upload_post", + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "$ref": "#/components/schemas/Body_upload_file_datasources_upload_post" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/datasources/documents/{document_id}/re-ingest": { + "post": { + "tags": [ + "datasources" + ], + "summary": "Re Ingest Document", + "description": "Re-ingest a failed document. Resets status to pending and queues for processing.", + "operationId": "re_ingest_document_datasources_documents__document_id__re_ingest_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "document_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Document Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/datasources/stats": { + "get": { + "tags": [ + "datasources" + ], + "summary": "Ingestion Stats", + "operationId": "ingestion_stats_datasources_stats_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IngestionStats" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/datasources/test-connection": { + "post": { + "tags": [ + "datasources" + ], + "summary": "Test Connection", + "description": "Test connectivity to a data source without persisting anything.\n\nThis endpoint validates the connection parameters and attempts a test\nconnection. Credentials are NOT persisted, NOT logged, and NOT returned.", + "operationId": "test_connection_datasources_test_connection_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TestConnectionRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TestConnectionResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/documents/": { + "get": { + "tags": [ + "documents" + ], + "summary": "List Documents", + "operationId": "list_documents_documents__get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "source_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Source Id" + } + }, + { + "name": "status", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/IngestionStatus" + }, + { + "type": "null" + } + ], + "title": "Status" + } + }, + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 500, + "default": 50, + "title": "Limit" + } + }, + { + "name": "offset", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "default": 0, + "title": "Offset" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DocumentRead" + }, + "title": "Response List Documents Documents Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/documents/{document_id}": { + "get": { + "tags": [ + "documents" + ], + "summary": "Get Document", + "operationId": "get_document_documents__document_id__get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "document_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Document Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DocumentRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/documents/{document_id}/chunks": { + "get": { + "tags": [ + "documents" + ], + "summary": "List Chunks", + "operationId": "list_chunks_documents__document_id__chunks_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "document_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Document Id" + } + }, + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 500, + "default": 50, + "title": "Limit" + } + }, + { + "name": "offset", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "default": 0, + "title": "Offset" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DocumentChunkRead" + }, + "title": "Response List Chunks Documents Document Id Chunks Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/datasources/{source_id}/sync-failures": { + "get": { + "tags": [ + "sync-failures" + ], + "summary": "List Sync Failures", + "operationId": "list_sync_failures_datasources__source_id__sync_failures_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "source_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Source Id" + } + }, + { + "name": "status", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Filter by status", + "title": "Status" + }, + "description": "Filter by status" + }, + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 500, + "minimum": 1, + "default": 50, + "title": "Limit" + } + }, + { + "name": "offset", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "minimum": 0, + "default": 0, + "title": "Offset" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SyncFailureRead" + }, + "title": "Response List Sync Failures Datasources Source Id Sync Failures Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/datasources/{source_id}/sync-failures/{failure_id}/retry": { + "post": { + "tags": [ + "sync-failures" + ], + "summary": "Retry Sync Failure", + "operationId": "retry_sync_failure_datasources__source_id__sync_failures__failure_id__retry_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "source_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Source Id" + } + }, + { + "name": "failure_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Failure Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/datasources/{source_id}/sync-failures/{failure_id}/dismiss": { + "post": { + "tags": [ + "sync-failures" + ], + "summary": "Dismiss Sync Failure", + "operationId": "dismiss_sync_failure_datasources__source_id__sync_failures__failure_id__dismiss_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "source_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Source Id" + } + }, + { + "name": "failure_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Failure Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/datasources/{source_id}/sync-failures/retry-all": { + "post": { + "tags": [ + "sync-failures" + ], + "summary": "Retry All Sync Failures", + "operationId": "retry_all_sync_failures_datasources__source_id__sync_failures_retry_all_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "source_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Source Id" + } + }, + { + "name": "status", + "in": "query", + "required": true, + "schema": { + "type": "string", + "description": "Status to reset — required", + "title": "Status" + }, + "description": "Status to reset — required" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/datasources/{source_id}/sync-failures/dismiss-all": { + "post": { + "tags": [ + "sync-failures" + ], + "summary": "Dismiss All Sync Failures", + "operationId": "dismiss_all_sync_failures_datasources__source_id__sync_failures_dismiss_all_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "source_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Source Id" + } + }, + { + "name": "status", + "in": "query", + "required": true, + "schema": { + "type": "string", + "description": "Status to dismiss — required", + "title": "Status" + }, + "description": "Status to dismiss — required" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/datasources/{source_id}/unpause": { + "post": { + "tags": [ + "sync-failures" + ], + "summary": "Unpause Source", + "operationId": "unpause_source_datasources__source_id__unpause_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "source_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Source Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/datasources/{source_id}/sync-run-log": { + "get": { + "tags": [ + "sync-failures" + ], + "summary": "Get Sync Run Log", + "operationId": "get_sync_run_log_datasources__source_id__sync_run_log_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "source_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Source Id" + } + }, + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 100, + "minimum": 1, + "default": 20, + "title": "Limit" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SyncRunLogRead" + }, + "title": "Response Get Sync Run Log Datasources Source Id Sync Run Log Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/search/query": { + "post": { + "tags": [ + "search" + ], + "summary": "Execute Search", + "description": "Execute a hybrid search query. Optionally synthesize an LLM answer.", + "operationId": "execute_search_search_query_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SearchRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SearchResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/search/sessions": { + "get": { + "tags": [ + "search" + ], + "summary": "List Sessions", + "description": "List the current user's search sessions.", + "operationId": "list_sessions_search_sessions_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "default": 20, + "title": "Limit" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SearchSessionRead" + }, + "title": "Response List Sessions Search Sessions Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/search/sessions/{session_id}": { + "get": { + "tags": [ + "search" + ], + "summary": "Get Session", + "description": "Get a search session with its query history.", + "operationId": "get_session_search_sessions__session_id__get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "session_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Session Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SearchSessionRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/search/filters": { + "get": { + "tags": [ + "search" + ], + "summary": "Get Filter Options", + "description": "Get available filter values for search.", + "operationId": "get_filter_options_search_filters_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SearchFilterOptions" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/search/export": { + "get": { + "tags": [ + "search" + ], + "summary": "Export Search Results", + "description": "Export search results as CSV. Runs a search and streams the results.", + "operationId": "export_search_results_search_export_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "query", + "in": "query", + "required": true, + "schema": { + "type": "string", + "title": "Query" + } + }, + { + "name": "format", + "in": "query", + "required": false, + "schema": { + "type": "string", + "default": "csv", + "title": "Format" + } + }, + { + "name": "department_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Department Id" + } + }, + { + "name": "file_type", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "File Type" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/requests/": { + "post": { + "tags": [ + "requests" + ], + "summary": "Create Request", + "operationId": "create_request_requests__post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RequestCreate" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RequestRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "get": { + "tags": [ + "requests" + ], + "summary": "List Requests", + "operationId": "list_requests_requests__get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "status", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/RequestStatus" + }, + { + "type": "null" + } + ], + "title": "Status" + } + }, + { + "name": "assigned_to", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + } + }, + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "default": 50, + "title": "Limit" + } + }, + { + "name": "offset", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "default": 0, + "title": "Offset" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RequestRead" + }, + "title": "Response List Requests Requests Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/requests/stats": { + "get": { + "tags": [ + "requests" + ], + "summary": "Request Stats", + "operationId": "request_stats_requests_stats_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RequestStats" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/requests/{request_id}": { + "get": { + "tags": [ + "requests" + ], + "summary": "Get Request", + "operationId": "get_request_requests__request_id__get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RequestRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "patch": { + "tags": [ + "requests" + ], + "summary": "Update Request", + "operationId": "update_request_requests__request_id__patch", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RequestUpdate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RequestRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/requests/{request_id}/documents": { + "post": { + "tags": [ + "requests" + ], + "summary": "Attach Document", + "operationId": "attach_document_requests__request_id__documents_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RequestDocumentAdd" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RequestDocumentRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "get": { + "tags": [ + "requests" + ], + "summary": "List Attached Documents", + "operationId": "list_attached_documents_requests__request_id__documents_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RequestDocumentRead" + }, + "title": "Response List Attached Documents Requests Request Id Documents Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/requests/{request_id}/documents/{doc_id}": { + "delete": { + "tags": [ + "requests" + ], + "summary": "Remove Document", + "operationId": "remove_document_requests__request_id__documents__doc_id__delete", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "doc_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Doc Id" + } + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/requests/{request_id}/submit-review": { + "post": { + "tags": [ + "requests" + ], + "summary": "Submit For Review", + "operationId": "submit_for_review_requests__request_id__submit_review_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RequestRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/requests/{request_id}/ready-for-release": { + "post": { + "tags": [ + "requests" + ], + "summary": "Mark Ready For Release", + "operationId": "mark_ready_for_release_requests__request_id__ready_for_release_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RequestRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/requests/{request_id}/approve": { + "post": { + "tags": [ + "requests" + ], + "summary": "Approve Request", + "operationId": "approve_request_requests__request_id__approve_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RequestRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/requests/{request_id}/reject": { + "post": { + "tags": [ + "requests" + ], + "summary": "Reject Request", + "operationId": "reject_request_requests__request_id__reject_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "reason", + "in": "query", + "required": false, + "schema": { + "type": "string", + "default": "", + "title": "Reason" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RequestRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/requests/{request_id}/timeline": { + "get": { + "tags": [ + "requests" + ], + "summary": "Get Timeline", + "operationId": "get_timeline_requests__request_id__timeline_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TimelineEventRead" + }, + "title": "Response Get Timeline Requests Request Id Timeline Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "tags": [ + "requests" + ], + "summary": "Add Timeline Event", + "operationId": "add_timeline_event_requests__request_id__timeline_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TimelineEventCreate" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TimelineEventRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/requests/{request_id}/messages": { + "get": { + "tags": [ + "requests" + ], + "summary": "Get Messages", + "operationId": "get_messages_requests__request_id__messages_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/MessageRead" + }, + "title": "Response Get Messages Requests Request Id Messages Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "tags": [ + "requests" + ], + "summary": "Add Message", + "operationId": "add_message_requests__request_id__messages_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MessageCreate" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MessageRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/requests/{request_id}/fees": { + "get": { + "tags": [ + "requests" + ], + "summary": "Get Fees", + "operationId": "get_fees_requests__request_id__fees_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FeeLineItemRead" + }, + "title": "Response Get Fees Requests Request Id Fees Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "tags": [ + "requests" + ], + "summary": "Add Fee", + "operationId": "add_fee_requests__request_id__fees_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FeeLineItemCreate" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FeeLineItemRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/requests/{request_id}/estimate-fees": { + "post": { + "tags": [ + "requests" + ], + "summary": "Estimate Fees", + "description": "Estimate fees based on staff-entered page count and fee schedule.\n\nPage count is a manual staff estimate — not inferred from ingested docs.", + "operationId": "estimate_fees_requests__request_id__estimate_fees_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FeeEstimateRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FeeEstimateResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/requests/{request_id}/fee-waiver": { + "post": { + "tags": [ + "requests" + ], + "summary": "Create Fee Waiver", + "description": "Request a fee waiver for this records request.", + "operationId": "create_fee_waiver_requests__request_id__fee_waiver_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FeeWaiverCreateRequest" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FeeWaiverReadResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/requests/{request_id}/fee-waiver/{waiver_id}": { + "patch": { + "tags": [ + "requests" + ], + "summary": "Review Fee Waiver", + "description": "Approve or deny a fee waiver. Reviewer/Admin only.", + "operationId": "review_fee_waiver_requests__request_id__fee_waiver__waiver_id__patch", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "waiver_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Waiver Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FeeWaiverReviewRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FeeWaiverReadResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/requests/{request_id}/response-letter": { + "post": { + "tags": [ + "requests" + ], + "summary": "Generate Response Letter", + "description": "Generate a draft response letter for a records request.\n\nAttempts LLM generation via Ollama first; falls back to a structured\ntemplate if the LLM is unavailable.", + "operationId": "generate_response_letter_requests__request_id__response_letter_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/ResponseLetterCreate" + }, + { + "type": "null" + } + ], + "title": "Data" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResponseLetterRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "get": { + "tags": [ + "requests" + ], + "summary": "Get Response Letter", + "description": "Get the latest response letter for a request.", + "operationId": "get_response_letter_requests__request_id__response_letter_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResponseLetterRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/requests/{request_id}/response-letter/{letter_id}": { + "patch": { + "tags": [ + "requests" + ], + "summary": "Update Response Letter", + "description": "Update a response letter's edited content or status.\n\nStatus changes to 'approved' require REVIEWER role.", + "operationId": "update_response_letter_requests__request_id__response_letter__letter_id__patch", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "letter_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Letter Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResponseLetterUpdate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResponseLetterRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/exemptions/rules/": { + "post": { + "tags": [ + "exemptions" + ], + "summary": "Create Rule", + "operationId": "create_rule_exemptions_rules__post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExemptionRuleCreate" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExemptionRuleRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "get": { + "tags": [ + "exemptions" + ], + "summary": "List Rules", + "operationId": "list_rules_exemptions_rules__get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "state_code", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State Code" + } + }, + { + "name": "enabled", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Enabled" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ExemptionRuleRead" + }, + "title": "Response List Rules Exemptions Rules Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/exemptions/rules/{rule_id}": { + "patch": { + "tags": [ + "exemptions" + ], + "summary": "Update Rule", + "operationId": "update_rule_exemptions_rules__rule_id__patch", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "rule_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Rule Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExemptionRuleUpdate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExemptionRuleRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/exemptions/rules/{rule_id}/history": { + "get": { + "tags": [ + "exemptions" + ], + "summary": "Get Rule History", + "description": "Get audit history for an exemption rule.", + "operationId": "get_rule_history_exemptions_rules__rule_id__history_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "rule_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Rule Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/exemptions/rules/{rule_id}/test": { + "post": { + "tags": [ + "exemptions" + ], + "summary": "Test Rule", + "description": "Test a rule against sample text. Returns match results.\n\nUses the `regex` library with timeout=2s to prevent ReDoS on\nadmin-entered patterns.", + "operationId": "test_rule_exemptions_rules__rule_id__test_post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "rule_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Rule Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RuleTestRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RuleTestResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/exemptions/scan/{request_id}": { + "post": { + "tags": [ + "exemptions" + ], + "summary": "Scan For Exemptions", + "description": "Scan all documents attached to a request for exemptions.", + "operationId": "scan_for_exemptions_exemptions_scan__request_id__post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "state_code", + "in": "query", + "required": false, + "schema": { + "type": "string", + "pattern": "^[A-Z]{2}$", + "default": "CO", + "title": "State Code" + } + }, + { + "name": "use_llm", + "in": "query", + "required": false, + "schema": { + "type": "boolean", + "default": false, + "title": "Use Llm" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/exemptions/flags/{request_id}": { + "get": { + "tags": [ + "exemptions" + ], + "summary": "List Flags", + "operationId": "list_flags_exemptions_flags__request_id__get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "status", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/FlagStatus" + }, + { + "type": "null" + } + ], + "title": "Status" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ExemptionFlagRead" + }, + "title": "Response List Flags Exemptions Flags Request Id Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/exemptions/flags/{flag_id}": { + "patch": { + "tags": [ + "exemptions" + ], + "summary": "Review Flag", + "operationId": "review_flag_exemptions_flags__flag_id__patch", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "flag_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Flag Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExemptionFlagReview" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExemptionFlagRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/exemptions/dashboard/accuracy": { + "get": { + "tags": [ + "exemptions" + ], + "summary": "Exemption Accuracy", + "description": "Acceptance/rejection rates by category, optionally filtered by department.", + "operationId": "exemption_accuracy_exemptions_dashboard_accuracy_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "department_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + } + }, + { + "name": "date_from", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Date From" + } + }, + { + "name": "date_to", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Date To" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ExemptionAccuracyReport" + }, + "title": "Response Exemption Accuracy Exemptions Dashboard Accuracy Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/exemptions/dashboard/export": { + "get": { + "tags": [ + "exemptions" + ], + "summary": "Export Flag Data", + "description": "Export exemption flag data as JSON or CSV.", + "operationId": "export_flag_data_exemptions_dashboard_export_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "format", + "in": "query", + "required": false, + "schema": { + "type": "string", + "default": "json", + "title": "Format" + } + }, + { + "name": "date_from", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Date From" + } + }, + { + "name": "date_to", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Date To" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/exemptions/dashboard": { + "get": { + "tags": [ + "exemptions" + ], + "summary": "Exemption Dashboard", + "operationId": "exemption_dashboard_exemptions_dashboard_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExemptionDashboard" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/exemptions/templates/": { + "get": { + "tags": [ + "exemptions" + ], + "summary": "List Templates", + "operationId": "list_templates_exemptions_templates__get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "template_type", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Template Type" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DisclosureTemplateRead" + }, + "title": "Response List Templates Exemptions Templates Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "tags": [ + "exemptions" + ], + "summary": "Create Template", + "operationId": "create_template_exemptions_templates__post", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DisclosureTemplateCreate" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DisclosureTemplateRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/exemptions/templates/{template_id}/render": { + "get": { + "tags": [ + "exemptions" + ], + "summary": "Render Template", + "description": "Render a template with city profile variables substituted.", + "operationId": "render_template_exemptions_templates__template_id__render_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "template_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Template Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DisclosureTemplateRendered" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/exemptions/templates/{template_id}": { + "put": { + "tags": [ + "exemptions" + ], + "summary": "Update Template", + "operationId": "update_template_exemptions_templates__template_id__put", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "template_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Template Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DisclosureTemplateUpdate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DisclosureTemplateRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/analytics/operational": { + "get": { + "tags": [ + "analytics" + ], + "summary": "Get Operational Metrics", + "operationId": "get_operational_metrics_analytics_operational_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OperationalMetrics" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/city-profile": { + "get": { + "tags": [ + "city-profile" + ], + "summary": "Get City Profile", + "operationId": "get_city_profile_city_profile_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/CityProfileRead" + }, + { + "type": "null" + } + ], + "title": "Response Get City Profile City Profile Get" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + }, + "post": { + "tags": [ + "city-profile" + ], + "summary": "Create City Profile", + "operationId": "create_city_profile_city_profile_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CityProfileCreate" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CityProfileRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + }, + "patch": { + "tags": [ + "city-profile" + ], + "summary": "Update City Profile", + "operationId": "update_city_profile_city_profile_patch", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CityProfileUpdate" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CityProfileRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/onboarding/interview": { + "post": { + "tags": [ + "onboarding" + ], + "summary": "Get Next Question", + "description": "Generate the next onboarding question and persist the last answer.", + "operationId": "get_next_question_onboarding_interview_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InterviewRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InterviewResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/catalog/domains": { + "get": { + "tags": [ + "catalog" + ], + "summary": "List Domains", + "operationId": "list_domains_catalog_domains_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/catalog/systems": { + "get": { + "tags": [ + "catalog" + ], + "summary": "List Systems", + "operationId": "list_systems_catalog_systems_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "domain", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Domain" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/catalog/connectors": { + "get": { + "tags": [ + "catalog" + ], + "summary": "List Connectors", + "operationId": "list_connectors_catalog_connectors_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "domain", + "in": "query", + "required": true, + "schema": { + "type": "string", + "title": "Domain" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/catalog/load": { + "post": { + "tags": [ + "catalog" + ], + "summary": "Trigger Catalog Load", + "operationId": "trigger_catalog_load_catalog_load_post", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/notifications/templates": { + "get": { + "tags": [ + "notifications" + ], + "summary": "List Templates", + "description": "List all notification templates.", + "operationId": "list_templates_notifications_templates_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/NotificationTemplateRead" + }, + "type": "array", + "title": "Response List Templates Notifications Templates Get" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + }, + "post": { + "tags": [ + "notifications" + ], + "summary": "Create Template", + "description": "Create a new notification template (admin only).", + "operationId": "create_template_notifications_templates_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotificationTemplateCreate" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotificationTemplateRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/notifications/templates/{template_id}": { + "patch": { + "tags": [ + "notifications" + ], + "summary": "Update Template", + "description": "Update a notification template (admin only).", + "operationId": "update_template_notifications_templates__template_id__patch", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "template_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Template Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotificationTemplateUpdate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotificationTemplateRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/notifications/log": { + "get": { + "tags": [ + "notifications" + ], + "summary": "List Notification Log", + "description": "List recent notification log entries.", + "operationId": "list_notification_log_notifications_log_get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 200, + "default": 50, + "title": "Limit" + } + }, + { + "name": "request_id", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Request Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/NotificationLogRead" + }, + "title": "Response List Notification Log Notifications Log Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/departments/": { + "get": { + "tags": [ + "departments" + ], + "summary": "List Departments", + "operationId": "list_departments_departments__get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/DepartmentRead" + }, + "type": "array", + "title": "Response List Departments Departments Get" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + }, + "post": { + "tags": [ + "departments" + ], + "summary": "Create Department", + "operationId": "create_department_departments__post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DepartmentCreate" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DepartmentRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + }, + "security": [ + { + "OAuth2PasswordBearer": [] + } + ] + } + }, + "/departments/{dept_id}": { + "get": { + "tags": [ + "departments" + ], + "summary": "Get Department", + "operationId": "get_department_departments__dept_id__get", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "dept_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Dept Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DepartmentRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "patch": { + "tags": [ + "departments" + ], + "summary": "Update Department", + "operationId": "update_department_departments__dept_id__patch", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "dept_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Dept Id" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DepartmentUpdate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DepartmentRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "delete": { + "tags": [ + "departments" + ], + "summary": "Delete Department", + "operationId": "delete_department_departments__dept_id__delete", + "security": [ + { + "OAuth2PasswordBearer": [] + } + ], + "parameters": [ + { + "name": "dept_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Dept Id" + } + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/station/context": { + "get": { + "tags": [ + "native-desktop", + "station-integration" + ], + "summary": "Context", + "operationId": "context_desktop_v1_station_context_get", + "parameters": [ + { + "name": "capability", + "in": "query", + "required": true, + "schema": { + "enum": [ + "capture", + "read" + ], + "type": "string", + "title": "Capability" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/requests/{request_id}/station-recordings": { + "post": { + "tags": [ + "native-desktop", + "station-integration" + ], + "summary": "Attach", + "operationId": "attach_desktop_v1_requests__request_id__station_recordings_post", + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Selection" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordsOperationRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/public/records-state": { + "get": { + "tags": [ + "native-desktop" + ], + "summary": "Public Records State", + "operationId": "public_records_state_desktop_v1_public_records_state_get", + "parameters": [ + { + "name": "X-Townlight-Public", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Public" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordsStateRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/public/requests": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Public Records Intake", + "operationId": "public_records_intake_desktop_v1_public_requests_post", + "parameters": [ + { + "name": "X-Townlight-Public", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Public" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PublicIntake" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/public/lookup": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Public Records Lookup", + "operationId": "public_records_lookup_desktop_v1_public_lookup_post", + "parameters": [ + { + "name": "X-Townlight-Public", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Public" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PublicLookup" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/public/messages": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Public Records Message", + "operationId": "public_records_message_desktop_v1_public_messages_post", + "parameters": [ + { + "name": "X-Townlight-Public", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Public" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PublicMessage" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/permitting-sources/search": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Search Permitting Sources", + "operationId": "search_permitting_sources_desktop_v1_permitting_sources_search_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MeetingsSearch" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/requests/{request_id}/permitting-sources": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Attach Permitting Source", + "operationId": "attach_permitting_source_desktop_v1_requests__request_id__permitting_sources_post", + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MeetingsSourceSelection" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordsOperationRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/inspections-sources/search": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Search Inspections Sources", + "operationId": "search_inspections_sources_desktop_v1_inspections_sources_search_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MeetingsSearch" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/requests/{request_id}/inspections-sources": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Attach Inspections Source", + "operationId": "attach_inspections_source_desktop_v1_requests__request_id__inspections_sources_post", + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MeetingsSourceSelection" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordsOperationRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning-sources/search": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Search Planning Sources", + "operationId": "search_planning_sources_desktop_v1_planning_sources_search_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MeetingsSearch" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/requests/{request_id}/planning-sources": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Attach Planning Source", + "operationId": "attach_planning_source_desktop_v1_requests__request_id__planning_sources_post", + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MeetingsSourceSelection" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordsOperationRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/zoning-sources/search": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Search Zoning Sources", + "operationId": "search_zoning_sources_desktop_v1_zoning_sources_search_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MeetingsSearch" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/requests/{request_id}/zoning-sources": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Attach Zoning Source", + "operationId": "attach_zoning_source_desktop_v1_requests__request_id__zoning_sources_post", + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MeetingsSourceSelection" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordsOperationRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/records-state": { + "get": { + "tags": [ + "native-desktop" + ], + "summary": "Get Native Records State", + "operationId": "get_native_records_state_desktop_v1_records_state_get", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordsStateRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings-sources/search": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Search Meetings Sources", + "operationId": "search_meetings_sources_desktop_v1_meetings_sources_search_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MeetingsSearch" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/requests/{request_id}/meetings-sources": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Attach Meetings Source", + "operationId": "attach_meetings_source_desktop_v1_requests__request_id__meetings_sources_post", + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MeetingsSourceSelection" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordsOperationRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/code-sources/search": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Search Code Sources", + "operationId": "search_code_sources_desktop_v1_code_sources_search_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CodeSearch" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/requests/{request_id}/code-sources": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Attach Code Source", + "operationId": "attach_code_source_desktop_v1_requests__request_id__code_sources_post", + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CodeSourceSelection" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordsOperationRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/notifications/{notification_id}/sent": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Mark Native Notification Sent", + "operationId": "mark_native_notification_sent_desktop_v1_notifications__notification_id__sent_post", + "parameters": [ + { + "name": "notification_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Notification Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordsStateRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/requests/{request_id}/documents": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Attach Native Document", + "operationId": "attach_native_document_desktop_v1_requests__request_id__documents_post", + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AttachDocument" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordsOperationRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/requests/{request_id}/documents/{attachment_id}/release-copy": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Attach Native Release Copy", + "operationId": "attach_native_release_copy_desktop_v1_requests__request_id__documents__attachment_id__release_copy_post", + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "attachment_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Attachment Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AttachReleaseCopy" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordsOperationRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/requests/{request_id}/artifacts": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Prepare Native Artifact", + "operationId": "prepare_native_artifact_desktop_v1_requests__request_id__artifacts_post", + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PrepareArtifact" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ArtifactPlan" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/requests/{request_id}/artifacts/{artifact_id}/complete": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Complete Native Artifact", + "operationId": "complete_native_artifact_desktop_v1_requests__request_id__artifacts__artifact_id__complete_post", + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "artifact_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Artifact Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CompleteArtifact" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordsOperationRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/requests": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Create Native Request", + "operationId": "create_native_request_desktop_v1_requests_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StaffRecordsIntake" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NativeRequestRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/requests/{request_id}": { + "get": { + "tags": [ + "native-desktop" + ], + "summary": "Get Native Request", + "operationId": "get_native_request_desktop_v1_requests__request_id__get", + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NativeRequestRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/requests/{request_id}/view": { + "get": { + "tags": [ + "native-desktop" + ], + "summary": "Get Native Request View", + "operationId": "get_native_request_view_desktop_v1_requests__request_id__view_get", + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordsView" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/requests/{request_id}/draft-context": { + "get": { + "tags": [ + "native-desktop" + ], + "summary": "Native Draft Context", + "operationId": "native_draft_context_desktop_v1_requests__request_id__draft_context_get", + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/requests/{request_id}/generated-draft": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Native Generated Draft", + "operationId": "native_generated_draft_desktop_v1_requests__request_id__generated_draft_post", + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GeneratedDraft" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordsOperationRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/requests/{request_id}/actions": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Native Request Operation", + "operationId": "native_request_operation_desktop_v1_requests__request_id__actions_post", + "parameters": [ + { + "name": "request_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "oneOf": [ + { + "$ref": "#/components/schemas/AssignCommand" + }, + { + "$ref": "#/components/schemas/DeadlineCommand" + }, + { + "$ref": "#/components/schemas/CalculateDeadlineCommand" + }, + { + "$ref": "#/components/schemas/ClarificationCommand" + }, + { + "$ref": "#/components/schemas/MessageCommand" + }, + { + "$ref": "#/components/schemas/SearchNoteCommand" + }, + { + "$ref": "#/components/schemas/SearchReceiptCommand" + }, + { + "$ref": "#/components/schemas/ExemptionNoteCommand" + }, + { + "$ref": "#/components/schemas/ExemptionDecisionCommand" + }, + { + "$ref": "#/components/schemas/FeeEstimateCommand" + }, + { + "$ref": "#/components/schemas/FeeLineCommand" + }, + { + "$ref": "#/components/schemas/FeeWaiverCommand" + }, + { + "$ref": "#/components/schemas/DraftCommand" + }, + { + "$ref": "#/components/schemas/ApprovalCommand" + }, + { + "$ref": "#/components/schemas/FinishCommand" + } + ], + "discriminator": { + "propertyName": "action", + "mapping": { + "assign-records-request": "#/components/schemas/AssignCommand", + "set-records-deadline": "#/components/schemas/DeadlineCommand", + "calculate-records-deadline": "#/components/schemas/CalculateDeadlineCommand", + "request-records-clarification": "#/components/schemas/ClarificationCommand", + "add-records-message": "#/components/schemas/MessageCommand", + "record-records-search": "#/components/schemas/SearchNoteCommand", + "record-records-search-session": "#/components/schemas/SearchReceiptCommand", + "add-records-exemption-review": "#/components/schemas/ExemptionNoteCommand", + "add-records-exemption-decision": "#/components/schemas/ExemptionDecisionCommand", + "estimate-records-fee": "#/components/schemas/FeeEstimateCommand", + "add-records-fee-line": "#/components/schemas/FeeLineCommand", + "waive-records-fee": "#/components/schemas/FeeWaiverCommand", + "draft-records-response": "#/components/schemas/DraftCommand", + "approve-records-response": "#/components/schemas/ApprovalCommand", + "fulfill-records-request": "#/components/schemas/FinishCommand", + "close-records-request": "#/components/schemas/FinishCommand" + } + }, + "title": "Command" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecordsOperationRead" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/health": { + "get": { + "summary": "Health", + "operationId": "health_health_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + } + } + } + }, + "/desktop/v1/access/state": { + "get": { + "tags": [ + "native-access" + ], + "summary": "Access State", + "operationId": "access_state_desktop_v1_access_state_get", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/access/review-context": { + "post": { + "tags": [ + "native-access" + ], + "summary": "Review Context", + "operationId": "review_context_desktop_v1_access_review_context_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReviewInput" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/access/reviews": { + "post": { + "tags": [ + "native-access" + ], + "summary": "Save Review", + "operationId": "save_review_desktop_v1_access_reviews_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SaveReview" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/access/reviews/{review_id}/delete": { + "post": { + "tags": [ + "native-access" + ], + "summary": "Delete Review", + "operationId": "delete_review_desktop_v1_access_reviews__review_id__delete_post", + "parameters": [ + { + "name": "review_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Review Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/access/tools": { + "post": { + "tags": [ + "native-access" + ], + "summary": "Tool", + "operationId": "tool_desktop_v1_access_tools_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "oneOf": [ + { + "$ref": "#/components/schemas/FormPlan" + }, + { + "$ref": "#/components/schemas/PublishingPlan" + }, + { + "$ref": "#/components/schemas/AdaPlan" + }, + { + "$ref": "#/components/schemas/TaggedPlan" + } + ], + "discriminator": { + "propertyName": "action", + "mapping": { + "form-plan": "#/components/schemas/FormPlan", + "publishing-workflow": "#/components/schemas/PublishingPlan", + "ada-title-ii": "#/components/schemas/AdaPlan", + "tagged-pdf": "#/components/schemas/TaggedPlan" + } + }, + "title": "Data" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/access/rewrite-context": { + "post": { + "tags": [ + "native-access" + ], + "summary": "Rewrite Context", + "operationId": "rewrite_context_desktop_v1_access_rewrite_context_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RewriteInput" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/access/rewrite-result": { + "post": { + "tags": [ + "native-access" + ], + "summary": "Rewrite Result", + "operationId": "rewrite_result_desktop_v1_access_rewrite_result_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RewriteResult" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/access/reviews/{review_id}/export": { + "post": { + "tags": [ + "native-access" + ], + "summary": "Prepare Export", + "operationId": "prepare_export_desktop_v1_access_reviews__review_id__export_post", + "parameters": [ + { + "name": "review_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Review Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/access/drafts/{draft_id}/export": { + "post": { + "tags": [ + "native-access" + ], + "summary": "Export Draft", + "operationId": "export_draft_desktop_v1_access_drafts__draft_id__export_post", + "parameters": [ + { + "name": "draft_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Draft Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/access/exports/{artifact_id}/complete": { + "post": { + "tags": [ + "native-access" + ], + "summary": "Complete Export", + "operationId": "complete_export_desktop_v1_access_exports__artifact_id__complete_post", + "parameters": [ + { + "name": "artifact_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Artifact Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExportReceipt" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/notice/notices": { + "get": { + "tags": [ + "native-notice" + ], + "summary": "Inventory", + "operationId": "inventory_desktop_v1_notice_notices_get", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "tags": [ + "native-notice" + ], + "summary": "Create", + "operationId": "create_desktop_v1_notice_notices_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NoticeDraft" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/notice/notices/{notice_id}": { + "get": { + "tags": [ + "native-notice" + ], + "summary": "Read", + "operationId": "read_desktop_v1_notice_notices__notice_id__get", + "parameters": [ + { + "name": "notice_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Notice Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/notice/notices/{notice_id}/revisions": { + "post": { + "tags": [ + "native-notice" + ], + "summary": "Edit", + "operationId": "edit_desktop_v1_notice_notices__notice_id__revisions_post", + "parameters": [ + { + "name": "notice_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Notice Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Revision" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/notice/notices/{notice_id}/review": { + "post": { + "tags": [ + "native-notice" + ], + "summary": "Review", + "operationId": "review_desktop_v1_notice_notices__notice_id__review_post", + "parameters": [ + { + "name": "notice_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Notice Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/townlight_runtime__notice_bridge__Review" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/notice/notices/{notice_id}/approval": { + "post": { + "tags": [ + "native-notice" + ], + "summary": "Approve", + "operationId": "approve_desktop_v1_notice_notices__notice_id__approval_post", + "parameters": [ + { + "name": "notice_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Notice Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Version" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/notice/notices/{notice_id}/proof": { + "post": { + "tags": [ + "native-notice" + ], + "summary": "Proof", + "operationId": "proof_desktop_v1_notice_notices__notice_id__proof_post", + "parameters": [ + { + "name": "notice_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Notice Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Proof" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/notice/notices/{notice_id}/archive": { + "post": { + "tags": [ + "native-notice" + ], + "summary": "Archive", + "operationId": "archive_desktop_v1_notice_notices__notice_id__archive_post", + "parameters": [ + { + "name": "notice_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Notice Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Version" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/notice/archives/{archive_id}": { + "get": { + "tags": [ + "native-notice" + ], + "summary": "Export", + "operationId": "export_desktop_v1_notice_archives__archive_id__get", + "parameters": [ + { + "name": "archive_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Archive Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/notice/archives/{archive_id}/records": { + "post": { + "tags": [ + "native-notice" + ], + "summary": "Handoff", + "operationId": "handoff_desktop_v1_notice_archives__archive_id__records_post", + "parameters": [ + { + "name": "archive_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Archive Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Handoff" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/suite/state": { + "get": { + "tags": [ + "native-records-snapshot" + ], + "summary": "Suite State", + "operationId": "suite_state_desktop_v1_suite_state_get", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/suite/search": { + "post": { + "tags": [ + "native-records-snapshot" + ], + "summary": "Search", + "operationId": "search_desktop_v1_suite_search_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SearchInput" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/meetings/{meeting_id}/stages": { + "post": { + "tags": [ + "native-meetings" + ], + "summary": "Record Meeting Stage", + "operationId": "record_meeting_stage_desktop_v1_meetings_meetings__meeting_id__stages_post", + "parameters": [ + { + "name": "meeting_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MeetingStageInput" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/meetings": { + "post": { + "tags": [ + "native-meetings" + ], + "summary": "Create Meeting", + "operationId": "create_meeting_desktop_v1_meetings_meetings_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MeetingInput" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/meetings/{meeting_id}": { + "get": { + "tags": [ + "native-meetings" + ], + "summary": "Get Meeting", + "operationId": "get_meeting_desktop_v1_meetings_meetings__meeting_id__get", + "parameters": [ + { + "name": "meeting_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/agenda-items": { + "post": { + "tags": [ + "native-meetings" + ], + "summary": "Create Agenda Item", + "operationId": "create_agenda_item_desktop_v1_meetings_agenda_items_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgendaInput" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/agenda-items/{item_id}": { + "get": { + "tags": [ + "native-meetings" + ], + "summary": "Get Agenda Item", + "operationId": "get_agenda_item_desktop_v1_meetings_agenda_items__item_id__get", + "parameters": [ + { + "name": "item_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Item Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/agenda-items/{item_id}/reviews": { + "post": { + "tags": [ + "native-meetings" + ], + "summary": "Record Agenda Review", + "operationId": "record_agenda_review_desktop_v1_meetings_agenda_items__item_id__reviews_post", + "parameters": [ + { + "name": "item_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Item Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgendaReviewInput" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/agenda-items/{item_id}/meeting": { + "post": { + "tags": [ + "native-meetings" + ], + "summary": "Assign Agenda", + "operationId": "assign_agenda_desktop_v1_meetings_agenda_items__item_id__meeting_post", + "parameters": [ + { + "name": "item_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Item Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgendaAssignment" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/notices/{notice_id}/template": { + "get": { + "tags": [ + "native-meetings" + ], + "summary": "Notice Template", + "operationId": "notice_template_desktop_v1_meetings_notices__notice_id__template_get", + "parameters": [ + { + "name": "notice_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Notice Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/notices/{notice_id}/document": { + "post": { + "tags": [ + "native-meetings" + ], + "summary": "Notice Document", + "operationId": "notice_document_desktop_v1_meetings_notices__notice_id__document_post", + "parameters": [ + { + "name": "notice_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Notice Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NoticeDocumentInput" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/meetings/{meeting_id}/notice-checks": { + "post": { + "tags": [ + "native-meetings" + ], + "summary": "Check Notice", + "operationId": "check_notice_desktop_v1_meetings_meetings__meeting_id__notice_checks_post", + "parameters": [ + { + "name": "meeting_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NoticeInput" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/notices/{notice_id}/proof": { + "post": { + "tags": [ + "native-meetings" + ], + "summary": "Record Notice Proof", + "operationId": "record_notice_proof_desktop_v1_meetings_notices__notice_id__proof_post", + "parameters": [ + { + "name": "notice_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Notice Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NoticeProofInput" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/meetings/{meeting_id}/transcripts": { + "post": { + "tags": [ + "native-meetings" + ], + "summary": "Capture Transcript", + "operationId": "capture_transcript_desktop_v1_meetings_meetings__meeting_id__transcripts_post", + "parameters": [ + { + "name": "meeting_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TranscriptInput" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/meetings/{meeting_id}/action-items": { + "post": { + "tags": [ + "native-meetings" + ], + "summary": "Capture Action Item", + "operationId": "capture_action_item_desktop_v1_meetings_meetings__meeting_id__action_items_post", + "parameters": [ + { + "name": "meeting_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ActionItemInput" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/meetings/{meeting_id}/archive": { + "post": { + "tags": [ + "native-meetings" + ], + "summary": "Archive Meeting", + "operationId": "archive_meeting_desktop_v1_meetings_meetings__meeting_id__archive_post", + "parameters": [ + { + "name": "meeting_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ArchiveInput" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/meetings/{meeting_id}/packet-snapshots": { + "post": { + "tags": [ + "native-meetings" + ], + "summary": "Capture Packet", + "operationId": "capture_packet_desktop_v1_meetings_meetings__meeting_id__packet_snapshots_post", + "parameters": [ + { + "name": "meeting_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PacketInput" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/packets/{packet_id}/deliver": { + "post": { + "tags": [ + "native-meetings" + ], + "summary": "Export Packet", + "operationId": "export_packet_desktop_v1_meetings_packets__packet_id__deliver_post", + "parameters": [ + { + "name": "packet_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Packet Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/minutes/{draft_id}/decisions": { + "post": { + "tags": [ + "native-meetings" + ], + "summary": "Decide Minutes", + "operationId": "decide_minutes_desktop_v1_meetings_minutes__draft_id__decisions_post", + "parameters": [ + { + "name": "draft_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Draft Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MinutesDecision" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/meetings/{meeting_id}/motions": { + "post": { + "tags": [ + "native-meetings" + ], + "summary": "Capture Motion", + "operationId": "capture_motion_desktop_v1_meetings_meetings__meeting_id__motions_post", + "parameters": [ + { + "name": "meeting_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MotionInput" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/motions/{motion_id}/corrections": { + "post": { + "tags": [ + "native-meetings" + ], + "summary": "Correct Motion", + "operationId": "correct_motion_desktop_v1_meetings_motions__motion_id__corrections_post", + "parameters": [ + { + "name": "motion_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Motion Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MotionCorrection" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/motions/{motion_id}/votes": { + "post": { + "tags": [ + "native-meetings" + ], + "summary": "Capture Vote", + "operationId": "capture_vote_desktop_v1_meetings_motions__motion_id__votes_post", + "parameters": [ + { + "name": "motion_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Motion Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VoteInput" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/votes/{vote_id}/corrections": { + "post": { + "tags": [ + "native-meetings" + ], + "summary": "Correct Vote", + "operationId": "correct_vote_desktop_v1_meetings_votes__vote_id__corrections_post", + "parameters": [ + { + "name": "vote_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Vote Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VoteCorrection" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/meetings/{meeting_id}/minutes/drafts": { + "post": { + "tags": [ + "native-meetings" + ], + "summary": "Create Minutes", + "operationId": "create_minutes_desktop_v1_meetings_meetings__meeting_id__minutes_drafts_post", + "parameters": [ + { + "name": "meeting_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DraftInput" + } + } + } + }, + "responses": { + "201": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/meetings/{meeting_id}/proceedings": { + "get": { + "tags": [ + "native-meetings" + ], + "summary": "Proceedings", + "operationId": "proceedings_desktop_v1_meetings_meetings__meeting_id__proceedings_get", + "parameters": [ + { + "name": "meeting_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/station/catalog": { + "get": { + "tags": [ + "native-meetings" + ], + "summary": "Station Catalog", + "description": "Authorized name-based operator selection from canonical Meetings data.", + "operationId": "station_catalog_desktop_v1_meetings_station_catalog_get", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/public/meetings": { + "get": { + "tags": [ + "public-meetings" + ], + "summary": "Public Archive Index", + "operationId": "public_archive_index_public_meetings_get", + "parameters": [ + { + "name": "q", + "in": "query", + "required": false, + "schema": { + "type": "string", + "default": "", + "title": "Q" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "text/html": { + "schema": { + "type": "string" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/public/meetings/{record_id}": { + "get": { + "tags": [ + "public-meetings" + ], + "summary": "Public Archive Detail", + "operationId": "public_archive_detail_public_meetings__record_id__get", + "parameters": [ + { + "name": "record_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Record Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "text/html": { + "schema": { + "type": "string" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/public/meetings/{record_id}/{kind}.txt": { + "get": { + "tags": [ + "public-meetings" + ], + "summary": "Public Archive Download", + "operationId": "public_archive_download_public_meetings__record_id___kind__txt_get", + "parameters": [ + { + "name": "record_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Record Id" + } + }, + { + "name": "kind", + "in": "path", + "required": true, + "schema": { + "enum": [ + "agenda", + "packet", + "minutes" + ], + "type": "string", + "title": "Kind" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/code/imports": { + "post": { + "tags": [ + "native-code" + ], + "summary": "Imports", + "operationId": "imports_desktop_v1_code_imports_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ImportBundleCreate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "get": { + "tags": [ + "native-code" + ], + "summary": "List Imports", + "operationId": "list_imports_desktop_v1_code_imports_get", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/code/sources": { + "get": { + "tags": [ + "native-code" + ], + "summary": "Sources", + "operationId": "sources_desktop_v1_code_sources_get", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/code/workspace": { + "get": { + "tags": [ + "native-code" + ], + "summary": "Workspace", + "operationId": "workspace_desktop_v1_code_workspace_get", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/code/lookup": { + "get": { + "tags": [ + "native-code" + ], + "summary": "Lookup", + "operationId": "lookup_desktop_v1_code_lookup_get", + "parameters": [ + { + "name": "section_number", + "in": "query", + "required": true, + "schema": { + "type": "string", + "title": "Section Number" + } + }, + { + "name": "as_of", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/code/sections/{section_id}/history": { + "get": { + "tags": [ + "native-code" + ], + "summary": "Section History", + "operationId": "section_history_desktop_v1_code_sections__section_id__history_get", + "parameters": [ + { + "name": "section_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Section Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/code/citation": { + "get": { + "tags": [ + "native-code" + ], + "summary": "Citation", + "operationId": "citation_desktop_v1_code_citation_get", + "parameters": [ + { + "name": "section_number", + "in": "query", + "required": true, + "schema": { + "type": "string", + "title": "Section Number" + } + }, + { + "name": "as_of", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/code/search": { + "get": { + "tags": [ + "native-code" + ], + "summary": "Search", + "operationId": "search_desktop_v1_code_search_get", + "parameters": [ + { + "name": "q", + "in": "query", + "required": true, + "schema": { + "type": "string", + "title": "Q" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/code/imports/{job_id}/tree": { + "get": { + "tags": [ + "native-code" + ], + "summary": "Import Tree", + "operationId": "import_tree_desktop_v1_code_imports__job_id__tree_get", + "parameters": [ + { + "name": "job_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Job Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/code/imports/{job_id}/provenance": { + "get": { + "tags": [ + "native-code" + ], + "summary": "Import Provenance", + "operationId": "import_provenance_desktop_v1_code_imports__job_id__provenance_get", + "parameters": [ + { + "name": "job_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Job Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/code/export": { + "get": { + "tags": [ + "native-code" + ], + "summary": "Export Section", + "operationId": "export_section_desktop_v1_code_export_get", + "parameters": [ + { + "name": "section_ref", + "in": "query", + "required": true, + "schema": { + "type": "string", + "title": "Section Ref" + } + }, + { + "name": "as_of", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/code/questions": { + "post": { + "tags": [ + "native-code" + ], + "summary": "Questions", + "operationId": "questions_desktop_v1_code_questions_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/QuestionAnswerRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/code/sections/{section_id}/notes": { + "post": { + "tags": [ + "native-code" + ], + "summary": "Create Note", + "operationId": "create_note_desktop_v1_code_sections__section_id__notes_post", + "parameters": [ + { + "name": "section_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Section Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InterpretationNoteCreate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "get": { + "tags": [ + "native-code" + ], + "summary": "List Notes", + "operationId": "list_notes_desktop_v1_code_sections__section_id__notes_get", + "parameters": [ + { + "name": "section_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Section Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/code/sections/{section_id}/summaries": { + "post": { + "tags": [ + "native-code" + ], + "summary": "Create Summary", + "operationId": "create_summary_desktop_v1_code_sections__section_id__summaries_post", + "parameters": [ + { + "name": "section_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Section Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PlainLanguageSummaryCreate" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "get": { + "tags": [ + "native-code" + ], + "summary": "List Summaries", + "operationId": "list_summaries_desktop_v1_code_sections__section_id__summaries_get", + "parameters": [ + { + "name": "section_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Section Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/code/summaries/{summary_id}/approve": { + "post": { + "tags": [ + "native-code" + ], + "summary": "Approve Summary", + "operationId": "approve_summary_desktop_v1_code_summaries__summary_id__approve_post", + "parameters": [ + { + "name": "summary_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Summary Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/code/connections": { + "get": { + "summary": "List Connections", + "operationId": "list_connections_desktop_v1_code_connections_get", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "summary": "Create Connection", + "operationId": "create_connection_desktop_v1_code_connections_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Proposal" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/code/connections/{connection_id}": { + "get": { + "summary": "Get Connection", + "operationId": "get_connection_desktop_v1_code_connections__connection_id__get", + "parameters": [ + { + "name": "connection_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Connection Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/code/connections/{connection_id}/closeout": { + "post": { + "summary": "Closeout Connection", + "operationId": "closeout_connection_desktop_v1_code_connections__connection_id__closeout_post", + "parameters": [ + { + "name": "connection_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Connection Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Closeout" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/code-connections": { + "get": { + "summary": "List Code Connections", + "operationId": "list_code_connections_desktop_v1_meetings_code_connections_get", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/code-connections/{connection_id}": { + "get": { + "summary": "Get Code Connection", + "operationId": "get_code_connection_desktop_v1_meetings_code_connections__connection_id__get", + "parameters": [ + { + "name": "connection_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Connection Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/meetings/code-connections/{connection_id}/decisions": { + "post": { + "summary": "Record Decision", + "operationId": "record_decision_desktop_v1_meetings_code_connections__connection_id__decisions_post", + "parameters": [ + { + "name": "connection_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Connection Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Decision" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/townlight_code": { + "get": { + "summary": "Home", + "operationId": "home_townlight_code_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "text/html": { + "schema": { + "type": "string" + } + } + } + } + } + } + }, + "/townlight_code/search": { + "get": { + "summary": "Search", + "operationId": "search_townlight_code_search_get", + "parameters": [ + { + "name": "q", + "in": "query", + "required": false, + "schema": { + "type": "string", + "default": "", + "title": "Q" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "text/html": { + "schema": { + "type": "string" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/townlight_code/answer": { + "get": { + "summary": "Answer", + "operationId": "answer_townlight_code_answer_get", + "parameters": [ + { + "name": "q", + "in": "query", + "required": false, + "schema": { + "type": "string", + "default": "", + "title": "Q" + } + }, + { + "name": "section_number", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Section Number" + } + }, + { + "name": "as_of", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "text/html": { + "schema": { + "type": "string" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/townlight_code/sections/{section_ref}": { + "get": { + "summary": "Detail", + "operationId": "detail_townlight_code_sections__section_ref__get", + "parameters": [ + { + "name": "section_ref", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Section Ref" + } + }, + { + "name": "as_of", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "text/html": { + "schema": { + "type": "string" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/townlight_code/sections/{section_ref}/export": { + "get": { + "summary": "Export", + "operationId": "export_townlight_code_sections__section_ref__export_get", + "parameters": [ + { + "name": "section_ref", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Section Ref" + } + }, + { + "name": "as_of", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "text/html": { + "schema": { + "type": "string" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/zoning/imports": { + "post": { + "tags": [ + "native-zoning" + ], + "summary": "Imports", + "operationId": "imports_desktop_v1_zoning_imports_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": true, + "title": "Payload" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/zoning/parcels/lookup": { + "post": { + "tags": [ + "native-zoning" + ], + "summary": "Parcel Lookup", + "operationId": "parcel_lookup_desktop_v1_zoning_parcels_lookup_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/_ParcelLookupIn" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/zoning/questions/{question_id}/history": { + "get": { + "tags": [ + "native-zoning" + ], + "summary": "Question History", + "operationId": "question_history_desktop_v1_zoning_questions__question_id__history_get", + "parameters": [ + { + "name": "question_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Question Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/zoning/meetings/search": { + "post": { + "tags": [ + "native-zoning" + ], + "summary": "Search Meetings", + "operationId": "search_meetings_desktop_v1_zoning_meetings_search_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MeetingSearch" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/zoning/questions/{question_id}/meetings": { + "post": { + "tags": [ + "native-zoning" + ], + "summary": "Link Meeting", + "operationId": "link_meeting_desktop_v1_zoning_questions__question_id__meetings_post", + "parameters": [ + { + "name": "question_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Question Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MeetingLink" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/zoning/questions/{question_id}/snapshots": { + "post": { + "tags": [ + "native-zoning" + ], + "summary": "Create Snapshot", + "operationId": "create_snapshot_desktop_v1_zoning_questions__question_id__snapshots_post", + "parameters": [ + { + "name": "question_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Question Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SourceSnapshot" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/zoning/rules": { + "post": { + "tags": [ + "native-zoning" + ], + "summary": "Create Rule", + "operationId": "create_rule_desktop_v1_zoning_rules_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Rule" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/zoning/questions": { + "post": { + "tags": [ + "native-zoning" + ], + "summary": "Create Question", + "operationId": "create_question_desktop_v1_zoning_questions_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Question" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/zoning/workspace": { + "get": { + "tags": [ + "native-zoning" + ], + "summary": "Get Workspace", + "operationId": "get_workspace_desktop_v1_zoning_workspace_get", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/zoning/questions/{question_id}/reviews": { + "post": { + "tags": [ + "native-zoning" + ], + "summary": "Create Review", + "operationId": "create_review_desktop_v1_zoning_questions__question_id__reviews_post", + "parameters": [ + { + "name": "question_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Question Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/townlight_runtime__zoning_bridge__Review" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/zoning/outlines": { + "post": { + "tags": [ + "native-zoning" + ], + "summary": "Create Outline", + "operationId": "create_outline_desktop_v1_zoning_outlines_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Outline" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/zoning/code-context": { + "post": { + "tags": [ + "native-zoning" + ], + "summary": "Create Code Context", + "operationId": "create_code_context_desktop_v1_zoning_code_context_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CodeContext" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/zoning/standards/process-explanation": { + "post": { + "tags": [ + "native-zoning" + ], + "summary": "Standards Explanation", + "description": "Cited variance/CUP/nonconformity process; never a determination.", + "operationId": "standards_explanation_desktop_v1_zoning_standards_process_explanation_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StandardsExplanation" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/townlight_zoning/questions": { + "post": { + "summary": "Public Question", + "operationId": "public_question_townlight_zoning_questions_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Question" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/townlight_zoning/parcels/lookup": { + "post": { + "summary": "Public Parcel Lookup", + "operationId": "public_parcel_lookup_townlight_zoning_parcels_lookup_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/_ParcelLookupIn" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/imports/preview": { + "post": { + "tags": [ + "native-planning" + ], + "summary": "Preview Import", + "operationId": "preview_import_desktop_v1_planning_imports_preview_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/townlight_runtime__planning_bridge__Import" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/imports": { + "post": { + "tags": [ + "native-planning" + ], + "summary": "Import Source", + "operationId": "import_source_desktop_v1_planning_imports_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/townlight_runtime__planning_bridge__Import" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/sources": { + "get": { + "tags": [ + "native-planning" + ], + "summary": "Source List", + "operationId": "source_list_desktop_v1_planning_sources_get", + "parameters": [ + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 100, + "minimum": 1, + "default": 50, + "title": "Limit" + } + }, + { + "name": "offset", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 100000, + "minimum": 0, + "default": 0, + "title": "Offset" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/sources/{plan_id}/history": { + "get": { + "tags": [ + "native-planning" + ], + "summary": "Source History", + "operationId": "source_history_desktop_v1_planning_sources__plan_id__history_get", + "parameters": [ + { + "name": "plan_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Plan Id" + } + }, + { + "name": "offset", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 100000, + "minimum": 0, + "default": 0, + "title": "Offset" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/revisions/{revision_id}": { + "get": { + "tags": [ + "native-planning" + ], + "summary": "Revision", + "operationId": "revision_desktop_v1_planning_revisions__revision_id__get", + "parameters": [ + { + "name": "revision_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Revision Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/revisions/{revision_id}/documents/{document_id}": { + "get": { + "tags": [ + "native-planning" + ], + "summary": "Staff Original", + "operationId": "staff_original_desktop_v1_planning_revisions__revision_id__documents__document_id__get", + "parameters": [ + { + "name": "revision_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Revision Id" + } + }, + { + "name": "document_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Document Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/policies/search": { + "post": { + "tags": [ + "native-planning" + ], + "summary": "Policies", + "operationId": "policies_desktop_v1_planning_policies_search_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/townlight_runtime__planning_bridge__Search" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/analyses": { + "get": { + "tags": [ + "native-planning" + ], + "summary": "Analyses", + "operationId": "analyses_desktop_v1_planning_analyses_get", + "parameters": [ + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 100, + "minimum": 1, + "default": 50, + "title": "Limit" + } + }, + { + "name": "offset", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 100000, + "minimum": 0, + "default": 0, + "title": "Offset" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "tags": [ + "native-planning" + ], + "summary": "Create Analysis", + "operationId": "create_analysis_desktop_v1_planning_analyses_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": true, + "title": "Body" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/analyses/{analysis_id}/revisions": { + "post": { + "tags": [ + "native-planning" + ], + "summary": "Revise Analysis", + "operationId": "revise_analysis_desktop_v1_planning_analyses__analysis_id__revisions_post", + "parameters": [ + { + "name": "analysis_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Analysis Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": true, + "title": "Body" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/analyses/{analysis_id}": { + "get": { + "tags": [ + "native-planning" + ], + "summary": "Analysis", + "operationId": "analysis_desktop_v1_planning_analyses__analysis_id__get", + "parameters": [ + { + "name": "analysis_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Analysis Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/analyses/{analysis_id}/history": { + "get": { + "tags": [ + "native-planning" + ], + "summary": "Analysis History", + "operationId": "analysis_history_desktop_v1_planning_analyses__analysis_id__history_get", + "parameters": [ + { + "name": "analysis_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Analysis Id" + } + }, + { + "name": "offset", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 100000, + "minimum": 0, + "default": 0, + "title": "Offset" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/analyses/{analysis_id}/snapshot-preview": { + "post": { + "tags": [ + "native-planning" + ], + "summary": "Preview Snapshot", + "operationId": "preview_snapshot_desktop_v1_planning_analyses__analysis_id__snapshot_preview_post", + "parameters": [ + { + "name": "analysis_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Analysis Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Snapshot" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/analyses/{analysis_id}/snapshots": { + "post": { + "tags": [ + "native-planning" + ], + "summary": "Snapshot", + "operationId": "snapshot_desktop_v1_planning_analyses__analysis_id__snapshots_post", + "parameters": [ + { + "name": "analysis_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Analysis Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Snapshot" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/snapshots": { + "get": { + "tags": [ + "native-planning" + ], + "summary": "Snapshots", + "operationId": "snapshots_desktop_v1_planning_snapshots_get", + "parameters": [ + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 100, + "minimum": 1, + "default": 50, + "title": "Limit" + } + }, + { + "name": "offset", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 100000, + "minimum": 0, + "default": 0, + "title": "Offset" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/snapshots/{snapshot_id}": { + "get": { + "tags": [ + "native-planning" + ], + "summary": "Document", + "operationId": "document_desktop_v1_planning_snapshots__snapshot_id__get", + "parameters": [ + { + "name": "snapshot_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Snapshot Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/snapshots/{snapshot_id}/access-advice": { + "post": { + "tags": [ + "native-planning" + ], + "summary": "Access Advice", + "operationId": "access_advice_desktop_v1_planning_snapshots__snapshot_id__access_advice_post", + "parameters": [ + { + "name": "snapshot_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Snapshot Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/connections/search": { + "post": { + "tags": [ + "native-planning" + ], + "summary": "Connections", + "operationId": "connections_desktop_v1_planning_connections_search_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConnectionSearch" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/progress/targets": { + "get": { + "tags": [ + "native-planning" + ], + "summary": "Municipal Progress", + "operationId": "municipal_progress_desktop_v1_planning_progress_targets_get", + "parameters": [ + { + "name": "offset", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 100000, + "minimum": 0, + "default": 0, + "title": "Offset" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/amendments/history": { + "get": { + "tags": [ + "native-planning" + ], + "summary": "Municipal Amendments", + "operationId": "municipal_amendments_desktop_v1_planning_amendments_history_get", + "parameters": [ + { + "name": "offset", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 100000, + "minimum": 0, + "default": 0, + "title": "Offset" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/municipal-work/{item_id}/history": { + "get": { + "tags": [ + "native-planning" + ], + "summary": "Municipal History", + "operationId": "municipal_history_desktop_v1_planning_municipal_work__item_id__history_get", + "parameters": [ + { + "name": "item_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Item Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/initiatives": { + "post": { + "tags": [ + "native-planning" + ], + "summary": "Create Initiative", + "operationId": "create_initiative_desktop_v1_planning_initiatives_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InitiativeInput" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/initiatives/{item_id}/revisions": { + "post": { + "tags": [ + "native-planning" + ], + "summary": "Update Initiative", + "operationId": "update_initiative_desktop_v1_planning_initiatives__item_id__revisions_post", + "parameters": [ + { + "name": "item_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Item Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InitiativeInput" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/amendments": { + "post": { + "tags": [ + "native-planning" + ], + "summary": "Create Amendment", + "operationId": "create_amendment_desktop_v1_planning_amendments_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AmendmentInput" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/planning/amendments/{item_id}/revisions": { + "post": { + "tags": [ + "native-planning" + ], + "summary": "Update Amendment", + "operationId": "update_amendment_desktop_v1_planning_amendments__item_id__revisions_post", + "parameters": [ + { + "name": "item_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Item Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AmendmentInput" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/townlight_planning/policies/search": { + "post": { + "tags": [ + "local-public-planning" + ], + "summary": "Public Policies", + "operationId": "public_policies_townlight_planning_policies_search_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/townlight_runtime__planning_bridge__Search" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/townlight_planning/plan-explore": { + "post": { + "tags": [ + "local-public-planning" + ], + "summary": "Public Plan Explore", + "description": "Topic/goal/plan-type exploration over adopted public plan sources only.", + "operationId": "public_plan_explore_townlight_planning_plan_explore_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PublicExplore" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/townlight_planning/snapshots": { + "get": { + "tags": [ + "local-public-planning" + ], + "summary": "Public Snapshots", + "operationId": "public_snapshots_townlight_planning_snapshots_get", + "parameters": [ + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 100, + "minimum": 1, + "default": 50, + "title": "Limit" + } + }, + { + "name": "offset", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 100000, + "minimum": 0, + "default": 0, + "title": "Offset" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/townlight_planning/snapshots/{snapshot_id}": { + "get": { + "tags": [ + "local-public-planning" + ], + "summary": "Public Document", + "operationId": "public_document_townlight_planning_snapshots__snapshot_id__get", + "parameters": [ + { + "name": "snapshot_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Snapshot Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/townlight_planning/revisions/{revision_id}/documents/{document_id}": { + "get": { + "tags": [ + "local-public-planning" + ], + "summary": "Public Original", + "operationId": "public_original_townlight_planning_revisions__revision_id__documents__document_id__get", + "parameters": [ + { + "name": "revision_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Revision Id" + } + }, + { + "name": "document_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Document Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/permitting/requirements": { + "post": { + "tags": [ + "native-permitting" + ], + "summary": "Import Requirements", + "operationId": "import_requirements_desktop_v1_permitting_requirements_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/townlight_runtime__permitting_bridge__Import" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "get": { + "tags": [ + "native-permitting" + ], + "summary": "Requirements", + "operationId": "requirements_desktop_v1_permitting_requirements_get", + "parameters": [ + { + "name": "offset", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 100000, + "minimum": 0, + "default": 0, + "title": "Offset" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/permitting/requirements/{revision_id}": { + "get": { + "tags": [ + "native-permitting" + ], + "summary": "Requirement", + "operationId": "requirement_desktop_v1_permitting_requirements__revision_id__get", + "parameters": [ + { + "name": "revision_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Revision Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/permitting/cases": { + "get": { + "tags": [ + "native-permitting" + ], + "summary": "Cases", + "operationId": "cases_desktop_v1_permitting_cases_get", + "parameters": [ + { + "name": "offset", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 100000, + "minimum": 0, + "default": 0, + "title": "Offset" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "tags": [ + "native-permitting" + ], + "summary": "Create Case", + "operationId": "create_case_desktop_v1_permitting_cases_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IntakeInput" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/permitting/cases/{case_id}": { + "get": { + "tags": [ + "native-permitting" + ], + "summary": "Case", + "operationId": "case_desktop_v1_permitting_cases__case_id__get", + "parameters": [ + { + "name": "case_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Case Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/permitting/cases/{case_id}/revisions": { + "post": { + "tags": [ + "native-permitting" + ], + "summary": "Revise", + "operationId": "revise_desktop_v1_permitting_cases__case_id__revisions_post", + "parameters": [ + { + "name": "case_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Case Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IntakeInput" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/permitting/cases/{case_id}/history": { + "get": { + "tags": [ + "native-permitting" + ], + "summary": "History", + "operationId": "history_desktop_v1_permitting_cases__case_id__history_get", + "parameters": [ + { + "name": "case_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Case Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/permitting/cases/{case_id}/packets": { + "post": { + "tags": [ + "native-permitting" + ], + "summary": "Packet", + "operationId": "packet_desktop_v1_permitting_cases__case_id__packets_post", + "parameters": [ + { + "name": "case_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Case Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Packet" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/permitting/packets/{packet_id}": { + "get": { + "tags": [ + "native-permitting" + ], + "summary": "Document", + "operationId": "document_desktop_v1_permitting_packets__packet_id__get", + "parameters": [ + { + "name": "packet_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Packet Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/permitting/pathway": { + "post": { + "tags": [ + "native-permitting" + ], + "summary": "Pathway", + "description": "Cited likely permit pathway, attachments and timeline; informational only.\n\n``use_model_assistance`` does not exist here: the resident live-model\nassistance flag (F-07) stays excluded, so only the deterministic cited\npathway is reachable from the shared shell.", + "operationId": "pathway_desktop_v1_permitting_pathway_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Pathway" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/permitting/connections/search": { + "post": { + "tags": [ + "native-permitting" + ], + "summary": "Connections", + "operationId": "connections_desktop_v1_permitting_connections_search_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/townlight_runtime__permitting_bridge__Search" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/inspections/repeat-cases": { + "post": { + "tags": [ + "native-inspections" + ], + "summary": "Repeat Cases", + "operationId": "repeat_cases_desktop_v1_inspections_repeat_cases_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RepeatLookup" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/inspections/notice-draft": { + "post": { + "tags": [ + "native-inspections" + ], + "summary": "Notice", + "operationId": "notice_desktop_v1_inspections_notice_draft_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InspectionInput" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/inspections/cases": { + "get": { + "tags": [ + "native-inspections" + ], + "summary": "Cases", + "operationId": "cases_desktop_v1_inspections_cases_get", + "parameters": [ + { + "name": "offset", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "maximum": 100000, + "minimum": 0, + "default": 0, + "title": "Offset" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "post": { + "tags": [ + "native-inspections" + ], + "summary": "Create Case", + "operationId": "create_case_desktop_v1_inspections_cases_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InspectionInput" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/inspections/cases/{case_id}": { + "get": { + "tags": [ + "native-inspections" + ], + "summary": "Case", + "operationId": "case_desktop_v1_inspections_cases__case_id__get", + "parameters": [ + { + "name": "case_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Case Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/inspections/cases/{case_id}/revisions": { + "post": { + "tags": [ + "native-inspections" + ], + "summary": "Revise", + "operationId": "revise_desktop_v1_inspections_cases__case_id__revisions_post", + "parameters": [ + { + "name": "case_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Case Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InspectionInput" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/inspections/cases/{case_id}/history": { + "get": { + "tags": [ + "native-inspections" + ], + "summary": "History", + "operationId": "history_desktop_v1_inspections_cases__case_id__history_get", + "parameters": [ + { + "name": "case_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Case Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/inspections/cases/{case_id}/packets": { + "post": { + "tags": [ + "native-inspections" + ], + "summary": "Packet", + "operationId": "packet_desktop_v1_inspections_cases__case_id__packets_post", + "parameters": [ + { + "name": "case_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Case Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Packet" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/inspections/packets/{packet_id}": { + "get": { + "tags": [ + "native-inspections" + ], + "summary": "Document", + "operationId": "document_desktop_v1_inspections_packets__packet_id__get", + "parameters": [ + { + "name": "packet_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Packet Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/inspections/evidence/supported-types": { + "get": { + "tags": [ + "native-inspections" + ], + "summary": "Supported Types", + "description": "The media types this deployment's product model actually accepts.", + "operationId": "supported_types_desktop_v1_inspections_evidence_supported_types_get", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/inspections/evidence/retain": { + "post": { + "tags": [ + "native-inspections" + ], + "summary": "Retain", + "operationId": "retain_desktop_v1_inspections_evidence_retain_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EvidenceItems" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/inspections/media/analyse": { + "post": { + "tags": [ + "native-inspections" + ], + "summary": "Media Analyse", + "description": "Run the configured adapters over retained originals; draft only.\n\nThe result carries the same observations/citations the product route returns\nplus ``analysis_record``: the exact ``AnalysisRecord`` the caller puts on its\ncase payload, so the reviewed draft is the analysed one.", + "operationId": "media_analyse_desktop_v1_inspections_media_analyse_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MediaAnalysis" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/inspections/connections/search": { + "post": { + "tags": [ + "native-inspections" + ], + "summary": "Connections", + "operationId": "connections_desktop_v1_inspections_connections_search_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/townlight_runtime__inspections_bridge__Search" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "ActionItemInput": { + "properties": { + "description": { + "type": "string", + "minLength": 1, + "title": "Description" + }, + "assigned_to": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "source_motion_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Source Motion Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "description" + ], + "title": "ActionItemInput" + }, + "AdaPlan": { + "properties": { + "action": { + "type": "string", + "const": "ada-title-ii", + "title": "Action" + }, + "serviceArea": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Servicearea" + }, + "hasCoordinatorReview": { + "type": "boolean", + "title": "Hascoordinatorreview", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "serviceArea" + ], + "title": "AdaPlan" + }, + "AdminUserCreateRequest": { + "properties": { + "email": { + "type": "string", + "title": "Email" + }, + "password": { + "type": "string", + "title": "Password" + }, + "full_name": { + "type": "string", + "title": "Full Name", + "default": "" + }, + "role": { + "type": "string", + "title": "Role", + "default": "staff" + } + }, + "type": "object", + "required": [ + "email", + "password" + ], + "title": "AdminUserCreateRequest" + }, + "AdminUserCreateResponse": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "email": { + "type": "string", + "title": "Email" + }, + "full_name": { + "type": "string", + "title": "Full Name" + }, + "role": { + "type": "string", + "title": "Role" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + } + }, + "type": "object", + "required": [ + "id", + "email", + "full_name", + "role", + "is_active" + ], + "title": "AdminUserCreateResponse" + }, + "AgendaAssignment": { + "properties": { + "meeting_id": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "meeting_id" + ], + "title": "AgendaAssignment" + }, + "AgendaInput": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "department_name": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Department Name" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "department_name" + ], + "title": "AgendaInput" + }, + "AgendaReviewInput": { + "properties": { + "to_status": { + "type": "string", + "enum": [ + "DRAFTED", + "SUBMITTED", + "DEPT_APPROVED", + "LEGAL_REVIEWED", + "CLERK_ACCEPTED", + "ON_AGENDA", + "IN_PACKET", + "POSTED", + "HEARD", + "DISPOSED", + "ARCHIVED" + ], + "title": "To Status" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "to_status" + ], + "title": "AgendaReviewInput" + }, + "AmendmentInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "policy": { + "$ref": "#/components/schemas/PolicySelection" + }, + "proposal": { + "type": "string", + "maxLength": 20000, + "minLength": 1, + "title": "Proposal" + }, + "responsible_staff": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Responsible Staff" + }, + "status": { + "type": "string", + "enum": [ + "draft", + "review", + "adopted", + "withdrawn" + ], + "title": "Status", + "default": "draft" + }, + "review_note": { + "type": "string", + "maxLength": 5000, + "title": "Review Note", + "default": "" + }, + "adoption_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Adoption Revision" + }, + "note": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "policy", + "proposal", + "responsible_staff", + "note" + ], + "title": "AmendmentInput" + }, + "AnalysisObservation": { + "properties": { + "source": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "title": "Source" + }, + "filename": { + "type": "string", + "maxLength": 160, + "title": "Filename", + "default": "" + }, + "media_type": { + "type": "string", + "maxLength": 80, + "title": "Media Type", + "default": "" + }, + "text": { + "type": "string", + "maxLength": 4000, + "minLength": 1, + "title": "Text" + }, + "adapter": { + "type": "string", + "maxLength": 120, + "title": "Adapter", + "default": "" + }, + "citation_source_ids": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 30, + "title": "Citation Source Ids" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source", + "text" + ], + "title": "AnalysisObservation", + "description": "One draft observation, named with the adapter that actually produced it." + }, + "AnalysisRecord": { + "properties": { + "observations": { + "items": { + "$ref": "#/components/schemas/AnalysisObservation" + }, + "type": "array", + "maxItems": 30, + "title": "Observations" + }, + "cited_sections": { + "items": { + "$ref": "#/components/schemas/CitedSection" + }, + "type": "array", + "maxItems": 30, + "title": "Cited Sections" + }, + "unavailable": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 30, + "title": "Unavailable" + }, + "runtime": { + "additionalProperties": true, + "type": "object", + "title": "Runtime" + }, + "review_required": { + "type": "boolean", + "title": "Review Required", + "default": true + } + }, + "additionalProperties": false, + "type": "object", + "title": "AnalysisRecord", + "description": "The adapter output that accompanies a saved inspection draft." + }, + "ApprovalCommand": { + "properties": { + "action": { + "type": "string", + "const": "approve-records-response", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ApprovalPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "ApprovalCommand" + }, + "ApprovalPayload": { + "properties": { + "approvalNote": { + "type": "string", + "title": "Approvalnote", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "title": "ApprovalPayload" + }, + "ArchiveInput": { + "properties": { + "visibility": { + "type": "string", + "enum": [ + "public", + "closed_session" + ], + "title": "Visibility" + }, + "packet_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Packet Id" + }, + "minutes_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Minutes Id" + }, + "plain_language_summary": { + "type": "string", + "title": "Plain Language Summary", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "visibility" + ], + "title": "ArchiveInput" + }, + "ArtifactPlan": { + "properties": { + "artifact_id": { + "type": "string", + "title": "Artifact Id" + }, + "file_name": { + "type": "string", + "title": "File Name" + }, + "content": { + "type": "string", + "title": "Content" + }, + "sha256": { + "type": "string", + "title": "Sha256" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "artifact_id", + "file_name", + "content", + "sha256", + "created_at_unix_seconds" + ], + "title": "ArtifactPlan" + }, + "AssignCommand": { + "properties": { + "action": { + "type": "string", + "const": "assign-records-request", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/AssignmentPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "AssignCommand" + }, + "AssignmentPayload": { + "properties": { + "assignedTo": { + "type": "string", + "minLength": 1, + "title": "Assignedto" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "assignedTo" + ], + "title": "AssignmentPayload" + }, + "AttachDocument": { + "properties": { + "title": { + "type": "string", + "minLength": 1, + "title": "Title" + }, + "citation": { + "type": "string", + "title": "Citation", + "default": "" + }, + "file": { + "$ref": "#/components/schemas/ManagedFileReceipt" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "file" + ], + "title": "AttachDocument" + }, + "AttachReleaseCopy": { + "properties": { + "status": { + "type": "string", + "enum": [ + "release-ready copy", + "redacted copy" + ], + "title": "Status" + }, + "note": { + "type": "string", + "title": "Note", + "default": "" + }, + "added_by": { + "type": "string", + "title": "Added By", + "default": "" + }, + "file": { + "$ref": "#/components/schemas/ManagedFileReceipt" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "status", + "file" + ], + "title": "AttachReleaseCopy" + }, + "AuditChainVerification": { + "properties": { + "is_valid": { + "type": "boolean", + "title": "Is Valid" + }, + "entries_checked": { + "type": "integer", + "title": "Entries Checked" + }, + "error_message": { + "type": "string", + "title": "Error Message" + } + }, + "type": "object", + "required": [ + "is_valid", + "entries_checked", + "error_message" + ], + "title": "AuditChainVerification" + }, + "AuditLogRead": { + "properties": { + "id": { + "type": "integer", + "title": "Id" + }, + "prev_hash": { + "type": "string", + "title": "Prev Hash" + }, + "entry_hash": { + "type": "string", + "title": "Entry Hash" + }, + "timestamp": { + "type": "string", + "format": "date-time", + "title": "Timestamp" + }, + "user_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "User Id" + }, + "action": { + "type": "string", + "title": "Action" + }, + "resource_type": { + "type": "string", + "title": "Resource Type" + }, + "resource_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Resource Id" + }, + "details": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Details" + }, + "ai_generated": { + "type": "boolean", + "title": "Ai Generated" + } + }, + "type": "object", + "required": [ + "id", + "prev_hash", + "entry_hash", + "timestamp", + "user_id", + "action", + "resource_type", + "resource_id", + "details", + "ai_generated" + ], + "title": "AuditLogRead" + }, + "AuditView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "module_id": { + "type": "string", + "title": "Module Id" + }, + "action": { + "type": "string", + "title": "Action" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + }, + "previous_hash": { + "type": "string", + "title": "Previous Hash" + }, + "entry_hash": { + "type": "string", + "title": "Entry Hash" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "module_id", + "action", + "summary", + "created_at_unix_seconds", + "previous_hash", + "entry_hash" + ], + "title": "AuditView" + }, + "BearerResponse": { + "properties": { + "access_token": { + "type": "string", + "title": "Access Token" + }, + "token_type": { + "type": "string", + "title": "Token Type" + } + }, + "type": "object", + "required": [ + "access_token", + "token_type" + ], + "title": "BearerResponse" + }, + "Body_auth_jwt_login_auth_jwt_login_post": { + "properties": { + "grant_type": { + "anyOf": [ + { + "type": "string", + "pattern": "^password$" + }, + { + "type": "null" + } + ], + "title": "Grant Type" + }, + "username": { + "type": "string", + "title": "Username" + }, + "password": { + "type": "string", + "format": "password", + "title": "Password" + }, + "scope": { + "type": "string", + "title": "Scope", + "default": "" + }, + "client_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Client Id" + }, + "client_secret": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "format": "password", + "title": "Client Secret" + } + }, + "type": "object", + "required": [ + "username", + "password" + ], + "title": "Body_auth_jwt_login_auth_jwt_login_post" + }, + "Body_upload_file_datasources_upload_post": { + "properties": { + "file": { + "type": "string", + "contentMediaType": "application/octet-stream", + "title": "File" + } + }, + "type": "object", + "required": [ + "file" + ], + "title": "Body_upload_file_datasources_upload_post" + }, + "CalculateDeadlineCommand": { + "properties": { + "action": { + "type": "string", + "const": "calculate-records-deadline", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/CalculateDeadlinePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "CalculateDeadlineCommand" + }, + "CalculateDeadlinePayload": { + "properties": { + "deadlineReceivedDate": { + "type": "string", + "title": "Deadlinereceiveddate" + }, + "deadlineRuleName": { + "type": "string", + "minLength": 1, + "title": "Deadlinerulename" + }, + "deadlineDayCount": { + "type": "string", + "title": "Deadlinedaycount" + }, + "deadlineDayType": { + "type": "string", + "title": "Deadlinedaytype" + }, + "deadlineBasis": { + "type": "string", + "minLength": 1, + "title": "Deadlinebasis" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "deadlineReceivedDate", + "deadlineRuleName", + "deadlineDayCount", + "deadlineDayType", + "deadlineBasis" + ], + "title": "CalculateDeadlinePayload" + }, + "ChapterCreate": { + "properties": { + "chapter_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Chapter Id" + }, + "title_id": { + "type": "string", + "minLength": 1, + "title": "Title Id" + }, + "chapter_number": { + "type": "string", + "minLength": 1, + "title": "Chapter Number" + }, + "chapter_name": { + "type": "string", + "minLength": 1, + "title": "Chapter Name" + }, + "sort_order": { + "type": "integer", + "title": "Sort Order", + "default": 0 + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title_id", + "chapter_number", + "chapter_name" + ], + "title": "ChapterCreate", + "description": "Request body for creating a code chapter." + }, + "CitedSection": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "citation": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Citation" + }, + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "version": { + "type": "string", + "maxLength": 80, + "title": "Version", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "citation" + ], + "title": "CitedSection", + "description": "One resolved public Code section; never a caller-supplied quotation." + }, + "CityProfileCreate": { + "properties": { + "city_name": { + "type": "string", + "title": "City Name" + }, + "state": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State" + }, + "county": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "County" + }, + "population_band": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Population Band" + }, + "email_platform": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Email Platform" + }, + "has_dedicated_it": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Has Dedicated It" + }, + "monthly_request_volume": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Monthly Request Volume" + }, + "profile_data": { + "additionalProperties": true, + "type": "object", + "title": "Profile Data", + "default": {} + }, + "gap_map": { + "additionalProperties": true, + "type": "object", + "title": "Gap Map", + "default": {} + } + }, + "type": "object", + "required": [ + "city_name" + ], + "title": "CityProfileCreate" + }, + "CityProfileRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "city_name": { + "type": "string", + "title": "City Name" + }, + "state": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State" + }, + "county": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "County" + }, + "population_band": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Population Band" + }, + "email_platform": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Email Platform" + }, + "has_dedicated_it": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Has Dedicated It" + }, + "monthly_request_volume": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Monthly Request Volume" + }, + "onboarding_status": { + "type": "string", + "title": "Onboarding Status" + }, + "profile_data": { + "additionalProperties": true, + "type": "object", + "title": "Profile Data" + }, + "gap_map": { + "additionalProperties": true, + "type": "object", + "title": "Gap Map" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "city_name", + "state", + "county", + "population_band", + "email_platform", + "has_dedicated_it", + "monthly_request_volume", + "onboarding_status", + "profile_data", + "gap_map", + "created_at", + "updated_at" + ], + "title": "CityProfileRead" + }, + "CityProfileUpdate": { + "properties": { + "city_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "City Name" + }, + "state": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State" + }, + "county": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "County" + }, + "population_band": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Population Band" + }, + "email_platform": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Email Platform" + }, + "has_dedicated_it": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Has Dedicated It" + }, + "monthly_request_volume": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Monthly Request Volume" + }, + "onboarding_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Onboarding Status" + }, + "profile_data": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Profile Data" + }, + "gap_map": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Gap Map" + } + }, + "type": "object", + "title": "CityProfileUpdate" + }, + "ClarificationCommand": { + "properties": { + "action": { + "type": "string", + "const": "request-records-clarification", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ClarificationPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "ClarificationCommand" + }, + "ClarificationPayload": { + "properties": { + "clarificationNote": { + "type": "string", + "minLength": 1, + "title": "Clarificationnote" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "clarificationNote" + ], + "title": "ClarificationPayload" + }, + "Closeout": { + "properties": { + "decision_id": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Decision Id" + }, + "version_id": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Version Id" + }, + "source_id": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Source Id" + }, + "version_label": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Version Label" + }, + "body": { + "type": "string", + "maxLength": 1000000, + "minLength": 1, + "title": "Body" + }, + "effective_start": { + "type": "string", + "format": "date", + "title": "Effective Start" + }, + "effective_end": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective End" + }, + "is_current": { + "type": "boolean", + "title": "Is Current" + }, + "reconciliation_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reconciliation Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "decision_id", + "version_id", + "source_id", + "version_label", + "body", + "effective_start", + "is_current" + ], + "title": "Closeout" + }, + "CodeContext": { + "properties": { + "section_number": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Section Number" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "section_number" + ], + "title": "CodeContext" + }, + "CodeLink": { + "properties": { + "provider": { + "type": "string", + "const": "code", + "title": "Provider", + "default": "code" + }, + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "CodeLink" + }, + "CodeSearch": { + "properties": { + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "CodeSearch" + }, + "CodeSourceSelection": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "CodeSourceSelection" + }, + "CompleteArtifact": { + "properties": { + "export_path": { + "type": "string", + "minLength": 1, + "title": "Export Path" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "export_path" + ], + "title": "CompleteArtifact" + }, + "ConnectionSearch": { + "properties": { + "provider": { + "type": "string", + "enum": [ + "meetings", + "zoning" + ], + "title": "Provider" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "query" + ], + "title": "ConnectionSearch" + }, + "CoverageGapResponse": { + "properties": { + "jurisdictions_without_rules": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Jurisdictions Without Rules" + }, + "departments_without_staff": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array", + "title": "Departments Without Staff" + }, + "uncovered_categories": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Uncovered Categories" + }, + "total_gaps": { + "type": "integer", + "title": "Total Gaps" + } + }, + "type": "object", + "required": [ + "jurisdictions_without_rules", + "departments_without_staff", + "uncovered_categories", + "total_gaps" + ], + "title": "CoverageGapResponse" + }, + "DataSourceAdminRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "source_type": { + "$ref": "#/components/schemas/SourceType" + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "type": "boolean", + "title": "Schedule Enabled", + "default": true + }, + "next_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Next Sync At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "last_ingestion_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Ingestion At" + }, + "last_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Sync At" + }, + "last_sync_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Sync Status" + }, + "last_error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Error Message" + }, + "consecutive_failure_count": { + "type": "integer", + "title": "Consecutive Failure Count", + "default": 0 + }, + "sync_paused": { + "type": "boolean", + "title": "Sync Paused", + "default": false + }, + "health_status": { + "type": "string", + "title": "Health Status", + "default": "healthy" + }, + "active_failure_count": { + "type": "integer", + "title": "Active Failure Count", + "default": 0 + }, + "connector_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Connector Type" + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At" + }, + "connection_config": { + "additionalProperties": true, + "type": "object", + "title": "Connection Config" + } + }, + "type": "object", + "required": [ + "id", + "name", + "source_type", + "is_active", + "created_by", + "created_at", + "last_ingestion_at", + "connection_config" + ], + "title": "DataSourceAdminRead", + "description": "Full datasource shape including connection_config. Returned only by admin-gated endpoints." + }, + "DataSourceCreate": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "source_type": { + "$ref": "#/components/schemas/SourceType" + }, + "connection_config": { + "additionalProperties": true, + "type": "object", + "title": "Connection Config", + "default": {} + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "type": "boolean", + "title": "Schedule Enabled", + "default": true + } + }, + "type": "object", + "required": [ + "name", + "source_type" + ], + "title": "DataSourceCreate" + }, + "DataSourceRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "source_type": { + "$ref": "#/components/schemas/SourceType" + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "type": "boolean", + "title": "Schedule Enabled", + "default": true + }, + "next_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Next Sync At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "last_ingestion_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Ingestion At" + }, + "last_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Sync At" + }, + "last_sync_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Sync Status" + }, + "last_error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Error Message" + }, + "consecutive_failure_count": { + "type": "integer", + "title": "Consecutive Failure Count", + "default": 0 + }, + "sync_paused": { + "type": "boolean", + "title": "Sync Paused", + "default": false + }, + "health_status": { + "type": "string", + "title": "Health Status", + "default": "healthy" + }, + "active_failure_count": { + "type": "integer", + "title": "Active Failure Count", + "default": 0 + }, + "connector_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Connector Type" + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "name", + "source_type", + "is_active", + "created_by", + "created_at", + "last_ingestion_at" + ], + "title": "DataSourceRead", + "description": "Redacted datasource shape — safe for non-admin roles. connection_config omitted." + }, + "DataSourceUpdate": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "connection_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Connection Config" + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Schedule Enabled" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "DataSourceUpdate" + }, + "DeadlineCommand": { + "properties": { + "action": { + "type": "string", + "const": "set-records-deadline", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/DeadlinePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "DeadlineCommand" + }, + "DeadlinePayload": { + "properties": { + "deadline": { + "type": "string", + "title": "Deadline" + }, + "deadlineBasis": { + "type": "string", + "minLength": 1, + "title": "Deadlinebasis" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "deadline", + "deadlineBasis" + ], + "title": "DeadlinePayload" + }, + "Decision": { + "properties": { + "id": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Id" + }, + "outcome": { + "type": "string", + "enum": [ + "adopted", + "not_adopted", + "deferred", + "withdrawn" + ], + "title": "Outcome" + }, + "decided_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Decided At" + }, + "decision_text": { + "type": "string", + "maxLength": 1000000, + "minLength": 1, + "title": "Decision Text" + }, + "supporting_references": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Supporting References" + }, + "supersedes_decision_id": { + "anyOf": [ + { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$" + }, + { + "type": "null" + } + ], + "title": "Supersedes Decision Id" + }, + "reconciliation_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reconciliation Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "outcome", + "decision_text" + ], + "title": "Decision" + }, + "DepartmentCreate": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "code": { + "type": "string", + "title": "Code" + }, + "contact_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Contact Email" + } + }, + "type": "object", + "required": [ + "name", + "code" + ], + "title": "DepartmentCreate" + }, + "DepartmentRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "code": { + "type": "string", + "title": "Code" + }, + "contact_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Contact Email" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "name", + "code", + "contact_email", + "created_at" + ], + "title": "DepartmentRead" + }, + "DepartmentUpdate": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Code" + }, + "contact_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Contact Email" + } + }, + "type": "object", + "title": "DepartmentUpdate" + }, + "DisclosureTemplateCreate": { + "properties": { + "template_type": { + "type": "string", + "title": "Template Type" + }, + "state_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State Code" + }, + "content": { + "type": "string", + "title": "Content" + } + }, + "type": "object", + "required": [ + "template_type", + "content" + ], + "title": "DisclosureTemplateCreate" + }, + "DisclosureTemplateRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "template_type": { + "type": "string", + "title": "Template Type" + }, + "state_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State Code" + }, + "content": { + "type": "string", + "title": "Content" + }, + "version": { + "type": "integer", + "title": "Version" + }, + "updated_by": { + "type": "string", + "format": "uuid", + "title": "Updated By" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "template_type", + "state_code", + "content", + "version", + "updated_by", + "updated_at" + ], + "title": "DisclosureTemplateRead" + }, + "DisclosureTemplateRendered": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "template_type": { + "type": "string", + "title": "Template Type" + }, + "rendered_content": { + "type": "string", + "title": "Rendered Content" + }, + "has_unresolved_variables": { + "type": "boolean", + "title": "Has Unresolved Variables" + } + }, + "type": "object", + "required": [ + "id", + "template_type", + "rendered_content", + "has_unresolved_variables" + ], + "title": "DisclosureTemplateRendered" + }, + "DisclosureTemplateUpdate": { + "properties": { + "content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Content" + }, + "state_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State Code" + } + }, + "type": "object", + "title": "DisclosureTemplateUpdate" + }, + "DocumentChunkRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "chunk_index": { + "type": "integer", + "title": "Chunk Index" + }, + "content_text": { + "type": "string", + "title": "Content Text" + }, + "token_count": { + "type": "integer", + "title": "Token Count" + }, + "page_number": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Page Number" + } + }, + "type": "object", + "required": [ + "id", + "document_id", + "chunk_index", + "content_text", + "token_count", + "page_number" + ], + "title": "DocumentChunkRead" + }, + "DocumentRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "source_id": { + "type": "string", + "format": "uuid", + "title": "Source Id" + }, + "source_path": { + "type": "string", + "title": "Source Path" + }, + "filename": { + "type": "string", + "title": "Filename" + }, + "file_type": { + "type": "string", + "title": "File Type" + }, + "file_hash": { + "type": "string", + "title": "File Hash" + }, + "file_size": { + "type": "integer", + "title": "File Size" + }, + "ingestion_status": { + "$ref": "#/components/schemas/IngestionStatus" + }, + "ingestion_error": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Ingestion Error" + }, + "chunk_count": { + "type": "integer", + "title": "Chunk Count" + }, + "ingested_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Ingested At" + }, + "connector_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Connector Type" + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "source_id", + "source_path", + "filename", + "file_type", + "file_hash", + "file_size", + "ingestion_status", + "ingestion_error", + "chunk_count", + "ingested_at" + ], + "title": "DocumentRead" + }, + "DraftCommand": { + "properties": { + "action": { + "type": "string", + "const": "draft-records-response", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/DraftPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "DraftCommand" + }, + "DraftInput": { + "properties": { + "source_materials": { + "items": { + "$ref": "#/components/schemas/SourceInput" + }, + "type": "array", + "title": "Source Materials" + }, + "sentences": { + "items": { + "$ref": "#/components/schemas/SentenceInput" + }, + "type": "array", + "minItems": 1, + "title": "Sentences" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sentences" + ], + "title": "DraftInput" + }, + "DraftPayload": { + "properties": { + "responseDraft": { + "type": "string", + "minLength": 1, + "title": "Responsedraft" + }, + "citation": { + "type": "string", + "title": "Citation", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "responseDraft" + ], + "title": "DraftPayload" + }, + "ErrorModel": { + "properties": { + "detail": { + "anyOf": [ + { + "type": "string" + }, + { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + ], + "title": "Detail" + } + }, + "type": "object", + "required": [ + "detail" + ], + "title": "ErrorModel" + }, + "Evidence": { + "properties": { + "filename": { + "type": "string", + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$", + "title": "Filename" + }, + "description": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Description" + }, + "media_type": { + "type": "string", + "enum": [ + "text/plain", + "image/jpeg", + "image/png", + "image/webp", + "application/pdf", + "audio/webm", + "audio/ogg", + "audio/wav", + "audio/mpeg", + "audio/mp4" + ], + "title": "Media Type" + }, + "content_base64": { + "type": "string", + "maxLength": 14000000, + "minLength": 1, + "title": "Content Base64" + }, + "sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "filename", + "description", + "media_type", + "content_base64", + "sha256" + ], + "title": "Evidence" + }, + "EvidenceItem": { + "properties": { + "filename": { + "type": "string", + "maxLength": 151, + "minLength": 1, + "title": "Filename" + }, + "media_type": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Media Type" + }, + "description": { + "type": "string", + "maxLength": 2000, + "title": "Description", + "default": "" + }, + "content_base64": { + "type": "string", + "maxLength": 14000000, + "minLength": 1, + "title": "Content Base64" + }, + "sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "filename", + "media_type", + "content_base64", + "sha256" + ], + "title": "EvidenceItem" + }, + "EvidenceItems": { + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/EvidenceItem" + }, + "type": "array", + "maxItems": 10, + "minItems": 1, + "title": "Items" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "items" + ], + "title": "EvidenceItems" + }, + "ExemptionAccuracyReport": { + "properties": { + "category": { + "type": "string", + "title": "Category" + }, + "total_flags": { + "type": "integer", + "title": "Total Flags" + }, + "accepted": { + "type": "integer", + "title": "Accepted" + }, + "rejected": { + "type": "integer", + "title": "Rejected" + }, + "pending": { + "type": "integer", + "title": "Pending" + }, + "acceptance_rate": { + "type": "number", + "title": "Acceptance Rate" + } + }, + "type": "object", + "required": [ + "category", + "total_flags", + "accepted", + "rejected", + "pending", + "acceptance_rate" + ], + "title": "ExemptionAccuracyReport" + }, + "ExemptionDashboard": { + "properties": { + "total_flags": { + "type": "integer", + "title": "Total Flags" + }, + "by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "By Status" + }, + "by_category": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "By Category" + }, + "acceptance_rate": { + "type": "number", + "title": "Acceptance Rate" + }, + "total_rules": { + "type": "integer", + "title": "Total Rules" + }, + "active_rules": { + "type": "integer", + "title": "Active Rules" + } + }, + "type": "object", + "required": [ + "total_flags", + "by_status", + "by_category", + "acceptance_rate", + "total_rules", + "active_rules" + ], + "title": "ExemptionDashboard" + }, + "ExemptionDecisionCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-exemption-decision", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ExemptionDecisionPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "ExemptionDecisionCommand" + }, + "ExemptionDecisionPayload": { + "properties": { + "exemptionSource": { + "type": "string", + "minLength": 1, + "title": "Exemptionsource" + }, + "exemptionKind": { + "type": "string", + "minLength": 1, + "title": "Exemptionkind" + }, + "exemptionFinding": { + "type": "string", + "minLength": 1, + "title": "Exemptionfinding" + }, + "exemptionDecision": { + "type": "string", + "enum": [ + "release", + "redact", + "exempt" + ], + "title": "Exemptiondecision" + }, + "exemptionBasis": { + "type": "string", + "minLength": 1, + "title": "Exemptionbasis" + }, + "exemptionReviewer": { + "type": "string", + "title": "Exemptionreviewer", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "exemptionSource", + "exemptionKind", + "exemptionFinding", + "exemptionDecision", + "exemptionBasis" + ], + "title": "ExemptionDecisionPayload" + }, + "ExemptionDecisionView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "source": { + "type": "string", + "title": "Source" + }, + "kind": { + "type": "string", + "title": "Kind" + }, + "finding": { + "type": "string", + "title": "Finding" + }, + "decision": { + "type": "string", + "enum": [ + "release", + "redact", + "exempt" + ], + "title": "Decision" + }, + "basis": { + "type": "string", + "title": "Basis" + }, + "reviewer": { + "type": "string", + "title": "Reviewer" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "source", + "kind", + "finding", + "decision", + "basis", + "reviewer", + "created_at_unix_seconds" + ], + "title": "ExemptionDecisionView" + }, + "ExemptionFlagRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "chunk_id": { + "type": "string", + "format": "uuid", + "title": "Chunk Id" + }, + "rule_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Rule Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "category": { + "type": "string", + "title": "Category" + }, + "matched_text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Matched Text" + }, + "confidence": { + "type": "number", + "title": "Confidence" + }, + "status": { + "$ref": "#/components/schemas/FlagStatus" + }, + "reviewed_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Reviewed By" + }, + "reviewed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Reviewed At" + }, + "review_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Reason" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "chunk_id", + "rule_id", + "request_id", + "category", + "matched_text", + "confidence", + "status", + "reviewed_by", + "reviewed_at", + "review_reason", + "created_at" + ], + "title": "ExemptionFlagRead" + }, + "ExemptionFlagReview": { + "properties": { + "status": { + "$ref": "#/components/schemas/FlagStatus" + }, + "review_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Reason" + } + }, + "type": "object", + "required": [ + "status" + ], + "title": "ExemptionFlagReview" + }, + "ExemptionNoteCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-exemption-review", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ExemptionNotePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "ExemptionNoteCommand" + }, + "ExemptionNotePayload": { + "properties": { + "exemptionNote": { + "type": "string", + "minLength": 1, + "title": "Exemptionnote" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "exemptionNote" + ], + "title": "ExemptionNotePayload" + }, + "ExemptionRuleCreate": { + "properties": { + "state_code": { + "type": "string", + "title": "State Code" + }, + "category": { + "type": "string", + "title": "Category" + }, + "rule_type": { + "$ref": "#/components/schemas/RuleType" + }, + "rule_definition": { + "type": "string", + "title": "Rule Definition" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "enabled": { + "type": "boolean", + "title": "Enabled", + "default": true + } + }, + "type": "object", + "required": [ + "state_code", + "category", + "rule_type", + "rule_definition" + ], + "title": "ExemptionRuleCreate" + }, + "ExemptionRuleRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "state_code": { + "type": "string", + "title": "State Code" + }, + "category": { + "type": "string", + "title": "Category" + }, + "rule_type": { + "$ref": "#/components/schemas/RuleType" + }, + "rule_definition": { + "type": "string", + "title": "Rule Definition" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "enabled": { + "type": "boolean", + "title": "Enabled" + }, + "version": { + "type": "integer", + "title": "Version", + "default": 1 + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "state_code", + "category", + "rule_type", + "rule_definition", + "description", + "enabled", + "created_by", + "created_at" + ], + "title": "ExemptionRuleRead" + }, + "ExemptionRuleUpdate": { + "properties": { + "rule_definition": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Rule Definition" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "enabled": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Enabled" + } + }, + "type": "object", + "title": "ExemptionRuleUpdate" + }, + "ExportReceipt": { + "properties": { + "export_path": { + "type": "string", + "maxLength": 32768, + "minLength": 1, + "title": "Export Path" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "export_path" + ], + "title": "ExportReceipt" + }, + "FeeEstimateCommand": { + "properties": { + "action": { + "type": "string", + "const": "estimate-records-fee", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/FeeEstimatePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "FeeEstimateCommand" + }, + "FeeEstimatePayload": { + "properties": { + "feeEstimate": { + "type": "string", + "minLength": 1, + "title": "Feeestimate" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "feeEstimate" + ], + "title": "FeeEstimatePayload" + }, + "FeeEstimateRequest": { + "properties": { + "page_count": { + "type": "integer", + "title": "Page Count" + }, + "fee_schedule_id": { + "type": "string", + "format": "uuid", + "title": "Fee Schedule Id" + } + }, + "type": "object", + "required": [ + "page_count", + "fee_schedule_id" + ], + "title": "FeeEstimateRequest" + }, + "FeeEstimateResponse": { + "properties": { + "page_count": { + "type": "integer", + "title": "Page Count" + }, + "unit_price": { + "type": "number", + "title": "Unit Price" + }, + "total": { + "type": "number", + "title": "Total" + }, + "fee_type": { + "type": "string", + "title": "Fee Type" + }, + "description": { + "type": "string", + "title": "Description" + } + }, + "type": "object", + "required": [ + "page_count", + "unit_price", + "total", + "fee_type", + "description" + ], + "title": "FeeEstimateResponse" + }, + "FeeLineCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-fee-line", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/FeeLinePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "FeeLineCommand" + }, + "FeeLineItemCreate": { + "properties": { + "description": { + "type": "string", + "title": "Description" + }, + "quantity": { + "type": "integer", + "title": "Quantity", + "default": 1 + }, + "unit_price": { + "type": "number", + "title": "Unit Price" + }, + "fee_schedule_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Fee Schedule Id" + } + }, + "type": "object", + "required": [ + "description", + "unit_price" + ], + "title": "FeeLineItemCreate" + }, + "FeeLineItemRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "fee_schedule_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Fee Schedule Id" + }, + "description": { + "type": "string", + "title": "Description" + }, + "quantity": { + "type": "integer", + "title": "Quantity" + }, + "unit_price": { + "type": "number", + "title": "Unit Price" + }, + "total": { + "type": "number", + "title": "Total" + }, + "status": { + "type": "string", + "title": "Status" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "fee_schedule_id", + "description", + "quantity", + "unit_price", + "total", + "status", + "created_at" + ], + "title": "FeeLineItemRead" + }, + "FeeLinePayload": { + "properties": { + "feeLineDescription": { + "type": "string", + "minLength": 1, + "title": "Feelinedescription" + }, + "feeScheduleBasis": { + "type": "string", + "minLength": 1, + "title": "Feeschedulebasis" + }, + "feeLineAmount": { + "type": "string", + "title": "Feelineamount" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "feeLineDescription", + "feeScheduleBasis", + "feeLineAmount" + ], + "title": "FeeLinePayload" + }, + "FeeLineView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "description": { + "type": "string", + "title": "Description" + }, + "schedule_basis": { + "type": "string", + "title": "Schedule Basis" + }, + "amount_cents": { + "type": "integer", + "title": "Amount Cents" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "description", + "schedule_basis", + "amount_cents", + "created_at_unix_seconds" + ], + "title": "FeeLineView" + }, + "FeeScheduleCreate": { + "properties": { + "jurisdiction": { + "type": "string", + "title": "Jurisdiction" + }, + "fee_type": { + "type": "string", + "title": "Fee Type" + }, + "amount": { + "type": "number", + "title": "Amount" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "effective_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective Date" + } + }, + "type": "object", + "required": [ + "jurisdiction", + "fee_type", + "amount" + ], + "title": "FeeScheduleCreate" + }, + "FeeScheduleRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "jurisdiction": { + "type": "string", + "title": "Jurisdiction" + }, + "fee_type": { + "type": "string", + "title": "Fee Type" + }, + "amount": { + "type": "number", + "title": "Amount" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "effective_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective Date" + }, + "created_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "jurisdiction", + "fee_type", + "amount", + "description", + "effective_date", + "created_by", + "created_at" + ], + "title": "FeeScheduleRead" + }, + "FeeScheduleUpdate": { + "properties": { + "fee_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Fee Type" + }, + "amount": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Amount" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "effective_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective Date" + } + }, + "type": "object", + "title": "FeeScheduleUpdate" + }, + "FeeWaiverCommand": { + "properties": { + "action": { + "type": "string", + "const": "waive-records-fee", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/FeeWaiverPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "FeeWaiverCommand" + }, + "FeeWaiverCreateRequest": { + "properties": { + "waiver_type": { + "type": "string", + "title": "Waiver Type" + }, + "reason": { + "type": "string", + "title": "Reason" + } + }, + "type": "object", + "required": [ + "waiver_type", + "reason" + ], + "title": "FeeWaiverCreateRequest" + }, + "FeeWaiverPayload": { + "properties": { + "feeWaiverReason": { + "type": "string", + "minLength": 1, + "title": "Feewaiverreason" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "feeWaiverReason" + ], + "title": "FeeWaiverPayload" + }, + "FeeWaiverReadResponse": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "waiver_type": { + "type": "string", + "title": "Waiver Type" + }, + "reason": { + "type": "string", + "title": "Reason" + }, + "status": { + "type": "string", + "title": "Status" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + }, + "created_at": { + "type": "string", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "waiver_type", + "reason", + "status", + "created_at" + ], + "title": "FeeWaiverReadResponse" + }, + "FeeWaiverReviewRequest": { + "properties": { + "status": { + "type": "string", + "title": "Status" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + } + }, + "type": "object", + "required": [ + "status" + ], + "title": "FeeWaiverReviewRequest" + }, + "FinishCommand": { + "properties": { + "action": { + "type": "string", + "enum": [ + "fulfill-records-request", + "close-records-request" + ], + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/NativePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "FinishCommand" + }, + "FlagStatus": { + "type": "string", + "enum": [ + "flagged", + "reviewed", + "accepted", + "rejected" + ], + "title": "FlagStatus" + }, + "FormPlan": { + "properties": { + "action": { + "type": "string", + "const": "form-plan", + "title": "Action" + }, + "formName": { + "type": "string", + "maxLength": 500, + "title": "Formname", + "default": "" + }, + "fields": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 50, + "title": "Fields" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "FormPlan" + }, + "GeneratedDraft": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "model": { + "type": "string", + "minLength": 1, + "title": "Model" + }, + "previous_response_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Previous Response Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text", + "model", + "previous_response_sha256" + ], + "title": "GeneratedDraft" + }, + "HTTPValidationError": { + "properties": { + "detail": { + "items": { + "$ref": "#/components/schemas/ValidationError" + }, + "type": "array", + "title": "Detail" + } + }, + "type": "object", + "title": "HTTPValidationError" + }, + "Handoff": { + "properties": { + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "request_id" + ], + "title": "Handoff" + }, + "ImportBundleCreate": { + "properties": { + "job_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Job Id" + }, + "connector_type": { + "type": "string", + "minLength": 1, + "title": "Connector Type" + }, + "source": { + "$ref": "#/components/schemas/SourceCreate" + }, + "sources": { + "items": { + "$ref": "#/components/schemas/SourceCreate" + }, + "type": "array", + "title": "Sources" + }, + "titles": { + "items": { + "$ref": "#/components/schemas/TitleCreate" + }, + "type": "array", + "title": "Titles" + }, + "chapters": { + "items": { + "$ref": "#/components/schemas/ChapterCreate" + }, + "type": "array", + "title": "Chapters" + }, + "sections": { + "items": { + "$ref": "#/components/schemas/SectionCreate" + }, + "type": "array", + "title": "Sections" + }, + "versions": { + "items": { + "$ref": "#/components/schemas/SectionVersionCreate" + }, + "type": "array", + "title": "Versions" + }, + "provenance": { + "additionalProperties": true, + "type": "object", + "title": "Provenance" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "connector_type", + "source" + ], + "title": "ImportBundleCreate", + "description": "Request body for local fixture/file-drop import jobs." + }, + "InclusionStatus": { + "type": "string", + "enum": [ + "included", + "excluded", + "pending" + ], + "title": "InclusionStatus" + }, + "IngestionStats": { + "properties": { + "total_sources": { + "type": "integer", + "title": "Total Sources" + }, + "active_sources": { + "type": "integer", + "title": "Active Sources" + }, + "total_documents": { + "type": "integer", + "title": "Total Documents" + }, + "documents_by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Documents By Status" + }, + "total_chunks": { + "type": "integer", + "title": "Total Chunks" + } + }, + "type": "object", + "required": [ + "total_sources", + "active_sources", + "total_documents", + "documents_by_status", + "total_chunks" + ], + "title": "IngestionStats" + }, + "IngestionStatus": { + "type": "string", + "enum": [ + "pending", + "processing", + "completed", + "failed" + ], + "title": "IngestionStatus" + }, + "InitiativeInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "policy": { + "$ref": "#/components/schemas/PolicySelection" + }, + "responsible_staff": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Responsible Staff" + }, + "target": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "title": "Target" + }, + "unit": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Unit" + }, + "due_on": { + "type": "string", + "format": "date", + "title": "Due On" + }, + "status": { + "type": "string", + "enum": [ + "planned", + "active", + "completed", + "cancelled" + ], + "title": "Status", + "default": "planned" + }, + "milestones": { + "items": { + "$ref": "#/components/schemas/Milestone" + }, + "type": "array", + "maxItems": 100, + "title": "Milestones" + }, + "measurements": { + "items": { + "$ref": "#/components/schemas/Measurement" + }, + "type": "array", + "maxItems": 1000, + "title": "Measurements" + }, + "note": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "policy", + "responsible_staff", + "target", + "unit", + "due_on", + "note" + ], + "title": "InitiativeInput" + }, + "InspectionInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "property_reference": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Property Reference" + }, + "inspection_reference": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Inspection Reference" + }, + "dataset_kind": { + "type": "string", + "enum": [ + "municipal", + "fictional" + ], + "title": "Dataset Kind" + }, + "inspector_notes": { + "type": "string", + "maxLength": 10000, + "minLength": 1, + "title": "Inspector Notes" + }, + "photo_observations": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 30, + "title": "Photo Observations" + }, + "voice_notes": { + "type": "string", + "maxLength": 10000, + "title": "Voice Notes", + "default": "" + }, + "evidence": { + "items": { + "$ref": "#/components/schemas/Evidence" + }, + "type": "array", + "maxItems": 10, + "title": "Evidence" + }, + "linked_sources": { + "items": { + "$ref": "#/components/schemas/townlight_inspections__workflow_models__SourceLink" + }, + "type": "array", + "maxItems": 30, + "title": "Linked Sources" + }, + "assigned_to": { + "type": "string", + "maxLength": 255, + "title": "Assigned To", + "default": "" + }, + "staff_notes": { + "type": "string", + "maxLength": 10000, + "title": "Staff Notes", + "default": "" + }, + "notice_draft": { + "type": "string", + "maxLength": 10000, + "title": "Notice Draft", + "default": "" + }, + "review_state": { + "type": "string", + "enum": [ + "draft", + "follow_up", + "reviewed" + ], + "title": "Review State", + "default": "draft" + }, + "review_notes": { + "type": "string", + "maxLength": 4000, + "title": "Review Notes", + "default": "" + }, + "public_summary": { + "type": "string", + "maxLength": 10000, + "title": "Public Summary", + "default": "" + }, + "analysis": { + "anyOf": [ + { + "$ref": "#/components/schemas/AnalysisRecord" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "property_reference", + "inspection_reference", + "dataset_kind", + "inspector_notes" + ], + "title": "InspectionInput" + }, + "IntakeInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "project_name": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Project Name" + }, + "project_description": { + "type": "string", + "maxLength": 10000, + "minLength": 1, + "title": "Project Description" + }, + "location": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Location" + }, + "applicant_contact": { + "type": "string", + "maxLength": 2000, + "title": "Applicant Contact", + "default": "" + }, + "requirement_revision": { + "type": "string", + "format": "uuid", + "title": "Requirement Revision" + }, + "materials": { + "items": { + "$ref": "#/components/schemas/MaterialReview" + }, + "type": "array", + "maxItems": 100, + "minItems": 1, + "title": "Materials" + }, + "linked_sources": { + "items": { + "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink" + }, + "type": "array", + "maxItems": 30, + "title": "Linked Sources" + }, + "staff_notes": { + "type": "string", + "maxLength": 10000, + "title": "Staff Notes", + "default": "" + }, + "assigned_to": { + "type": "string", + "maxLength": 255, + "title": "Assigned To", + "default": "" + }, + "review_state": { + "type": "string", + "enum": [ + "draft", + "follow_up", + "reviewed" + ], + "title": "Review State", + "default": "draft" + }, + "review_notes": { + "type": "string", + "maxLength": 4000, + "title": "Review Notes", + "default": "" + }, + "public_summary": { + "type": "string", + "maxLength": 10000, + "title": "Public Summary", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "project_name", + "project_description", + "location", + "requirement_revision", + "materials" + ], + "title": "IntakeInput" + }, + "InterpretationNoteCreate": { + "properties": { + "note_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Note Id" + }, + "note_text": { + "type": "string", + "minLength": 1, + "title": "Note Text" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "note_text" + ], + "title": "InterpretationNoteCreate", + "description": "Request body for staff-only interpretation notes." + }, + "InterviewRequest": { + "properties": { + "last_answer": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Answer" + }, + "last_field": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Field" + }, + "skipped_fields": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Skipped Fields" + } + }, + "type": "object", + "title": "InterviewRequest" + }, + "InterviewResponse": { + "properties": { + "question": { + "type": "string", + "title": "Question" + }, + "target_field": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Target Field" + }, + "all_complete": { + "type": "boolean", + "title": "All Complete" + }, + "completed_fields": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Completed Fields" + }, + "onboarding_status": { + "type": "string", + "title": "Onboarding Status" + }, + "skipped_fields": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Skipped Fields" + } + }, + "type": "object", + "required": [ + "question", + "target_field", + "all_complete", + "completed_fields", + "onboarding_status", + "skipped_fields" + ], + "title": "InterviewResponse" + }, + "ManagedFileReceipt": { + "properties": { + "original_path": { + "type": "string", + "minLength": 1, + "title": "Original Path" + }, + "stored_path": { + "type": "string", + "minLength": 1, + "title": "Stored Path" + }, + "file_name": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "File Name" + }, + "sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Sha256" + }, + "size_bytes": { + "type": "integer", + "maximum": 2147483647.0, + "minimum": 0.0, + "title": "Size Bytes" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "original_path", + "stored_path", + "file_name", + "sha256", + "size_bytes" + ], + "title": "ManagedFileReceipt" + }, + "ManagedSource": { + "properties": { + "original_path": { + "type": "string", + "title": "Original Path" + }, + "stored_path": { + "type": "string", + "title": "Stored Path" + }, + "file_name": { + "type": "string", + "title": "File Name" + }, + "sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Sha256" + }, + "size_bytes": { + "type": "integer", + "minimum": 0.0, + "title": "Size Bytes" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "original_path", + "stored_path", + "file_name", + "sha256", + "size_bytes" + ], + "title": "ManagedSource" + }, + "Material": { + "properties": { + "material_id": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]{1,80}$", + "title": "Material Id" + }, + "description": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Description" + }, + "citation": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Citation" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "material_id", + "description", + "citation" + ], + "title": "Material" + }, + "MaterialReview": { + "properties": { + "material_id": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Material Id" + }, + "status": { + "type": "string", + "enum": [ + "not_reviewed", + "provided", + "missing", + "unclear" + ], + "title": "Status", + "default": "not_reviewed" + }, + "note": { + "type": "string", + "maxLength": 2000, + "title": "Note", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "material_id" + ], + "title": "MaterialReview" + }, + "Measurement": { + "properties": { + "recorded_on": { + "type": "string", + "format": "date", + "title": "Recorded On" + }, + "value": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "title": "Value" + }, + "evidence": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Evidence" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "recorded_on", + "value", + "evidence" + ], + "title": "Measurement" + }, + "MediaAnalysis": { + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/EvidenceItem" + }, + "type": "array", + "maxItems": 10, + "minItems": 1, + "title": "Items" + }, + "code_links": { + "items": { + "$ref": "#/components/schemas/CodeLink" + }, + "type": "array", + "maxItems": 30, + "title": "Code Links" + }, + "inspector_supplied_text": { + "type": "string", + "maxLength": 10000, + "title": "Inspector Supplied Text", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "items" + ], + "title": "MediaAnalysis" + }, + "MeetingInput": { + "properties": { + "title": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Title" + }, + "scheduled_start": { + "type": "string", + "format": "date-time", + "title": "Scheduled Start" + }, + "location": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Location" + }, + "meeting_type": { + "type": "string", + "enum": [ + "regular", + "special", + "emergency", + "closed_session", + "executive" + ], + "title": "Meeting Type", + "default": "regular" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "scheduled_start", + "location" + ], + "title": "MeetingInput" + }, + "MeetingLink": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + }, + "relation": { + "type": "string", + "enum": [ + "hearing", + "context", + "precedent" + ], + "title": "Relation" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256", + "relation" + ], + "title": "MeetingLink" + }, + "MeetingSearch": { + "properties": { + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "MeetingSearch" + }, + "MeetingStageInput": { + "properties": { + "to_status": { + "type": "string", + "enum": [ + "SCHEDULED", + "NOTICED", + "PACKET_POSTED", + "IN_PROGRESS", + "RECESSED", + "ADJOURNED", + "TRANSCRIPT_READY", + "MINUTES_DRAFTED", + "MINUTES_POSTED", + "MINUTES_ADOPTED", + "MINUTES_SIGNED", + "ARCHIVED", + "CANCELLED" + ], + "title": "To Status" + }, + "statutory_basis": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Statutory Basis" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "to_status" + ], + "title": "MeetingStageInput" + }, + "MeetingsSearch": { + "properties": { + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "MeetingsSearch" + }, + "MeetingsSourceSelection": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "MeetingsSourceSelection" + }, + "MessageCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-message", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/MessagePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "MessageCommand" + }, + "MessageCreate": { + "properties": { + "message_text": { + "type": "string", + "title": "Message Text" + }, + "is_internal": { + "type": "boolean", + "title": "Is Internal", + "default": false + } + }, + "type": "object", + "required": [ + "message_text" + ], + "title": "MessageCreate" + }, + "MessagePayload": { + "properties": { + "requestMessageBody": { + "type": "string", + "minLength": 1, + "title": "Requestmessagebody" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requestMessageBody" + ], + "title": "MessagePayload" + }, + "MessageRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "sender_type": { + "type": "string", + "title": "Sender Type" + }, + "sender_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Sender Id" + }, + "message_text": { + "type": "string", + "title": "Message Text" + }, + "is_internal": { + "type": "boolean", + "title": "Is Internal" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "sender_type", + "sender_id", + "message_text", + "is_internal", + "created_at" + ], + "title": "MessageRead" + }, + "MessageView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "author": { + "type": "string", + "title": "Author" + }, + "author_role": { + "type": "string", + "title": "Author Role" + }, + "body": { + "type": "string", + "title": "Body" + }, + "visibility": { + "type": "string", + "title": "Visibility" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "author", + "author_role", + "body", + "visibility", + "created_at_unix_seconds" + ], + "title": "MessageView" + }, + "Milestone": { + "properties": { + "title": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Title" + }, + "due_on": { + "type": "string", + "format": "date", + "title": "Due On" + }, + "completed_on": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Completed On" + }, + "evidence": { + "type": "string", + "maxLength": 2000, + "title": "Evidence", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "due_on" + ], + "title": "Milestone" + }, + "MinutesDecision": { + "properties": { + "action": { + "type": "string", + "enum": [ + "post", + "adopt", + "sign" + ], + "title": "Action" + }, + "note": { + "type": "string", + "title": "Note", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "MinutesDecision" + }, + "ModelRegistryCreate": { + "properties": { + "model_name": { + "type": "string", + "title": "Model Name" + }, + "model_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Version" + }, + "parameter_count": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parameter Count" + }, + "license": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License" + }, + "model_card_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Card Url" + }, + "is_active": { + "type": "boolean", + "title": "Is Active", + "default": false + }, + "context_window_size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Context Window Size" + }, + "supports_ner": { + "type": "boolean", + "title": "Supports Ner", + "default": false + }, + "supports_vision": { + "type": "boolean", + "title": "Supports Vision", + "default": false + } + }, + "type": "object", + "required": [ + "model_name" + ], + "title": "ModelRegistryCreate", + "description": "Schema for creating a new model_registry record (POST body)." + }, + "ModelRegistryRead": { + "properties": { + "id": { + "type": "integer", + "title": "Id" + }, + "model_name": { + "type": "string", + "title": "Model Name" + }, + "model_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Version" + }, + "parameter_count": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parameter Count" + }, + "license": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License" + }, + "model_card_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Card Url" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "added_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Added At" + }, + "context_window_size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Context Window Size" + }, + "supports_ner": { + "type": "boolean", + "title": "Supports Ner" + }, + "supports_vision": { + "type": "boolean", + "title": "Supports Vision" + } + }, + "type": "object", + "required": [ + "id", + "model_name", + "is_active", + "supports_ner", + "supports_vision" + ], + "title": "ModelRegistryRead", + "description": "Schema for returning a model_registry record (GET response).\n\n``from_attributes=True`` allows construction directly from an ORM instance." + }, + "ModelRegistryUpdate": { + "properties": { + "model_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Name" + }, + "model_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Version" + }, + "parameter_count": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parameter Count" + }, + "license": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License" + }, + "model_card_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Card Url" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + }, + "context_window_size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Context Window Size" + }, + "supports_ner": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Supports Ner" + }, + "supports_vision": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Supports Vision" + } + }, + "type": "object", + "title": "ModelRegistryUpdate", + "description": "Schema for partially updating a model_registry record (PATCH body).\n\nEvery field is optional so callers can send only the fields they want to\nchange." + }, + "MotionCorrection": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "reason": { + "type": "string", + "minLength": 1, + "title": "Reason" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text", + "reason" + ], + "title": "MotionCorrection" + }, + "MotionInput": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "seconded_by": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Seconded By" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text" + ], + "title": "MotionInput" + }, + "NativePayload": { + "properties": {}, + "additionalProperties": false, + "type": "object", + "title": "NativePayload" + }, + "NativeRequestRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "requester_name": { + "type": "string", + "title": "Requester Name" + }, + "requester_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Email" + }, + "requester_phone": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Phone" + }, + "requester_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Type" + }, + "date_received": { + "type": "string", + "format": "date-time", + "title": "Date Received" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "description": { + "type": "string", + "title": "Description" + }, + "status": { + "$ref": "#/components/schemas/RequestStatus" + }, + "assigned_to": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "created_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "response_draft": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Response Draft" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + }, + "estimated_fee": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Estimated Fee" + }, + "fee_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Fee Status" + }, + "fee_waiver_requested": { + "type": "boolean", + "title": "Fee Waiver Requested", + "default": false + }, + "priority": { + "type": "string", + "title": "Priority", + "default": "normal" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + }, + "closed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Closed At" + }, + "closure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Closure Reason" + }, + "desktop_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Desktop Id" + }, + "public_tracking_number": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Public Tracking Number" + }, + "submitted_via": { + "type": "string", + "title": "Submitted Via" + }, + "deadline_label": { + "type": "string", + "title": "Deadline Label" + }, + "deadline_basis": { + "type": "string", + "title": "Deadline Basis" + }, + "deadline_reviewed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Deadline Reviewed At" + } + }, + "type": "object", + "required": [ + "id", + "requester_name", + "requester_email", + "date_received", + "statutory_deadline", + "description", + "status", + "assigned_to", + "created_by", + "created_at", + "response_draft", + "review_notes", + "desktop_id", + "public_tracking_number", + "submitted_via", + "deadline_label", + "deadline_basis", + "deadline_reviewed_at" + ], + "title": "NativeRequestRead" + }, + "NoticeDocumentInput": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text" + ], + "title": "NoticeDocumentInput" + }, + "NoticeDraft": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "body": { + "type": "string", + "maxLength": 100000, + "minLength": 1, + "title": "Body" + }, + "notice_type": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Notice Type" + }, + "statutory_basis": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Statutory Basis" + }, + "event_date": { + "type": "string", + "format": "date", + "title": "Event Date" + }, + "lead_days": { + "type": "integer", + "maximum": 365.0, + "minimum": 0.0, + "title": "Lead Days" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "body", + "notice_type", + "statutory_basis", + "event_date", + "lead_days" + ], + "title": "NoticeDraft" + }, + "NoticeInput": { + "properties": { + "notice_type": { + "type": "string", + "enum": [ + "regular", + "special", + "emergency", + "closed_session", + "executive" + ], + "title": "Notice Type" + }, + "posted_at": { + "type": "string", + "format": "date-time", + "title": "Posted At" + }, + "minimum_notice_hours": { + "type": "integer", + "minimum": 0.0, + "title": "Minimum Notice Hours" + }, + "statutory_basis": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Statutory Basis" + }, + "approved_by": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Approved By" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "notice_type", + "posted_at", + "minimum_notice_hours" + ], + "title": "NoticeInput" + }, + "NoticeProofInput": { + "properties": { + "location": { + "type": "string", + "minLength": 1, + "title": "Location" + }, + "note": { + "type": "string", + "title": "Note", + "default": "" + }, + "document_delivery_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Document Delivery Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "location" + ], + "title": "NoticeProofInput" + }, + "NotificationLogRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "template_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Template Id" + }, + "recipient_email": { + "type": "string", + "title": "Recipient Email" + }, + "request_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Request Id" + }, + "channel": { + "type": "string", + "title": "Channel" + }, + "status": { + "type": "string", + "title": "Status" + }, + "sent_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Sent At" + }, + "error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Message" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "template_id", + "recipient_email", + "request_id", + "channel", + "status", + "sent_at", + "error_message", + "created_at" + ], + "title": "NotificationLogRead" + }, + "NotificationTemplateCreate": { + "properties": { + "event_type": { + "type": "string", + "title": "Event Type" + }, + "channel": { + "type": "string", + "title": "Channel", + "default": "email" + }, + "subject_template": { + "type": "string", + "title": "Subject Template" + }, + "body_template": { + "type": "string", + "title": "Body Template" + } + }, + "type": "object", + "required": [ + "event_type", + "subject_template", + "body_template" + ], + "title": "NotificationTemplateCreate" + }, + "NotificationTemplateRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "event_type": { + "type": "string", + "title": "Event Type" + }, + "channel": { + "type": "string", + "title": "Channel" + }, + "subject_template": { + "type": "string", + "title": "Subject Template" + }, + "body_template": { + "type": "string", + "title": "Body Template" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "event_type", + "channel", + "subject_template", + "body_template", + "is_active", + "created_at" + ], + "title": "NotificationTemplateRead" + }, + "NotificationTemplateUpdate": { + "properties": { + "subject_template": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Subject Template" + }, + "body_template": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Body Template" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "NotificationTemplateUpdate" + }, + "NotificationView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "notification_id": { + "type": "string", + "title": "Notification Id" + }, + "module_id": { + "type": "string", + "title": "Module Id" + }, + "record_id": { + "type": "string", + "title": "Record Id" + }, + "audience": { + "type": "string", + "title": "Audience" + }, + "channel": { + "type": "string", + "title": "Channel" + }, + "subject": { + "type": "string", + "title": "Subject" + }, + "body": { + "type": "string", + "title": "Body" + }, + "status": { + "type": "string", + "title": "Status" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + }, + "sent_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Sent At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "notification_id", + "module_id", + "record_id", + "audience", + "channel", + "subject", + "body", + "status", + "created_at_unix_seconds", + "sent_at_unix_seconds" + ], + "title": "NotificationView" + }, + "OllamaModelInfo": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Size" + }, + "details": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Details" + } + }, + "type": "object", + "required": [ + "name" + ], + "title": "OllamaModelInfo" + }, + "OllamaStatus": { + "properties": { + "status": { + "type": "string", + "title": "Status" + }, + "models": { + "items": { + "$ref": "#/components/schemas/OllamaModelInfo" + }, + "type": "array", + "title": "Models" + } + }, + "type": "object", + "required": [ + "status", + "models" + ], + "title": "OllamaStatus" + }, + "OperationalMetrics": { + "properties": { + "average_response_time_days": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Average Response Time Days" + }, + "median_response_time_days": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Median Response Time Days" + }, + "requests_by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Requests By Status" + }, + "requests_by_department": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Requests By Department" + }, + "deadline_compliance_rate": { + "type": "number", + "title": "Deadline Compliance Rate" + }, + "total_open": { + "type": "integer", + "title": "Total Open" + }, + "total_closed": { + "type": "integer", + "title": "Total Closed" + }, + "total_overdue": { + "type": "integer", + "title": "Total Overdue" + }, + "clarification_frequency": { + "type": "number", + "title": "Clarification Frequency" + }, + "top_request_topics": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Top Request Topics" + } + }, + "type": "object", + "required": [ + "average_response_time_days", + "median_response_time_days", + "requests_by_status", + "requests_by_department", + "deadline_compliance_rate", + "total_open", + "total_closed", + "total_overdue", + "clarification_frequency", + "top_request_topics" + ], + "title": "OperationalMetrics" + }, + "Outline": { + "properties": { + "title": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Title" + }, + "question_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "maxItems": 50, + "minItems": 1, + "title": "Question Ids" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "question_ids" + ], + "title": "Outline" + }, + "Packet": { + "properties": { + "expected_revision": { + "type": "string", + "format": "uuid", + "title": "Expected Revision" + }, + "visibility": { + "type": "string", + "enum": [ + "staff_only", + "records_copy" + ], + "title": "Visibility" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "expected_revision", + "visibility" + ], + "title": "Packet" + }, + "PacketInput": { + "properties": { + "agenda_item_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "title": "Agenda Item Ids" + }, + "source_files": { + "items": { + "$ref": "#/components/schemas/ManagedSource" + }, + "type": "array", + "title": "Source Files" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "agenda_item_ids" + ], + "title": "PacketInput" + }, + "Pathway": { + "properties": { + "project_type": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Project Type" + }, + "proposal": { + "type": "string", + "maxLength": 4000, + "title": "Proposal", + "default": "" + }, + "location_context": { + "type": "string", + "maxLength": 1000, + "title": "Location Context", + "default": "" + }, + "requirement_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Requirement Revision" + }, + "fee_link": { + "anyOf": [ + { + "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "project_type" + ], + "title": "Pathway" + }, + "PathwayStep": { + "properties": { + "step": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Step" + }, + "citation": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Citation" + }, + "typical_time": { + "type": "string", + "maxLength": 1000, + "title": "Typical Time", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "step", + "citation" + ], + "title": "PathwayStep" + }, + "PlainLanguageSummaryCreate": { + "properties": { + "summary_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Summary Id" + }, + "section_version_id": { + "type": "string", + "minLength": 1, + "title": "Section Version Id" + }, + "summary_text": { + "type": "string", + "minLength": 1, + "title": "Summary Text" + }, + "language_code": { + "type": "string", + "title": "Language Code", + "default": "en" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "section_version_id", + "summary_text" + ], + "title": "PlainLanguageSummaryCreate", + "description": "Request body for staff-drafted plain-language summaries." + }, + "PolicySelection": { + "properties": { + "plan_id": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Plan Id" + }, + "revision_id": { + "type": "string", + "maxLength": 36, + "minLength": 36, + "title": "Revision Id" + }, + "policy_id": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Policy Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "plan_id", + "revision_id", + "policy_id" + ], + "title": "PolicySelection" + }, + "PortalModeResponse": { + "properties": { + "mode": { + "type": "string", + "enum": [ + "public", + "private" + ], + "title": "Mode", + "description": "Active portal posture for this deployment. ``public`` = minimal resident surface (landing + authenticated records-request submission + resident registration) reachable without staff auth. ``private`` = staff-only; no public routes, no resident self-registration." + } + }, + "type": "object", + "required": [ + "mode" + ], + "title": "PortalModeResponse", + "description": "T5D — schema for ``GET /config/portal-mode``.\n\nExposed to the frontend on boot so it can branch routing without a\nuser-identity lookup. The payload is intentionally the single field\nbelow — no staff config, no user state, no schema version." + }, + "PrepareArtifact": { + "properties": { + "kind": { + "type": "string", + "enum": [ + "response", + "release-package" + ], + "title": "Kind" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "kind" + ], + "title": "PrepareArtifact" + }, + "Proof": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + }, + "filename": { + "type": "string", + "maxLength": 150, + "minLength": 1, + "title": "Filename" + }, + "content_base64": { + "type": "string", + "maxLength": 7000000, + "minLength": 1, + "title": "Content Base64" + }, + "location": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Location" + }, + "published_at": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Published At" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence", + "filename", + "content_base64", + "location", + "published_at" + ], + "title": "Proof" + }, + "Proposal": { + "properties": { + "id": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Id" + }, + "version_id": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Version Id" + }, + "meeting_id": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "ordinance_number": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Ordinance Number" + }, + "proposed_text": { + "type": "string", + "maxLength": 1000000, + "minLength": 1, + "title": "Proposed Text" + }, + "supersedes_id": { + "anyOf": [ + { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$" + }, + { + "type": "null" + } + ], + "title": "Supersedes Id" + }, + "reconciliation_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reconciliation Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "version_id", + "meeting_id", + "title", + "ordinance_number", + "proposed_text" + ], + "title": "Proposal" + }, + "PublicExplore": { + "properties": { + "goal": { + "type": "string", + "maxLength": 500, + "title": "Goal", + "default": "" + }, + "topic": { + "type": "string", + "maxLength": 160, + "title": "Topic", + "default": "" + }, + "neighborhood": { + "type": "string", + "maxLength": 255, + "title": "Neighborhood", + "default": "" + }, + "plan_type": { + "type": "string", + "maxLength": 120, + "title": "Plan Type", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "title": "PublicExplore" + }, + "PublicIntake": { + "properties": { + "requester": { + "type": "string", + "minLength": 1, + "title": "Requester" + }, + "requesterContact": { + "type": "string", + "minLength": 1, + "title": "Requestercontact" + }, + "summary": { + "type": "string", + "minLength": 1, + "title": "Summary" + }, + "deadline": { + "type": "string", + "title": "Deadline", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requester", + "requesterContact", + "summary" + ], + "title": "PublicIntake" + }, + "PublicLookup": { + "properties": { + "trackingNumber": { + "type": "string", + "minLength": 1, + "title": "Trackingnumber" + }, + "requesterContact": { + "type": "string", + "minLength": 1, + "title": "Requestercontact" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "trackingNumber", + "requesterContact" + ], + "title": "PublicLookup" + }, + "PublicMessage": { + "properties": { + "trackingNumber": { + "type": "string", + "minLength": 1, + "title": "Trackingnumber" + }, + "requesterContact": { + "type": "string", + "minLength": 1, + "title": "Requestercontact" + }, + "publicRequestMessage": { + "type": "string", + "minLength": 1, + "title": "Publicrequestmessage" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "trackingNumber", + "requesterContact", + "publicRequestMessage" + ], + "title": "PublicMessage" + }, + "PublicStatusView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "label": { + "type": "string", + "title": "Label" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "status": { + "type": "string", + "title": "Status" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "label", + "summary", + "status", + "created_at_unix_seconds" + ], + "title": "PublicStatusView" + }, + "PublicationView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "source_module": { + "type": "string", + "title": "Source Module" + }, + "source_record_id": { + "type": "string", + "title": "Source Record Id" + }, + "record_type": { + "type": "string", + "title": "Record Type" + }, + "public_payload": { + "type": "string", + "title": "Public Payload" + }, + "payload_hash": { + "type": "string", + "title": "Payload Hash" + }, + "published_at_unix_seconds": { + "type": "integer", + "title": "Published At Unix Seconds" + }, + "retracted_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Retracted At Unix Seconds" + }, + "retracted_by": { + "type": "string", + "title": "Retracted By", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "source_module", + "source_record_id", + "record_type", + "public_payload", + "payload_hash", + "published_at_unix_seconds" + ], + "title": "PublicationView" + }, + "PublishingPlan": { + "properties": { + "action": { + "type": "string", + "const": "publishing-workflow", + "title": "Action" + }, + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "hasReview": { + "type": "boolean", + "title": "Hasreview", + "default": false + }, + "hasPlainLanguage": { + "type": "boolean", + "title": "Hasplainlanguage", + "default": false + }, + "hasTranslationReview": { + "type": "boolean", + "title": "Hastranslationreview", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "PublishingPlan" + }, + "Question": { + "properties": { + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + }, + "question": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Question" + }, + "kind": { + "type": "string", + "enum": [ + "use", + "dimension" + ], + "title": "Kind" + }, + "key": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Key" + }, + "audience": { + "type": "string", + "enum": [ + "resident", + "staff" + ], + "title": "Audience", + "default": "resident" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "jurisdiction", + "query", + "question", + "kind", + "key" + ], + "title": "Question" + }, + "QuestionAnswerRequest": { + "properties": { + "question": { + "type": "string", + "minLength": 1, + "title": "Question" + }, + "section_number": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Section Number" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "question" + ], + "title": "QuestionAnswerRequest", + "description": "Request body for citation-grounded code Q&A." + }, + "RecordsDocumentView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "attachment_id": { + "type": "string", + "title": "Attachment Id" + }, + "title": { + "type": "string", + "title": "Title" + }, + "original_path": { + "type": "string", + "title": "Original Path" + }, + "stored_path": { + "type": "string", + "title": "Stored Path" + }, + "citation": { + "type": "string", + "title": "Citation" + }, + "sha256": { + "type": "string", + "title": "Sha256" + }, + "size_bytes": { + "type": "integer", + "title": "Size Bytes" + }, + "status": { + "type": "string", + "title": "Status" + }, + "added_by": { + "type": "string", + "title": "Added By" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + }, + "release_original_path": { + "type": "string", + "title": "Release Original Path", + "default": "" + }, + "release_stored_path": { + "type": "string", + "title": "Release Stored Path", + "default": "" + }, + "release_file_name": { + "type": "string", + "title": "Release File Name", + "default": "" + }, + "release_sha256": { + "type": "string", + "title": "Release Sha256", + "default": "" + }, + "release_size_bytes": { + "type": "integer", + "title": "Release Size Bytes", + "default": 0 + }, + "release_status": { + "type": "string", + "title": "Release Status", + "default": "" + }, + "release_note": { + "type": "string", + "title": "Release Note", + "default": "" + }, + "release_added_by": { + "type": "string", + "title": "Release Added By", + "default": "" + }, + "release_added_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Release Added At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "attachment_id", + "title", + "original_path", + "stored_path", + "citation", + "sha256", + "size_bytes", + "status", + "added_by", + "created_at_unix_seconds" + ], + "title": "RecordsDocumentView" + }, + "RecordsOperationRead": { + "properties": { + "action": { + "type": "string", + "title": "Action" + }, + "message": { + "type": "string", + "title": "Message" + }, + "request": { + "$ref": "#/components/schemas/RecordsView" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "message", + "request" + ], + "title": "RecordsOperationRead" + }, + "RecordsStateRead": { + "properties": { + "demo_fixture": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Demo Fixture" + }, + "records_requests": { + "items": { + "$ref": "#/components/schemas/RecordsView" + }, + "type": "array", + "title": "Records Requests" + }, + "notification_events": { + "items": { + "$ref": "#/components/schemas/NotificationView" + }, + "type": "array", + "title": "Notification Events" + }, + "publication_events": { + "items": { + "$ref": "#/components/schemas/PublicationView" + }, + "type": "array", + "title": "Publication Events" + }, + "audit_entries": { + "items": { + "$ref": "#/components/schemas/AuditView" + }, + "type": "array", + "title": "Audit Entries" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "records_requests" + ], + "title": "RecordsStateRead" + }, + "RecordsView": { + "properties": { + "request_id": { + "type": "string", + "title": "Request Id" + }, + "id": { + "type": "string", + "title": "Id" + }, + "public_tracking_number": { + "type": "string", + "title": "Public Tracking Number" + }, + "requester": { + "type": "string", + "title": "Requester" + }, + "requester_contact": { + "type": "string", + "title": "Requester Contact" + }, + "submitted_via": { + "type": "string", + "title": "Submitted Via" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "deadline": { + "type": "string", + "title": "Deadline" + }, + "deadline_basis": { + "type": "string", + "title": "Deadline Basis" + }, + "status": { + "type": "string", + "title": "Status" + }, + "assigned_to": { + "type": "string", + "title": "Assigned To" + }, + "clarification_notes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Clarification Notes" + }, + "search_notes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Search Notes" + }, + "search_sessions": { + "items": { + "$ref": "#/components/schemas/SearchReceiptView" + }, + "type": "array", + "title": "Search Sessions" + }, + "exemption_reviews": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Exemption Reviews" + }, + "exemption_decisions": { + "items": { + "$ref": "#/components/schemas/ExemptionDecisionView" + }, + "type": "array", + "title": "Exemption Decisions" + }, + "fee_estimate": { + "type": "string", + "title": "Fee Estimate" + }, + "fee_line_items": { + "items": { + "$ref": "#/components/schemas/FeeLineView" + }, + "type": "array", + "title": "Fee Line Items" + }, + "fee_waiver_reason": { + "type": "string", + "title": "Fee Waiver Reason" + }, + "citations": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Citations" + }, + "response_draft": { + "type": "string", + "title": "Response Draft" + }, + "approval_notes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Approval Notes" + }, + "exports": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Exports" + }, + "documents": { + "items": { + "$ref": "#/components/schemas/RecordsDocumentView" + }, + "type": "array", + "title": "Documents" + }, + "release_packages": { + "items": { + "$ref": "#/components/schemas/ReleasePackageView" + }, + "type": "array", + "title": "Release Packages" + }, + "timeline": { + "items": { + "$ref": "#/components/schemas/TimelineView" + }, + "type": "array", + "title": "Timeline" + }, + "public_status_events": { + "items": { + "$ref": "#/components/schemas/PublicStatusView" + }, + "type": "array", + "title": "Public Status Events" + }, + "messages": { + "items": { + "$ref": "#/components/schemas/MessageView" + }, + "type": "array", + "title": "Messages" + }, + "deadline_reviewed_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Deadline Reviewed At Unix Seconds" + }, + "approved_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Approved At Unix Seconds" + }, + "fulfilled_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Fulfilled At Unix Seconds" + }, + "closed_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Closed At Unix Seconds" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "request_id", + "id", + "public_tracking_number", + "requester", + "requester_contact", + "submitted_via", + "summary", + "deadline", + "deadline_basis", + "status", + "assigned_to", + "clarification_notes", + "search_notes", + "search_sessions", + "exemption_reviews", + "exemption_decisions", + "fee_estimate", + "fee_line_items", + "fee_waiver_reason", + "citations", + "response_draft", + "approval_notes", + "exports", + "timeline", + "public_status_events", + "messages", + "deadline_reviewed_at_unix_seconds", + "approved_at_unix_seconds", + "fulfilled_at_unix_seconds", + "closed_at_unix_seconds", + "created_at_unix_seconds" + ], + "title": "RecordsView" + }, + "ReleasePackageView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "export_path": { + "type": "string", + "title": "Export Path" + }, + "package_hash": { + "type": "string", + "title": "Package Hash" + }, + "document_count": { + "type": "integer", + "title": "Document Count" + }, + "release_artifact_count": { + "type": "integer", + "title": "Release Artifact Count" + }, + "search_session_count": { + "type": "integer", + "title": "Search Session Count" + }, + "release_count": { + "type": "integer", + "title": "Release Count" + }, + "redacted_count": { + "type": "integer", + "title": "Redacted Count" + }, + "exempt_count": { + "type": "integer", + "title": "Exempt Count" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "export_path", + "package_hash", + "document_count", + "release_artifact_count", + "search_session_count", + "release_count", + "redacted_count", + "exempt_count", + "created_at_unix_seconds" + ], + "title": "ReleasePackageView" + }, + "RepeatLookup": { + "properties": { + "property_reference": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Property Reference" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "property_reference" + ], + "title": "RepeatLookup" + }, + "RequestCreate": { + "properties": { + "requester_name": { + "type": "string", + "maxLength": 255, + "title": "Requester Name" + }, + "requester_email": { + "anyOf": [ + { + "type": "string", + "maxLength": 255 + }, + { + "type": "null" + } + ], + "title": "Requester Email" + }, + "requester_phone": { + "anyOf": [ + { + "type": "string", + "maxLength": 50 + }, + { + "type": "null" + } + ], + "title": "Requester Phone" + }, + "requester_type": { + "anyOf": [ + { + "type": "string", + "maxLength": 100 + }, + { + "type": "null" + } + ], + "title": "Requester Type" + }, + "description": { + "type": "string", + "maxLength": 10000, + "title": "Description" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "priority": { + "type": "string", + "title": "Priority", + "default": "normal" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string", + "pattern": "^(narrow|moderate|broad)$" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + } + }, + "type": "object", + "required": [ + "requester_name", + "description" + ], + "title": "RequestCreate" + }, + "RequestDocumentAdd": { + "properties": { + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "relevance_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Relevance Note" + } + }, + "type": "object", + "required": [ + "document_id" + ], + "title": "RequestDocumentAdd" + }, + "RequestDocumentRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "relevance_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Relevance Note" + }, + "exemption_flags": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Exemption Flags" + }, + "inclusion_status": { + "$ref": "#/components/schemas/InclusionStatus" + }, + "attached_at": { + "type": "string", + "format": "date-time", + "title": "Attached At" + }, + "attached_by": { + "type": "string", + "format": "uuid", + "title": "Attached By" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "document_id", + "relevance_note", + "exemption_flags", + "inclusion_status", + "attached_at", + "attached_by" + ], + "title": "RequestDocumentRead" + }, + "RequestRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "requester_name": { + "type": "string", + "title": "Requester Name" + }, + "requester_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Email" + }, + "requester_phone": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Phone" + }, + "requester_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Type" + }, + "date_received": { + "type": "string", + "format": "date-time", + "title": "Date Received" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "description": { + "type": "string", + "title": "Description" + }, + "status": { + "$ref": "#/components/schemas/RequestStatus" + }, + "assigned_to": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "created_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "response_draft": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Response Draft" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + }, + "estimated_fee": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Estimated Fee" + }, + "fee_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Fee Status" + }, + "fee_waiver_requested": { + "type": "boolean", + "title": "Fee Waiver Requested", + "default": false + }, + "priority": { + "type": "string", + "title": "Priority", + "default": "normal" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + }, + "closed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Closed At" + }, + "closure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Closure Reason" + } + }, + "type": "object", + "required": [ + "id", + "requester_name", + "requester_email", + "date_received", + "statutory_deadline", + "description", + "status", + "assigned_to", + "created_by", + "created_at", + "response_draft", + "review_notes" + ], + "title": "RequestRead" + }, + "RequestStats": { + "properties": { + "total_requests": { + "type": "integer", + "title": "Total Requests" + }, + "by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "By Status" + }, + "approaching_deadline": { + "type": "integer", + "title": "Approaching Deadline" + }, + "overdue": { + "type": "integer", + "title": "Overdue" + } + }, + "type": "object", + "required": [ + "total_requests", + "by_status", + "approaching_deadline", + "overdue" + ], + "title": "RequestStats" + }, + "RequestStatus": { + "type": "string", + "enum": [ + "received", + "clarification_needed", + "assigned", + "searching", + "in_review", + "ready_for_release", + "drafted", + "approved", + "fulfilled", + "closed" + ], + "title": "RequestStatus" + }, + "RequestUpdate": { + "properties": { + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "status": { + "anyOf": [ + { + "$ref": "#/components/schemas/RequestStatus" + }, + { + "type": "null" + } + ] + }, + "assigned_to": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "response_draft": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Response Draft" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + } + }, + "type": "object", + "title": "RequestUpdate" + }, + "RequirementBundle": { + "properties": { + "requirement_id": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]{1,100}$", + "title": "Requirement Id" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "project_type": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Project Type" + }, + "source_reference": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Source Reference" + }, + "source_date": { + "type": "string", + "format": "date", + "title": "Source Date" + }, + "effective_on": { + "type": "string", + "format": "date", + "title": "Effective On" + }, + "dataset_kind": { + "type": "string", + "enum": [ + "municipal", + "fictional" + ], + "title": "Dataset Kind" + }, + "filename": { + "type": "string", + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$", + "title": "Filename" + }, + "content_base64": { + "type": "string", + "maxLength": 14000000, + "minLength": 1, + "title": "Content Base64" + }, + "sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Sha256" + }, + "materials": { + "items": { + "$ref": "#/components/schemas/Material" + }, + "type": "array", + "maxItems": 100, + "minItems": 1, + "title": "Materials" + }, + "pathway": { + "items": { + "$ref": "#/components/schemas/PathwayStep" + }, + "type": "array", + "maxItems": 100, + "title": "Pathway" + }, + "fee_link": { + "anyOf": [ + { + "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink" + }, + { + "type": "null" + } + ] + }, + "staff_note": { + "type": "string", + "maxLength": 4000, + "title": "Staff Note", + "default": "" + }, + "change_note": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Change Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requirement_id", + "title", + "jurisdiction", + "project_type", + "source_reference", + "source_date", + "effective_on", + "dataset_kind", + "filename", + "content_base64", + "sha256", + "materials", + "change_note" + ], + "title": "RequirementBundle" + }, + "ResponseLetterCreate": { + "properties": { + "template_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Template Id" + } + }, + "type": "object", + "title": "ResponseLetterCreate" + }, + "ResponseLetterRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "template_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Template Id" + }, + "generated_content": { + "type": "string", + "title": "Generated Content" + }, + "edited_content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Edited Content" + }, + "status": { + "type": "string", + "title": "Status" + }, + "generated_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Generated By" + }, + "approved_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Approved By" + }, + "sent_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Sent At" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "template_id", + "generated_content", + "edited_content", + "status", + "generated_by", + "approved_by", + "sent_at", + "created_at" + ], + "title": "ResponseLetterRead" + }, + "ResponseLetterUpdate": { + "properties": { + "edited_content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Edited Content" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + } + }, + "type": "object", + "title": "ResponseLetterUpdate" + }, + "ReviewInput": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "body": { + "type": "string", + "maxLength": 5000, + "title": "Body", + "default": "" + }, + "hasAltText": { + "type": "boolean", + "title": "Hasalttext", + "default": false + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "en" + } + }, + "additionalProperties": false, + "type": "object", + "title": "ReviewInput" + }, + "Revision": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + }, + "document": { + "$ref": "#/components/schemas/NoticeDraft" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence", + "document" + ], + "title": "Revision" + }, + "RewriteInput": { + "properties": { + "action": { + "type": "string", + "enum": [ + "plain-language", + "language-variant" + ], + "title": "Action" + }, + "text": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Text" + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "text" + ], + "title": "RewriteInput" + }, + "RewriteResult": { + "properties": { + "action": { + "type": "string", + "enum": [ + "plain-language", + "language-variant" + ], + "title": "Action" + }, + "text": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Text" + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "" + }, + "outcome": { + "type": "string", + "enum": [ + "generated", + "unavailable" + ], + "title": "Outcome" + }, + "generated": { + "anyOf": [ + { + "type": "string", + "maxLength": 100000 + }, + { + "type": "null" + } + ], + "title": "Generated" + }, + "model": { + "anyOf": [ + { + "type": "string", + "maxLength": 200 + }, + { + "type": "null" + } + ], + "title": "Model" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "text", + "outcome" + ], + "title": "RewriteResult" + }, + "Rule": { + "properties": { + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "zone_code": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Zone Code" + }, + "key": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Key" + }, + "section_number": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Section Number" + }, + "kind": { + "type": "string", + "enum": [ + "use", + "dimension" + ], + "title": "Kind" + }, + "value": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Value" + }, + "overlay_code": { + "anyOf": [ + { + "type": "string", + "maxLength": 255 + }, + { + "type": "null" + } + ], + "title": "Overlay Code" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "jurisdiction", + "zone_code", + "key", + "section_number", + "kind", + "value" + ], + "title": "Rule" + }, + "RuleTestMatch": { + "properties": { + "matched_text": { + "type": "string", + "title": "Matched Text" + }, + "start": { + "type": "integer", + "title": "Start" + }, + "end": { + "type": "integer", + "title": "End" + } + }, + "type": "object", + "required": [ + "matched_text", + "start", + "end" + ], + "title": "RuleTestMatch" + }, + "RuleTestRequest": { + "properties": { + "sample_text": { + "type": "string", + "title": "Sample Text" + } + }, + "type": "object", + "required": [ + "sample_text" + ], + "title": "RuleTestRequest" + }, + "RuleTestResponse": { + "properties": { + "rule_id": { + "type": "string", + "format": "uuid", + "title": "Rule Id" + }, + "rule_type": { + "type": "string", + "title": "Rule Type" + }, + "matched": { + "type": "boolean", + "title": "Matched" + }, + "matches": { + "items": { + "$ref": "#/components/schemas/RuleTestMatch" + }, + "type": "array", + "title": "Matches" + } + }, + "type": "object", + "required": [ + "rule_id", + "rule_type", + "matched", + "matches" + ], + "title": "RuleTestResponse" + }, + "RuleType": { + "type": "string", + "enum": [ + "regex", + "keyword", + "llm_prompt" + ], + "title": "RuleType" + }, + "SaveReview": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "body": { + "type": "string", + "maxLength": 5000, + "title": "Body", + "default": "" + }, + "hasAltText": { + "type": "boolean", + "title": "Hasalttext", + "default": false + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "en" + }, + "ai_analysis": { + "anyOf": [ + { + "type": "string", + "maxLength": 100000 + }, + { + "type": "null" + } + ], + "title": "Ai Analysis" + }, + "ai_analysis_model": { + "anyOf": [ + { + "type": "string", + "maxLength": 200 + }, + { + "type": "null" + } + ], + "title": "Ai Analysis Model" + }, + "ai_outcome": { + "type": "string", + "enum": [ + "generated", + "unavailable", + "failed" + ], + "title": "Ai Outcome" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "ai_outcome" + ], + "title": "SaveReview" + }, + "SearchFilterOptions": { + "properties": { + "file_types": { + "items": { + "type": "string" + }, + "type": "array", + "title": "File Types" + }, + "source_names": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Source Names" + }, + "departments": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array", + "title": "Departments", + "default": [] + }, + "date_range": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Date Range" + } + }, + "type": "object", + "required": [ + "file_types", + "source_names" + ], + "title": "SearchFilterOptions" + }, + "SearchInput": { + "properties": { + "query": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "SearchInput" + }, + "SearchNoteCommand": { + "properties": { + "action": { + "type": "string", + "const": "record-records-search", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/SearchNotePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "SearchNoteCommand" + }, + "SearchNotePayload": { + "properties": { + "sourceNote": { + "type": "string", + "minLength": 1, + "title": "Sourcenote" + }, + "citation": { + "type": "string", + "title": "Citation", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sourceNote" + ], + "title": "SearchNotePayload" + }, + "SearchReceiptCommand": { + "properties": { + "action": { + "type": "string", + "const": "record-records-search-session", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/SearchReceiptPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "SearchReceiptCommand" + }, + "SearchReceiptPayload": { + "properties": { + "searchQuery": { + "type": "string", + "minLength": 1, + "title": "Searchquery" + }, + "searchLocations": { + "type": "string", + "minLength": 1, + "title": "Searchlocations" + }, + "searchResultTitle": { + "type": "string", + "minLength": 1, + "title": "Searchresulttitle" + }, + "searchResultCitation": { + "type": "string", + "minLength": 1, + "title": "Searchresultcitation" + }, + "searchResultSummary": { + "type": "string", + "minLength": 1, + "title": "Searchresultsummary" + }, + "searchResultStatus": { + "type": "string", + "title": "Searchresultstatus", + "default": "" + }, + "searchReviewer": { + "type": "string", + "title": "Searchreviewer", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "searchQuery", + "searchLocations", + "searchResultTitle", + "searchResultCitation", + "searchResultSummary" + ], + "title": "SearchReceiptPayload" + }, + "SearchReceiptView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "query": { + "type": "string", + "title": "Query" + }, + "locations": { + "type": "string", + "title": "Locations" + }, + "reviewer": { + "type": "string", + "title": "Reviewer" + }, + "results": { + "items": { + "$ref": "#/components/schemas/SearchResultView" + }, + "type": "array", + "title": "Results" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "query", + "locations", + "reviewer", + "results", + "created_at_unix_seconds" + ], + "title": "SearchReceiptView" + }, + "SearchRequest": { + "properties": { + "query": { + "type": "string", + "title": "Query" + }, + "session_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Session Id" + }, + "filters": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Filters" + }, + "limit": { + "type": "integer", + "maximum": 50.0, + "title": "Limit", + "default": 10 + }, + "synthesize": { + "type": "boolean", + "title": "Synthesize", + "default": false + } + }, + "type": "object", + "required": [ + "query" + ], + "title": "SearchRequest" + }, + "SearchResponse": { + "properties": { + "query_id": { + "type": "string", + "format": "uuid", + "title": "Query Id" + }, + "session_id": { + "type": "string", + "format": "uuid", + "title": "Session Id" + }, + "query_text": { + "type": "string", + "title": "Query Text" + }, + "results": { + "items": { + "$ref": "#/components/schemas/SearchResultItem" + }, + "type": "array", + "title": "Results" + }, + "results_count": { + "type": "integer", + "title": "Results Count" + }, + "synthesized_answer": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Synthesized Answer" + }, + "ai_generated": { + "type": "boolean", + "title": "Ai Generated", + "default": false + } + }, + "type": "object", + "required": [ + "query_id", + "session_id", + "query_text", + "results", + "results_count" + ], + "title": "SearchResponse" + }, + "SearchResultItem": { + "properties": { + "chunk_id": { + "type": "string", + "format": "uuid", + "title": "Chunk Id" + }, + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "filename": { + "type": "string", + "title": "Filename" + }, + "file_type": { + "type": "string", + "title": "File Type" + }, + "source_path": { + "type": "string", + "title": "Source Path" + }, + "page_number": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Page Number" + }, + "content_text": { + "type": "string", + "title": "Content Text" + }, + "similarity_score": { + "type": "number", + "title": "Similarity Score" + }, + "rank": { + "type": "integer", + "title": "Rank" + } + }, + "type": "object", + "required": [ + "chunk_id", + "document_id", + "filename", + "file_type", + "source_path", + "page_number", + "content_text", + "similarity_score", + "rank" + ], + "title": "SearchResultItem" + }, + "SearchResultView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "title": { + "type": "string", + "title": "Title" + }, + "citation": { + "type": "string", + "title": "Citation" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "status": { + "type": "string", + "title": "Status" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "title", + "citation", + "summary", + "status" + ], + "title": "SearchResultView" + }, + "SearchSessionRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "user_id": { + "type": "string", + "format": "uuid", + "title": "User Id" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "queries": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array", + "title": "Queries", + "default": [] + } + }, + "type": "object", + "required": [ + "id", + "user_id", + "created_at" + ], + "title": "SearchSessionRead" + }, + "SectionCreate": { + "properties": { + "section_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Section Id" + }, + "chapter_id": { + "type": "string", + "minLength": 1, + "title": "Chapter Id" + }, + "section_number": { + "type": "string", + "minLength": 1, + "title": "Section Number" + }, + "section_heading": { + "type": "string", + "minLength": 1, + "title": "Section Heading" + }, + "parent_section_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parent Section Id" + }, + "sort_order": { + "type": "integer", + "title": "Sort Order", + "default": 0 + }, + "administrative_regulation_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Administrative Regulation Refs" + }, + "resolution_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Resolution Refs" + }, + "policy_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Policy Refs" + }, + "approved_summary_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Approved Summary Refs" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "chapter_id", + "section_number", + "section_heading" + ], + "title": "SectionCreate", + "description": "Request body for creating a code section or subsection." + }, + "SectionVersionCreate": { + "properties": { + "version_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Version Id" + }, + "section_id": { + "type": "string", + "minLength": 1, + "title": "Section Id" + }, + "source_id": { + "type": "string", + "minLength": 1, + "title": "Source Id" + }, + "version_label": { + "type": "string", + "minLength": 1, + "title": "Version Label" + }, + "body": { + "type": "string", + "minLength": 1, + "title": "Body" + }, + "effective_start": { + "type": "string", + "format": "date", + "title": "Effective Start" + }, + "effective_end": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective End" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + }, + "is_current": { + "type": "boolean", + "title": "Is Current", + "default": false + }, + "adoption_event_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Adoption Event Id" + }, + "amendment_event_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Amendment Event Id" + }, + "amendment_summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Amendment Summary" + }, + "prior_version_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Prior Version Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "section_id", + "source_id", + "version_label", + "body", + "effective_start" + ], + "title": "SectionVersionCreate", + "description": "Request body for adding an immutable section version." + }, + "Selection": { + "properties": { + "recording_id": { + "type": "string", + "format": "uuid", + "title": "Recording Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "recording_id", + "expected_sha256" + ], + "title": "Selection" + }, + "SentenceInput": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "citations": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Citations" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text" + ], + "title": "SentenceInput" + }, + "ServiceAccountCreate": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole", + "default": "read_only" + } + }, + "type": "object", + "required": [ + "name" + ], + "title": "ServiceAccountCreate" + }, + "ServiceAccountCreated": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "api_key": { + "type": "string", + "title": "Api Key" + } + }, + "type": "object", + "required": [ + "id", + "name", + "role", + "created_by", + "created_at", + "is_active", + "api_key" + ], + "title": "ServiceAccountCreated", + "description": "Returned only on creation — includes the plaintext API key (shown once)." + }, + "ServiceAccountRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + } + }, + "type": "object", + "required": [ + "id", + "name", + "role", + "created_by", + "created_at", + "is_active" + ], + "title": "ServiceAccountRead" + }, + "ServiceAccountUpdate": { + "properties": { + "role": { + "anyOf": [ + { + "$ref": "#/components/schemas/UserRole" + }, + { + "type": "null" + } + ] + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "ServiceAccountUpdate" + }, + "Snapshot": { + "properties": { + "expected_revision": { + "type": "string", + "format": "uuid", + "title": "Expected Revision" + }, + "visibility": { + "type": "string", + "enum": [ + "staff_only", + "public" + ], + "title": "Visibility" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "expected_revision", + "visibility" + ], + "title": "Snapshot" + }, + "SourceCreate": { + "properties": { + "source_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Id" + }, + "name": { + "type": "string", + "minLength": 1, + "title": "Name" + }, + "publisher": { + "type": "string", + "minLength": 1, + "title": "Publisher" + }, + "source_type": { + "type": "string", + "minLength": 1, + "title": "Source Type" + }, + "source_category": { + "type": "string", + "minLength": 1, + "title": "Source Category" + }, + "source_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Url" + }, + "file_reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "File Reference" + }, + "retrieved_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Retrieved At" + }, + "retrieval_method": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Retrieval Method" + }, + "checksum": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Checksum" + }, + "source_owner": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Owner" + }, + "is_official": { + "type": "boolean", + "title": "Is Official", + "default": true + }, + "official_status_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Official Status Note" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + }, + "staff_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Staff Notes" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "name", + "publisher", + "source_type", + "source_category" + ], + "title": "SourceCreate", + "description": "Request body for registering an official or explicitly labeled source." + }, + "SourceInput": { + "properties": { + "source_id": { + "type": "string", + "minLength": 1, + "title": "Source Id" + }, + "label": { + "type": "string", + "minLength": 1, + "title": "Label" + }, + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "label", + "text" + ], + "title": "SourceInput" + }, + "SourceSnapshot": { + "properties": { + "visibility": { + "type": "string", + "enum": [ + "public", + "staff_only" + ], + "title": "Visibility" + }, + "meeting_event_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "maxItems": 50, + "title": "Meeting Event Ids" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "visibility" + ], + "title": "SourceSnapshot" + }, + "SourceType": { + "type": "string", + "enum": [ + "manual_drop", + "file_system", + "rest_api", + "odbc" + ], + "title": "SourceType" + }, + "StaffRecordsIntake": { + "properties": { + "requester": { + "type": "string", + "minLength": 1, + "title": "Requester" + }, + "summary": { + "type": "string", + "minLength": 1, + "title": "Summary" + }, + "deadline": { + "type": "string", + "title": "Deadline" + }, + "deadlineBasis": { + "type": "string", + "title": "Deadlinebasis", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requester", + "summary", + "deadline" + ], + "title": "StaffRecordsIntake", + "description": "Existing native create-records-request input; no caller-supplied actor." + }, + "StandardsExplanation": { + "properties": { + "question": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Question" + }, + "process_section": { + "type": "string", + "maxLength": 255, + "title": "Process Section", + "default": "" + }, + "zone_code": { + "type": "string", + "maxLength": 40, + "title": "Zone Code", + "default": "" + }, + "rule_types": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 10, + "title": "Rule Types" + }, + "observed": { + "additionalProperties": { + "type": "string" + }, + "type": "object", + "title": "Observed" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "question" + ], + "title": "StandardsExplanation" + }, + "SyncFailureRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "source_id": { + "type": "string", + "format": "uuid", + "title": "Source Id" + }, + "source_path": { + "type": "string", + "title": "Source Path" + }, + "error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Message" + }, + "error_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Class" + }, + "http_status_code": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Http Status Code" + }, + "retry_count": { + "type": "integer", + "title": "Retry Count" + }, + "status": { + "type": "string", + "title": "Status" + }, + "first_failed_at": { + "type": "string", + "format": "date-time", + "title": "First Failed At" + }, + "last_retried_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Retried At" + }, + "dismissed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Dismissed At" + }, + "dismissed_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Dismissed By" + } + }, + "type": "object", + "required": [ + "id", + "source_id", + "source_path", + "error_message", + "error_class", + "http_status_code", + "retry_count", + "status", + "first_failed_at", + "last_retried_at", + "dismissed_at", + "dismissed_by" + ], + "title": "SyncFailureRead" + }, + "SyncRunLogRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "source_id": { + "type": "string", + "format": "uuid", + "title": "Source Id" + }, + "started_at": { + "type": "string", + "format": "date-time", + "title": "Started At" + }, + "finished_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Finished At" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + }, + "records_attempted": { + "type": "integer", + "title": "Records Attempted" + }, + "records_succeeded": { + "type": "integer", + "title": "Records Succeeded" + }, + "records_failed": { + "type": "integer", + "title": "Records Failed" + }, + "error_summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Summary" + } + }, + "type": "object", + "required": [ + "id", + "source_id", + "started_at", + "finished_at", + "status", + "records_attempted", + "records_succeeded", + "records_failed", + "error_summary" + ], + "title": "SyncRunLogRead" + }, + "SystemStatus": { + "properties": { + "version": { + "type": "string", + "title": "Version" + }, + "database": { + "type": "string", + "title": "Database" + }, + "ollama": { + "type": "string", + "title": "Ollama" + }, + "redis": { + "type": "string", + "title": "Redis" + }, + "user_count": { + "type": "integer", + "title": "User Count" + }, + "audit_log_count": { + "type": "integer", + "title": "Audit Log Count" + }, + "suite_session": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Suite Session" + } + }, + "type": "object", + "required": [ + "version", + "database", + "ollama", + "redis", + "user_count", + "audit_log_count" + ], + "title": "SystemStatus" + }, + "TaggedPlan": { + "properties": { + "action": { + "type": "string", + "const": "tagged-pdf", + "title": "Action" + }, + "headingLevels": { + "items": { + "type": "integer", + "maximum": 4294967295.0, + "minimum": 0.0 + }, + "type": "array", + "maxItems": 50, + "title": "Headinglevels" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "TaggedPlan" + }, + "TestConnectionRequest": { + "properties": { + "source_type": { + "type": "string", + "title": "Source Type" + }, + "host": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Host" + }, + "port": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Port" + }, + "path": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Path" + }, + "username": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Username" + }, + "password": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Password" + }, + "rest_api_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Rest Api Config" + }, + "odbc_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Odbc Config" + } + }, + "type": "object", + "required": [ + "source_type" + ], + "title": "TestConnectionRequest", + "description": "Dedicated schema for test-connection. NOT the create schema.\n\nSecurity: credentials in this request body are never persisted, never\nwritten to audit logs, and never returned in the response." + }, + "TestConnectionResponse": { + "properties": { + "success": { + "type": "boolean", + "title": "Success" + }, + "message": { + "type": "string", + "title": "Message" + }, + "latency_ms": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Latency Ms" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + }, + "warning": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Warning" + }, + "differing_keys": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Differing Keys" + } + }, + "type": "object", + "required": [ + "success", + "message" + ], + "title": "TestConnectionResponse" + }, + "TimelineEventCreate": { + "properties": { + "event_type": { + "type": "string", + "title": "Event Type" + }, + "description": { + "type": "string", + "title": "Description" + }, + "internal_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Internal Note" + } + }, + "type": "object", + "required": [ + "event_type", + "description" + ], + "title": "TimelineEventCreate" + }, + "TimelineEventRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "event_type": { + "type": "string", + "title": "Event Type" + }, + "actor_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Actor Id" + }, + "actor_role": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Actor Role" + }, + "description": { + "type": "string", + "title": "Description" + }, + "internal_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Internal Note" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "event_type", + "actor_id", + "actor_role", + "description", + "internal_note", + "created_at" + ], + "title": "TimelineEventRead" + }, + "TimelineView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "action": { + "type": "string", + "title": "Action" + }, + "actor": { + "type": "string", + "title": "Actor" + }, + "note": { + "type": "string", + "title": "Note" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "action", + "actor", + "note", + "created_at_unix_seconds" + ], + "title": "TimelineView" + }, + "TitleCreate": { + "properties": { + "title_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Title Id" + }, + "title_number": { + "type": "string", + "minLength": 1, + "title": "Title Number" + }, + "title_name": { + "type": "string", + "minLength": 1, + "title": "Title Name" + }, + "sort_order": { + "type": "integer", + "title": "Sort Order", + "default": 0 + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title_number", + "title_name" + ], + "title": "TitleCreate", + "description": "Request body for creating a code title." + }, + "TranscriptInput": { + "properties": { + "source_label": { + "type": "string", + "minLength": 1, + "title": "Source Label" + }, + "transcript_text": { + "type": "string", + "minLength": 1, + "title": "Transcript Text" + }, + "correction_of_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Correction Of Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_label", + "transcript_text" + ], + "title": "TranscriptInput" + }, + "UserRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "email": { + "type": "string", + "format": "email", + "title": "Email" + }, + "is_active": { + "type": "boolean", + "title": "Is Active", + "default": true + }, + "is_superuser": { + "type": "boolean", + "title": "Is Superuser", + "default": false + }, + "is_verified": { + "type": "boolean", + "title": "Is Verified", + "default": false + }, + "full_name": { + "type": "string", + "title": "Full Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "last_login": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Login" + }, + "must_change_password": { + "type": "boolean", + "title": "Must Change Password", + "default": false + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + } + }, + "type": "object", + "required": [ + "id", + "email", + "full_name", + "role", + "created_at", + "last_login" + ], + "title": "UserRead" + }, + "UserRole": { + "type": "string", + "enum": [ + "admin", + "staff", + "reviewer", + "read_only", + "liaison", + "public" + ], + "title": "UserRole" + }, + "UserSelfUpdate": { + "properties": { + "password": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Password" + }, + "email": { + "anyOf": [ + { + "type": "string", + "format": "email" + }, + { + "type": "null" + } + ], + "title": "Email" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + }, + "is_superuser": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Superuser" + }, + "is_verified": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Verified" + }, + "full_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Full Name" + } + }, + "type": "object", + "title": "UserSelfUpdate", + "description": "Schema for user self-update via PATCH /users/me.\n\nExcludes role and department_id. Any payload containing those fields is\nrejected at parse time (HTTP 422). Role and department changes require\nadmin privileges via /admin/users/{id}." + }, + "UserUpdateRequest": { + "properties": { + "full_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Full Name" + }, + "role": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Role" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "UserUpdateRequest" + }, + "ValidationError": { + "properties": { + "loc": { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "integer" + } + ] + }, + "type": "array", + "title": "Location" + }, + "msg": { + "type": "string", + "title": "Message" + }, + "type": { + "type": "string", + "title": "Error Type" + }, + "input": { + "title": "Input" + }, + "ctx": { + "type": "object", + "title": "Context" + } + }, + "type": "object", + "required": [ + "loc", + "msg", + "type" + ], + "title": "ValidationError" + }, + "Version": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence" + ], + "title": "Version" + }, + "VoteCorrection": { + "properties": { + "vote": { + "type": "string", + "minLength": 1, + "title": "Vote" + }, + "reason": { + "type": "string", + "minLength": 1, + "title": "Reason" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "vote", + "reason" + ], + "title": "VoteCorrection" + }, + "VoteInput": { + "properties": { + "voter_name": { + "type": "string", + "minLength": 1, + "title": "Voter Name" + }, + "vote": { + "type": "string", + "minLength": 1, + "title": "Vote" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "voter_name", + "vote" + ], + "title": "VoteInput" + }, + "_ParcelLookupIn": { + "properties": { + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "jurisdiction", + "query" + ], + "title": "_ParcelLookupIn" + }, + "townlight_inspections__workflow_models__SourceLink": { + "properties": { + "provider": { + "type": "string", + "const": "code", + "title": "Provider", + "default": "code" + }, + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "SourceLink" + }, + "townlight_permitting__workflow_models__SourceLink": { + "properties": { + "provider": { + "type": "string", + "enum": [ + "code", + "zoning" + ], + "title": "Provider" + }, + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "source_id", + "expected_sha256" + ], + "title": "SourceLink" + }, + "townlight_runtime__inspections_bridge__Search": { + "properties": { + "provider": { + "type": "string", + "const": "code", + "title": "Provider" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "query" + ], + "title": "Search" + }, + "townlight_runtime__notice_bridge__Review": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + }, + "note": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence", + "note" + ], + "title": "Review" + }, + "townlight_runtime__permitting_bridge__Import": { + "properties": { + "bundle": { + "$ref": "#/components/schemas/RequirementBundle" + }, + "expected_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "bundle" + ], + "title": "Import" + }, + "townlight_runtime__permitting_bridge__Search": { + "properties": { + "provider": { + "type": "string", + "enum": [ + "code", + "zoning" + ], + "title": "Provider" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "query" + ], + "title": "Search" + }, + "townlight_runtime__planning_bridge__Import": { + "properties": { + "bundle": { + "additionalProperties": true, + "type": "object", + "title": "Bundle" + }, + "expected_previous_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Expected Previous Revision" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "bundle" + ], + "title": "Import" + }, + "townlight_runtime__planning_bridge__Search": { + "properties": { + "query": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Query" + }, + "plan_type": { + "anyOf": [ + { + "type": "string", + "maxLength": 40 + }, + { + "type": "null" + } + ], + "title": "Plan Type" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "Search" + }, + "townlight_runtime__zoning_bridge__Review": { + "properties": { + "answer": { + "type": "string", + "maxLength": 10000, + "title": "Answer", + "default": "" + }, + "notes": { + "type": "string", + "maxLength": 10000, + "title": "Notes", + "default": "" + }, + "queue_status": { + "type": "string", + "enum": [ + "open", + "in_review", + "resolved", + "closed" + ], + "title": "Queue Status", + "default": "resolved" + } + }, + "additionalProperties": false, + "type": "object", + "title": "Review" + } + }, + "securitySchemes": { + "OAuth2PasswordBearer": { + "type": "oauth2", + "flows": { + "password": { + "scopes": {}, + "tokenUrl": "auth/jwt/login" + } + } + } + } + }, + "x-townlight-component": { + "view": "suite", + "identity": "Desktop source 1.7.0-1; townlight-runtime 0.2.0", + "evidence": "source-schema-only" + } +} diff --git a/docs/beta-1/api/suite.html b/docs/beta-1/api/suite.html new file mode 100644 index 0000000..7afab04 --- /dev/null +++ b/docs/beta-1/api/suite.html @@ -0,0 +1,27524 @@ +Townlight Suite API reference
Townlight

Townlight Suite API reference

+

Prepared source candidate, November 2, 2026. New signed Windows installed acceptance and publication remain pending.

+

Desktop source 1.7.0-1; townlight-runtime 0.2.0. The HTTP host is Townlight Records 1.8.0.dev2. Component package versions and the host API version are separate identities.

+

Generated from the actual native inspections-preview composition without application lifespan, migrations or database/network access. It describes route and validation contracts; it does not establish endpoint behavior, individual authorization or installed acceptance. Standalone product applications have separate deployment boundaries.

+

Machine-readable OpenAPI schema · Operating manual and limits

+

HTTP operations

+
GET /admin/coverage-gaps +
{
+  "tags": [
+    "admin"
+  ],
+  "summary": "Get Coverage Gaps",
+  "description": "Identify coverage gaps across jurisdictions, departments, and exemption categories.\n\nReturns:\n- Jurisdictions (state codes) that have no exemption rules\n- Departments with no assigned staff users\n- Exemption categories without any active rules",
+  "operationId": "get_coverage_gaps_admin_coverage_gaps_get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/CoverageGapResponse"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
GET /admin/fee-schedules +
{
+  "tags": [
+    "admin"
+  ],
+  "summary": "List Fee Schedules",
+  "description": "List all fee schedules. Admin only.",
+  "operationId": "list_fee_schedules_admin_fee_schedules_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "jurisdiction",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Jurisdiction"
+      }
+    },
+    {
+      "name": "limit",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "default": 50,
+        "title": "Limit"
+      }
+    },
+    {
+      "name": "offset",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "default": 0,
+        "title": "Offset"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/FeeScheduleRead"
+            },
+            "title": "Response List Fee Schedules Admin Fee Schedules Get"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /admin/fee-schedules +
{
+  "tags": [
+    "admin"
+  ],
+  "summary": "Create Fee Schedule",
+  "description": "Create a new fee schedule. Admin only.",
+  "operationId": "create_fee_schedule_admin_fee_schedules_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/FeeScheduleCreate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/FeeScheduleRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
PATCH /admin/fee-schedules/{schedule_id} +
{
+  "tags": [
+    "admin"
+  ],
+  "summary": "Update Fee Schedule",
+  "description": "Update a fee schedule. Admin only.",
+  "operationId": "update_fee_schedule_admin_fee_schedules__schedule_id__patch",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "schedule_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Schedule Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/FeeScheduleUpdate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/FeeScheduleRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
DELETE /admin/fee-schedules/{schedule_id} +
{
+  "tags": [
+    "admin"
+  ],
+  "summary": "Delete Fee Schedule",
+  "description": "Delete a fee schedule. Admin only.",
+  "operationId": "delete_fee_schedule_admin_fee_schedules__schedule_id__delete",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "schedule_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Schedule Id"
+      }
+    }
+  ],
+  "responses": {
+    "204": {
+      "description": "Successful Response"
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /admin/models +
{
+  "tags": [
+    "admin"
+  ],
+  "summary": "List Models",
+  "operationId": "list_models_admin_models_get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/OllamaStatus"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
GET /admin/models/registry +
{
+  "tags": [
+    "admin"
+  ],
+  "summary": "List Model Registry",
+  "operationId": "list_model_registry_admin_models_registry_get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "items": {
+              "$ref": "#/components/schemas/ModelRegistryRead"
+            },
+            "type": "array",
+            "title": "Response List Model Registry Admin Models Registry Get"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
POST /admin/models/registry +
{
+  "tags": [
+    "admin"
+  ],
+  "summary": "Register Model",
+  "operationId": "register_model_admin_models_registry_post",
+  "requestBody": {
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/ModelRegistryCreate"
+        }
+      }
+    },
+    "required": true
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/ModelRegistryRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
PATCH /admin/models/registry/{model_id} +
{
+  "tags": [
+    "admin"
+  ],
+  "summary": "Update Model Registry",
+  "operationId": "update_model_registry_admin_models_registry__model_id__patch",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "model_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "integer",
+        "title": "Model Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/ModelRegistryUpdate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/ModelRegistryRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
DELETE /admin/models/registry/{model_id} +
{
+  "tags": [
+    "admin"
+  ],
+  "summary": "Delete Model Registry",
+  "operationId": "delete_model_registry_admin_models_registry__model_id__delete",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "model_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "integer",
+        "title": "Model Id"
+      }
+    }
+  ],
+  "responses": {
+    "204": {
+      "description": "Successful Response"
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /admin/status +
{
+  "tags": [
+    "admin"
+  ],
+  "summary": "System Status",
+  "operationId": "system_status_admin_status_get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/SystemStatus"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
GET /admin/users +
{
+  "tags": [
+    "admin"
+  ],
+  "summary": "List Users",
+  "description": "List all users. Admin only.",
+  "operationId": "list_users_admin_users_get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "items": {
+              "$ref": "#/components/schemas/UserRead"
+            },
+            "type": "array",
+            "title": "Response List Users Admin Users Get"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
POST /admin/users +
{
+  "tags": [
+    "admin"
+  ],
+  "summary": "Create User",
+  "description": "Create a new user. Admin only.",
+  "operationId": "create_user_admin_users_post",
+  "requestBody": {
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/AdminUserCreateRequest"
+        }
+      }
+    },
+    "required": true
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/AdminUserCreateResponse"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
PATCH /admin/users/{user_id} +
{
+  "tags": [
+    "admin"
+  ],
+  "summary": "Update User",
+  "description": "Update user fields. Admin only.\n\nGuards against self-demotion: admins cannot change their own role.",
+  "operationId": "update_user_admin_users__user_id__patch",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "user_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "User Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/UserUpdateRequest"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/AdminUserCreateResponse"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /analytics/operational +
{
+  "tags": [
+    "analytics"
+  ],
+  "summary": "Get Operational Metrics",
+  "operationId": "get_operational_metrics_analytics_operational_get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/OperationalMetrics"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
GET /audit/export +
{
+  "tags": [
+    "audit"
+  ],
+  "summary": "Export Audit Logs",
+  "operationId": "export_audit_logs_audit_export_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "format",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "string",
+        "default": "json",
+        "title": "Format"
+      }
+    },
+    {
+      "name": "start_date",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Start Date"
+      }
+    },
+    {
+      "name": "end_date",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "End Date"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /audit/logs +
{
+  "tags": [
+    "audit"
+  ],
+  "summary": "List Audit Logs",
+  "operationId": "list_audit_logs_audit_logs_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "action",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Action"
+      }
+    },
+    {
+      "name": "resource_type",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Resource Type"
+      }
+    },
+    {
+      "name": "user_id",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string",
+            "format": "uuid"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "User Id"
+      }
+    },
+    {
+      "name": "start_date",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string",
+            "format": "date-time"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Start Date"
+      }
+    },
+    {
+      "name": "end_date",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string",
+            "format": "date-time"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "End Date"
+      }
+    },
+    {
+      "name": "limit",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 200,
+        "default": 50,
+        "title": "Limit"
+      }
+    },
+    {
+      "name": "offset",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "default": 0,
+        "title": "Offset"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/AuditLogRead"
+            },
+            "title": "Response List Audit Logs Audit Logs Get"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /audit/verify +
{
+  "tags": [
+    "audit"
+  ],
+  "summary": "Verify Audit Chain",
+  "operationId": "verify_audit_chain_audit_verify_get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/AuditChainVerification"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
POST /auth/jwt/login +
{
+  "tags": [
+    "auth"
+  ],
+  "summary": "Auth:Jwt.Login",
+  "operationId": "auth_jwt_login_auth_jwt_login_post",
+  "requestBody": {
+    "content": {
+      "application/x-www-form-urlencoded": {
+        "schema": {
+          "$ref": "#/components/schemas/Body_auth_jwt_login_auth_jwt_login_post"
+        }
+      }
+    },
+    "required": true
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/BearerResponse"
+          },
+          "example": {
+            "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiOTIyMWZmYzktNjQwZi00MzcyLTg2ZDMtY2U2NDJjYmE1NjAzIiwiYXVkIjoiZmFzdGFwaS11c2VyczphdXRoIiwiZXhwIjoxNTcxNTA0MTkzfQ.M10bjOe45I5Ncu_uXvOmVV8QxnL-nZfcH96U90JaocI",
+            "token_type": "bearer"
+          }
+        }
+      }
+    },
+    "400": {
+      "description": "Bad Request",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/ErrorModel"
+          },
+          "examples": {
+            "LOGIN_BAD_CREDENTIALS": {
+              "summary": "Bad credentials or the user is inactive.",
+              "value": {
+                "detail": "LOGIN_BAD_CREDENTIALS"
+              }
+            },
+            "LOGIN_USER_NOT_VERIFIED": {
+              "summary": "The user is not verified.",
+              "value": {
+                "detail": "LOGIN_USER_NOT_VERIFIED"
+              }
+            }
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /auth/jwt/logout +
{
+  "tags": [
+    "auth"
+  ],
+  "summary": "Auth:Jwt.Logout",
+  "operationId": "auth_jwt_logout_auth_jwt_logout_post",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "401": {
+      "description": "Missing token or inactive user."
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
GET /catalog/connectors +
{
+  "tags": [
+    "catalog"
+  ],
+  "summary": "List Connectors",
+  "operationId": "list_connectors_catalog_connectors_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "domain",
+      "in": "query",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Domain"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /catalog/domains +
{
+  "tags": [
+    "catalog"
+  ],
+  "summary": "List Domains",
+  "operationId": "list_domains_catalog_domains_get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
POST /catalog/load +
{
+  "tags": [
+    "catalog"
+  ],
+  "summary": "Trigger Catalog Load",
+  "operationId": "trigger_catalog_load_catalog_load_post",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
GET /catalog/systems +
{
+  "tags": [
+    "catalog"
+  ],
+  "summary": "List Systems",
+  "operationId": "list_systems_catalog_systems_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "domain",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Domain"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /city-profile +
{
+  "tags": [
+    "city-profile"
+  ],
+  "summary": "Get City Profile",
+  "operationId": "get_city_profile_city_profile_get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "anyOf": [
+              {
+                "$ref": "#/components/schemas/CityProfileRead"
+              },
+              {
+                "type": "null"
+              }
+            ],
+            "title": "Response Get City Profile City Profile Get"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
POST /city-profile +
{
+  "tags": [
+    "city-profile"
+  ],
+  "summary": "Create City Profile",
+  "operationId": "create_city_profile_city_profile_post",
+  "requestBody": {
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/CityProfileCreate"
+        }
+      }
+    },
+    "required": true
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/CityProfileRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
PATCH /city-profile +
{
+  "tags": [
+    "city-profile"
+  ],
+  "summary": "Update City Profile",
+  "operationId": "update_city_profile_city_profile_patch",
+  "requestBody": {
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/CityProfileUpdate"
+        }
+      }
+    },
+    "required": true
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/CityProfileRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
GET /config/portal-mode +
{
+  "tags": [
+    "public"
+  ],
+  "summary": "Get the deployment's current portal posture.",
+  "operationId": "get_portal_mode_config_portal_mode_get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/PortalModeResponse"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /datasources/ +
{
+  "tags": [
+    "datasources"
+  ],
+  "summary": "List Datasources",
+  "operationId": "list_datasources_datasources__get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "items": {
+              "$ref": "#/components/schemas/DataSourceRead"
+            },
+            "type": "array",
+            "title": "Response List Datasources Datasources  Get"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
POST /datasources/ +
{
+  "tags": [
+    "datasources"
+  ],
+  "summary": "Create Datasource",
+  "operationId": "create_datasource_datasources__post",
+  "requestBody": {
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/DataSourceCreate"
+        }
+      }
+    },
+    "required": true
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/DataSourceAdminRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
POST /datasources/documents/{document_id}/re-ingest +
{
+  "tags": [
+    "datasources"
+  ],
+  "summary": "Re Ingest Document",
+  "description": "Re-ingest a failed document. Resets status to pending and queues for processing.",
+  "operationId": "re_ingest_document_datasources_documents__document_id__re_ingest_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "document_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Document Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /datasources/stats +
{
+  "tags": [
+    "datasources"
+  ],
+  "summary": "Ingestion Stats",
+  "operationId": "ingestion_stats_datasources_stats_get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/IngestionStats"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
POST /datasources/test-connection +
{
+  "tags": [
+    "datasources"
+  ],
+  "summary": "Test Connection",
+  "description": "Test connectivity to a data source without persisting anything.\n\nThis endpoint validates the connection parameters and attempts a test\nconnection. Credentials are NOT persisted, NOT logged, and NOT returned.",
+  "operationId": "test_connection_datasources_test_connection_post",
+  "requestBody": {
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/TestConnectionRequest"
+        }
+      }
+    },
+    "required": true
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/TestConnectionResponse"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
POST /datasources/upload +
{
+  "tags": [
+    "datasources"
+  ],
+  "summary": "Upload File",
+  "operationId": "upload_file_datasources_upload_post",
+  "requestBody": {
+    "content": {
+      "multipart/form-data": {
+        "schema": {
+          "$ref": "#/components/schemas/Body_upload_file_datasources_upload_post"
+        }
+      }
+    },
+    "required": true
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
PATCH /datasources/{source_id} +
{
+  "tags": [
+    "datasources"
+  ],
+  "summary": "Update Datasource",
+  "operationId": "update_datasource_datasources__source_id__patch",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "source_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Source Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/DataSourceUpdate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/DataSourceAdminRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /datasources/{source_id}/ingest +
{
+  "tags": [
+    "datasources"
+  ],
+  "summary": "Trigger Ingestion",
+  "operationId": "trigger_ingestion_datasources__source_id__ingest_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "source_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Source Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /datasources/{source_id}/sync-failures +
{
+  "tags": [
+    "sync-failures"
+  ],
+  "summary": "List Sync Failures",
+  "operationId": "list_sync_failures_datasources__source_id__sync_failures_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "source_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Source Id"
+      }
+    },
+    {
+      "name": "status",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "description": "Filter by status",
+        "title": "Status"
+      },
+      "description": "Filter by status"
+    },
+    {
+      "name": "limit",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 500,
+        "minimum": 1,
+        "default": 50,
+        "title": "Limit"
+      }
+    },
+    {
+      "name": "offset",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "minimum": 0,
+        "default": 0,
+        "title": "Offset"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/SyncFailureRead"
+            },
+            "title": "Response List Sync Failures Datasources  Source Id  Sync Failures Get"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /datasources/{source_id}/sync-failures/dismiss-all +
{
+  "tags": [
+    "sync-failures"
+  ],
+  "summary": "Dismiss All Sync Failures",
+  "operationId": "dismiss_all_sync_failures_datasources__source_id__sync_failures_dismiss_all_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "source_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Source Id"
+      }
+    },
+    {
+      "name": "status",
+      "in": "query",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "description": "Status to dismiss — required",
+        "title": "Status"
+      },
+      "description": "Status to dismiss — required"
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /datasources/{source_id}/sync-failures/retry-all +
{
+  "tags": [
+    "sync-failures"
+  ],
+  "summary": "Retry All Sync Failures",
+  "operationId": "retry_all_sync_failures_datasources__source_id__sync_failures_retry_all_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "source_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Source Id"
+      }
+    },
+    {
+      "name": "status",
+      "in": "query",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "description": "Status to reset — required",
+        "title": "Status"
+      },
+      "description": "Status to reset — required"
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /datasources/{source_id}/sync-failures/{failure_id}/dismiss +
{
+  "tags": [
+    "sync-failures"
+  ],
+  "summary": "Dismiss Sync Failure",
+  "operationId": "dismiss_sync_failure_datasources__source_id__sync_failures__failure_id__dismiss_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "source_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Source Id"
+      }
+    },
+    {
+      "name": "failure_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Failure Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /datasources/{source_id}/sync-failures/{failure_id}/retry +
{
+  "tags": [
+    "sync-failures"
+  ],
+  "summary": "Retry Sync Failure",
+  "operationId": "retry_sync_failure_datasources__source_id__sync_failures__failure_id__retry_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "source_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Source Id"
+      }
+    },
+    {
+      "name": "failure_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Failure Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /datasources/{source_id}/sync-run-log +
{
+  "tags": [
+    "sync-failures"
+  ],
+  "summary": "Get Sync Run Log",
+  "operationId": "get_sync_run_log_datasources__source_id__sync_run_log_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "source_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Source Id"
+      }
+    },
+    {
+      "name": "limit",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 100,
+        "minimum": 1,
+        "default": 20,
+        "title": "Limit"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/SyncRunLogRead"
+            },
+            "title": "Response Get Sync Run Log Datasources  Source Id  Sync Run Log Get"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /datasources/{source_id}/unpause +
{
+  "tags": [
+    "sync-failures"
+  ],
+  "summary": "Unpause Source",
+  "operationId": "unpause_source_datasources__source_id__unpause_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "source_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Source Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /departments/ +
{
+  "tags": [
+    "departments"
+  ],
+  "summary": "List Departments",
+  "operationId": "list_departments_departments__get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "items": {
+              "$ref": "#/components/schemas/DepartmentRead"
+            },
+            "type": "array",
+            "title": "Response List Departments Departments  Get"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
POST /departments/ +
{
+  "tags": [
+    "departments"
+  ],
+  "summary": "Create Department",
+  "operationId": "create_department_departments__post",
+  "requestBody": {
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/DepartmentCreate"
+        }
+      }
+    },
+    "required": true
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/DepartmentRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
GET /departments/{dept_id} +
{
+  "tags": [
+    "departments"
+  ],
+  "summary": "Get Department",
+  "operationId": "get_department_departments__dept_id__get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "dept_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Dept Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/DepartmentRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
PATCH /departments/{dept_id} +
{
+  "tags": [
+    "departments"
+  ],
+  "summary": "Update Department",
+  "operationId": "update_department_departments__dept_id__patch",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "dept_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Dept Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/DepartmentUpdate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/DepartmentRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
DELETE /departments/{dept_id} +
{
+  "tags": [
+    "departments"
+  ],
+  "summary": "Delete Department",
+  "operationId": "delete_department_departments__dept_id__delete",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "dept_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Dept Id"
+      }
+    }
+  ],
+  "responses": {
+    "204": {
+      "description": "Successful Response"
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/access/drafts/{draft_id}/export +
{
+  "tags": [
+    "native-access"
+  ],
+  "summary": "Export Draft",
+  "operationId": "export_draft_desktop_v1_access_drafts__draft_id__export_post",
+  "parameters": [
+    {
+      "name": "draft_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Draft Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/access/exports/{artifact_id}/complete +
{
+  "tags": [
+    "native-access"
+  ],
+  "summary": "Complete Export",
+  "operationId": "complete_export_desktop_v1_access_exports__artifact_id__complete_post",
+  "parameters": [
+    {
+      "name": "artifact_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Artifact Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/ExportReceipt"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/access/review-context +
{
+  "tags": [
+    "native-access"
+  ],
+  "summary": "Review Context",
+  "operationId": "review_context_desktop_v1_access_review_context_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/ReviewInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/access/reviews +
{
+  "tags": [
+    "native-access"
+  ],
+  "summary": "Save Review",
+  "operationId": "save_review_desktop_v1_access_reviews_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/SaveReview"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/access/reviews/{review_id}/delete +
{
+  "tags": [
+    "native-access"
+  ],
+  "summary": "Delete Review",
+  "operationId": "delete_review_desktop_v1_access_reviews__review_id__delete_post",
+  "parameters": [
+    {
+      "name": "review_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Review Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/access/reviews/{review_id}/export +
{
+  "tags": [
+    "native-access"
+  ],
+  "summary": "Prepare Export",
+  "operationId": "prepare_export_desktop_v1_access_reviews__review_id__export_post",
+  "parameters": [
+    {
+      "name": "review_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Review Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/access/rewrite-context +
{
+  "tags": [
+    "native-access"
+  ],
+  "summary": "Rewrite Context",
+  "operationId": "rewrite_context_desktop_v1_access_rewrite_context_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/RewriteInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/access/rewrite-result +
{
+  "tags": [
+    "native-access"
+  ],
+  "summary": "Rewrite Result",
+  "operationId": "rewrite_result_desktop_v1_access_rewrite_result_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/RewriteResult"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/access/state +
{
+  "tags": [
+    "native-access"
+  ],
+  "summary": "Access State",
+  "operationId": "access_state_desktop_v1_access_state_get",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/access/tools +
{
+  "tags": [
+    "native-access"
+  ],
+  "summary": "Tool",
+  "operationId": "tool_desktop_v1_access_tools_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "oneOf": [
+            {
+              "$ref": "#/components/schemas/FormPlan"
+            },
+            {
+              "$ref": "#/components/schemas/PublishingPlan"
+            },
+            {
+              "$ref": "#/components/schemas/AdaPlan"
+            },
+            {
+              "$ref": "#/components/schemas/TaggedPlan"
+            }
+          ],
+          "discriminator": {
+            "propertyName": "action",
+            "mapping": {
+              "form-plan": "#/components/schemas/FormPlan",
+              "publishing-workflow": "#/components/schemas/PublishingPlan",
+              "ada-title-ii": "#/components/schemas/AdaPlan",
+              "tagged-pdf": "#/components/schemas/TaggedPlan"
+            }
+          },
+          "title": "Data"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/code-sources/search +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Search Code Sources",
+  "operationId": "search_code_sources_desktop_v1_code_sources_search_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/CodeSearch"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/code/citation +
{
+  "tags": [
+    "native-code"
+  ],
+  "summary": "Citation",
+  "operationId": "citation_desktop_v1_code_citation_get",
+  "parameters": [
+    {
+      "name": "section_number",
+      "in": "query",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Section Number"
+      }
+    },
+    {
+      "name": "as_of",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string",
+            "format": "date"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "As Of"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/code/connections +
{
+  "summary": "List Connections",
+  "operationId": "list_connections_desktop_v1_code_connections_get",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/code/connections +
{
+  "summary": "Create Connection",
+  "operationId": "create_connection_desktop_v1_code_connections_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/Proposal"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/code/connections/{connection_id} +
{
+  "summary": "Get Connection",
+  "operationId": "get_connection_desktop_v1_code_connections__connection_id__get",
+  "parameters": [
+    {
+      "name": "connection_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "pattern": "^[A-Za-z0-9_-]{1,64}$",
+        "title": "Connection Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/code/connections/{connection_id}/closeout +
{
+  "summary": "Closeout Connection",
+  "operationId": "closeout_connection_desktop_v1_code_connections__connection_id__closeout_post",
+  "parameters": [
+    {
+      "name": "connection_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "pattern": "^[A-Za-z0-9_-]{1,64}$",
+        "title": "Connection Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/Closeout"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/code/export +
{
+  "tags": [
+    "native-code"
+  ],
+  "summary": "Export Section",
+  "operationId": "export_section_desktop_v1_code_export_get",
+  "parameters": [
+    {
+      "name": "section_ref",
+      "in": "query",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Section Ref"
+      }
+    },
+    {
+      "name": "as_of",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string",
+            "format": "date"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "As Of"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/code/imports +
{
+  "tags": [
+    "native-code"
+  ],
+  "summary": "Imports",
+  "operationId": "imports_desktop_v1_code_imports_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/ImportBundleCreate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/code/imports +
{
+  "tags": [
+    "native-code"
+  ],
+  "summary": "List Imports",
+  "operationId": "list_imports_desktop_v1_code_imports_get",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/code/imports/{job_id}/provenance +
{
+  "tags": [
+    "native-code"
+  ],
+  "summary": "Import Provenance",
+  "operationId": "import_provenance_desktop_v1_code_imports__job_id__provenance_get",
+  "parameters": [
+    {
+      "name": "job_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Job Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/code/imports/{job_id}/tree +
{
+  "tags": [
+    "native-code"
+  ],
+  "summary": "Import Tree",
+  "operationId": "import_tree_desktop_v1_code_imports__job_id__tree_get",
+  "parameters": [
+    {
+      "name": "job_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Job Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/code/lookup +
{
+  "tags": [
+    "native-code"
+  ],
+  "summary": "Lookup",
+  "operationId": "lookup_desktop_v1_code_lookup_get",
+  "parameters": [
+    {
+      "name": "section_number",
+      "in": "query",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Section Number"
+      }
+    },
+    {
+      "name": "as_of",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string",
+            "format": "date"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "As Of"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/code/questions +
{
+  "tags": [
+    "native-code"
+  ],
+  "summary": "Questions",
+  "operationId": "questions_desktop_v1_code_questions_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/QuestionAnswerRequest"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/code/search +
{
+  "tags": [
+    "native-code"
+  ],
+  "summary": "Search",
+  "operationId": "search_desktop_v1_code_search_get",
+  "parameters": [
+    {
+      "name": "q",
+      "in": "query",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Q"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/code/sections/{section_id}/history +
{
+  "tags": [
+    "native-code"
+  ],
+  "summary": "Section History",
+  "operationId": "section_history_desktop_v1_code_sections__section_id__history_get",
+  "parameters": [
+    {
+      "name": "section_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Section Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/code/sections/{section_id}/notes +
{
+  "tags": [
+    "native-code"
+  ],
+  "summary": "Create Note",
+  "operationId": "create_note_desktop_v1_code_sections__section_id__notes_post",
+  "parameters": [
+    {
+      "name": "section_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Section Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/InterpretationNoteCreate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/code/sections/{section_id}/notes +
{
+  "tags": [
+    "native-code"
+  ],
+  "summary": "List Notes",
+  "operationId": "list_notes_desktop_v1_code_sections__section_id__notes_get",
+  "parameters": [
+    {
+      "name": "section_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Section Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/code/sections/{section_id}/summaries +
{
+  "tags": [
+    "native-code"
+  ],
+  "summary": "Create Summary",
+  "operationId": "create_summary_desktop_v1_code_sections__section_id__summaries_post",
+  "parameters": [
+    {
+      "name": "section_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Section Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/PlainLanguageSummaryCreate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/code/sections/{section_id}/summaries +
{
+  "tags": [
+    "native-code"
+  ],
+  "summary": "List Summaries",
+  "operationId": "list_summaries_desktop_v1_code_sections__section_id__summaries_get",
+  "parameters": [
+    {
+      "name": "section_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Section Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/code/sources +
{
+  "tags": [
+    "native-code"
+  ],
+  "summary": "Sources",
+  "operationId": "sources_desktop_v1_code_sources_get",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/code/summaries/{summary_id}/approve +
{
+  "tags": [
+    "native-code"
+  ],
+  "summary": "Approve Summary",
+  "operationId": "approve_summary_desktop_v1_code_summaries__summary_id__approve_post",
+  "parameters": [
+    {
+      "name": "summary_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Summary Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/code/workspace +
{
+  "tags": [
+    "native-code"
+  ],
+  "summary": "Workspace",
+  "operationId": "workspace_desktop_v1_code_workspace_get",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/inspections-sources/search +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Search Inspections Sources",
+  "operationId": "search_inspections_sources_desktop_v1_inspections_sources_search_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MeetingsSearch"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/inspections/cases +
{
+  "tags": [
+    "native-inspections"
+  ],
+  "summary": "Cases",
+  "operationId": "cases_desktop_v1_inspections_cases_get",
+  "parameters": [
+    {
+      "name": "offset",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 100000,
+        "minimum": 0,
+        "default": 0,
+        "title": "Offset"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/inspections/cases +
{
+  "tags": [
+    "native-inspections"
+  ],
+  "summary": "Create Case",
+  "operationId": "create_case_desktop_v1_inspections_cases_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/InspectionInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/inspections/cases/{case_id} +
{
+  "tags": [
+    "native-inspections"
+  ],
+  "summary": "Case",
+  "operationId": "case_desktop_v1_inspections_cases__case_id__get",
+  "parameters": [
+    {
+      "name": "case_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Case Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/inspections/cases/{case_id}/history +
{
+  "tags": [
+    "native-inspections"
+  ],
+  "summary": "History",
+  "operationId": "history_desktop_v1_inspections_cases__case_id__history_get",
+  "parameters": [
+    {
+      "name": "case_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Case Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/inspections/cases/{case_id}/packets +
{
+  "tags": [
+    "native-inspections"
+  ],
+  "summary": "Packet",
+  "operationId": "packet_desktop_v1_inspections_cases__case_id__packets_post",
+  "parameters": [
+    {
+      "name": "case_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Case Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/Packet"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/inspections/cases/{case_id}/revisions +
{
+  "tags": [
+    "native-inspections"
+  ],
+  "summary": "Revise",
+  "operationId": "revise_desktop_v1_inspections_cases__case_id__revisions_post",
+  "parameters": [
+    {
+      "name": "case_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Case Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/InspectionInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/inspections/connections/search +
{
+  "tags": [
+    "native-inspections"
+  ],
+  "summary": "Connections",
+  "operationId": "connections_desktop_v1_inspections_connections_search_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/townlight_runtime__inspections_bridge__Search"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/inspections/evidence/retain +
{
+  "tags": [
+    "native-inspections"
+  ],
+  "summary": "Retain",
+  "operationId": "retain_desktop_v1_inspections_evidence_retain_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/EvidenceItems"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/inspections/evidence/supported-types +
{
+  "tags": [
+    "native-inspections"
+  ],
+  "summary": "Supported Types",
+  "description": "The media types this deployment's product model actually accepts.",
+  "operationId": "supported_types_desktop_v1_inspections_evidence_supported_types_get",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/inspections/media/analyse +
{
+  "tags": [
+    "native-inspections"
+  ],
+  "summary": "Media Analyse",
+  "description": "Run the configured adapters over retained originals; draft only.\n\nThe result carries the same observations/citations the product route returns\nplus ``analysis_record``: the exact ``AnalysisRecord`` the caller puts on its\ncase payload, so the reviewed draft is the analysed one.",
+  "operationId": "media_analyse_desktop_v1_inspections_media_analyse_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MediaAnalysis"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/inspections/notice-draft +
{
+  "tags": [
+    "native-inspections"
+  ],
+  "summary": "Notice",
+  "operationId": "notice_desktop_v1_inspections_notice_draft_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/InspectionInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/inspections/packets/{packet_id} +
{
+  "tags": [
+    "native-inspections"
+  ],
+  "summary": "Document",
+  "operationId": "document_desktop_v1_inspections_packets__packet_id__get",
+  "parameters": [
+    {
+      "name": "packet_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Packet Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/inspections/repeat-cases +
{
+  "tags": [
+    "native-inspections"
+  ],
+  "summary": "Repeat Cases",
+  "operationId": "repeat_cases_desktop_v1_inspections_repeat_cases_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/RepeatLookup"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings-sources/search +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Search Meetings Sources",
+  "operationId": "search_meetings_sources_desktop_v1_meetings_sources_search_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MeetingsSearch"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/agenda-items +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Create Agenda Item",
+  "operationId": "create_agenda_item_desktop_v1_meetings_agenda_items_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/AgendaInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/meetings/agenda-items/{item_id} +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Get Agenda Item",
+  "operationId": "get_agenda_item_desktop_v1_meetings_agenda_items__item_id__get",
+  "parameters": [
+    {
+      "name": "item_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Item Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/agenda-items/{item_id}/meeting +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Assign Agenda",
+  "operationId": "assign_agenda_desktop_v1_meetings_agenda_items__item_id__meeting_post",
+  "parameters": [
+    {
+      "name": "item_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Item Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/AgendaAssignment"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/agenda-items/{item_id}/reviews +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Record Agenda Review",
+  "operationId": "record_agenda_review_desktop_v1_meetings_agenda_items__item_id__reviews_post",
+  "parameters": [
+    {
+      "name": "item_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Item Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/AgendaReviewInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/meetings/code-connections +
{
+  "summary": "List Code Connections",
+  "operationId": "list_code_connections_desktop_v1_meetings_code_connections_get",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/meetings/code-connections/{connection_id} +
{
+  "summary": "Get Code Connection",
+  "operationId": "get_code_connection_desktop_v1_meetings_code_connections__connection_id__get",
+  "parameters": [
+    {
+      "name": "connection_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "pattern": "^[A-Za-z0-9_-]{1,64}$",
+        "title": "Connection Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/code-connections/{connection_id}/decisions +
{
+  "summary": "Record Decision",
+  "operationId": "record_decision_desktop_v1_meetings_code_connections__connection_id__decisions_post",
+  "parameters": [
+    {
+      "name": "connection_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "pattern": "^[A-Za-z0-9_-]{1,64}$",
+        "title": "Connection Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/Decision"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/meetings +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Create Meeting",
+  "operationId": "create_meeting_desktop_v1_meetings_meetings_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MeetingInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/meetings/meetings/{meeting_id} +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Get Meeting",
+  "operationId": "get_meeting_desktop_v1_meetings_meetings__meeting_id__get",
+  "parameters": [
+    {
+      "name": "meeting_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Meeting Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/meetings/{meeting_id}/action-items +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Capture Action Item",
+  "operationId": "capture_action_item_desktop_v1_meetings_meetings__meeting_id__action_items_post",
+  "parameters": [
+    {
+      "name": "meeting_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Meeting Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/ActionItemInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/meetings/{meeting_id}/archive +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Archive Meeting",
+  "operationId": "archive_meeting_desktop_v1_meetings_meetings__meeting_id__archive_post",
+  "parameters": [
+    {
+      "name": "meeting_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Meeting Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/ArchiveInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/meetings/{meeting_id}/minutes/drafts +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Create Minutes",
+  "operationId": "create_minutes_desktop_v1_meetings_meetings__meeting_id__minutes_drafts_post",
+  "parameters": [
+    {
+      "name": "meeting_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Meeting Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/DraftInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/meetings/{meeting_id}/motions +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Capture Motion",
+  "operationId": "capture_motion_desktop_v1_meetings_meetings__meeting_id__motions_post",
+  "parameters": [
+    {
+      "name": "meeting_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Meeting Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MotionInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/meetings/{meeting_id}/notice-checks +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Check Notice",
+  "operationId": "check_notice_desktop_v1_meetings_meetings__meeting_id__notice_checks_post",
+  "parameters": [
+    {
+      "name": "meeting_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Meeting Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/NoticeInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/meetings/{meeting_id}/packet-snapshots +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Capture Packet",
+  "operationId": "capture_packet_desktop_v1_meetings_meetings__meeting_id__packet_snapshots_post",
+  "parameters": [
+    {
+      "name": "meeting_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Meeting Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/PacketInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/meetings/meetings/{meeting_id}/proceedings +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Proceedings",
+  "operationId": "proceedings_desktop_v1_meetings_meetings__meeting_id__proceedings_get",
+  "parameters": [
+    {
+      "name": "meeting_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Meeting Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/meetings/{meeting_id}/stages +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Record Meeting Stage",
+  "operationId": "record_meeting_stage_desktop_v1_meetings_meetings__meeting_id__stages_post",
+  "parameters": [
+    {
+      "name": "meeting_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Meeting Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MeetingStageInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/meetings/{meeting_id}/transcripts +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Capture Transcript",
+  "operationId": "capture_transcript_desktop_v1_meetings_meetings__meeting_id__transcripts_post",
+  "parameters": [
+    {
+      "name": "meeting_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Meeting Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/TranscriptInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/minutes/{draft_id}/decisions +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Decide Minutes",
+  "operationId": "decide_minutes_desktop_v1_meetings_minutes__draft_id__decisions_post",
+  "parameters": [
+    {
+      "name": "draft_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Draft Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MinutesDecision"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/motions/{motion_id}/corrections +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Correct Motion",
+  "operationId": "correct_motion_desktop_v1_meetings_motions__motion_id__corrections_post",
+  "parameters": [
+    {
+      "name": "motion_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Motion Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MotionCorrection"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/motions/{motion_id}/votes +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Capture Vote",
+  "operationId": "capture_vote_desktop_v1_meetings_motions__motion_id__votes_post",
+  "parameters": [
+    {
+      "name": "motion_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Motion Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/VoteInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/notices/{notice_id}/document +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Notice Document",
+  "operationId": "notice_document_desktop_v1_meetings_notices__notice_id__document_post",
+  "parameters": [
+    {
+      "name": "notice_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Notice Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/NoticeDocumentInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/notices/{notice_id}/proof +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Record Notice Proof",
+  "operationId": "record_notice_proof_desktop_v1_meetings_notices__notice_id__proof_post",
+  "parameters": [
+    {
+      "name": "notice_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Notice Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/NoticeProofInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/meetings/notices/{notice_id}/template +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Notice Template",
+  "operationId": "notice_template_desktop_v1_meetings_notices__notice_id__template_get",
+  "parameters": [
+    {
+      "name": "notice_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Notice Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/packets/{packet_id}/deliver +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Export Packet",
+  "operationId": "export_packet_desktop_v1_meetings_packets__packet_id__deliver_post",
+  "parameters": [
+    {
+      "name": "packet_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Packet Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/meetings/station/catalog +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Station Catalog",
+  "description": "Authorized name-based operator selection from canonical Meetings data.",
+  "operationId": "station_catalog_desktop_v1_meetings_station_catalog_get",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/meetings/votes/{vote_id}/corrections +
{
+  "tags": [
+    "native-meetings"
+  ],
+  "summary": "Correct Vote",
+  "operationId": "correct_vote_desktop_v1_meetings_votes__vote_id__corrections_post",
+  "parameters": [
+    {
+      "name": "vote_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Vote Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/VoteCorrection"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/notice/archives/{archive_id} +
{
+  "tags": [
+    "native-notice"
+  ],
+  "summary": "Export",
+  "operationId": "export_desktop_v1_notice_archives__archive_id__get",
+  "parameters": [
+    {
+      "name": "archive_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Archive Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/notice/archives/{archive_id}/records +
{
+  "tags": [
+    "native-notice"
+  ],
+  "summary": "Handoff",
+  "operationId": "handoff_desktop_v1_notice_archives__archive_id__records_post",
+  "parameters": [
+    {
+      "name": "archive_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Archive Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/Handoff"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/notice/notices +
{
+  "tags": [
+    "native-notice"
+  ],
+  "summary": "Inventory",
+  "operationId": "inventory_desktop_v1_notice_notices_get",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/notice/notices +
{
+  "tags": [
+    "native-notice"
+  ],
+  "summary": "Create",
+  "operationId": "create_desktop_v1_notice_notices_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/NoticeDraft"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/notice/notices/{notice_id} +
{
+  "tags": [
+    "native-notice"
+  ],
+  "summary": "Read",
+  "operationId": "read_desktop_v1_notice_notices__notice_id__get",
+  "parameters": [
+    {
+      "name": "notice_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Notice Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/notice/notices/{notice_id}/approval +
{
+  "tags": [
+    "native-notice"
+  ],
+  "summary": "Approve",
+  "operationId": "approve_desktop_v1_notice_notices__notice_id__approval_post",
+  "parameters": [
+    {
+      "name": "notice_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Notice Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/Version"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/notice/notices/{notice_id}/archive +
{
+  "tags": [
+    "native-notice"
+  ],
+  "summary": "Archive",
+  "operationId": "archive_desktop_v1_notice_notices__notice_id__archive_post",
+  "parameters": [
+    {
+      "name": "notice_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Notice Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/Version"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/notice/notices/{notice_id}/proof +
{
+  "tags": [
+    "native-notice"
+  ],
+  "summary": "Proof",
+  "operationId": "proof_desktop_v1_notice_notices__notice_id__proof_post",
+  "parameters": [
+    {
+      "name": "notice_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Notice Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/Proof"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/notice/notices/{notice_id}/review +
{
+  "tags": [
+    "native-notice"
+  ],
+  "summary": "Review",
+  "operationId": "review_desktop_v1_notice_notices__notice_id__review_post",
+  "parameters": [
+    {
+      "name": "notice_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Notice Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/townlight_runtime__notice_bridge__Review"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/notice/notices/{notice_id}/revisions +
{
+  "tags": [
+    "native-notice"
+  ],
+  "summary": "Edit",
+  "operationId": "edit_desktop_v1_notice_notices__notice_id__revisions_post",
+  "parameters": [
+    {
+      "name": "notice_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Notice Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/Revision"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/notifications/{notification_id}/sent +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Mark Native Notification Sent",
+  "operationId": "mark_native_notification_sent_desktop_v1_notifications__notification_id__sent_post",
+  "parameters": [
+    {
+      "name": "notification_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Notification Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RecordsStateRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/permitting-sources/search +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Search Permitting Sources",
+  "operationId": "search_permitting_sources_desktop_v1_permitting_sources_search_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MeetingsSearch"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/permitting/cases +
{
+  "tags": [
+    "native-permitting"
+  ],
+  "summary": "Cases",
+  "operationId": "cases_desktop_v1_permitting_cases_get",
+  "parameters": [
+    {
+      "name": "offset",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 100000,
+        "minimum": 0,
+        "default": 0,
+        "title": "Offset"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/permitting/cases +
{
+  "tags": [
+    "native-permitting"
+  ],
+  "summary": "Create Case",
+  "operationId": "create_case_desktop_v1_permitting_cases_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/IntakeInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/permitting/cases/{case_id} +
{
+  "tags": [
+    "native-permitting"
+  ],
+  "summary": "Case",
+  "operationId": "case_desktop_v1_permitting_cases__case_id__get",
+  "parameters": [
+    {
+      "name": "case_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Case Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/permitting/cases/{case_id}/history +
{
+  "tags": [
+    "native-permitting"
+  ],
+  "summary": "History",
+  "operationId": "history_desktop_v1_permitting_cases__case_id__history_get",
+  "parameters": [
+    {
+      "name": "case_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Case Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/permitting/cases/{case_id}/packets +
{
+  "tags": [
+    "native-permitting"
+  ],
+  "summary": "Packet",
+  "operationId": "packet_desktop_v1_permitting_cases__case_id__packets_post",
+  "parameters": [
+    {
+      "name": "case_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Case Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/Packet"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/permitting/cases/{case_id}/revisions +
{
+  "tags": [
+    "native-permitting"
+  ],
+  "summary": "Revise",
+  "operationId": "revise_desktop_v1_permitting_cases__case_id__revisions_post",
+  "parameters": [
+    {
+      "name": "case_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Case Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/IntakeInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/permitting/connections/search +
{
+  "tags": [
+    "native-permitting"
+  ],
+  "summary": "Connections",
+  "operationId": "connections_desktop_v1_permitting_connections_search_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/townlight_runtime__permitting_bridge__Search"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/permitting/packets/{packet_id} +
{
+  "tags": [
+    "native-permitting"
+  ],
+  "summary": "Document",
+  "operationId": "document_desktop_v1_permitting_packets__packet_id__get",
+  "parameters": [
+    {
+      "name": "packet_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Packet Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/permitting/pathway +
{
+  "tags": [
+    "native-permitting"
+  ],
+  "summary": "Pathway",
+  "description": "Cited likely permit pathway, attachments and timeline; informational only.\n\n``use_model_assistance`` does not exist here: the resident live-model\nassistance flag (F-07) stays excluded, so only the deterministic cited\npathway is reachable from the shared shell.",
+  "operationId": "pathway_desktop_v1_permitting_pathway_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/Pathway"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/permitting/requirements +
{
+  "tags": [
+    "native-permitting"
+  ],
+  "summary": "Import Requirements",
+  "operationId": "import_requirements_desktop_v1_permitting_requirements_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/townlight_runtime__permitting_bridge__Import"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/permitting/requirements +
{
+  "tags": [
+    "native-permitting"
+  ],
+  "summary": "Requirements",
+  "operationId": "requirements_desktop_v1_permitting_requirements_get",
+  "parameters": [
+    {
+      "name": "offset",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 100000,
+        "minimum": 0,
+        "default": 0,
+        "title": "Offset"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/permitting/requirements/{revision_id} +
{
+  "tags": [
+    "native-permitting"
+  ],
+  "summary": "Requirement",
+  "operationId": "requirement_desktop_v1_permitting_requirements__revision_id__get",
+  "parameters": [
+    {
+      "name": "revision_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Revision Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/planning-sources/search +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Search Planning Sources",
+  "operationId": "search_planning_sources_desktop_v1_planning_sources_search_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MeetingsSearch"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/planning/amendments +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Create Amendment",
+  "operationId": "create_amendment_desktop_v1_planning_amendments_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/AmendmentInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/planning/amendments/history +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Municipal Amendments",
+  "operationId": "municipal_amendments_desktop_v1_planning_amendments_history_get",
+  "parameters": [
+    {
+      "name": "offset",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 100000,
+        "minimum": 0,
+        "default": 0,
+        "title": "Offset"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/planning/amendments/{item_id}/revisions +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Update Amendment",
+  "operationId": "update_amendment_desktop_v1_planning_amendments__item_id__revisions_post",
+  "parameters": [
+    {
+      "name": "item_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Item Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/AmendmentInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/planning/analyses +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Analyses",
+  "operationId": "analyses_desktop_v1_planning_analyses_get",
+  "parameters": [
+    {
+      "name": "limit",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 100,
+        "minimum": 1,
+        "default": 50,
+        "title": "Limit"
+      }
+    },
+    {
+      "name": "offset",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 100000,
+        "minimum": 0,
+        "default": 0,
+        "title": "Offset"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/planning/analyses +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Create Analysis",
+  "operationId": "create_analysis_desktop_v1_planning_analyses_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "type": "object",
+          "additionalProperties": true,
+          "title": "Body"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/planning/analyses/{analysis_id} +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Analysis",
+  "operationId": "analysis_desktop_v1_planning_analyses__analysis_id__get",
+  "parameters": [
+    {
+      "name": "analysis_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Analysis Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/planning/analyses/{analysis_id}/history +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Analysis History",
+  "operationId": "analysis_history_desktop_v1_planning_analyses__analysis_id__history_get",
+  "parameters": [
+    {
+      "name": "analysis_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Analysis Id"
+      }
+    },
+    {
+      "name": "offset",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 100000,
+        "minimum": 0,
+        "default": 0,
+        "title": "Offset"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/planning/analyses/{analysis_id}/revisions +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Revise Analysis",
+  "operationId": "revise_analysis_desktop_v1_planning_analyses__analysis_id__revisions_post",
+  "parameters": [
+    {
+      "name": "analysis_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Analysis Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "type": "object",
+          "additionalProperties": true,
+          "title": "Body"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/planning/analyses/{analysis_id}/snapshot-preview +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Preview Snapshot",
+  "operationId": "preview_snapshot_desktop_v1_planning_analyses__analysis_id__snapshot_preview_post",
+  "parameters": [
+    {
+      "name": "analysis_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Analysis Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/Snapshot"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/planning/analyses/{analysis_id}/snapshots +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Snapshot",
+  "operationId": "snapshot_desktop_v1_planning_analyses__analysis_id__snapshots_post",
+  "parameters": [
+    {
+      "name": "analysis_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Analysis Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/Snapshot"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/planning/connections/search +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Connections",
+  "operationId": "connections_desktop_v1_planning_connections_search_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/ConnectionSearch"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/planning/imports +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Import Source",
+  "operationId": "import_source_desktop_v1_planning_imports_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/townlight_runtime__planning_bridge__Import"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/planning/imports/preview +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Preview Import",
+  "operationId": "preview_import_desktop_v1_planning_imports_preview_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/townlight_runtime__planning_bridge__Import"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/planning/initiatives +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Create Initiative",
+  "operationId": "create_initiative_desktop_v1_planning_initiatives_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/InitiativeInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/planning/initiatives/{item_id}/revisions +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Update Initiative",
+  "operationId": "update_initiative_desktop_v1_planning_initiatives__item_id__revisions_post",
+  "parameters": [
+    {
+      "name": "item_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Item Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/InitiativeInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/planning/municipal-work/{item_id}/history +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Municipal History",
+  "operationId": "municipal_history_desktop_v1_planning_municipal_work__item_id__history_get",
+  "parameters": [
+    {
+      "name": "item_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Item Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/planning/policies/search +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Policies",
+  "operationId": "policies_desktop_v1_planning_policies_search_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/townlight_runtime__planning_bridge__Search"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/planning/progress/targets +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Municipal Progress",
+  "operationId": "municipal_progress_desktop_v1_planning_progress_targets_get",
+  "parameters": [
+    {
+      "name": "offset",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 100000,
+        "minimum": 0,
+        "default": 0,
+        "title": "Offset"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/planning/revisions/{revision_id} +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Revision",
+  "operationId": "revision_desktop_v1_planning_revisions__revision_id__get",
+  "parameters": [
+    {
+      "name": "revision_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Revision Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/planning/revisions/{revision_id}/documents/{document_id} +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Staff Original",
+  "operationId": "staff_original_desktop_v1_planning_revisions__revision_id__documents__document_id__get",
+  "parameters": [
+    {
+      "name": "revision_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Revision Id"
+      }
+    },
+    {
+      "name": "document_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Document Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/planning/snapshots +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Snapshots",
+  "operationId": "snapshots_desktop_v1_planning_snapshots_get",
+  "parameters": [
+    {
+      "name": "limit",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 100,
+        "minimum": 1,
+        "default": 50,
+        "title": "Limit"
+      }
+    },
+    {
+      "name": "offset",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 100000,
+        "minimum": 0,
+        "default": 0,
+        "title": "Offset"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/planning/snapshots/{snapshot_id} +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Document",
+  "operationId": "document_desktop_v1_planning_snapshots__snapshot_id__get",
+  "parameters": [
+    {
+      "name": "snapshot_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Snapshot Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/planning/snapshots/{snapshot_id}/access-advice +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Access Advice",
+  "operationId": "access_advice_desktop_v1_planning_snapshots__snapshot_id__access_advice_post",
+  "parameters": [
+    {
+      "name": "snapshot_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Snapshot Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/planning/sources +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Source List",
+  "operationId": "source_list_desktop_v1_planning_sources_get",
+  "parameters": [
+    {
+      "name": "limit",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 100,
+        "minimum": 1,
+        "default": 50,
+        "title": "Limit"
+      }
+    },
+    {
+      "name": "offset",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 100000,
+        "minimum": 0,
+        "default": 0,
+        "title": "Offset"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/planning/sources/{plan_id}/history +
{
+  "tags": [
+    "native-planning"
+  ],
+  "summary": "Source History",
+  "operationId": "source_history_desktop_v1_planning_sources__plan_id__history_get",
+  "parameters": [
+    {
+      "name": "plan_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Plan Id"
+      }
+    },
+    {
+      "name": "offset",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 100000,
+        "minimum": 0,
+        "default": 0,
+        "title": "Offset"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/public/lookup +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Public Records Lookup",
+  "operationId": "public_records_lookup_desktop_v1_public_lookup_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Public",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Public"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/PublicLookup"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/public/messages +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Public Records Message",
+  "operationId": "public_records_message_desktop_v1_public_messages_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Public",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Public"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/PublicMessage"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/public/records-state +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Public Records State",
+  "operationId": "public_records_state_desktop_v1_public_records_state_get",
+  "parameters": [
+    {
+      "name": "X-Townlight-Public",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Public"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RecordsStateRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/public/requests +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Public Records Intake",
+  "operationId": "public_records_intake_desktop_v1_public_requests_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Public",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Public"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/PublicIntake"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/records-state +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Get Native Records State",
+  "operationId": "get_native_records_state_desktop_v1_records_state_get",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RecordsStateRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/requests +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Create Native Request",
+  "operationId": "create_native_request_desktop_v1_requests_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/StaffRecordsIntake"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/NativeRequestRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/requests/{request_id} +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Get Native Request",
+  "operationId": "get_native_request_desktop_v1_requests__request_id__get",
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/NativeRequestRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/requests/{request_id}/actions +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Native Request Operation",
+  "operationId": "native_request_operation_desktop_v1_requests__request_id__actions_post",
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "oneOf": [
+            {
+              "$ref": "#/components/schemas/AssignCommand"
+            },
+            {
+              "$ref": "#/components/schemas/DeadlineCommand"
+            },
+            {
+              "$ref": "#/components/schemas/CalculateDeadlineCommand"
+            },
+            {
+              "$ref": "#/components/schemas/ClarificationCommand"
+            },
+            {
+              "$ref": "#/components/schemas/MessageCommand"
+            },
+            {
+              "$ref": "#/components/schemas/SearchNoteCommand"
+            },
+            {
+              "$ref": "#/components/schemas/SearchReceiptCommand"
+            },
+            {
+              "$ref": "#/components/schemas/ExemptionNoteCommand"
+            },
+            {
+              "$ref": "#/components/schemas/ExemptionDecisionCommand"
+            },
+            {
+              "$ref": "#/components/schemas/FeeEstimateCommand"
+            },
+            {
+              "$ref": "#/components/schemas/FeeLineCommand"
+            },
+            {
+              "$ref": "#/components/schemas/FeeWaiverCommand"
+            },
+            {
+              "$ref": "#/components/schemas/DraftCommand"
+            },
+            {
+              "$ref": "#/components/schemas/ApprovalCommand"
+            },
+            {
+              "$ref": "#/components/schemas/FinishCommand"
+            }
+          ],
+          "discriminator": {
+            "propertyName": "action",
+            "mapping": {
+              "assign-records-request": "#/components/schemas/AssignCommand",
+              "set-records-deadline": "#/components/schemas/DeadlineCommand",
+              "calculate-records-deadline": "#/components/schemas/CalculateDeadlineCommand",
+              "request-records-clarification": "#/components/schemas/ClarificationCommand",
+              "add-records-message": "#/components/schemas/MessageCommand",
+              "record-records-search": "#/components/schemas/SearchNoteCommand",
+              "record-records-search-session": "#/components/schemas/SearchReceiptCommand",
+              "add-records-exemption-review": "#/components/schemas/ExemptionNoteCommand",
+              "add-records-exemption-decision": "#/components/schemas/ExemptionDecisionCommand",
+              "estimate-records-fee": "#/components/schemas/FeeEstimateCommand",
+              "add-records-fee-line": "#/components/schemas/FeeLineCommand",
+              "waive-records-fee": "#/components/schemas/FeeWaiverCommand",
+              "draft-records-response": "#/components/schemas/DraftCommand",
+              "approve-records-response": "#/components/schemas/ApprovalCommand",
+              "fulfill-records-request": "#/components/schemas/FinishCommand",
+              "close-records-request": "#/components/schemas/FinishCommand"
+            }
+          },
+          "title": "Command"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RecordsOperationRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/requests/{request_id}/artifacts +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Prepare Native Artifact",
+  "operationId": "prepare_native_artifact_desktop_v1_requests__request_id__artifacts_post",
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/PrepareArtifact"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/ArtifactPlan"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/requests/{request_id}/artifacts/{artifact_id}/complete +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Complete Native Artifact",
+  "operationId": "complete_native_artifact_desktop_v1_requests__request_id__artifacts__artifact_id__complete_post",
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "artifact_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Artifact Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/CompleteArtifact"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RecordsOperationRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/requests/{request_id}/code-sources +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Attach Code Source",
+  "operationId": "attach_code_source_desktop_v1_requests__request_id__code_sources_post",
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/CodeSourceSelection"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RecordsOperationRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/requests/{request_id}/documents +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Attach Native Document",
+  "operationId": "attach_native_document_desktop_v1_requests__request_id__documents_post",
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/AttachDocument"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RecordsOperationRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/requests/{request_id}/documents/{attachment_id}/release-copy +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Attach Native Release Copy",
+  "operationId": "attach_native_release_copy_desktop_v1_requests__request_id__documents__attachment_id__release_copy_post",
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "attachment_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Attachment Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/AttachReleaseCopy"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RecordsOperationRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/requests/{request_id}/draft-context +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Native Draft Context",
+  "operationId": "native_draft_context_desktop_v1_requests__request_id__draft_context_get",
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/requests/{request_id}/generated-draft +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Native Generated Draft",
+  "operationId": "native_generated_draft_desktop_v1_requests__request_id__generated_draft_post",
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/GeneratedDraft"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RecordsOperationRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/requests/{request_id}/inspections-sources +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Attach Inspections Source",
+  "operationId": "attach_inspections_source_desktop_v1_requests__request_id__inspections_sources_post",
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MeetingsSourceSelection"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RecordsOperationRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/requests/{request_id}/meetings-sources +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Attach Meetings Source",
+  "operationId": "attach_meetings_source_desktop_v1_requests__request_id__meetings_sources_post",
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MeetingsSourceSelection"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RecordsOperationRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/requests/{request_id}/permitting-sources +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Attach Permitting Source",
+  "operationId": "attach_permitting_source_desktop_v1_requests__request_id__permitting_sources_post",
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MeetingsSourceSelection"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RecordsOperationRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/requests/{request_id}/planning-sources +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Attach Planning Source",
+  "operationId": "attach_planning_source_desktop_v1_requests__request_id__planning_sources_post",
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MeetingsSourceSelection"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RecordsOperationRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/requests/{request_id}/station-recordings +
{
+  "tags": [
+    "native-desktop",
+    "station-integration"
+  ],
+  "summary": "Attach",
+  "operationId": "attach_desktop_v1_requests__request_id__station_recordings_post",
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/Selection"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RecordsOperationRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/requests/{request_id}/view +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Get Native Request View",
+  "operationId": "get_native_request_view_desktop_v1_requests__request_id__view_get",
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RecordsView"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/requests/{request_id}/zoning-sources +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Attach Zoning Source",
+  "operationId": "attach_zoning_source_desktop_v1_requests__request_id__zoning_sources_post",
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MeetingsSourceSelection"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RecordsOperationRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/station/context +
{
+  "tags": [
+    "native-desktop",
+    "station-integration"
+  ],
+  "summary": "Context",
+  "operationId": "context_desktop_v1_station_context_get",
+  "parameters": [
+    {
+      "name": "capability",
+      "in": "query",
+      "required": true,
+      "schema": {
+        "enum": [
+          "capture",
+          "read"
+        ],
+        "type": "string",
+        "title": "Capability"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/suite/search +
{
+  "tags": [
+    "native-records-snapshot"
+  ],
+  "summary": "Search",
+  "operationId": "search_desktop_v1_suite_search_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/SearchInput"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/suite/state +
{
+  "tags": [
+    "native-records-snapshot"
+  ],
+  "summary": "Suite State",
+  "operationId": "suite_state_desktop_v1_suite_state_get",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/zoning-sources/search +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Search Zoning Sources",
+  "operationId": "search_zoning_sources_desktop_v1_zoning_sources_search_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MeetingsSearch"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/zoning/code-context +
{
+  "tags": [
+    "native-zoning"
+  ],
+  "summary": "Create Code Context",
+  "operationId": "create_code_context_desktop_v1_zoning_code_context_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/CodeContext"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/zoning/imports +
{
+  "tags": [
+    "native-zoning"
+  ],
+  "summary": "Imports",
+  "operationId": "imports_desktop_v1_zoning_imports_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "type": "object",
+          "additionalProperties": true,
+          "title": "Payload"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/zoning/meetings/search +
{
+  "tags": [
+    "native-zoning"
+  ],
+  "summary": "Search Meetings",
+  "operationId": "search_meetings_desktop_v1_zoning_meetings_search_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MeetingSearch"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/zoning/outlines +
{
+  "tags": [
+    "native-zoning"
+  ],
+  "summary": "Create Outline",
+  "operationId": "create_outline_desktop_v1_zoning_outlines_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/Outline"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/zoning/parcels/lookup +
{
+  "tags": [
+    "native-zoning"
+  ],
+  "summary": "Parcel Lookup",
+  "operationId": "parcel_lookup_desktop_v1_zoning_parcels_lookup_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/_ParcelLookupIn"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/zoning/questions +
{
+  "tags": [
+    "native-zoning"
+  ],
+  "summary": "Create Question",
+  "operationId": "create_question_desktop_v1_zoning_questions_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/Question"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/zoning/questions/{question_id}/history +
{
+  "tags": [
+    "native-zoning"
+  ],
+  "summary": "Question History",
+  "operationId": "question_history_desktop_v1_zoning_questions__question_id__history_get",
+  "parameters": [
+    {
+      "name": "question_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Question Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/zoning/questions/{question_id}/meetings +
{
+  "tags": [
+    "native-zoning"
+  ],
+  "summary": "Link Meeting",
+  "operationId": "link_meeting_desktop_v1_zoning_questions__question_id__meetings_post",
+  "parameters": [
+    {
+      "name": "question_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Question Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MeetingLink"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/zoning/questions/{question_id}/reviews +
{
+  "tags": [
+    "native-zoning"
+  ],
+  "summary": "Create Review",
+  "operationId": "create_review_desktop_v1_zoning_questions__question_id__reviews_post",
+  "parameters": [
+    {
+      "name": "question_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Question Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/townlight_runtime__zoning_bridge__Review"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/zoning/questions/{question_id}/snapshots +
{
+  "tags": [
+    "native-zoning"
+  ],
+  "summary": "Create Snapshot",
+  "operationId": "create_snapshot_desktop_v1_zoning_questions__question_id__snapshots_post",
+  "parameters": [
+    {
+      "name": "question_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Question Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/SourceSnapshot"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/zoning/rules +
{
+  "tags": [
+    "native-zoning"
+  ],
+  "summary": "Create Rule",
+  "operationId": "create_rule_desktop_v1_zoning_rules_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/Rule"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/zoning/standards/process-explanation +
{
+  "tags": [
+    "native-zoning"
+  ],
+  "summary": "Standards Explanation",
+  "description": "Cited variance/CUP/nonconformity process; never a determination.",
+  "operationId": "standards_explanation_desktop_v1_zoning_standards_process_explanation_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/StandardsExplanation"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/zoning/workspace +
{
+  "tags": [
+    "native-zoning"
+  ],
+  "summary": "Get Workspace",
+  "operationId": "get_workspace_desktop_v1_zoning_workspace_get",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /documents/ +
{
+  "tags": [
+    "documents"
+  ],
+  "summary": "List Documents",
+  "operationId": "list_documents_documents__get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "source_id",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string",
+            "format": "uuid"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Source Id"
+      }
+    },
+    {
+      "name": "status",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "$ref": "#/components/schemas/IngestionStatus"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Status"
+      }
+    },
+    {
+      "name": "limit",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 500,
+        "default": 50,
+        "title": "Limit"
+      }
+    },
+    {
+      "name": "offset",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "default": 0,
+        "title": "Offset"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/DocumentRead"
+            },
+            "title": "Response List Documents Documents  Get"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /documents/{document_id} +
{
+  "tags": [
+    "documents"
+  ],
+  "summary": "Get Document",
+  "operationId": "get_document_documents__document_id__get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "document_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Document Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/DocumentRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /documents/{document_id}/chunks +
{
+  "tags": [
+    "documents"
+  ],
+  "summary": "List Chunks",
+  "operationId": "list_chunks_documents__document_id__chunks_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "document_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Document Id"
+      }
+    },
+    {
+      "name": "limit",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 500,
+        "default": 50,
+        "title": "Limit"
+      }
+    },
+    {
+      "name": "offset",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "default": 0,
+        "title": "Offset"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/DocumentChunkRead"
+            },
+            "title": "Response List Chunks Documents  Document Id  Chunks Get"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /exemptions/dashboard +
{
+  "tags": [
+    "exemptions"
+  ],
+  "summary": "Exemption Dashboard",
+  "operationId": "exemption_dashboard_exemptions_dashboard_get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/ExemptionDashboard"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
GET /exemptions/dashboard/accuracy +
{
+  "tags": [
+    "exemptions"
+  ],
+  "summary": "Exemption Accuracy",
+  "description": "Acceptance/rejection rates by category, optionally filtered by department.",
+  "operationId": "exemption_accuracy_exemptions_dashboard_accuracy_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "department_id",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string",
+            "format": "uuid"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Department Id"
+      }
+    },
+    {
+      "name": "date_from",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string",
+            "format": "date-time"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Date From"
+      }
+    },
+    {
+      "name": "date_to",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string",
+            "format": "date-time"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Date To"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/ExemptionAccuracyReport"
+            },
+            "title": "Response Exemption Accuracy Exemptions Dashboard Accuracy Get"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /exemptions/dashboard/export +
{
+  "tags": [
+    "exemptions"
+  ],
+  "summary": "Export Flag Data",
+  "description": "Export exemption flag data as JSON or CSV.",
+  "operationId": "export_flag_data_exemptions_dashboard_export_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "format",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "string",
+        "default": "json",
+        "title": "Format"
+      }
+    },
+    {
+      "name": "date_from",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string",
+            "format": "date-time"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Date From"
+      }
+    },
+    {
+      "name": "date_to",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string",
+            "format": "date-time"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Date To"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
PATCH /exemptions/flags/{flag_id} +
{
+  "tags": [
+    "exemptions"
+  ],
+  "summary": "Review Flag",
+  "operationId": "review_flag_exemptions_flags__flag_id__patch",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "flag_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Flag Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/ExemptionFlagReview"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/ExemptionFlagRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /exemptions/flags/{request_id} +
{
+  "tags": [
+    "exemptions"
+  ],
+  "summary": "List Flags",
+  "operationId": "list_flags_exemptions_flags__request_id__get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "status",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "$ref": "#/components/schemas/FlagStatus"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Status"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/ExemptionFlagRead"
+            },
+            "title": "Response List Flags Exemptions Flags  Request Id  Get"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /exemptions/rules/ +
{
+  "tags": [
+    "exemptions"
+  ],
+  "summary": "Create Rule",
+  "operationId": "create_rule_exemptions_rules__post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/ExemptionRuleCreate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/ExemptionRuleRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /exemptions/rules/ +
{
+  "tags": [
+    "exemptions"
+  ],
+  "summary": "List Rules",
+  "operationId": "list_rules_exemptions_rules__get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "state_code",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "State Code"
+      }
+    },
+    {
+      "name": "enabled",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "boolean"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Enabled"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/ExemptionRuleRead"
+            },
+            "title": "Response List Rules Exemptions Rules  Get"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
PATCH /exemptions/rules/{rule_id} +
{
+  "tags": [
+    "exemptions"
+  ],
+  "summary": "Update Rule",
+  "operationId": "update_rule_exemptions_rules__rule_id__patch",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "rule_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Rule Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/ExemptionRuleUpdate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/ExemptionRuleRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /exemptions/rules/{rule_id}/history +
{
+  "tags": [
+    "exemptions"
+  ],
+  "summary": "Get Rule History",
+  "description": "Get audit history for an exemption rule.",
+  "operationId": "get_rule_history_exemptions_rules__rule_id__history_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "rule_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Rule Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /exemptions/rules/{rule_id}/test +
{
+  "tags": [
+    "exemptions"
+  ],
+  "summary": "Test Rule",
+  "description": "Test a rule against sample text. Returns match results.\n\nUses the `regex` library with timeout=2s to prevent ReDoS on\nadmin-entered patterns.",
+  "operationId": "test_rule_exemptions_rules__rule_id__test_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "rule_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Rule Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/RuleTestRequest"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RuleTestResponse"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /exemptions/scan/{request_id} +
{
+  "tags": [
+    "exemptions"
+  ],
+  "summary": "Scan For Exemptions",
+  "description": "Scan all documents attached to a request for exemptions.",
+  "operationId": "scan_for_exemptions_exemptions_scan__request_id__post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "state_code",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "string",
+        "pattern": "^[A-Z]{2}$",
+        "default": "CO",
+        "title": "State Code"
+      }
+    },
+    {
+      "name": "use_llm",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "boolean",
+        "default": false,
+        "title": "Use Llm"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /exemptions/templates/ +
{
+  "tags": [
+    "exemptions"
+  ],
+  "summary": "List Templates",
+  "operationId": "list_templates_exemptions_templates__get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "template_type",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Template Type"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/DisclosureTemplateRead"
+            },
+            "title": "Response List Templates Exemptions Templates  Get"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /exemptions/templates/ +
{
+  "tags": [
+    "exemptions"
+  ],
+  "summary": "Create Template",
+  "operationId": "create_template_exemptions_templates__post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/DisclosureTemplateCreate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/DisclosureTemplateRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
PUT /exemptions/templates/{template_id} +
{
+  "tags": [
+    "exemptions"
+  ],
+  "summary": "Update Template",
+  "operationId": "update_template_exemptions_templates__template_id__put",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "template_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Template Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/DisclosureTemplateUpdate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/DisclosureTemplateRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /exemptions/templates/{template_id}/render +
{
+  "tags": [
+    "exemptions"
+  ],
+  "summary": "Render Template",
+  "description": "Render a template with city profile variables substituted.",
+  "operationId": "render_template_exemptions_templates__template_id__render_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "template_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Template Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/DisclosureTemplateRendered"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /health +
{
+  "summary": "Health",
+  "operationId": "health_health_get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    }
+  }
+}
+
GET /notifications/log +
{
+  "tags": [
+    "notifications"
+  ],
+  "summary": "List Notification Log",
+  "description": "List recent notification log entries.",
+  "operationId": "list_notification_log_notifications_log_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "limit",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 200,
+        "default": 50,
+        "title": "Limit"
+      }
+    },
+    {
+      "name": "request_id",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string",
+            "format": "uuid"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Request Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/NotificationLogRead"
+            },
+            "title": "Response List Notification Log Notifications Log Get"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /notifications/templates +
{
+  "tags": [
+    "notifications"
+  ],
+  "summary": "List Templates",
+  "description": "List all notification templates.",
+  "operationId": "list_templates_notifications_templates_get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "items": {
+              "$ref": "#/components/schemas/NotificationTemplateRead"
+            },
+            "type": "array",
+            "title": "Response List Templates Notifications Templates Get"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
POST /notifications/templates +
{
+  "tags": [
+    "notifications"
+  ],
+  "summary": "Create Template",
+  "description": "Create a new notification template (admin only).",
+  "operationId": "create_template_notifications_templates_post",
+  "requestBody": {
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/NotificationTemplateCreate"
+        }
+      }
+    },
+    "required": true
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/NotificationTemplateRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
PATCH /notifications/templates/{template_id} +
{
+  "tags": [
+    "notifications"
+  ],
+  "summary": "Update Template",
+  "description": "Update a notification template (admin only).",
+  "operationId": "update_template_notifications_templates__template_id__patch",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "template_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Template Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/NotificationTemplateUpdate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/NotificationTemplateRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /onboarding/interview +
{
+  "tags": [
+    "onboarding"
+  ],
+  "summary": "Get Next Question",
+  "description": "Generate the next onboarding question and persist the last answer.",
+  "operationId": "get_next_question_onboarding_interview_post",
+  "requestBody": {
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/InterviewRequest"
+        }
+      }
+    },
+    "required": true
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/InterviewResponse"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
GET /public/meetings +
{
+  "tags": [
+    "public-meetings"
+  ],
+  "summary": "Public Archive Index",
+  "operationId": "public_archive_index_public_meetings_get",
+  "parameters": [
+    {
+      "name": "q",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "string",
+        "default": "",
+        "title": "Q"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "text/html": {
+          "schema": {
+            "type": "string"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /public/meetings/{record_id} +
{
+  "tags": [
+    "public-meetings"
+  ],
+  "summary": "Public Archive Detail",
+  "operationId": "public_archive_detail_public_meetings__record_id__get",
+  "parameters": [
+    {
+      "name": "record_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Record Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "text/html": {
+          "schema": {
+            "type": "string"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /public/meetings/{record_id}/{kind}.txt +
{
+  "tags": [
+    "public-meetings"
+  ],
+  "summary": "Public Archive Download",
+  "operationId": "public_archive_download_public_meetings__record_id___kind__txt_get",
+  "parameters": [
+    {
+      "name": "record_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Record Id"
+      }
+    },
+    {
+      "name": "kind",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "enum": [
+          "agenda",
+          "packet",
+          "minutes"
+        ],
+        "type": "string",
+        "title": "Kind"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /requests/ +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Create Request",
+  "operationId": "create_request_requests__post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/RequestCreate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RequestRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /requests/ +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "List Requests",
+  "operationId": "list_requests_requests__get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "status",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "$ref": "#/components/schemas/RequestStatus"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Status"
+      }
+    },
+    {
+      "name": "assigned_to",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string",
+            "format": "uuid"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Assigned To"
+      }
+    },
+    {
+      "name": "limit",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "default": 50,
+        "title": "Limit"
+      }
+    },
+    {
+      "name": "offset",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "default": 0,
+        "title": "Offset"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/RequestRead"
+            },
+            "title": "Response List Requests Requests  Get"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /requests/stats +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Request Stats",
+  "operationId": "request_stats_requests_stats_get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RequestStats"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
GET /requests/{request_id} +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Get Request",
+  "operationId": "get_request_requests__request_id__get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RequestRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
PATCH /requests/{request_id} +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Update Request",
+  "operationId": "update_request_requests__request_id__patch",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/RequestUpdate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RequestRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /requests/{request_id}/approve +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Approve Request",
+  "operationId": "approve_request_requests__request_id__approve_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RequestRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /requests/{request_id}/documents +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Attach Document",
+  "operationId": "attach_document_requests__request_id__documents_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/RequestDocumentAdd"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RequestDocumentRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /requests/{request_id}/documents +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "List Attached Documents",
+  "operationId": "list_attached_documents_requests__request_id__documents_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/RequestDocumentRead"
+            },
+            "title": "Response List Attached Documents Requests  Request Id  Documents Get"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
DELETE /requests/{request_id}/documents/{doc_id} +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Remove Document",
+  "operationId": "remove_document_requests__request_id__documents__doc_id__delete",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "doc_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Doc Id"
+      }
+    }
+  ],
+  "responses": {
+    "204": {
+      "description": "Successful Response"
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /requests/{request_id}/estimate-fees +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Estimate Fees",
+  "description": "Estimate fees based on staff-entered page count and fee schedule.\n\nPage count is a manual staff estimate — not inferred from ingested docs.",
+  "operationId": "estimate_fees_requests__request_id__estimate_fees_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/FeeEstimateRequest"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/FeeEstimateResponse"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /requests/{request_id}/fee-waiver +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Create Fee Waiver",
+  "description": "Request a fee waiver for this records request.",
+  "operationId": "create_fee_waiver_requests__request_id__fee_waiver_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/FeeWaiverCreateRequest"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/FeeWaiverReadResponse"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
PATCH /requests/{request_id}/fee-waiver/{waiver_id} +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Review Fee Waiver",
+  "description": "Approve or deny a fee waiver. Reviewer/Admin only.",
+  "operationId": "review_fee_waiver_requests__request_id__fee_waiver__waiver_id__patch",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "waiver_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Waiver Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/FeeWaiverReviewRequest"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/FeeWaiverReadResponse"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /requests/{request_id}/fees +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Get Fees",
+  "operationId": "get_fees_requests__request_id__fees_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/FeeLineItemRead"
+            },
+            "title": "Response Get Fees Requests  Request Id  Fees Get"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /requests/{request_id}/fees +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Add Fee",
+  "operationId": "add_fee_requests__request_id__fees_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/FeeLineItemCreate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/FeeLineItemRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /requests/{request_id}/messages +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Get Messages",
+  "operationId": "get_messages_requests__request_id__messages_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/MessageRead"
+            },
+            "title": "Response Get Messages Requests  Request Id  Messages Get"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /requests/{request_id}/messages +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Add Message",
+  "operationId": "add_message_requests__request_id__messages_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MessageCreate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/MessageRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /requests/{request_id}/ready-for-release +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Mark Ready For Release",
+  "operationId": "mark_ready_for_release_requests__request_id__ready_for_release_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RequestRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /requests/{request_id}/reject +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Reject Request",
+  "operationId": "reject_request_requests__request_id__reject_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "reason",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "string",
+        "default": "",
+        "title": "Reason"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RequestRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /requests/{request_id}/response-letter +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Generate Response Letter",
+  "description": "Generate a draft response letter for a records request.\n\nAttempts LLM generation via Ollama first; falls back to a structured\ntemplate if the LLM is unavailable.",
+  "operationId": "generate_response_letter_requests__request_id__response_letter_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "content": {
+      "application/json": {
+        "schema": {
+          "anyOf": [
+            {
+              "$ref": "#/components/schemas/ResponseLetterCreate"
+            },
+            {
+              "type": "null"
+            }
+          ],
+          "title": "Data"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/ResponseLetterRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /requests/{request_id}/response-letter +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Get Response Letter",
+  "description": "Get the latest response letter for a request.",
+  "operationId": "get_response_letter_requests__request_id__response_letter_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/ResponseLetterRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
PATCH /requests/{request_id}/response-letter/{letter_id} +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Update Response Letter",
+  "description": "Update a response letter's edited content or status.\n\nStatus changes to 'approved' require REVIEWER role.",
+  "operationId": "update_response_letter_requests__request_id__response_letter__letter_id__patch",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    },
+    {
+      "name": "letter_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Letter Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/ResponseLetterUpdate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/ResponseLetterRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /requests/{request_id}/submit-review +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Submit For Review",
+  "operationId": "submit_for_review_requests__request_id__submit_review_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/RequestRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /requests/{request_id}/timeline +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Get Timeline",
+  "operationId": "get_timeline_requests__request_id__timeline_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/TimelineEventRead"
+            },
+            "title": "Response Get Timeline Requests  Request Id  Timeline Get"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /requests/{request_id}/timeline +
{
+  "tags": [
+    "requests"
+  ],
+  "summary": "Add Timeline Event",
+  "operationId": "add_timeline_event_requests__request_id__timeline_post",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "request_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Request Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/TimelineEventCreate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/TimelineEventRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /search/export +
{
+  "tags": [
+    "search"
+  ],
+  "summary": "Export Search Results",
+  "description": "Export search results as CSV. Runs a search and streams the results.",
+  "operationId": "export_search_results_search_export_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "query",
+      "in": "query",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Query"
+      }
+    },
+    {
+      "name": "format",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "string",
+        "default": "csv",
+        "title": "Format"
+      }
+    },
+    {
+      "name": "department_id",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Department Id"
+      }
+    },
+    {
+      "name": "file_type",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "File Type"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /search/filters +
{
+  "tags": [
+    "search"
+  ],
+  "summary": "Get Filter Options",
+  "description": "Get available filter values for search.",
+  "operationId": "get_filter_options_search_filters_get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/SearchFilterOptions"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
POST /search/query +
{
+  "tags": [
+    "search"
+  ],
+  "summary": "Execute Search",
+  "description": "Execute a hybrid search query. Optionally synthesize an LLM answer.",
+  "operationId": "execute_search_search_query_post",
+  "requestBody": {
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/SearchRequest"
+        }
+      }
+    },
+    "required": true
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/SearchResponse"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
GET /search/sessions +
{
+  "tags": [
+    "search"
+  ],
+  "summary": "List Sessions",
+  "description": "List the current user's search sessions.",
+  "operationId": "list_sessions_search_sessions_get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "limit",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "default": 20,
+        "title": "Limit"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/SearchSessionRead"
+            },
+            "title": "Response List Sessions Search Sessions Get"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /search/sessions/{session_id} +
{
+  "tags": [
+    "search"
+  ],
+  "summary": "Get Session",
+  "description": "Get a search session with its query history.",
+  "operationId": "get_session_search_sessions__session_id__get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "session_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Session Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/SearchSessionRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /service-accounts/ +
{
+  "tags": [
+    "service-accounts"
+  ],
+  "summary": "List Service Accounts",
+  "operationId": "list_service_accounts_service_accounts__get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "items": {
+              "$ref": "#/components/schemas/ServiceAccountRead"
+            },
+            "type": "array",
+            "title": "Response List Service Accounts Service Accounts  Get"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
POST /service-accounts/ +
{
+  "tags": [
+    "service-accounts"
+  ],
+  "summary": "Create Service Account",
+  "operationId": "create_service_account_service_accounts__post",
+  "requestBody": {
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/ServiceAccountCreate"
+        }
+      }
+    },
+    "required": true
+  },
+  "responses": {
+    "201": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/ServiceAccountCreated"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
PATCH /service-accounts/{account_id} +
{
+  "tags": [
+    "service-accounts"
+  ],
+  "summary": "Update Service Account",
+  "operationId": "update_service_account_service_accounts__account_id__patch",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "account_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Account Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/ServiceAccountUpdate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/ServiceAccountRead"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /townlight_code +
{
+  "summary": "Home",
+  "operationId": "home_townlight_code_get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "text/html": {
+          "schema": {
+            "type": "string"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /townlight_code/answer +
{
+  "summary": "Answer",
+  "operationId": "answer_townlight_code_answer_get",
+  "parameters": [
+    {
+      "name": "q",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "string",
+        "default": "",
+        "title": "Q"
+      }
+    },
+    {
+      "name": "section_number",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "Section Number"
+      }
+    },
+    {
+      "name": "as_of",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string",
+            "format": "date"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "As Of"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "text/html": {
+          "schema": {
+            "type": "string"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /townlight_code/search +
{
+  "summary": "Search",
+  "operationId": "search_townlight_code_search_get",
+  "parameters": [
+    {
+      "name": "q",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "string",
+        "default": "",
+        "title": "Q"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "text/html": {
+          "schema": {
+            "type": "string"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /townlight_code/sections/{section_ref} +
{
+  "summary": "Detail",
+  "operationId": "detail_townlight_code_sections__section_ref__get",
+  "parameters": [
+    {
+      "name": "section_ref",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Section Ref"
+      }
+    },
+    {
+      "name": "as_of",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string",
+            "format": "date"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "As Of"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "text/html": {
+          "schema": {
+            "type": "string"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /townlight_code/sections/{section_ref}/export +
{
+  "summary": "Export",
+  "operationId": "export_townlight_code_sections__section_ref__export_get",
+  "parameters": [
+    {
+      "name": "section_ref",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Section Ref"
+      }
+    },
+    {
+      "name": "as_of",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string",
+            "format": "date"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "As Of"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "text/html": {
+          "schema": {
+            "type": "string"
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /townlight_planning/plan-explore +
{
+  "tags": [
+    "local-public-planning"
+  ],
+  "summary": "Public Plan Explore",
+  "description": "Topic/goal/plan-type exploration over adopted public plan sources only.",
+  "operationId": "public_plan_explore_townlight_planning_plan_explore_post",
+  "requestBody": {
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/PublicExplore"
+        }
+      }
+    },
+    "required": true
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /townlight_planning/policies/search +
{
+  "tags": [
+    "local-public-planning"
+  ],
+  "summary": "Public Policies",
+  "operationId": "public_policies_townlight_planning_policies_search_post",
+  "requestBody": {
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/townlight_runtime__planning_bridge__Search"
+        }
+      }
+    },
+    "required": true
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /townlight_planning/revisions/{revision_id}/documents/{document_id} +
{
+  "tags": [
+    "local-public-planning"
+  ],
+  "summary": "Public Original",
+  "operationId": "public_original_townlight_planning_revisions__revision_id__documents__document_id__get",
+  "parameters": [
+    {
+      "name": "revision_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Revision Id"
+      }
+    },
+    {
+      "name": "document_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Document Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /townlight_planning/snapshots +
{
+  "tags": [
+    "local-public-planning"
+  ],
+  "summary": "Public Snapshots",
+  "operationId": "public_snapshots_townlight_planning_snapshots_get",
+  "parameters": [
+    {
+      "name": "limit",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 100,
+        "minimum": 1,
+        "default": 50,
+        "title": "Limit"
+      }
+    },
+    {
+      "name": "offset",
+      "in": "query",
+      "required": false,
+      "schema": {
+        "type": "integer",
+        "maximum": 100000,
+        "minimum": 0,
+        "default": 0,
+        "title": "Offset"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /townlight_planning/snapshots/{snapshot_id} +
{
+  "tags": [
+    "local-public-planning"
+  ],
+  "summary": "Public Document",
+  "operationId": "public_document_townlight_planning_snapshots__snapshot_id__get",
+  "parameters": [
+    {
+      "name": "snapshot_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Snapshot Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /townlight_zoning/parcels/lookup +
{
+  "summary": "Public Parcel Lookup",
+  "operationId": "public_parcel_lookup_townlight_zoning_parcels_lookup_post",
+  "requestBody": {
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/_ParcelLookupIn"
+        }
+      }
+    },
+    "required": true
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /townlight_zoning/questions +
{
+  "summary": "Public Question",
+  "operationId": "public_question_townlight_zoning_questions_post",
+  "requestBody": {
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/Question"
+        }
+      }
+    },
+    "required": true
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /users/me +
{
+  "tags": [
+    "users"
+  ],
+  "summary": "Users:Current User",
+  "operationId": "users_current_user_users_me_get",
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/UserRead"
+          }
+        }
+      }
+    },
+    "401": {
+      "description": "Missing token or inactive user."
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
PATCH /users/me +
{
+  "tags": [
+    "users"
+  ],
+  "summary": "Users:Patch Current User",
+  "operationId": "users_patch_current_user_users_me_patch",
+  "requestBody": {
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/UserSelfUpdate"
+        }
+      }
+    },
+    "required": true
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/UserRead"
+          }
+        }
+      }
+    },
+    "401": {
+      "description": "Missing token or inactive user."
+    },
+    "400": {
+      "description": "Bad Request",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/ErrorModel"
+          },
+          "examples": {
+            "UPDATE_USER_EMAIL_ALREADY_EXISTS": {
+              "summary": "A user with this email already exists.",
+              "value": {
+                "detail": "UPDATE_USER_EMAIL_ALREADY_EXISTS"
+              }
+            },
+            "UPDATE_USER_INVALID_PASSWORD": {
+              "summary": "Password validation failed.",
+              "value": {
+                "detail": {
+                  "code": "UPDATE_USER_INVALID_PASSWORD",
+                  "reason": "Password should beat least 3 characters"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  },
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ]
+}
+
GET /users/{id} +
{
+  "tags": [
+    "users"
+  ],
+  "summary": "Users:User",
+  "operationId": "users_user_users__id__get",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Id"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/UserRead"
+          }
+        }
+      }
+    },
+    "401": {
+      "description": "Missing token or inactive user."
+    },
+    "403": {
+      "description": "Not a superuser."
+    },
+    "404": {
+      "description": "The user does not exist."
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
PATCH /users/{id} +
{
+  "tags": [
+    "users"
+  ],
+  "summary": "Users:Patch User",
+  "operationId": "users_patch_user_users__id__patch",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Id"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/UserSelfUpdate"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/UserRead"
+          }
+        }
+      }
+    },
+    "401": {
+      "description": "Missing token or inactive user."
+    },
+    "403": {
+      "description": "Not a superuser."
+    },
+    "404": {
+      "description": "The user does not exist."
+    },
+    "400": {
+      "content": {
+        "application/json": {
+          "examples": {
+            "UPDATE_USER_EMAIL_ALREADY_EXISTS": {
+              "summary": "A user with this email already exists.",
+              "value": {
+                "detail": "UPDATE_USER_EMAIL_ALREADY_EXISTS"
+              }
+            },
+            "UPDATE_USER_INVALID_PASSWORD": {
+              "summary": "Password validation failed.",
+              "value": {
+                "detail": {
+                  "code": "UPDATE_USER_INVALID_PASSWORD",
+                  "reason": "Password should beat least 3 characters"
+                }
+              }
+            }
+          },
+          "schema": {
+            "$ref": "#/components/schemas/ErrorModel"
+          }
+        }
+      },
+      "description": "Bad Request"
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
DELETE /users/{id} +
{
+  "tags": [
+    "users"
+  ],
+  "summary": "Users:Delete User",
+  "operationId": "users_delete_user_users__id__delete",
+  "security": [
+    {
+      "OAuth2PasswordBearer": []
+    }
+  ],
+  "parameters": [
+    {
+      "name": "id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "title": "Id"
+      }
+    }
+  ],
+  "responses": {
+    "204": {
+      "description": "Successful Response"
+    },
+    "401": {
+      "description": "Missing token or inactive user."
+    },
+    "403": {
+      "description": "Not a superuser."
+    },
+    "404": {
+      "description": "The user does not exist."
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+

Request and response data dictionary

+

Each schema includes the actual required fields, types, constraints and descriptions. References resolve against the machine-readable document.

+
ActionItemInput
+{
+  "properties": {
+    "description": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Description"
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "source_motion_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Motion Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "description"
+  ],
+  "title": "ActionItemInput"
+}
+
+
AdaPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "ada-title-ii",
+      "title": "Action"
+    },
+    "serviceArea": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Servicearea"
+    },
+    "hasCoordinatorReview": {
+      "type": "boolean",
+      "title": "Hascoordinatorreview",
+      "default": false
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "serviceArea"
+  ],
+  "title": "AdaPlan"
+}
+
+
AdminUserCreateRequest
+{
+  "properties": {
+    "email": {
+      "type": "string",
+      "title": "Email"
+    },
+    "password": {
+      "type": "string",
+      "title": "Password"
+    },
+    "full_name": {
+      "type": "string",
+      "title": "Full Name",
+      "default": ""
+    },
+    "role": {
+      "type": "string",
+      "title": "Role",
+      "default": "staff"
+    }
+  },
+  "type": "object",
+  "required": [
+    "email",
+    "password"
+  ],
+  "title": "AdminUserCreateRequest"
+}
+
+
AdminUserCreateResponse
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "email": {
+      "type": "string",
+      "title": "Email"
+    },
+    "full_name": {
+      "type": "string",
+      "title": "Full Name"
+    },
+    "role": {
+      "type": "string",
+      "title": "Role"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "email",
+    "full_name",
+    "role",
+    "is_active"
+  ],
+  "title": "AdminUserCreateResponse"
+}
+
+
AgendaAssignment
+{
+  "properties": {
+    "meeting_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Meeting Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "meeting_id"
+  ],
+  "title": "AgendaAssignment"
+}
+
+
AgendaInput
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "department_name": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Department Name"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "department_name"
+  ],
+  "title": "AgendaInput"
+}
+
+
AgendaReviewInput
+{
+  "properties": {
+    "to_status": {
+      "type": "string",
+      "enum": [
+        "DRAFTED",
+        "SUBMITTED",
+        "DEPT_APPROVED",
+        "LEGAL_REVIEWED",
+        "CLERK_ACCEPTED",
+        "ON_AGENDA",
+        "IN_PACKET",
+        "POSTED",
+        "HEARD",
+        "DISPOSED",
+        "ARCHIVED"
+      ],
+      "title": "To Status"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "to_status"
+  ],
+  "title": "AgendaReviewInput"
+}
+
+
AmendmentInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "policy": {
+      "$ref": "#/components/schemas/PolicySelection"
+    },
+    "proposal": {
+      "type": "string",
+      "maxLength": 20000,
+      "minLength": 1,
+      "title": "Proposal"
+    },
+    "responsible_staff": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Responsible Staff"
+    },
+    "status": {
+      "type": "string",
+      "enum": [
+        "draft",
+        "review",
+        "adopted",
+        "withdrawn"
+      ],
+      "title": "Status",
+      "default": "draft"
+    },
+    "review_note": {
+      "type": "string",
+      "maxLength": 5000,
+      "title": "Review Note",
+      "default": ""
+    },
+    "adoption_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Adoption Revision"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "policy",
+    "proposal",
+    "responsible_staff",
+    "note"
+  ],
+  "title": "AmendmentInput"
+}
+
+
AnalysisObservation
+{
+  "properties": {
+    "source": {
+      "type": "string",
+      "maxLength": 64,
+      "minLength": 1,
+      "title": "Source"
+    },
+    "filename": {
+      "type": "string",
+      "maxLength": 160,
+      "title": "Filename",
+      "default": ""
+    },
+    "media_type": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Media Type",
+      "default": ""
+    },
+    "text": {
+      "type": "string",
+      "maxLength": 4000,
+      "minLength": 1,
+      "title": "Text"
+    },
+    "adapter": {
+      "type": "string",
+      "maxLength": 120,
+      "title": "Adapter",
+      "default": ""
+    },
+    "citation_source_ids": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Citation Source Ids"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source",
+    "text"
+  ],
+  "title": "AnalysisObservation",
+  "description": "One draft observation, named with the adapter that actually produced it."
+}
+
+
AnalysisRecord
+{
+  "properties": {
+    "observations": {
+      "items": {
+        "$ref": "#/components/schemas/AnalysisObservation"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Observations"
+    },
+    "cited_sections": {
+      "items": {
+        "$ref": "#/components/schemas/CitedSection"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Cited Sections"
+    },
+    "unavailable": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Unavailable"
+    },
+    "runtime": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Runtime"
+    },
+    "review_required": {
+      "type": "boolean",
+      "title": "Review Required",
+      "default": true
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "AnalysisRecord",
+  "description": "The adapter output that accompanies a saved inspection draft."
+}
+
+
ApprovalCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "approve-records-response",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ApprovalPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "ApprovalCommand"
+}
+
+
ApprovalPayload
+{
+  "properties": {
+    "approvalNote": {
+      "type": "string",
+      "title": "Approvalnote",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "ApprovalPayload"
+}
+
+
ArchiveInput
+{
+  "properties": {
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "public",
+        "closed_session"
+      ],
+      "title": "Visibility"
+    },
+    "packet_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Packet Id"
+    },
+    "minutes_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Minutes Id"
+    },
+    "plain_language_summary": {
+      "type": "string",
+      "title": "Plain Language Summary",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "visibility"
+  ],
+  "title": "ArchiveInput"
+}
+
+
ArtifactPlan
+{
+  "properties": {
+    "artifact_id": {
+      "type": "string",
+      "title": "Artifact Id"
+    },
+    "file_name": {
+      "type": "string",
+      "title": "File Name"
+    },
+    "content": {
+      "type": "string",
+      "title": "Content"
+    },
+    "sha256": {
+      "type": "string",
+      "title": "Sha256"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "artifact_id",
+    "file_name",
+    "content",
+    "sha256",
+    "created_at_unix_seconds"
+  ],
+  "title": "ArtifactPlan"
+}
+
+
AssignCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "assign-records-request",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/AssignmentPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "AssignCommand"
+}
+
+
AssignmentPayload
+{
+  "properties": {
+    "assignedTo": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Assignedto"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "assignedTo"
+  ],
+  "title": "AssignmentPayload"
+}
+
+
AttachDocument
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation",
+      "default": ""
+    },
+    "file": {
+      "$ref": "#/components/schemas/ManagedFileReceipt"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "file"
+  ],
+  "title": "AttachDocument"
+}
+
+
AttachReleaseCopy
+{
+  "properties": {
+    "status": {
+      "type": "string",
+      "enum": [
+        "release-ready copy",
+        "redacted copy"
+      ],
+      "title": "Status"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note",
+      "default": ""
+    },
+    "added_by": {
+      "type": "string",
+      "title": "Added By",
+      "default": ""
+    },
+    "file": {
+      "$ref": "#/components/schemas/ManagedFileReceipt"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "status",
+    "file"
+  ],
+  "title": "AttachReleaseCopy"
+}
+
+
AuditChainVerification
+{
+  "properties": {
+    "is_valid": {
+      "type": "boolean",
+      "title": "Is Valid"
+    },
+    "entries_checked": {
+      "type": "integer",
+      "title": "Entries Checked"
+    },
+    "error_message": {
+      "type": "string",
+      "title": "Error Message"
+    }
+  },
+  "type": "object",
+  "required": [
+    "is_valid",
+    "entries_checked",
+    "error_message"
+  ],
+  "title": "AuditChainVerification"
+}
+
+
AuditLogRead
+{
+  "properties": {
+    "id": {
+      "type": "integer",
+      "title": "Id"
+    },
+    "prev_hash": {
+      "type": "string",
+      "title": "Prev Hash"
+    },
+    "entry_hash": {
+      "type": "string",
+      "title": "Entry Hash"
+    },
+    "timestamp": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Timestamp"
+    },
+    "user_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "User Id"
+    },
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "resource_type": {
+      "type": "string",
+      "title": "Resource Type"
+    },
+    "resource_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Resource Id"
+    },
+    "details": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Details"
+    },
+    "ai_generated": {
+      "type": "boolean",
+      "title": "Ai Generated"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "prev_hash",
+    "entry_hash",
+    "timestamp",
+    "user_id",
+    "action",
+    "resource_type",
+    "resource_id",
+    "details",
+    "ai_generated"
+  ],
+  "title": "AuditLogRead"
+}
+
+
AuditView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "module_id": {
+      "type": "string",
+      "title": "Module Id"
+    },
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    },
+    "previous_hash": {
+      "type": "string",
+      "title": "Previous Hash"
+    },
+    "entry_hash": {
+      "type": "string",
+      "title": "Entry Hash"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "module_id",
+    "action",
+    "summary",
+    "created_at_unix_seconds",
+    "previous_hash",
+    "entry_hash"
+  ],
+  "title": "AuditView"
+}
+
+
BearerResponse
+{
+  "properties": {
+    "access_token": {
+      "type": "string",
+      "title": "Access Token"
+    },
+    "token_type": {
+      "type": "string",
+      "title": "Token Type"
+    }
+  },
+  "type": "object",
+  "required": [
+    "access_token",
+    "token_type"
+  ],
+  "title": "BearerResponse"
+}
+
+
Body_auth_jwt_login_auth_jwt_login_post
+{
+  "properties": {
+    "grant_type": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^password$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Grant Type"
+    },
+    "username": {
+      "type": "string",
+      "title": "Username"
+    },
+    "password": {
+      "type": "string",
+      "format": "password",
+      "title": "Password"
+    },
+    "scope": {
+      "type": "string",
+      "title": "Scope",
+      "default": ""
+    },
+    "client_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Client Id"
+    },
+    "client_secret": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "format": "password",
+      "title": "Client Secret"
+    }
+  },
+  "type": "object",
+  "required": [
+    "username",
+    "password"
+  ],
+  "title": "Body_auth_jwt_login_auth_jwt_login_post"
+}
+
+
Body_upload_file_datasources_upload_post
+{
+  "properties": {
+    "file": {
+      "type": "string",
+      "contentMediaType": "application/octet-stream",
+      "title": "File"
+    }
+  },
+  "type": "object",
+  "required": [
+    "file"
+  ],
+  "title": "Body_upload_file_datasources_upload_post"
+}
+
+
CalculateDeadlineCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "calculate-records-deadline",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/CalculateDeadlinePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "CalculateDeadlineCommand"
+}
+
+
CalculateDeadlinePayload
+{
+  "properties": {
+    "deadlineReceivedDate": {
+      "type": "string",
+      "title": "Deadlinereceiveddate"
+    },
+    "deadlineRuleName": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Deadlinerulename"
+    },
+    "deadlineDayCount": {
+      "type": "string",
+      "title": "Deadlinedaycount"
+    },
+    "deadlineDayType": {
+      "type": "string",
+      "title": "Deadlinedaytype"
+    },
+    "deadlineBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Deadlinebasis"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "deadlineReceivedDate",
+    "deadlineRuleName",
+    "deadlineDayCount",
+    "deadlineDayType",
+    "deadlineBasis"
+  ],
+  "title": "CalculateDeadlinePayload"
+}
+
+
ChapterCreate
+{
+  "properties": {
+    "chapter_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Chapter Id"
+    },
+    "title_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title Id"
+    },
+    "chapter_number": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Chapter Number"
+    },
+    "chapter_name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Chapter Name"
+    },
+    "sort_order": {
+      "type": "integer",
+      "title": "Sort Order",
+      "default": 0
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title_id",
+    "chapter_number",
+    "chapter_name"
+  ],
+  "title": "ChapterCreate",
+  "description": "Request body for creating a code chapter."
+}
+
+
CitedSection
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "citation": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Citation"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "version": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Version",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "citation"
+  ],
+  "title": "CitedSection",
+  "description": "One resolved public Code section; never a caller-supplied quotation."
+}
+
+
CityProfileCreate
+{
+  "properties": {
+    "city_name": {
+      "type": "string",
+      "title": "City Name"
+    },
+    "state": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State"
+    },
+    "county": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "County"
+    },
+    "population_band": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Population Band"
+    },
+    "email_platform": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email Platform"
+    },
+    "has_dedicated_it": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Has Dedicated It"
+    },
+    "monthly_request_volume": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Monthly Request Volume"
+    },
+    "profile_data": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Profile Data",
+      "default": {}
+    },
+    "gap_map": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Gap Map",
+      "default": {}
+    }
+  },
+  "type": "object",
+  "required": [
+    "city_name"
+  ],
+  "title": "CityProfileCreate"
+}
+
+
CityProfileRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "city_name": {
+      "type": "string",
+      "title": "City Name"
+    },
+    "state": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State"
+    },
+    "county": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "County"
+    },
+    "population_band": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Population Band"
+    },
+    "email_platform": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email Platform"
+    },
+    "has_dedicated_it": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Has Dedicated It"
+    },
+    "monthly_request_volume": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Monthly Request Volume"
+    },
+    "onboarding_status": {
+      "type": "string",
+      "title": "Onboarding Status"
+    },
+    "profile_data": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Profile Data"
+    },
+    "gap_map": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Gap Map"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "updated_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "city_name",
+    "state",
+    "county",
+    "population_band",
+    "email_platform",
+    "has_dedicated_it",
+    "monthly_request_volume",
+    "onboarding_status",
+    "profile_data",
+    "gap_map",
+    "created_at",
+    "updated_at"
+  ],
+  "title": "CityProfileRead"
+}
+
+
CityProfileUpdate
+{
+  "properties": {
+    "city_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "City Name"
+    },
+    "state": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State"
+    },
+    "county": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "County"
+    },
+    "population_band": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Population Band"
+    },
+    "email_platform": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email Platform"
+    },
+    "has_dedicated_it": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Has Dedicated It"
+    },
+    "monthly_request_volume": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Monthly Request Volume"
+    },
+    "onboarding_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Onboarding Status"
+    },
+    "profile_data": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Profile Data"
+    },
+    "gap_map": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Gap Map"
+    }
+  },
+  "type": "object",
+  "title": "CityProfileUpdate"
+}
+
+
ClarificationCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "request-records-clarification",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ClarificationPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "ClarificationCommand"
+}
+
+
ClarificationPayload
+{
+  "properties": {
+    "clarificationNote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Clarificationnote"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "clarificationNote"
+  ],
+  "title": "ClarificationPayload"
+}
+
+
Closeout
+{
+  "properties": {
+    "decision_id": {
+      "type": "string",
+      "pattern": "^[A-Za-z0-9_-]{1,64}$",
+      "title": "Decision Id"
+    },
+    "version_id": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Version Id"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "version_label": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Version Label"
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 1000000,
+      "minLength": 1,
+      "title": "Body"
+    },
+    "effective_start": {
+      "type": "string",
+      "format": "date",
+      "title": "Effective Start"
+    },
+    "effective_end": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective End"
+    },
+    "is_current": {
+      "type": "boolean",
+      "title": "Is Current"
+    },
+    "reconciliation_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reconciliation Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "decision_id",
+    "version_id",
+    "source_id",
+    "version_label",
+    "body",
+    "effective_start",
+    "is_current"
+  ],
+  "title": "Closeout"
+}
+
+
CodeContext
+{
+  "properties": {
+    "section_number": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Section Number"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "section_number"
+  ],
+  "title": "CodeContext"
+}
+
+
CodeLink
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "const": "code",
+      "title": "Provider",
+      "default": "code"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "CodeLink"
+}
+
+
CodeSearch
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "CodeSearch"
+}
+
+
CodeSourceSelection
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 200,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "CodeSourceSelection"
+}
+
+
CompleteArtifact
+{
+  "properties": {
+    "export_path": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Export Path"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "export_path"
+  ],
+  "title": "CompleteArtifact"
+}
+
+
ConnectionSearch
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "enum": [
+        "meetings",
+        "zoning"
+      ],
+      "title": "Provider"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "query"
+  ],
+  "title": "ConnectionSearch"
+}
+
+
CoverageGapResponse
+{
+  "properties": {
+    "jurisdictions_without_rules": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Jurisdictions Without Rules"
+    },
+    "departments_without_staff": {
+      "items": {
+        "additionalProperties": true,
+        "type": "object"
+      },
+      "type": "array",
+      "title": "Departments Without Staff"
+    },
+    "uncovered_categories": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Uncovered Categories"
+    },
+    "total_gaps": {
+      "type": "integer",
+      "title": "Total Gaps"
+    }
+  },
+  "type": "object",
+  "required": [
+    "jurisdictions_without_rules",
+    "departments_without_staff",
+    "uncovered_categories",
+    "total_gaps"
+  ],
+  "title": "CoverageGapResponse"
+}
+
+
DataSourceAdminRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "source_type": {
+      "$ref": "#/components/schemas/SourceType"
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "type": "boolean",
+      "title": "Schedule Enabled",
+      "default": true
+    },
+    "next_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Next Sync At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "last_ingestion_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Ingestion At"
+    },
+    "last_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync At"
+    },
+    "last_sync_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync Status"
+    },
+    "last_error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Error Message"
+    },
+    "consecutive_failure_count": {
+      "type": "integer",
+      "title": "Consecutive Failure Count",
+      "default": 0
+    },
+    "sync_paused": {
+      "type": "boolean",
+      "title": "Sync Paused",
+      "default": false
+    },
+    "health_status": {
+      "type": "string",
+      "title": "Health Status",
+      "default": "healthy"
+    },
+    "active_failure_count": {
+      "type": "integer",
+      "title": "Active Failure Count",
+      "default": 0
+    },
+    "connector_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connector Type"
+    },
+    "updated_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Updated At"
+    },
+    "connection_config": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Connection Config"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "source_type",
+    "is_active",
+    "created_by",
+    "created_at",
+    "last_ingestion_at",
+    "connection_config"
+  ],
+  "title": "DataSourceAdminRead",
+  "description": "Full datasource shape including connection_config. Returned only by admin-gated endpoints."
+}
+
+
DataSourceCreate
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "source_type": {
+      "$ref": "#/components/schemas/SourceType"
+    },
+    "connection_config": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Connection Config",
+      "default": {}
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "type": "boolean",
+      "title": "Schedule Enabled",
+      "default": true
+    }
+  },
+  "type": "object",
+  "required": [
+    "name",
+    "source_type"
+  ],
+  "title": "DataSourceCreate"
+}
+
+
DataSourceRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "source_type": {
+      "$ref": "#/components/schemas/SourceType"
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "type": "boolean",
+      "title": "Schedule Enabled",
+      "default": true
+    },
+    "next_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Next Sync At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "last_ingestion_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Ingestion At"
+    },
+    "last_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync At"
+    },
+    "last_sync_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync Status"
+    },
+    "last_error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Error Message"
+    },
+    "consecutive_failure_count": {
+      "type": "integer",
+      "title": "Consecutive Failure Count",
+      "default": 0
+    },
+    "sync_paused": {
+      "type": "boolean",
+      "title": "Sync Paused",
+      "default": false
+    },
+    "health_status": {
+      "type": "string",
+      "title": "Health Status",
+      "default": "healthy"
+    },
+    "active_failure_count": {
+      "type": "integer",
+      "title": "Active Failure Count",
+      "default": 0
+    },
+    "connector_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connector Type"
+    },
+    "updated_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "source_type",
+    "is_active",
+    "created_by",
+    "created_at",
+    "last_ingestion_at"
+  ],
+  "title": "DataSourceRead",
+  "description": "Redacted datasource shape — safe for non-admin roles. connection_config omitted."
+}
+
+
DataSourceUpdate
+{
+  "properties": {
+    "name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Name"
+    },
+    "connection_config": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connection Config"
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Schedule Enabled"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "DataSourceUpdate"
+}
+
+
DeadlineCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "set-records-deadline",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/DeadlinePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "DeadlineCommand"
+}
+
+
DeadlinePayload
+{
+  "properties": {
+    "deadline": {
+      "type": "string",
+      "title": "Deadline"
+    },
+    "deadlineBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Deadlinebasis"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "deadline",
+    "deadlineBasis"
+  ],
+  "title": "DeadlinePayload"
+}
+
+
Decision
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "pattern": "^[A-Za-z0-9_-]{1,64}$",
+      "title": "Id"
+    },
+    "outcome": {
+      "type": "string",
+      "enum": [
+        "adopted",
+        "not_adopted",
+        "deferred",
+        "withdrawn"
+      ],
+      "title": "Outcome"
+    },
+    "decided_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Decided At"
+    },
+    "decision_text": {
+      "type": "string",
+      "maxLength": 1000000,
+      "minLength": 1,
+      "title": "Decision Text"
+    },
+    "supporting_references": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Supporting References"
+    },
+    "supersedes_decision_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^[A-Za-z0-9_-]{1,64}$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supersedes Decision Id"
+    },
+    "reconciliation_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reconciliation Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "outcome",
+    "decision_text"
+  ],
+  "title": "Decision"
+}
+
+
DepartmentCreate
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "code": {
+      "type": "string",
+      "title": "Code"
+    },
+    "contact_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Contact Email"
+    }
+  },
+  "type": "object",
+  "required": [
+    "name",
+    "code"
+  ],
+  "title": "DepartmentCreate"
+}
+
+
DepartmentRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "code": {
+      "type": "string",
+      "title": "Code"
+    },
+    "contact_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Contact Email"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "code",
+    "contact_email",
+    "created_at"
+  ],
+  "title": "DepartmentRead"
+}
+
+
DepartmentUpdate
+{
+  "properties": {
+    "name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Name"
+    },
+    "code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Code"
+    },
+    "contact_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Contact Email"
+    }
+  },
+  "type": "object",
+  "title": "DepartmentUpdate"
+}
+
+
DisclosureTemplateCreate
+{
+  "properties": {
+    "template_type": {
+      "type": "string",
+      "title": "Template Type"
+    },
+    "state_code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State Code"
+    },
+    "content": {
+      "type": "string",
+      "title": "Content"
+    }
+  },
+  "type": "object",
+  "required": [
+    "template_type",
+    "content"
+  ],
+  "title": "DisclosureTemplateCreate"
+}
+
+
DisclosureTemplateRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "template_type": {
+      "type": "string",
+      "title": "Template Type"
+    },
+    "state_code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State Code"
+    },
+    "content": {
+      "type": "string",
+      "title": "Content"
+    },
+    "version": {
+      "type": "integer",
+      "title": "Version"
+    },
+    "updated_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Updated By"
+    },
+    "updated_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "template_type",
+    "state_code",
+    "content",
+    "version",
+    "updated_by",
+    "updated_at"
+  ],
+  "title": "DisclosureTemplateRead"
+}
+
+
DisclosureTemplateRendered
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "template_type": {
+      "type": "string",
+      "title": "Template Type"
+    },
+    "rendered_content": {
+      "type": "string",
+      "title": "Rendered Content"
+    },
+    "has_unresolved_variables": {
+      "type": "boolean",
+      "title": "Has Unresolved Variables"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "template_type",
+    "rendered_content",
+    "has_unresolved_variables"
+  ],
+  "title": "DisclosureTemplateRendered"
+}
+
+
DisclosureTemplateUpdate
+{
+  "properties": {
+    "content": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Content"
+    },
+    "state_code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State Code"
+    }
+  },
+  "type": "object",
+  "title": "DisclosureTemplateUpdate"
+}
+
+
DocumentChunkRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "chunk_index": {
+      "type": "integer",
+      "title": "Chunk Index"
+    },
+    "content_text": {
+      "type": "string",
+      "title": "Content Text"
+    },
+    "token_count": {
+      "type": "integer",
+      "title": "Token Count"
+    },
+    "page_number": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Page Number"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "document_id",
+    "chunk_index",
+    "content_text",
+    "token_count",
+    "page_number"
+  ],
+  "title": "DocumentChunkRead"
+}
+
+
DocumentRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "source_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Source Id"
+    },
+    "source_path": {
+      "type": "string",
+      "title": "Source Path"
+    },
+    "filename": {
+      "type": "string",
+      "title": "Filename"
+    },
+    "file_type": {
+      "type": "string",
+      "title": "File Type"
+    },
+    "file_hash": {
+      "type": "string",
+      "title": "File Hash"
+    },
+    "file_size": {
+      "type": "integer",
+      "title": "File Size"
+    },
+    "ingestion_status": {
+      "$ref": "#/components/schemas/IngestionStatus"
+    },
+    "ingestion_error": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ingestion Error"
+    },
+    "chunk_count": {
+      "type": "integer",
+      "title": "Chunk Count"
+    },
+    "ingested_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ingested At"
+    },
+    "connector_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connector Type"
+    },
+    "updated_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "source_id",
+    "source_path",
+    "filename",
+    "file_type",
+    "file_hash",
+    "file_size",
+    "ingestion_status",
+    "ingestion_error",
+    "chunk_count",
+    "ingested_at"
+  ],
+  "title": "DocumentRead"
+}
+
+
DraftCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "draft-records-response",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/DraftPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "DraftCommand"
+}
+
+
DraftInput
+{
+  "properties": {
+    "source_materials": {
+      "items": {
+        "$ref": "#/components/schemas/SourceInput"
+      },
+      "type": "array",
+      "title": "Source Materials"
+    },
+    "sentences": {
+      "items": {
+        "$ref": "#/components/schemas/SentenceInput"
+      },
+      "type": "array",
+      "minItems": 1,
+      "title": "Sentences"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sentences"
+  ],
+  "title": "DraftInput"
+}
+
+
DraftPayload
+{
+  "properties": {
+    "responseDraft": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Responsedraft"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "responseDraft"
+  ],
+  "title": "DraftPayload"
+}
+
+
ErrorModel
+{
+  "properties": {
+    "detail": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "additionalProperties": {
+            "type": "string"
+          },
+          "type": "object"
+        }
+      ],
+      "title": "Detail"
+    }
+  },
+  "type": "object",
+  "required": [
+    "detail"
+  ],
+  "title": "ErrorModel"
+}
+
+
Evidence
+{
+  "properties": {
+    "filename": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$",
+      "title": "Filename"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Description"
+    },
+    "media_type": {
+      "type": "string",
+      "enum": [
+        "text/plain",
+        "image/jpeg",
+        "image/png",
+        "image/webp",
+        "application/pdf",
+        "audio/webm",
+        "audio/ogg",
+        "audio/wav",
+        "audio/mpeg",
+        "audio/mp4"
+      ],
+      "title": "Media Type"
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 14000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "filename",
+    "description",
+    "media_type",
+    "content_base64",
+    "sha256"
+  ],
+  "title": "Evidence"
+}
+
+
EvidenceItem
+{
+  "properties": {
+    "filename": {
+      "type": "string",
+      "maxLength": 151,
+      "minLength": 1,
+      "title": "Filename"
+    },
+    "media_type": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Media Type"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Description",
+      "default": ""
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 14000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "filename",
+    "media_type",
+    "content_base64",
+    "sha256"
+  ],
+  "title": "EvidenceItem"
+}
+
+
EvidenceItems
+{
+  "properties": {
+    "items": {
+      "items": {
+        "$ref": "#/components/schemas/EvidenceItem"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "minItems": 1,
+      "title": "Items"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "items"
+  ],
+  "title": "EvidenceItems"
+}
+
+
ExemptionAccuracyReport
+{
+  "properties": {
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "total_flags": {
+      "type": "integer",
+      "title": "Total Flags"
+    },
+    "accepted": {
+      "type": "integer",
+      "title": "Accepted"
+    },
+    "rejected": {
+      "type": "integer",
+      "title": "Rejected"
+    },
+    "pending": {
+      "type": "integer",
+      "title": "Pending"
+    },
+    "acceptance_rate": {
+      "type": "number",
+      "title": "Acceptance Rate"
+    }
+  },
+  "type": "object",
+  "required": [
+    "category",
+    "total_flags",
+    "accepted",
+    "rejected",
+    "pending",
+    "acceptance_rate"
+  ],
+  "title": "ExemptionAccuracyReport"
+}
+
+
ExemptionDashboard
+{
+  "properties": {
+    "total_flags": {
+      "type": "integer",
+      "title": "Total Flags"
+    },
+    "by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "By Status"
+    },
+    "by_category": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "By Category"
+    },
+    "acceptance_rate": {
+      "type": "number",
+      "title": "Acceptance Rate"
+    },
+    "total_rules": {
+      "type": "integer",
+      "title": "Total Rules"
+    },
+    "active_rules": {
+      "type": "integer",
+      "title": "Active Rules"
+    }
+  },
+  "type": "object",
+  "required": [
+    "total_flags",
+    "by_status",
+    "by_category",
+    "acceptance_rate",
+    "total_rules",
+    "active_rules"
+  ],
+  "title": "ExemptionDashboard"
+}
+
+
ExemptionDecisionCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-exemption-decision",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ExemptionDecisionPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "ExemptionDecisionCommand"
+}
+
+
ExemptionDecisionPayload
+{
+  "properties": {
+    "exemptionSource": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionsource"
+    },
+    "exemptionKind": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionkind"
+    },
+    "exemptionFinding": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionfinding"
+    },
+    "exemptionDecision": {
+      "type": "string",
+      "enum": [
+        "release",
+        "redact",
+        "exempt"
+      ],
+      "title": "Exemptiondecision"
+    },
+    "exemptionBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionbasis"
+    },
+    "exemptionReviewer": {
+      "type": "string",
+      "title": "Exemptionreviewer",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "exemptionSource",
+    "exemptionKind",
+    "exemptionFinding",
+    "exemptionDecision",
+    "exemptionBasis"
+  ],
+  "title": "ExemptionDecisionPayload"
+}
+
+
ExemptionDecisionView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "source": {
+      "type": "string",
+      "title": "Source"
+    },
+    "kind": {
+      "type": "string",
+      "title": "Kind"
+    },
+    "finding": {
+      "type": "string",
+      "title": "Finding"
+    },
+    "decision": {
+      "type": "string",
+      "enum": [
+        "release",
+        "redact",
+        "exempt"
+      ],
+      "title": "Decision"
+    },
+    "basis": {
+      "type": "string",
+      "title": "Basis"
+    },
+    "reviewer": {
+      "type": "string",
+      "title": "Reviewer"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "source",
+    "kind",
+    "finding",
+    "decision",
+    "basis",
+    "reviewer",
+    "created_at_unix_seconds"
+  ],
+  "title": "ExemptionDecisionView"
+}
+
+
ExemptionFlagRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "chunk_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Chunk Id"
+    },
+    "rule_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Rule Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "matched_text": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Matched Text"
+    },
+    "confidence": {
+      "type": "number",
+      "title": "Confidence"
+    },
+    "status": {
+      "$ref": "#/components/schemas/FlagStatus"
+    },
+    "reviewed_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reviewed By"
+    },
+    "reviewed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reviewed At"
+    },
+    "review_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Reason"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "chunk_id",
+    "rule_id",
+    "request_id",
+    "category",
+    "matched_text",
+    "confidence",
+    "status",
+    "reviewed_by",
+    "reviewed_at",
+    "review_reason",
+    "created_at"
+  ],
+  "title": "ExemptionFlagRead"
+}
+
+
ExemptionFlagReview
+{
+  "properties": {
+    "status": {
+      "$ref": "#/components/schemas/FlagStatus"
+    },
+    "review_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Reason"
+    }
+  },
+  "type": "object",
+  "required": [
+    "status"
+  ],
+  "title": "ExemptionFlagReview"
+}
+
+
ExemptionNoteCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-exemption-review",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ExemptionNotePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "ExemptionNoteCommand"
+}
+
+
ExemptionNotePayload
+{
+  "properties": {
+    "exemptionNote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionnote"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "exemptionNote"
+  ],
+  "title": "ExemptionNotePayload"
+}
+
+
ExemptionRuleCreate
+{
+  "properties": {
+    "state_code": {
+      "type": "string",
+      "title": "State Code"
+    },
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "rule_type": {
+      "$ref": "#/components/schemas/RuleType"
+    },
+    "rule_definition": {
+      "type": "string",
+      "title": "Rule Definition"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "enabled": {
+      "type": "boolean",
+      "title": "Enabled",
+      "default": true
+    }
+  },
+  "type": "object",
+  "required": [
+    "state_code",
+    "category",
+    "rule_type",
+    "rule_definition"
+  ],
+  "title": "ExemptionRuleCreate"
+}
+
+
ExemptionRuleRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "state_code": {
+      "type": "string",
+      "title": "State Code"
+    },
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "rule_type": {
+      "$ref": "#/components/schemas/RuleType"
+    },
+    "rule_definition": {
+      "type": "string",
+      "title": "Rule Definition"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "enabled": {
+      "type": "boolean",
+      "title": "Enabled"
+    },
+    "version": {
+      "type": "integer",
+      "title": "Version",
+      "default": 1
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "state_code",
+    "category",
+    "rule_type",
+    "rule_definition",
+    "description",
+    "enabled",
+    "created_by",
+    "created_at"
+  ],
+  "title": "ExemptionRuleRead"
+}
+
+
ExemptionRuleUpdate
+{
+  "properties": {
+    "rule_definition": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Rule Definition"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "enabled": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Enabled"
+    }
+  },
+  "type": "object",
+  "title": "ExemptionRuleUpdate"
+}
+
+
ExportReceipt
+{
+  "properties": {
+    "export_path": {
+      "type": "string",
+      "maxLength": 32768,
+      "minLength": 1,
+      "title": "Export Path"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "export_path"
+  ],
+  "title": "ExportReceipt"
+}
+
+
FeeEstimateCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "estimate-records-fee",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/FeeEstimatePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "FeeEstimateCommand"
+}
+
+
FeeEstimatePayload
+{
+  "properties": {
+    "feeEstimate": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feeestimate"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "feeEstimate"
+  ],
+  "title": "FeeEstimatePayload"
+}
+
+
FeeEstimateRequest
+{
+  "properties": {
+    "page_count": {
+      "type": "integer",
+      "title": "Page Count"
+    },
+    "fee_schedule_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Fee Schedule Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "page_count",
+    "fee_schedule_id"
+  ],
+  "title": "FeeEstimateRequest"
+}
+
+
FeeEstimateResponse
+{
+  "properties": {
+    "page_count": {
+      "type": "integer",
+      "title": "Page Count"
+    },
+    "unit_price": {
+      "type": "number",
+      "title": "Unit Price"
+    },
+    "total": {
+      "type": "number",
+      "title": "Total"
+    },
+    "fee_type": {
+      "type": "string",
+      "title": "Fee Type"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    }
+  },
+  "type": "object",
+  "required": [
+    "page_count",
+    "unit_price",
+    "total",
+    "fee_type",
+    "description"
+  ],
+  "title": "FeeEstimateResponse"
+}
+
+
FeeLineCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-fee-line",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/FeeLinePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "FeeLineCommand"
+}
+
+
FeeLineItemCreate
+{
+  "properties": {
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "quantity": {
+      "type": "integer",
+      "title": "Quantity",
+      "default": 1
+    },
+    "unit_price": {
+      "type": "number",
+      "title": "Unit Price"
+    },
+    "fee_schedule_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Schedule Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "description",
+    "unit_price"
+  ],
+  "title": "FeeLineItemCreate"
+}
+
+
FeeLineItemRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "fee_schedule_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Schedule Id"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "quantity": {
+      "type": "integer",
+      "title": "Quantity"
+    },
+    "unit_price": {
+      "type": "number",
+      "title": "Unit Price"
+    },
+    "total": {
+      "type": "number",
+      "title": "Total"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "fee_schedule_id",
+    "description",
+    "quantity",
+    "unit_price",
+    "total",
+    "status",
+    "created_at"
+  ],
+  "title": "FeeLineItemRead"
+}
+
+
FeeLinePayload
+{
+  "properties": {
+    "feeLineDescription": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feelinedescription"
+    },
+    "feeScheduleBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feeschedulebasis"
+    },
+    "feeLineAmount": {
+      "type": "string",
+      "title": "Feelineamount"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "feeLineDescription",
+    "feeScheduleBasis",
+    "feeLineAmount"
+  ],
+  "title": "FeeLinePayload"
+}
+
+
FeeLineView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "schedule_basis": {
+      "type": "string",
+      "title": "Schedule Basis"
+    },
+    "amount_cents": {
+      "type": "integer",
+      "title": "Amount Cents"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "description",
+    "schedule_basis",
+    "amount_cents",
+    "created_at_unix_seconds"
+  ],
+  "title": "FeeLineView"
+}
+
+
FeeScheduleCreate
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "title": "Jurisdiction"
+    },
+    "fee_type": {
+      "type": "string",
+      "title": "Fee Type"
+    },
+    "amount": {
+      "type": "number",
+      "title": "Amount"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "effective_date": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective Date"
+    }
+  },
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "fee_type",
+    "amount"
+  ],
+  "title": "FeeScheduleCreate"
+}
+
+
FeeScheduleRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "jurisdiction": {
+      "type": "string",
+      "title": "Jurisdiction"
+    },
+    "fee_type": {
+      "type": "string",
+      "title": "Fee Type"
+    },
+    "amount": {
+      "type": "number",
+      "title": "Amount"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "effective_date": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective Date"
+    },
+    "created_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "jurisdiction",
+    "fee_type",
+    "amount",
+    "description",
+    "effective_date",
+    "created_by",
+    "created_at"
+  ],
+  "title": "FeeScheduleRead"
+}
+
+
FeeScheduleUpdate
+{
+  "properties": {
+    "fee_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Type"
+    },
+    "amount": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Amount"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "effective_date": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective Date"
+    }
+  },
+  "type": "object",
+  "title": "FeeScheduleUpdate"
+}
+
+
FeeWaiverCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "waive-records-fee",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/FeeWaiverPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "FeeWaiverCommand"
+}
+
+
FeeWaiverCreateRequest
+{
+  "properties": {
+    "waiver_type": {
+      "type": "string",
+      "title": "Waiver Type"
+    },
+    "reason": {
+      "type": "string",
+      "title": "Reason"
+    }
+  },
+  "type": "object",
+  "required": [
+    "waiver_type",
+    "reason"
+  ],
+  "title": "FeeWaiverCreateRequest"
+}
+
+
FeeWaiverPayload
+{
+  "properties": {
+    "feeWaiverReason": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feewaiverreason"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "feeWaiverReason"
+  ],
+  "title": "FeeWaiverPayload"
+}
+
+
FeeWaiverReadResponse
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "waiver_type": {
+      "type": "string",
+      "title": "Waiver Type"
+    },
+    "reason": {
+      "type": "string",
+      "title": "Reason"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    },
+    "created_at": {
+      "type": "string",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "waiver_type",
+    "reason",
+    "status",
+    "created_at"
+  ],
+  "title": "FeeWaiverReadResponse"
+}
+
+
FeeWaiverReviewRequest
+{
+  "properties": {
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    }
+  },
+  "type": "object",
+  "required": [
+    "status"
+  ],
+  "title": "FeeWaiverReviewRequest"
+}
+
+
FinishCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "fulfill-records-request",
+        "close-records-request"
+      ],
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/NativePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "FinishCommand"
+}
+
+
FlagStatus
+{
+  "type": "string",
+  "enum": [
+    "flagged",
+    "reviewed",
+    "accepted",
+    "rejected"
+  ],
+  "title": "FlagStatus"
+}
+
+
FormPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "form-plan",
+      "title": "Action"
+    },
+    "formName": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Formname",
+      "default": ""
+    },
+    "fields": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 50,
+      "title": "Fields"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "FormPlan"
+}
+
+
GeneratedDraft
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "model": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Model"
+    },
+    "previous_response_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Previous Response Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text",
+    "model",
+    "previous_response_sha256"
+  ],
+  "title": "GeneratedDraft"
+}
+
+
HTTPValidationError
+{
+  "properties": {
+    "detail": {
+      "items": {
+        "$ref": "#/components/schemas/ValidationError"
+      },
+      "type": "array",
+      "title": "Detail"
+    }
+  },
+  "type": "object",
+  "title": "HTTPValidationError"
+}
+
+
Handoff
+{
+  "properties": {
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "request_id"
+  ],
+  "title": "Handoff"
+}
+
+
ImportBundleCreate
+{
+  "properties": {
+    "job_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Job Id"
+    },
+    "connector_type": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Connector Type"
+    },
+    "source": {
+      "$ref": "#/components/schemas/SourceCreate"
+    },
+    "sources": {
+      "items": {
+        "$ref": "#/components/schemas/SourceCreate"
+      },
+      "type": "array",
+      "title": "Sources"
+    },
+    "titles": {
+      "items": {
+        "$ref": "#/components/schemas/TitleCreate"
+      },
+      "type": "array",
+      "title": "Titles"
+    },
+    "chapters": {
+      "items": {
+        "$ref": "#/components/schemas/ChapterCreate"
+      },
+      "type": "array",
+      "title": "Chapters"
+    },
+    "sections": {
+      "items": {
+        "$ref": "#/components/schemas/SectionCreate"
+      },
+      "type": "array",
+      "title": "Sections"
+    },
+    "versions": {
+      "items": {
+        "$ref": "#/components/schemas/SectionVersionCreate"
+      },
+      "type": "array",
+      "title": "Versions"
+    },
+    "provenance": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Provenance"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "connector_type",
+    "source"
+  ],
+  "title": "ImportBundleCreate",
+  "description": "Request body for local fixture/file-drop import jobs."
+}
+
+
InclusionStatus
+{
+  "type": "string",
+  "enum": [
+    "included",
+    "excluded",
+    "pending"
+  ],
+  "title": "InclusionStatus"
+}
+
+
IngestionStats
+{
+  "properties": {
+    "total_sources": {
+      "type": "integer",
+      "title": "Total Sources"
+    },
+    "active_sources": {
+      "type": "integer",
+      "title": "Active Sources"
+    },
+    "total_documents": {
+      "type": "integer",
+      "title": "Total Documents"
+    },
+    "documents_by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "Documents By Status"
+    },
+    "total_chunks": {
+      "type": "integer",
+      "title": "Total Chunks"
+    }
+  },
+  "type": "object",
+  "required": [
+    "total_sources",
+    "active_sources",
+    "total_documents",
+    "documents_by_status",
+    "total_chunks"
+  ],
+  "title": "IngestionStats"
+}
+
+
IngestionStatus
+{
+  "type": "string",
+  "enum": [
+    "pending",
+    "processing",
+    "completed",
+    "failed"
+  ],
+  "title": "IngestionStatus"
+}
+
+
InitiativeInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "policy": {
+      "$ref": "#/components/schemas/PolicySelection"
+    },
+    "responsible_staff": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Responsible Staff"
+    },
+    "target": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "string"
+        }
+      ],
+      "title": "Target"
+    },
+    "unit": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Unit"
+    },
+    "due_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Due On"
+    },
+    "status": {
+      "type": "string",
+      "enum": [
+        "planned",
+        "active",
+        "completed",
+        "cancelled"
+      ],
+      "title": "Status",
+      "default": "planned"
+    },
+    "milestones": {
+      "items": {
+        "$ref": "#/components/schemas/Milestone"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "title": "Milestones"
+    },
+    "measurements": {
+      "items": {
+        "$ref": "#/components/schemas/Measurement"
+      },
+      "type": "array",
+      "maxItems": 1000,
+      "title": "Measurements"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "policy",
+    "responsible_staff",
+    "target",
+    "unit",
+    "due_on",
+    "note"
+  ],
+  "title": "InitiativeInput"
+}
+
+
InspectionInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "property_reference": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Property Reference"
+    },
+    "inspection_reference": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Inspection Reference"
+    },
+    "dataset_kind": {
+      "type": "string",
+      "enum": [
+        "municipal",
+        "fictional"
+      ],
+      "title": "Dataset Kind"
+    },
+    "inspector_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "minLength": 1,
+      "title": "Inspector Notes"
+    },
+    "photo_observations": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Photo Observations"
+    },
+    "voice_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Voice Notes",
+      "default": ""
+    },
+    "evidence": {
+      "items": {
+        "$ref": "#/components/schemas/Evidence"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "title": "Evidence"
+    },
+    "linked_sources": {
+      "items": {
+        "$ref": "#/components/schemas/townlight_inspections__workflow_models__SourceLink"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Linked Sources"
+    },
+    "assigned_to": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Assigned To",
+      "default": ""
+    },
+    "staff_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Staff Notes",
+      "default": ""
+    },
+    "notice_draft": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Notice Draft",
+      "default": ""
+    },
+    "review_state": {
+      "type": "string",
+      "enum": [
+        "draft",
+        "follow_up",
+        "reviewed"
+      ],
+      "title": "Review State",
+      "default": "draft"
+    },
+    "review_notes": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Review Notes",
+      "default": ""
+    },
+    "public_summary": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Public Summary",
+      "default": ""
+    },
+    "analysis": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/AnalysisRecord"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "property_reference",
+    "inspection_reference",
+    "dataset_kind",
+    "inspector_notes"
+  ],
+  "title": "InspectionInput"
+}
+
+
IntakeInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "project_name": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Project Name"
+    },
+    "project_description": {
+      "type": "string",
+      "maxLength": 10000,
+      "minLength": 1,
+      "title": "Project Description"
+    },
+    "location": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Location"
+    },
+    "applicant_contact": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Applicant Contact",
+      "default": ""
+    },
+    "requirement_revision": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Requirement Revision"
+    },
+    "materials": {
+      "items": {
+        "$ref": "#/components/schemas/MaterialReview"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "minItems": 1,
+      "title": "Materials"
+    },
+    "linked_sources": {
+      "items": {
+        "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Linked Sources"
+    },
+    "staff_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Staff Notes",
+      "default": ""
+    },
+    "assigned_to": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Assigned To",
+      "default": ""
+    },
+    "review_state": {
+      "type": "string",
+      "enum": [
+        "draft",
+        "follow_up",
+        "reviewed"
+      ],
+      "title": "Review State",
+      "default": "draft"
+    },
+    "review_notes": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Review Notes",
+      "default": ""
+    },
+    "public_summary": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Public Summary",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "project_name",
+    "project_description",
+    "location",
+    "requirement_revision",
+    "materials"
+  ],
+  "title": "IntakeInput"
+}
+
+
InterpretationNoteCreate
+{
+  "properties": {
+    "note_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Note Id"
+    },
+    "note_text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Note Text"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "note_text"
+  ],
+  "title": "InterpretationNoteCreate",
+  "description": "Request body for staff-only interpretation notes."
+}
+
+
InterviewRequest
+{
+  "properties": {
+    "last_answer": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Answer"
+    },
+    "last_field": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Field"
+    },
+    "skipped_fields": {
+      "anyOf": [
+        {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Skipped Fields"
+    }
+  },
+  "type": "object",
+  "title": "InterviewRequest"
+}
+
+
InterviewResponse
+{
+  "properties": {
+    "question": {
+      "type": "string",
+      "title": "Question"
+    },
+    "target_field": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Target Field"
+    },
+    "all_complete": {
+      "type": "boolean",
+      "title": "All Complete"
+    },
+    "completed_fields": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Completed Fields"
+    },
+    "onboarding_status": {
+      "type": "string",
+      "title": "Onboarding Status"
+    },
+    "skipped_fields": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Skipped Fields"
+    }
+  },
+  "type": "object",
+  "required": [
+    "question",
+    "target_field",
+    "all_complete",
+    "completed_fields",
+    "onboarding_status",
+    "skipped_fields"
+  ],
+  "title": "InterviewResponse"
+}
+
+
ManagedFileReceipt
+{
+  "properties": {
+    "original_path": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Original Path"
+    },
+    "stored_path": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Stored Path"
+    },
+    "file_name": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "File Name"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Sha256"
+    },
+    "size_bytes": {
+      "type": "integer",
+      "maximum": 2147483647.0,
+      "minimum": 0.0,
+      "title": "Size Bytes"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "original_path",
+    "stored_path",
+    "file_name",
+    "sha256",
+    "size_bytes"
+  ],
+  "title": "ManagedFileReceipt"
+}
+
+
ManagedSource
+{
+  "properties": {
+    "original_path": {
+      "type": "string",
+      "title": "Original Path"
+    },
+    "stored_path": {
+      "type": "string",
+      "title": "Stored Path"
+    },
+    "file_name": {
+      "type": "string",
+      "title": "File Name"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Sha256"
+    },
+    "size_bytes": {
+      "type": "integer",
+      "minimum": 0.0,
+      "title": "Size Bytes"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "original_path",
+    "stored_path",
+    "file_name",
+    "sha256",
+    "size_bytes"
+  ],
+  "title": "ManagedSource"
+}
+
+
Material
+{
+  "properties": {
+    "material_id": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9_-]{1,80}$",
+      "title": "Material Id"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Description"
+    },
+    "citation": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Citation"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "material_id",
+    "description",
+    "citation"
+  ],
+  "title": "Material"
+}
+
+
MaterialReview
+{
+  "properties": {
+    "material_id": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Material Id"
+    },
+    "status": {
+      "type": "string",
+      "enum": [
+        "not_reviewed",
+        "provided",
+        "missing",
+        "unclear"
+      ],
+      "title": "Status",
+      "default": "not_reviewed"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Note",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "material_id"
+  ],
+  "title": "MaterialReview"
+}
+
+
Measurement
+{
+  "properties": {
+    "recorded_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Recorded On"
+    },
+    "value": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "string"
+        }
+      ],
+      "title": "Value"
+    },
+    "evidence": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Evidence"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "recorded_on",
+    "value",
+    "evidence"
+  ],
+  "title": "Measurement"
+}
+
+
MediaAnalysis
+{
+  "properties": {
+    "items": {
+      "items": {
+        "$ref": "#/components/schemas/EvidenceItem"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "minItems": 1,
+      "title": "Items"
+    },
+    "code_links": {
+      "items": {
+        "$ref": "#/components/schemas/CodeLink"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Code Links"
+    },
+    "inspector_supplied_text": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Inspector Supplied Text",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "items"
+  ],
+  "title": "MediaAnalysis"
+}
+
+
MeetingInput
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "scheduled_start": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Scheduled Start"
+    },
+    "location": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Location"
+    },
+    "meeting_type": {
+      "type": "string",
+      "enum": [
+        "regular",
+        "special",
+        "emergency",
+        "closed_session",
+        "executive"
+      ],
+      "title": "Meeting Type",
+      "default": "regular"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "scheduled_start",
+    "location"
+  ],
+  "title": "MeetingInput"
+}
+
+
MeetingLink
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 200,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    },
+    "relation": {
+      "type": "string",
+      "enum": [
+        "hearing",
+        "context",
+        "precedent"
+      ],
+      "title": "Relation"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256",
+    "relation"
+  ],
+  "title": "MeetingLink"
+}
+
+
MeetingSearch
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "MeetingSearch"
+}
+
+
MeetingStageInput
+{
+  "properties": {
+    "to_status": {
+      "type": "string",
+      "enum": [
+        "SCHEDULED",
+        "NOTICED",
+        "PACKET_POSTED",
+        "IN_PROGRESS",
+        "RECESSED",
+        "ADJOURNED",
+        "TRANSCRIPT_READY",
+        "MINUTES_DRAFTED",
+        "MINUTES_POSTED",
+        "MINUTES_ADOPTED",
+        "MINUTES_SIGNED",
+        "ARCHIVED",
+        "CANCELLED"
+      ],
+      "title": "To Status"
+    },
+    "statutory_basis": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Basis"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "to_status"
+  ],
+  "title": "MeetingStageInput"
+}
+
+
MeetingsSearch
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "MeetingsSearch"
+}
+
+
MeetingsSourceSelection
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 200,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "MeetingsSourceSelection"
+}
+
+
MessageCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-message",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/MessagePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "MessageCommand"
+}
+
+
MessageCreate
+{
+  "properties": {
+    "message_text": {
+      "type": "string",
+      "title": "Message Text"
+    },
+    "is_internal": {
+      "type": "boolean",
+      "title": "Is Internal",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "message_text"
+  ],
+  "title": "MessageCreate"
+}
+
+
MessagePayload
+{
+  "properties": {
+    "requestMessageBody": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestmessagebody"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requestMessageBody"
+  ],
+  "title": "MessagePayload"
+}
+
+
MessageRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "sender_type": {
+      "type": "string",
+      "title": "Sender Type"
+    },
+    "sender_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sender Id"
+    },
+    "message_text": {
+      "type": "string",
+      "title": "Message Text"
+    },
+    "is_internal": {
+      "type": "boolean",
+      "title": "Is Internal"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "sender_type",
+    "sender_id",
+    "message_text",
+    "is_internal",
+    "created_at"
+  ],
+  "title": "MessageRead"
+}
+
+
MessageView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "author": {
+      "type": "string",
+      "title": "Author"
+    },
+    "author_role": {
+      "type": "string",
+      "title": "Author Role"
+    },
+    "body": {
+      "type": "string",
+      "title": "Body"
+    },
+    "visibility": {
+      "type": "string",
+      "title": "Visibility"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "author",
+    "author_role",
+    "body",
+    "visibility",
+    "created_at_unix_seconds"
+  ],
+  "title": "MessageView"
+}
+
+
Milestone
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "due_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Due On"
+    },
+    "completed_on": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Completed On"
+    },
+    "evidence": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Evidence",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "due_on"
+  ],
+  "title": "Milestone"
+}
+
+
MinutesDecision
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "post",
+        "adopt",
+        "sign"
+      ],
+      "title": "Action"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "MinutesDecision"
+}
+
+
ModelRegistryCreate
+{
+  "properties": {
+    "model_name": {
+      "type": "string",
+      "title": "Model Name"
+    },
+    "model_version": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Version"
+    },
+    "parameter_count": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parameter Count"
+    },
+    "license": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "License"
+    },
+    "model_card_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Card Url"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active",
+      "default": false
+    },
+    "context_window_size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Context Window Size"
+    },
+    "supports_ner": {
+      "type": "boolean",
+      "title": "Supports Ner",
+      "default": false
+    },
+    "supports_vision": {
+      "type": "boolean",
+      "title": "Supports Vision",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "model_name"
+  ],
+  "title": "ModelRegistryCreate",
+  "description": "Schema for creating a new model_registry record (POST body)."
+}
+
+
ModelRegistryRead
+{
+  "properties": {
+    "id": {
+      "type": "integer",
+      "title": "Id"
+    },
+    "model_name": {
+      "type": "string",
+      "title": "Model Name"
+    },
+    "model_version": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Version"
+    },
+    "parameter_count": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parameter Count"
+    },
+    "license": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "License"
+    },
+    "model_card_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Card Url"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "added_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Added At"
+    },
+    "context_window_size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Context Window Size"
+    },
+    "supports_ner": {
+      "type": "boolean",
+      "title": "Supports Ner"
+    },
+    "supports_vision": {
+      "type": "boolean",
+      "title": "Supports Vision"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "model_name",
+    "is_active",
+    "supports_ner",
+    "supports_vision"
+  ],
+  "title": "ModelRegistryRead",
+  "description": "Schema for returning a model_registry record (GET response).\n\n``from_attributes=True`` allows construction directly from an ORM instance."
+}
+
+
ModelRegistryUpdate
+{
+  "properties": {
+    "model_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Name"
+    },
+    "model_version": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Version"
+    },
+    "parameter_count": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parameter Count"
+    },
+    "license": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "License"
+    },
+    "model_card_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Card Url"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    },
+    "context_window_size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Context Window Size"
+    },
+    "supports_ner": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supports Ner"
+    },
+    "supports_vision": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supports Vision"
+    }
+  },
+  "type": "object",
+  "title": "ModelRegistryUpdate",
+  "description": "Schema for partially updating a model_registry record (PATCH body).\n\nEvery field is optional so callers can send only the fields they want to\nchange."
+}
+
+
MotionCorrection
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "reason": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Reason"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text",
+    "reason"
+  ],
+  "title": "MotionCorrection"
+}
+
+
MotionInput
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "seconded_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "minLength": 1
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Seconded By"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text"
+  ],
+  "title": "MotionInput"
+}
+
+
NativePayload
+{
+  "properties": {},
+  "additionalProperties": false,
+  "type": "object",
+  "title": "NativePayload"
+}
+
+
NativeRequestRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "requester_name": {
+      "type": "string",
+      "title": "Requester Name"
+    },
+    "requester_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Email"
+    },
+    "requester_phone": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Phone"
+    },
+    "requester_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Type"
+    },
+    "date_received": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Date Received"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "status": {
+      "$ref": "#/components/schemas/RequestStatus"
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "created_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "response_draft": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Response Draft"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    },
+    "estimated_fee": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Estimated Fee"
+    },
+    "fee_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Status"
+    },
+    "fee_waiver_requested": {
+      "type": "boolean",
+      "title": "Fee Waiver Requested",
+      "default": false
+    },
+    "priority": {
+      "type": "string",
+      "title": "Priority",
+      "default": "normal"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    },
+    "closed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closed At"
+    },
+    "closure_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closure Reason"
+    },
+    "desktop_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Desktop Id"
+    },
+    "public_tracking_number": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Public Tracking Number"
+    },
+    "submitted_via": {
+      "type": "string",
+      "title": "Submitted Via"
+    },
+    "deadline_label": {
+      "type": "string",
+      "title": "Deadline Label"
+    },
+    "deadline_basis": {
+      "type": "string",
+      "title": "Deadline Basis"
+    },
+    "deadline_reviewed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Deadline Reviewed At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "requester_name",
+    "requester_email",
+    "date_received",
+    "statutory_deadline",
+    "description",
+    "status",
+    "assigned_to",
+    "created_by",
+    "created_at",
+    "response_draft",
+    "review_notes",
+    "desktop_id",
+    "public_tracking_number",
+    "submitted_via",
+    "deadline_label",
+    "deadline_basis",
+    "deadline_reviewed_at"
+  ],
+  "title": "NativeRequestRead"
+}
+
+
NoticeDocumentInput
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text"
+  ],
+  "title": "NoticeDocumentInput"
+}
+
+
NoticeDraft
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 100000,
+      "minLength": 1,
+      "title": "Body"
+    },
+    "notice_type": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Notice Type"
+    },
+    "statutory_basis": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Statutory Basis"
+    },
+    "event_date": {
+      "type": "string",
+      "format": "date",
+      "title": "Event Date"
+    },
+    "lead_days": {
+      "type": "integer",
+      "maximum": 365.0,
+      "minimum": 0.0,
+      "title": "Lead Days"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "body",
+    "notice_type",
+    "statutory_basis",
+    "event_date",
+    "lead_days"
+  ],
+  "title": "NoticeDraft"
+}
+
+
NoticeInput
+{
+  "properties": {
+    "notice_type": {
+      "type": "string",
+      "enum": [
+        "regular",
+        "special",
+        "emergency",
+        "closed_session",
+        "executive"
+      ],
+      "title": "Notice Type"
+    },
+    "posted_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Posted At"
+    },
+    "minimum_notice_hours": {
+      "type": "integer",
+      "minimum": 0.0,
+      "title": "Minimum Notice Hours"
+    },
+    "statutory_basis": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Basis"
+    },
+    "approved_by": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Approved By"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "notice_type",
+    "posted_at",
+    "minimum_notice_hours"
+  ],
+  "title": "NoticeInput"
+}
+
+
NoticeProofInput
+{
+  "properties": {
+    "location": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Location"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note",
+      "default": ""
+    },
+    "document_delivery_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Document Delivery Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "location"
+  ],
+  "title": "NoticeProofInput"
+}
+
+
NotificationLogRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "template_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Template Id"
+    },
+    "recipient_email": {
+      "type": "string",
+      "title": "Recipient Email"
+    },
+    "request_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Request Id"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "sent_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sent At"
+    },
+    "error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Message"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "template_id",
+    "recipient_email",
+    "request_id",
+    "channel",
+    "status",
+    "sent_at",
+    "error_message",
+    "created_at"
+  ],
+  "title": "NotificationLogRead"
+}
+
+
NotificationTemplateCreate
+{
+  "properties": {
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel",
+      "default": "email"
+    },
+    "subject_template": {
+      "type": "string",
+      "title": "Subject Template"
+    },
+    "body_template": {
+      "type": "string",
+      "title": "Body Template"
+    }
+  },
+  "type": "object",
+  "required": [
+    "event_type",
+    "subject_template",
+    "body_template"
+  ],
+  "title": "NotificationTemplateCreate"
+}
+
+
NotificationTemplateRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel"
+    },
+    "subject_template": {
+      "type": "string",
+      "title": "Subject Template"
+    },
+    "body_template": {
+      "type": "string",
+      "title": "Body Template"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "event_type",
+    "channel",
+    "subject_template",
+    "body_template",
+    "is_active",
+    "created_at"
+  ],
+  "title": "NotificationTemplateRead"
+}
+
+
NotificationTemplateUpdate
+{
+  "properties": {
+    "subject_template": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Subject Template"
+    },
+    "body_template": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Body Template"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "NotificationTemplateUpdate"
+}
+
+
NotificationView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "notification_id": {
+      "type": "string",
+      "title": "Notification Id"
+    },
+    "module_id": {
+      "type": "string",
+      "title": "Module Id"
+    },
+    "record_id": {
+      "type": "string",
+      "title": "Record Id"
+    },
+    "audience": {
+      "type": "string",
+      "title": "Audience"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel"
+    },
+    "subject": {
+      "type": "string",
+      "title": "Subject"
+    },
+    "body": {
+      "type": "string",
+      "title": "Body"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    },
+    "sent_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sent At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "notification_id",
+    "module_id",
+    "record_id",
+    "audience",
+    "channel",
+    "subject",
+    "body",
+    "status",
+    "created_at_unix_seconds",
+    "sent_at_unix_seconds"
+  ],
+  "title": "NotificationView"
+}
+
+
OllamaModelInfo
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Size"
+    },
+    "details": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Details"
+    }
+  },
+  "type": "object",
+  "required": [
+    "name"
+  ],
+  "title": "OllamaModelInfo"
+}
+
+
OllamaStatus
+{
+  "properties": {
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "models": {
+      "items": {
+        "$ref": "#/components/schemas/OllamaModelInfo"
+      },
+      "type": "array",
+      "title": "Models"
+    }
+  },
+  "type": "object",
+  "required": [
+    "status",
+    "models"
+  ],
+  "title": "OllamaStatus"
+}
+
+
OperationalMetrics
+{
+  "properties": {
+    "average_response_time_days": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Average Response Time Days"
+    },
+    "median_response_time_days": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Median Response Time Days"
+    },
+    "requests_by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "Requests By Status"
+    },
+    "requests_by_department": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "Requests By Department"
+    },
+    "deadline_compliance_rate": {
+      "type": "number",
+      "title": "Deadline Compliance Rate"
+    },
+    "total_open": {
+      "type": "integer",
+      "title": "Total Open"
+    },
+    "total_closed": {
+      "type": "integer",
+      "title": "Total Closed"
+    },
+    "total_overdue": {
+      "type": "integer",
+      "title": "Total Overdue"
+    },
+    "clarification_frequency": {
+      "type": "number",
+      "title": "Clarification Frequency"
+    },
+    "top_request_topics": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Top Request Topics"
+    }
+  },
+  "type": "object",
+  "required": [
+    "average_response_time_days",
+    "median_response_time_days",
+    "requests_by_status",
+    "requests_by_department",
+    "deadline_compliance_rate",
+    "total_open",
+    "total_closed",
+    "total_overdue",
+    "clarification_frequency",
+    "top_request_topics"
+  ],
+  "title": "OperationalMetrics"
+}
+
+
Outline
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "question_ids": {
+      "items": {
+        "type": "string",
+        "format": "uuid"
+      },
+      "type": "array",
+      "maxItems": 50,
+      "minItems": 1,
+      "title": "Question Ids"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "question_ids"
+  ],
+  "title": "Outline"
+}
+
+
Packet
+{
+  "properties": {
+    "expected_revision": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Expected Revision"
+    },
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "staff_only",
+        "records_copy"
+      ],
+      "title": "Visibility"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "expected_revision",
+    "visibility"
+  ],
+  "title": "Packet"
+}
+
+
PacketInput
+{
+  "properties": {
+    "agenda_item_ids": {
+      "items": {
+        "type": "string",
+        "format": "uuid"
+      },
+      "type": "array",
+      "title": "Agenda Item Ids"
+    },
+    "source_files": {
+      "items": {
+        "$ref": "#/components/schemas/ManagedSource"
+      },
+      "type": "array",
+      "title": "Source Files"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "agenda_item_ids"
+  ],
+  "title": "PacketInput"
+}
+
+
Pathway
+{
+  "properties": {
+    "project_type": {
+      "type": "string",
+      "maxLength": 120,
+      "minLength": 1,
+      "title": "Project Type"
+    },
+    "proposal": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Proposal",
+      "default": ""
+    },
+    "location_context": {
+      "type": "string",
+      "maxLength": 1000,
+      "title": "Location Context",
+      "default": ""
+    },
+    "requirement_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requirement Revision"
+    },
+    "fee_link": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "project_type"
+  ],
+  "title": "Pathway"
+}
+
+
PathwayStep
+{
+  "properties": {
+    "step": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Step"
+    },
+    "citation": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Citation"
+    },
+    "typical_time": {
+      "type": "string",
+      "maxLength": 1000,
+      "title": "Typical Time",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "step",
+    "citation"
+  ],
+  "title": "PathwayStep"
+}
+
+
PlainLanguageSummaryCreate
+{
+  "properties": {
+    "summary_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Summary Id"
+    },
+    "section_version_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Version Id"
+    },
+    "summary_text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Summary Text"
+    },
+    "language_code": {
+      "type": "string",
+      "title": "Language Code",
+      "default": "en"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "section_version_id",
+    "summary_text"
+  ],
+  "title": "PlainLanguageSummaryCreate",
+  "description": "Request body for staff-drafted plain-language summaries."
+}
+
+
PolicySelection
+{
+  "properties": {
+    "plan_id": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Plan Id"
+    },
+    "revision_id": {
+      "type": "string",
+      "maxLength": 36,
+      "minLength": 36,
+      "title": "Revision Id"
+    },
+    "policy_id": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Policy Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "plan_id",
+    "revision_id",
+    "policy_id"
+  ],
+  "title": "PolicySelection"
+}
+
+
PortalModeResponse
+{
+  "properties": {
+    "mode": {
+      "type": "string",
+      "enum": [
+        "public",
+        "private"
+      ],
+      "title": "Mode",
+      "description": "Active portal posture for this deployment. ``public`` = minimal resident surface (landing + authenticated records-request submission + resident registration) reachable without staff auth. ``private`` = staff-only; no public routes, no resident self-registration."
+    }
+  },
+  "type": "object",
+  "required": [
+    "mode"
+  ],
+  "title": "PortalModeResponse",
+  "description": "T5D — schema for ``GET /config/portal-mode``.\n\nExposed to the frontend on boot so it can branch routing without a\nuser-identity lookup. The payload is intentionally the single field\nbelow — no staff config, no user state, no schema version."
+}
+
+
PrepareArtifact
+{
+  "properties": {
+    "kind": {
+      "type": "string",
+      "enum": [
+        "response",
+        "release-package"
+      ],
+      "title": "Kind"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "kind"
+  ],
+  "title": "PrepareArtifact"
+}
+
+
Proof
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    },
+    "filename": {
+      "type": "string",
+      "maxLength": 150,
+      "minLength": 1,
+      "title": "Filename"
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 7000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "location": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Location"
+    },
+    "published_at": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Published At"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence",
+    "filename",
+    "content_base64",
+    "location",
+    "published_at"
+  ],
+  "title": "Proof"
+}
+
+
Proposal
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "pattern": "^[A-Za-z0-9_-]{1,64}$",
+      "title": "Id"
+    },
+    "version_id": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Version Id"
+    },
+    "meeting_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Meeting Id"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "ordinance_number": {
+      "type": "string",
+      "maxLength": 120,
+      "minLength": 1,
+      "title": "Ordinance Number"
+    },
+    "proposed_text": {
+      "type": "string",
+      "maxLength": 1000000,
+      "minLength": 1,
+      "title": "Proposed Text"
+    },
+    "supersedes_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^[A-Za-z0-9_-]{1,64}$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supersedes Id"
+    },
+    "reconciliation_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reconciliation Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "version_id",
+    "meeting_id",
+    "title",
+    "ordinance_number",
+    "proposed_text"
+  ],
+  "title": "Proposal"
+}
+
+
PublicExplore
+{
+  "properties": {
+    "goal": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Goal",
+      "default": ""
+    },
+    "topic": {
+      "type": "string",
+      "maxLength": 160,
+      "title": "Topic",
+      "default": ""
+    },
+    "neighborhood": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Neighborhood",
+      "default": ""
+    },
+    "plan_type": {
+      "type": "string",
+      "maxLength": 120,
+      "title": "Plan Type",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "PublicExplore"
+}
+
+
PublicIntake
+{
+  "properties": {
+    "requester": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requester"
+    },
+    "requesterContact": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestercontact"
+    },
+    "summary": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Summary"
+    },
+    "deadline": {
+      "type": "string",
+      "title": "Deadline",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requester",
+    "requesterContact",
+    "summary"
+  ],
+  "title": "PublicIntake"
+}
+
+
PublicLookup
+{
+  "properties": {
+    "trackingNumber": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Trackingnumber"
+    },
+    "requesterContact": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestercontact"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "trackingNumber",
+    "requesterContact"
+  ],
+  "title": "PublicLookup"
+}
+
+
PublicMessage
+{
+  "properties": {
+    "trackingNumber": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Trackingnumber"
+    },
+    "requesterContact": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestercontact"
+    },
+    "publicRequestMessage": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Publicrequestmessage"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "trackingNumber",
+    "requesterContact",
+    "publicRequestMessage"
+  ],
+  "title": "PublicMessage"
+}
+
+
PublicStatusView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "label": {
+      "type": "string",
+      "title": "Label"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "label",
+    "summary",
+    "status",
+    "created_at_unix_seconds"
+  ],
+  "title": "PublicStatusView"
+}
+
+
PublicationView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "source_module": {
+      "type": "string",
+      "title": "Source Module"
+    },
+    "source_record_id": {
+      "type": "string",
+      "title": "Source Record Id"
+    },
+    "record_type": {
+      "type": "string",
+      "title": "Record Type"
+    },
+    "public_payload": {
+      "type": "string",
+      "title": "Public Payload"
+    },
+    "payload_hash": {
+      "type": "string",
+      "title": "Payload Hash"
+    },
+    "published_at_unix_seconds": {
+      "type": "integer",
+      "title": "Published At Unix Seconds"
+    },
+    "retracted_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Retracted At Unix Seconds"
+    },
+    "retracted_by": {
+      "type": "string",
+      "title": "Retracted By",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "source_module",
+    "source_record_id",
+    "record_type",
+    "public_payload",
+    "payload_hash",
+    "published_at_unix_seconds"
+  ],
+  "title": "PublicationView"
+}
+
+
PublishingPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "publishing-workflow",
+      "title": "Action"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "hasReview": {
+      "type": "boolean",
+      "title": "Hasreview",
+      "default": false
+    },
+    "hasPlainLanguage": {
+      "type": "boolean",
+      "title": "Hasplainlanguage",
+      "default": false
+    },
+    "hasTranslationReview": {
+      "type": "boolean",
+      "title": "Hastranslationreview",
+      "default": false
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "PublishingPlan"
+}
+
+
Question
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    },
+    "question": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Question"
+    },
+    "kind": {
+      "type": "string",
+      "enum": [
+        "use",
+        "dimension"
+      ],
+      "title": "Kind"
+    },
+    "key": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Key"
+    },
+    "audience": {
+      "type": "string",
+      "enum": [
+        "resident",
+        "staff"
+      ],
+      "title": "Audience",
+      "default": "resident"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "query",
+    "question",
+    "kind",
+    "key"
+  ],
+  "title": "Question"
+}
+
+
QuestionAnswerRequest
+{
+  "properties": {
+    "question": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Question"
+    },
+    "section_number": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Section Number"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "question"
+  ],
+  "title": "QuestionAnswerRequest",
+  "description": "Request body for citation-grounded code Q&A."
+}
+
+
RecordsDocumentView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "attachment_id": {
+      "type": "string",
+      "title": "Attachment Id"
+    },
+    "title": {
+      "type": "string",
+      "title": "Title"
+    },
+    "original_path": {
+      "type": "string",
+      "title": "Original Path"
+    },
+    "stored_path": {
+      "type": "string",
+      "title": "Stored Path"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation"
+    },
+    "sha256": {
+      "type": "string",
+      "title": "Sha256"
+    },
+    "size_bytes": {
+      "type": "integer",
+      "title": "Size Bytes"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "added_by": {
+      "type": "string",
+      "title": "Added By"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    },
+    "release_original_path": {
+      "type": "string",
+      "title": "Release Original Path",
+      "default": ""
+    },
+    "release_stored_path": {
+      "type": "string",
+      "title": "Release Stored Path",
+      "default": ""
+    },
+    "release_file_name": {
+      "type": "string",
+      "title": "Release File Name",
+      "default": ""
+    },
+    "release_sha256": {
+      "type": "string",
+      "title": "Release Sha256",
+      "default": ""
+    },
+    "release_size_bytes": {
+      "type": "integer",
+      "title": "Release Size Bytes",
+      "default": 0
+    },
+    "release_status": {
+      "type": "string",
+      "title": "Release Status",
+      "default": ""
+    },
+    "release_note": {
+      "type": "string",
+      "title": "Release Note",
+      "default": ""
+    },
+    "release_added_by": {
+      "type": "string",
+      "title": "Release Added By",
+      "default": ""
+    },
+    "release_added_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Release Added At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "attachment_id",
+    "title",
+    "original_path",
+    "stored_path",
+    "citation",
+    "sha256",
+    "size_bytes",
+    "status",
+    "added_by",
+    "created_at_unix_seconds"
+  ],
+  "title": "RecordsDocumentView"
+}
+
+
RecordsOperationRead
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "message": {
+      "type": "string",
+      "title": "Message"
+    },
+    "request": {
+      "$ref": "#/components/schemas/RecordsView"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "message",
+    "request"
+  ],
+  "title": "RecordsOperationRead"
+}
+
+
RecordsStateRead
+{
+  "properties": {
+    "demo_fixture": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Demo Fixture"
+    },
+    "records_requests": {
+      "items": {
+        "$ref": "#/components/schemas/RecordsView"
+      },
+      "type": "array",
+      "title": "Records Requests"
+    },
+    "notification_events": {
+      "items": {
+        "$ref": "#/components/schemas/NotificationView"
+      },
+      "type": "array",
+      "title": "Notification Events"
+    },
+    "publication_events": {
+      "items": {
+        "$ref": "#/components/schemas/PublicationView"
+      },
+      "type": "array",
+      "title": "Publication Events"
+    },
+    "audit_entries": {
+      "items": {
+        "$ref": "#/components/schemas/AuditView"
+      },
+      "type": "array",
+      "title": "Audit Entries"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "records_requests"
+  ],
+  "title": "RecordsStateRead"
+}
+
+
RecordsView
+{
+  "properties": {
+    "request_id": {
+      "type": "string",
+      "title": "Request Id"
+    },
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "public_tracking_number": {
+      "type": "string",
+      "title": "Public Tracking Number"
+    },
+    "requester": {
+      "type": "string",
+      "title": "Requester"
+    },
+    "requester_contact": {
+      "type": "string",
+      "title": "Requester Contact"
+    },
+    "submitted_via": {
+      "type": "string",
+      "title": "Submitted Via"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "deadline": {
+      "type": "string",
+      "title": "Deadline"
+    },
+    "deadline_basis": {
+      "type": "string",
+      "title": "Deadline Basis"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "assigned_to": {
+      "type": "string",
+      "title": "Assigned To"
+    },
+    "clarification_notes": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Clarification Notes"
+    },
+    "search_notes": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Search Notes"
+    },
+    "search_sessions": {
+      "items": {
+        "$ref": "#/components/schemas/SearchReceiptView"
+      },
+      "type": "array",
+      "title": "Search Sessions"
+    },
+    "exemption_reviews": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Exemption Reviews"
+    },
+    "exemption_decisions": {
+      "items": {
+        "$ref": "#/components/schemas/ExemptionDecisionView"
+      },
+      "type": "array",
+      "title": "Exemption Decisions"
+    },
+    "fee_estimate": {
+      "type": "string",
+      "title": "Fee Estimate"
+    },
+    "fee_line_items": {
+      "items": {
+        "$ref": "#/components/schemas/FeeLineView"
+      },
+      "type": "array",
+      "title": "Fee Line Items"
+    },
+    "fee_waiver_reason": {
+      "type": "string",
+      "title": "Fee Waiver Reason"
+    },
+    "citations": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Citations"
+    },
+    "response_draft": {
+      "type": "string",
+      "title": "Response Draft"
+    },
+    "approval_notes": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Approval Notes"
+    },
+    "exports": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Exports"
+    },
+    "documents": {
+      "items": {
+        "$ref": "#/components/schemas/RecordsDocumentView"
+      },
+      "type": "array",
+      "title": "Documents"
+    },
+    "release_packages": {
+      "items": {
+        "$ref": "#/components/schemas/ReleasePackageView"
+      },
+      "type": "array",
+      "title": "Release Packages"
+    },
+    "timeline": {
+      "items": {
+        "$ref": "#/components/schemas/TimelineView"
+      },
+      "type": "array",
+      "title": "Timeline"
+    },
+    "public_status_events": {
+      "items": {
+        "$ref": "#/components/schemas/PublicStatusView"
+      },
+      "type": "array",
+      "title": "Public Status Events"
+    },
+    "messages": {
+      "items": {
+        "$ref": "#/components/schemas/MessageView"
+      },
+      "type": "array",
+      "title": "Messages"
+    },
+    "deadline_reviewed_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Deadline Reviewed At Unix Seconds"
+    },
+    "approved_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Approved At Unix Seconds"
+    },
+    "fulfilled_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fulfilled At Unix Seconds"
+    },
+    "closed_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closed At Unix Seconds"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "request_id",
+    "id",
+    "public_tracking_number",
+    "requester",
+    "requester_contact",
+    "submitted_via",
+    "summary",
+    "deadline",
+    "deadline_basis",
+    "status",
+    "assigned_to",
+    "clarification_notes",
+    "search_notes",
+    "search_sessions",
+    "exemption_reviews",
+    "exemption_decisions",
+    "fee_estimate",
+    "fee_line_items",
+    "fee_waiver_reason",
+    "citations",
+    "response_draft",
+    "approval_notes",
+    "exports",
+    "timeline",
+    "public_status_events",
+    "messages",
+    "deadline_reviewed_at_unix_seconds",
+    "approved_at_unix_seconds",
+    "fulfilled_at_unix_seconds",
+    "closed_at_unix_seconds",
+    "created_at_unix_seconds"
+  ],
+  "title": "RecordsView"
+}
+
+
ReleasePackageView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "export_path": {
+      "type": "string",
+      "title": "Export Path"
+    },
+    "package_hash": {
+      "type": "string",
+      "title": "Package Hash"
+    },
+    "document_count": {
+      "type": "integer",
+      "title": "Document Count"
+    },
+    "release_artifact_count": {
+      "type": "integer",
+      "title": "Release Artifact Count"
+    },
+    "search_session_count": {
+      "type": "integer",
+      "title": "Search Session Count"
+    },
+    "release_count": {
+      "type": "integer",
+      "title": "Release Count"
+    },
+    "redacted_count": {
+      "type": "integer",
+      "title": "Redacted Count"
+    },
+    "exempt_count": {
+      "type": "integer",
+      "title": "Exempt Count"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "export_path",
+    "package_hash",
+    "document_count",
+    "release_artifact_count",
+    "search_session_count",
+    "release_count",
+    "redacted_count",
+    "exempt_count",
+    "created_at_unix_seconds"
+  ],
+  "title": "ReleasePackageView"
+}
+
+
RepeatLookup
+{
+  "properties": {
+    "property_reference": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Property Reference"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "property_reference"
+  ],
+  "title": "RepeatLookup"
+}
+
+
RequestCreate
+{
+  "properties": {
+    "requester_name": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Requester Name"
+    },
+    "requester_email": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 255
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Email"
+    },
+    "requester_phone": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 50
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Phone"
+    },
+    "requester_type": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 100
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Type"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Description"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "priority": {
+      "type": "string",
+      "title": "Priority",
+      "default": "normal"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^(narrow|moderate|broad)$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "requester_name",
+    "description"
+  ],
+  "title": "RequestCreate"
+}
+
+
RequestDocumentAdd
+{
+  "properties": {
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "relevance_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Relevance Note"
+    }
+  },
+  "type": "object",
+  "required": [
+    "document_id"
+  ],
+  "title": "RequestDocumentAdd"
+}
+
+
RequestDocumentRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "relevance_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Relevance Note"
+    },
+    "exemption_flags": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Exemption Flags"
+    },
+    "inclusion_status": {
+      "$ref": "#/components/schemas/InclusionStatus"
+    },
+    "attached_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Attached At"
+    },
+    "attached_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Attached By"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "document_id",
+    "relevance_note",
+    "exemption_flags",
+    "inclusion_status",
+    "attached_at",
+    "attached_by"
+  ],
+  "title": "RequestDocumentRead"
+}
+
+
RequestRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "requester_name": {
+      "type": "string",
+      "title": "Requester Name"
+    },
+    "requester_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Email"
+    },
+    "requester_phone": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Phone"
+    },
+    "requester_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Type"
+    },
+    "date_received": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Date Received"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "status": {
+      "$ref": "#/components/schemas/RequestStatus"
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "created_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "response_draft": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Response Draft"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    },
+    "estimated_fee": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Estimated Fee"
+    },
+    "fee_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Status"
+    },
+    "fee_waiver_requested": {
+      "type": "boolean",
+      "title": "Fee Waiver Requested",
+      "default": false
+    },
+    "priority": {
+      "type": "string",
+      "title": "Priority",
+      "default": "normal"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    },
+    "closed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closed At"
+    },
+    "closure_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closure Reason"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "requester_name",
+    "requester_email",
+    "date_received",
+    "statutory_deadline",
+    "description",
+    "status",
+    "assigned_to",
+    "created_by",
+    "created_at",
+    "response_draft",
+    "review_notes"
+  ],
+  "title": "RequestRead"
+}
+
+
RequestStats
+{
+  "properties": {
+    "total_requests": {
+      "type": "integer",
+      "title": "Total Requests"
+    },
+    "by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "By Status"
+    },
+    "approaching_deadline": {
+      "type": "integer",
+      "title": "Approaching Deadline"
+    },
+    "overdue": {
+      "type": "integer",
+      "title": "Overdue"
+    }
+  },
+  "type": "object",
+  "required": [
+    "total_requests",
+    "by_status",
+    "approaching_deadline",
+    "overdue"
+  ],
+  "title": "RequestStats"
+}
+
+
RequestStatus
+{
+  "type": "string",
+  "enum": [
+    "received",
+    "clarification_needed",
+    "assigned",
+    "searching",
+    "in_review",
+    "ready_for_release",
+    "drafted",
+    "approved",
+    "fulfilled",
+    "closed"
+  ],
+  "title": "RequestStatus"
+}
+
+
RequestUpdate
+{
+  "properties": {
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/RequestStatus"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "response_draft": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Response Draft"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    }
+  },
+  "type": "object",
+  "title": "RequestUpdate"
+}
+
+
RequirementBundle
+{
+  "properties": {
+    "requirement_id": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9_-]{1,100}$",
+      "title": "Requirement Id"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "project_type": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Project Type"
+    },
+    "source_reference": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Source Reference"
+    },
+    "source_date": {
+      "type": "string",
+      "format": "date",
+      "title": "Source Date"
+    },
+    "effective_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Effective On"
+    },
+    "dataset_kind": {
+      "type": "string",
+      "enum": [
+        "municipal",
+        "fictional"
+      ],
+      "title": "Dataset Kind"
+    },
+    "filename": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$",
+      "title": "Filename"
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 14000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Sha256"
+    },
+    "materials": {
+      "items": {
+        "$ref": "#/components/schemas/Material"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "minItems": 1,
+      "title": "Materials"
+    },
+    "pathway": {
+      "items": {
+        "$ref": "#/components/schemas/PathwayStep"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "title": "Pathway"
+    },
+    "fee_link": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    },
+    "staff_note": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Staff Note",
+      "default": ""
+    },
+    "change_note": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Change Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requirement_id",
+    "title",
+    "jurisdiction",
+    "project_type",
+    "source_reference",
+    "source_date",
+    "effective_on",
+    "dataset_kind",
+    "filename",
+    "content_base64",
+    "sha256",
+    "materials",
+    "change_note"
+  ],
+  "title": "RequirementBundle"
+}
+
+
ResponseLetterCreate
+{
+  "properties": {
+    "template_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Template Id"
+    }
+  },
+  "type": "object",
+  "title": "ResponseLetterCreate"
+}
+
+
ResponseLetterRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "template_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Template Id"
+    },
+    "generated_content": {
+      "type": "string",
+      "title": "Generated Content"
+    },
+    "edited_content": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Edited Content"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "generated_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Generated By"
+    },
+    "approved_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Approved By"
+    },
+    "sent_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sent At"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "template_id",
+    "generated_content",
+    "edited_content",
+    "status",
+    "generated_by",
+    "approved_by",
+    "sent_at",
+    "created_at"
+  ],
+  "title": "ResponseLetterRead"
+}
+
+
ResponseLetterUpdate
+{
+  "properties": {
+    "edited_content": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Edited Content"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Status"
+    }
+  },
+  "type": "object",
+  "title": "ResponseLetterUpdate"
+}
+
+
ReviewInput
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 5000,
+      "title": "Body",
+      "default": ""
+    },
+    "hasAltText": {
+      "type": "boolean",
+      "title": "Hasalttext",
+      "default": false
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": "en"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "ReviewInput"
+}
+
+
Revision
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    },
+    "document": {
+      "$ref": "#/components/schemas/NoticeDraft"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence",
+    "document"
+  ],
+  "title": "Revision"
+}
+
+
RewriteInput
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "plain-language",
+        "language-variant"
+      ],
+      "title": "Action"
+    },
+    "text": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Text"
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "text"
+  ],
+  "title": "RewriteInput"
+}
+
+
RewriteResult
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "plain-language",
+        "language-variant"
+      ],
+      "title": "Action"
+    },
+    "text": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Text"
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": ""
+    },
+    "outcome": {
+      "type": "string",
+      "enum": [
+        "generated",
+        "unavailable"
+      ],
+      "title": "Outcome"
+    },
+    "generated": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 100000
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Generated"
+    },
+    "model": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 200
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "text",
+    "outcome"
+  ],
+  "title": "RewriteResult"
+}
+
+
Rule
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "zone_code": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Zone Code"
+    },
+    "key": {
+      "type": "string",
+      "maxLength": 120,
+      "minLength": 1,
+      "title": "Key"
+    },
+    "section_number": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Section Number"
+    },
+    "kind": {
+      "type": "string",
+      "enum": [
+        "use",
+        "dimension"
+      ],
+      "title": "Kind"
+    },
+    "value": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Value"
+    },
+    "overlay_code": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 255
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Overlay Code"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "zone_code",
+    "key",
+    "section_number",
+    "kind",
+    "value"
+  ],
+  "title": "Rule"
+}
+
+
RuleTestMatch
+{
+  "properties": {
+    "matched_text": {
+      "type": "string",
+      "title": "Matched Text"
+    },
+    "start": {
+      "type": "integer",
+      "title": "Start"
+    },
+    "end": {
+      "type": "integer",
+      "title": "End"
+    }
+  },
+  "type": "object",
+  "required": [
+    "matched_text",
+    "start",
+    "end"
+  ],
+  "title": "RuleTestMatch"
+}
+
+
RuleTestRequest
+{
+  "properties": {
+    "sample_text": {
+      "type": "string",
+      "title": "Sample Text"
+    }
+  },
+  "type": "object",
+  "required": [
+    "sample_text"
+  ],
+  "title": "RuleTestRequest"
+}
+
+
RuleTestResponse
+{
+  "properties": {
+    "rule_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Rule Id"
+    },
+    "rule_type": {
+      "type": "string",
+      "title": "Rule Type"
+    },
+    "matched": {
+      "type": "boolean",
+      "title": "Matched"
+    },
+    "matches": {
+      "items": {
+        "$ref": "#/components/schemas/RuleTestMatch"
+      },
+      "type": "array",
+      "title": "Matches"
+    }
+  },
+  "type": "object",
+  "required": [
+    "rule_id",
+    "rule_type",
+    "matched",
+    "matches"
+  ],
+  "title": "RuleTestResponse"
+}
+
+
RuleType
+{
+  "type": "string",
+  "enum": [
+    "regex",
+    "keyword",
+    "llm_prompt"
+  ],
+  "title": "RuleType"
+}
+
+
SaveReview
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 5000,
+      "title": "Body",
+      "default": ""
+    },
+    "hasAltText": {
+      "type": "boolean",
+      "title": "Hasalttext",
+      "default": false
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": "en"
+    },
+    "ai_analysis": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 100000
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ai Analysis"
+    },
+    "ai_analysis_model": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 200
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ai Analysis Model"
+    },
+    "ai_outcome": {
+      "type": "string",
+      "enum": [
+        "generated",
+        "unavailable",
+        "failed"
+      ],
+      "title": "Ai Outcome"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "ai_outcome"
+  ],
+  "title": "SaveReview"
+}
+
+
SearchFilterOptions
+{
+  "properties": {
+    "file_types": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "File Types"
+    },
+    "source_names": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Source Names"
+    },
+    "departments": {
+      "items": {
+        "additionalProperties": true,
+        "type": "object"
+      },
+      "type": "array",
+      "title": "Departments",
+      "default": []
+    },
+    "date_range": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Date Range"
+    }
+  },
+  "type": "object",
+  "required": [
+    "file_types",
+    "source_names"
+  ],
+  "title": "SearchFilterOptions"
+}
+
+
SearchInput
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "SearchInput"
+}
+
+
SearchNoteCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "record-records-search",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/SearchNotePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "SearchNoteCommand"
+}
+
+
SearchNotePayload
+{
+  "properties": {
+    "sourceNote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Sourcenote"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sourceNote"
+  ],
+  "title": "SearchNotePayload"
+}
+
+
SearchReceiptCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "record-records-search-session",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/SearchReceiptPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "SearchReceiptCommand"
+}
+
+
SearchReceiptPayload
+{
+  "properties": {
+    "searchQuery": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchquery"
+    },
+    "searchLocations": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchlocations"
+    },
+    "searchResultTitle": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchresulttitle"
+    },
+    "searchResultCitation": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchresultcitation"
+    },
+    "searchResultSummary": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchresultsummary"
+    },
+    "searchResultStatus": {
+      "type": "string",
+      "title": "Searchresultstatus",
+      "default": ""
+    },
+    "searchReviewer": {
+      "type": "string",
+      "title": "Searchreviewer",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "searchQuery",
+    "searchLocations",
+    "searchResultTitle",
+    "searchResultCitation",
+    "searchResultSummary"
+  ],
+  "title": "SearchReceiptPayload"
+}
+
+
SearchReceiptView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "query": {
+      "type": "string",
+      "title": "Query"
+    },
+    "locations": {
+      "type": "string",
+      "title": "Locations"
+    },
+    "reviewer": {
+      "type": "string",
+      "title": "Reviewer"
+    },
+    "results": {
+      "items": {
+        "$ref": "#/components/schemas/SearchResultView"
+      },
+      "type": "array",
+      "title": "Results"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "query",
+    "locations",
+    "reviewer",
+    "results",
+    "created_at_unix_seconds"
+  ],
+  "title": "SearchReceiptView"
+}
+
+
SearchRequest
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "title": "Query"
+    },
+    "session_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Session Id"
+    },
+    "filters": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Filters"
+    },
+    "limit": {
+      "type": "integer",
+      "maximum": 50.0,
+      "title": "Limit",
+      "default": 10
+    },
+    "synthesize": {
+      "type": "boolean",
+      "title": "Synthesize",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "SearchRequest"
+}
+
+
SearchResponse
+{
+  "properties": {
+    "query_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Query Id"
+    },
+    "session_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Session Id"
+    },
+    "query_text": {
+      "type": "string",
+      "title": "Query Text"
+    },
+    "results": {
+      "items": {
+        "$ref": "#/components/schemas/SearchResultItem"
+      },
+      "type": "array",
+      "title": "Results"
+    },
+    "results_count": {
+      "type": "integer",
+      "title": "Results Count"
+    },
+    "synthesized_answer": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Synthesized Answer"
+    },
+    "ai_generated": {
+      "type": "boolean",
+      "title": "Ai Generated",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "query_id",
+    "session_id",
+    "query_text",
+    "results",
+    "results_count"
+  ],
+  "title": "SearchResponse"
+}
+
+
SearchResultItem
+{
+  "properties": {
+    "chunk_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Chunk Id"
+    },
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "filename": {
+      "type": "string",
+      "title": "Filename"
+    },
+    "file_type": {
+      "type": "string",
+      "title": "File Type"
+    },
+    "source_path": {
+      "type": "string",
+      "title": "Source Path"
+    },
+    "page_number": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Page Number"
+    },
+    "content_text": {
+      "type": "string",
+      "title": "Content Text"
+    },
+    "similarity_score": {
+      "type": "number",
+      "title": "Similarity Score"
+    },
+    "rank": {
+      "type": "integer",
+      "title": "Rank"
+    }
+  },
+  "type": "object",
+  "required": [
+    "chunk_id",
+    "document_id",
+    "filename",
+    "file_type",
+    "source_path",
+    "page_number",
+    "content_text",
+    "similarity_score",
+    "rank"
+  ],
+  "title": "SearchResultItem"
+}
+
+
SearchResultView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "title": {
+      "type": "string",
+      "title": "Title"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "title",
+    "citation",
+    "summary",
+    "status"
+  ],
+  "title": "SearchResultView"
+}
+
+
SearchSessionRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "user_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "User Id"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "queries": {
+      "items": {
+        "additionalProperties": true,
+        "type": "object"
+      },
+      "type": "array",
+      "title": "Queries",
+      "default": []
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "user_id",
+    "created_at"
+  ],
+  "title": "SearchSessionRead"
+}
+
+
SectionCreate
+{
+  "properties": {
+    "section_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Section Id"
+    },
+    "chapter_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Chapter Id"
+    },
+    "section_number": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Number"
+    },
+    "section_heading": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Heading"
+    },
+    "parent_section_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parent Section Id"
+    },
+    "sort_order": {
+      "type": "integer",
+      "title": "Sort Order",
+      "default": 0
+    },
+    "administrative_regulation_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Administrative Regulation Refs"
+    },
+    "resolution_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Resolution Refs"
+    },
+    "policy_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Policy Refs"
+    },
+    "approved_summary_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Approved Summary Refs"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "chapter_id",
+    "section_number",
+    "section_heading"
+  ],
+  "title": "SectionCreate",
+  "description": "Request body for creating a code section or subsection."
+}
+
+
SectionVersionCreate
+{
+  "properties": {
+    "version_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Version Id"
+    },
+    "section_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Id"
+    },
+    "source_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "version_label": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Version Label"
+    },
+    "body": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Body"
+    },
+    "effective_start": {
+      "type": "string",
+      "format": "date",
+      "title": "Effective Start"
+    },
+    "effective_end": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective End"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    },
+    "is_current": {
+      "type": "boolean",
+      "title": "Is Current",
+      "default": false
+    },
+    "adoption_event_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Adoption Event Id"
+    },
+    "amendment_event_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Amendment Event Id"
+    },
+    "amendment_summary": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Amendment Summary"
+    },
+    "prior_version_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Prior Version Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "section_id",
+    "source_id",
+    "version_label",
+    "body",
+    "effective_start"
+  ],
+  "title": "SectionVersionCreate",
+  "description": "Request body for adding an immutable section version."
+}
+
+
Selection
+{
+  "properties": {
+    "recording_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Recording Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "recording_id",
+    "expected_sha256"
+  ],
+  "title": "Selection"
+}
+
+
SentenceInput
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "citations": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Citations"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text"
+  ],
+  "title": "SentenceInput"
+}
+
+
ServiceAccountCreate
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole",
+      "default": "read_only"
+    }
+  },
+  "type": "object",
+  "required": [
+    "name"
+  ],
+  "title": "ServiceAccountCreate"
+}
+
+
ServiceAccountCreated
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "api_key": {
+      "type": "string",
+      "title": "Api Key"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "role",
+    "created_by",
+    "created_at",
+    "is_active",
+    "api_key"
+  ],
+  "title": "ServiceAccountCreated",
+  "description": "Returned only on creation — includes the plaintext API key (shown once)."
+}
+
+
ServiceAccountRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "role",
+    "created_by",
+    "created_at",
+    "is_active"
+  ],
+  "title": "ServiceAccountRead"
+}
+
+
ServiceAccountUpdate
+{
+  "properties": {
+    "role": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/UserRole"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "ServiceAccountUpdate"
+}
+
+
Snapshot
+{
+  "properties": {
+    "expected_revision": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Expected Revision"
+    },
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "staff_only",
+        "public"
+      ],
+      "title": "Visibility"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "expected_revision",
+    "visibility"
+  ],
+  "title": "Snapshot"
+}
+
+
SourceCreate
+{
+  "properties": {
+    "source_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Id"
+    },
+    "name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Name"
+    },
+    "publisher": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Publisher"
+    },
+    "source_type": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Type"
+    },
+    "source_category": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Category"
+    },
+    "source_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Url"
+    },
+    "file_reference": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "File Reference"
+    },
+    "retrieved_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Retrieved At"
+    },
+    "retrieval_method": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Retrieval Method"
+    },
+    "checksum": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Checksum"
+    },
+    "source_owner": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Owner"
+    },
+    "is_official": {
+      "type": "boolean",
+      "title": "Is Official",
+      "default": true
+    },
+    "official_status_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Official Status Note"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    },
+    "staff_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Staff Notes"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "name",
+    "publisher",
+    "source_type",
+    "source_category"
+  ],
+  "title": "SourceCreate",
+  "description": "Request body for registering an official or explicitly labeled source."
+}
+
+
SourceInput
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "label": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Label"
+    },
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "label",
+    "text"
+  ],
+  "title": "SourceInput"
+}
+
+
SourceSnapshot
+{
+  "properties": {
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "public",
+        "staff_only"
+      ],
+      "title": "Visibility"
+    },
+    "meeting_event_ids": {
+      "items": {
+        "type": "string",
+        "format": "uuid"
+      },
+      "type": "array",
+      "maxItems": 50,
+      "title": "Meeting Event Ids"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "visibility"
+  ],
+  "title": "SourceSnapshot"
+}
+
+
SourceType
+{
+  "type": "string",
+  "enum": [
+    "manual_drop",
+    "file_system",
+    "rest_api",
+    "odbc"
+  ],
+  "title": "SourceType"
+}
+
+
StaffRecordsIntake
+{
+  "properties": {
+    "requester": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requester"
+    },
+    "summary": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Summary"
+    },
+    "deadline": {
+      "type": "string",
+      "title": "Deadline"
+    },
+    "deadlineBasis": {
+      "type": "string",
+      "title": "Deadlinebasis",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requester",
+    "summary",
+    "deadline"
+  ],
+  "title": "StaffRecordsIntake",
+  "description": "Existing native create-records-request input; no caller-supplied actor."
+}
+
+
StandardsExplanation
+{
+  "properties": {
+    "question": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Question"
+    },
+    "process_section": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Process Section",
+      "default": ""
+    },
+    "zone_code": {
+      "type": "string",
+      "maxLength": 40,
+      "title": "Zone Code",
+      "default": ""
+    },
+    "rule_types": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "title": "Rule Types"
+    },
+    "observed": {
+      "additionalProperties": {
+        "type": "string"
+      },
+      "type": "object",
+      "title": "Observed"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "question"
+  ],
+  "title": "StandardsExplanation"
+}
+
+
SyncFailureRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "source_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Source Id"
+    },
+    "source_path": {
+      "type": "string",
+      "title": "Source Path"
+    },
+    "error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Message"
+    },
+    "error_class": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Class"
+    },
+    "http_status_code": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Http Status Code"
+    },
+    "retry_count": {
+      "type": "integer",
+      "title": "Retry Count"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "first_failed_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "First Failed At"
+    },
+    "last_retried_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Retried At"
+    },
+    "dismissed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Dismissed At"
+    },
+    "dismissed_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Dismissed By"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "source_id",
+    "source_path",
+    "error_message",
+    "error_class",
+    "http_status_code",
+    "retry_count",
+    "status",
+    "first_failed_at",
+    "last_retried_at",
+    "dismissed_at",
+    "dismissed_by"
+  ],
+  "title": "SyncFailureRead"
+}
+
+
SyncRunLogRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "source_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Source Id"
+    },
+    "started_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Started At"
+    },
+    "finished_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Finished At"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Status"
+    },
+    "records_attempted": {
+      "type": "integer",
+      "title": "Records Attempted"
+    },
+    "records_succeeded": {
+      "type": "integer",
+      "title": "Records Succeeded"
+    },
+    "records_failed": {
+      "type": "integer",
+      "title": "Records Failed"
+    },
+    "error_summary": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Summary"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "source_id",
+    "started_at",
+    "finished_at",
+    "status",
+    "records_attempted",
+    "records_succeeded",
+    "records_failed",
+    "error_summary"
+  ],
+  "title": "SyncRunLogRead"
+}
+
+
SystemStatus
+{
+  "properties": {
+    "version": {
+      "type": "string",
+      "title": "Version"
+    },
+    "database": {
+      "type": "string",
+      "title": "Database"
+    },
+    "ollama": {
+      "type": "string",
+      "title": "Ollama"
+    },
+    "redis": {
+      "type": "string",
+      "title": "Redis"
+    },
+    "user_count": {
+      "type": "integer",
+      "title": "User Count"
+    },
+    "audit_log_count": {
+      "type": "integer",
+      "title": "Audit Log Count"
+    },
+    "suite_session": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Suite Session"
+    }
+  },
+  "type": "object",
+  "required": [
+    "version",
+    "database",
+    "ollama",
+    "redis",
+    "user_count",
+    "audit_log_count"
+  ],
+  "title": "SystemStatus"
+}
+
+
TaggedPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "tagged-pdf",
+      "title": "Action"
+    },
+    "headingLevels": {
+      "items": {
+        "type": "integer",
+        "maximum": 4294967295.0,
+        "minimum": 0.0
+      },
+      "type": "array",
+      "maxItems": 50,
+      "title": "Headinglevels"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "TaggedPlan"
+}
+
+
TestConnectionRequest
+{
+  "properties": {
+    "source_type": {
+      "type": "string",
+      "title": "Source Type"
+    },
+    "host": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Host"
+    },
+    "port": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Port"
+    },
+    "path": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Path"
+    },
+    "username": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Username"
+    },
+    "password": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Password"
+    },
+    "rest_api_config": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Rest Api Config"
+    },
+    "odbc_config": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Odbc Config"
+    }
+  },
+  "type": "object",
+  "required": [
+    "source_type"
+  ],
+  "title": "TestConnectionRequest",
+  "description": "Dedicated schema for test-connection. NOT the create schema.\n\nSecurity: credentials in this request body are never persisted, never\nwritten to audit logs, and never returned in the response."
+}
+
+
TestConnectionResponse
+{
+  "properties": {
+    "success": {
+      "type": "boolean",
+      "title": "Success"
+    },
+    "message": {
+      "type": "string",
+      "title": "Message"
+    },
+    "latency_ms": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Latency Ms"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Status"
+    },
+    "warning": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Warning"
+    },
+    "differing_keys": {
+      "anyOf": [
+        {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Differing Keys"
+    }
+  },
+  "type": "object",
+  "required": [
+    "success",
+    "message"
+  ],
+  "title": "TestConnectionResponse"
+}
+
+
TimelineEventCreate
+{
+  "properties": {
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "internal_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Internal Note"
+    }
+  },
+  "type": "object",
+  "required": [
+    "event_type",
+    "description"
+  ],
+  "title": "TimelineEventCreate"
+}
+
+
TimelineEventRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "actor_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Actor Id"
+    },
+    "actor_role": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Actor Role"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "internal_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Internal Note"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "event_type",
+    "actor_id",
+    "actor_role",
+    "description",
+    "internal_note",
+    "created_at"
+  ],
+  "title": "TimelineEventRead"
+}
+
+
TimelineView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "actor": {
+      "type": "string",
+      "title": "Actor"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "action",
+    "actor",
+    "note",
+    "created_at_unix_seconds"
+  ],
+  "title": "TimelineView"
+}
+
+
TitleCreate
+{
+  "properties": {
+    "title_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Title Id"
+    },
+    "title_number": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title Number"
+    },
+    "title_name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title Name"
+    },
+    "sort_order": {
+      "type": "integer",
+      "title": "Sort Order",
+      "default": 0
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title_number",
+    "title_name"
+  ],
+  "title": "TitleCreate",
+  "description": "Request body for creating a code title."
+}
+
+
TranscriptInput
+{
+  "properties": {
+    "source_label": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Label"
+    },
+    "transcript_text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Transcript Text"
+    },
+    "correction_of_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Correction Of Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_label",
+    "transcript_text"
+  ],
+  "title": "TranscriptInput"
+}
+
+
UserRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "email": {
+      "type": "string",
+      "format": "email",
+      "title": "Email"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active",
+      "default": true
+    },
+    "is_superuser": {
+      "type": "boolean",
+      "title": "Is Superuser",
+      "default": false
+    },
+    "is_verified": {
+      "type": "boolean",
+      "title": "Is Verified",
+      "default": false
+    },
+    "full_name": {
+      "type": "string",
+      "title": "Full Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "last_login": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Login"
+    },
+    "must_change_password": {
+      "type": "boolean",
+      "title": "Must Change Password",
+      "default": false
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "email",
+    "full_name",
+    "role",
+    "created_at",
+    "last_login"
+  ],
+  "title": "UserRead"
+}
+
+
UserRole
+{
+  "type": "string",
+  "enum": [
+    "admin",
+    "staff",
+    "reviewer",
+    "read_only",
+    "liaison",
+    "public"
+  ],
+  "title": "UserRole"
+}
+
+
UserSelfUpdate
+{
+  "properties": {
+    "password": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Password"
+    },
+    "email": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "email"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    },
+    "is_superuser": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Superuser"
+    },
+    "is_verified": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Verified"
+    },
+    "full_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Full Name"
+    }
+  },
+  "type": "object",
+  "title": "UserSelfUpdate",
+  "description": "Schema for user self-update via PATCH /users/me.\n\nExcludes role and department_id. Any payload containing those fields is\nrejected at parse time (HTTP 422). Role and department changes require\nadmin privileges via /admin/users/{id}."
+}
+
+
UserUpdateRequest
+{
+  "properties": {
+    "full_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Full Name"
+    },
+    "role": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Role"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "UserUpdateRequest"
+}
+
+
ValidationError
+{
+  "properties": {
+    "loc": {
+      "items": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "integer"
+          }
+        ]
+      },
+      "type": "array",
+      "title": "Location"
+    },
+    "msg": {
+      "type": "string",
+      "title": "Message"
+    },
+    "type": {
+      "type": "string",
+      "title": "Error Type"
+    },
+    "input": {
+      "title": "Input"
+    },
+    "ctx": {
+      "type": "object",
+      "title": "Context"
+    }
+  },
+  "type": "object",
+  "required": [
+    "loc",
+    "msg",
+    "type"
+  ],
+  "title": "ValidationError"
+}
+
+
Version
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence"
+  ],
+  "title": "Version"
+}
+
+
VoteCorrection
+{
+  "properties": {
+    "vote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Vote"
+    },
+    "reason": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Reason"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "vote",
+    "reason"
+  ],
+  "title": "VoteCorrection"
+}
+
+
VoteInput
+{
+  "properties": {
+    "voter_name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Voter Name"
+    },
+    "vote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Vote"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "voter_name",
+    "vote"
+  ],
+  "title": "VoteInput"
+}
+
+
_ParcelLookupIn
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "query"
+  ],
+  "title": "_ParcelLookupIn"
+}
+
+
townlight_inspections__workflow_models__SourceLink
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "const": "code",
+      "title": "Provider",
+      "default": "code"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "SourceLink"
+}
+
+
townlight_permitting__workflow_models__SourceLink
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "enum": [
+        "code",
+        "zoning"
+      ],
+      "title": "Provider"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "SourceLink"
+}
+
+
townlight_runtime__inspections_bridge__Search
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "const": "code",
+      "title": "Provider"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "query"
+  ],
+  "title": "Search"
+}
+
+
townlight_runtime__notice_bridge__Review
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence",
+    "note"
+  ],
+  "title": "Review"
+}
+
+
townlight_runtime__permitting_bridge__Import
+{
+  "properties": {
+    "bundle": {
+      "$ref": "#/components/schemas/RequirementBundle"
+    },
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "bundle"
+  ],
+  "title": "Import"
+}
+
+
townlight_runtime__permitting_bridge__Search
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "enum": [
+        "code",
+        "zoning"
+      ],
+      "title": "Provider"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "query"
+  ],
+  "title": "Search"
+}
+
+
townlight_runtime__planning_bridge__Import
+{
+  "properties": {
+    "bundle": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Bundle"
+    },
+    "expected_previous_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Previous Revision"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "bundle"
+  ],
+  "title": "Import"
+}
+
+
townlight_runtime__planning_bridge__Search
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Query"
+    },
+    "plan_type": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 40
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Plan Type"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "Search"
+}
+
+
townlight_runtime__zoning_bridge__Review
+{
+  "properties": {
+    "answer": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Answer",
+      "default": ""
+    },
+    "notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Notes",
+      "default": ""
+    },
+    "queue_status": {
+      "type": "string",
+      "enum": [
+        "open",
+        "in_review",
+        "resolved",
+        "closed"
+      ],
+      "title": "Queue Status",
+      "default": "resolved"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "Review"
+}
+
Townlight · AGPL-3.0-only · Source schema evidence only
\ No newline at end of file diff --git a/docs/beta-1/api/zoning-openapi.json b/docs/beta-1/api/zoning-openapi.json new file mode 100644 index 0000000..7e374ad --- /dev/null +++ b/docs/beta-1/api/zoning-openapi.json @@ -0,0 +1,11822 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "Townlight Records", + "description": "Prepared source schema for the actual native composition; installed acceptance remains pending. Exported without lifespan, migrations or database/network access.", + "version": "1.8.0.dev2" + }, + "paths": { + "/desktop/v1/zoning-sources/search": { + "post": { + "tags": [ + "native-desktop" + ], + "summary": "Search Zoning Sources", + "operationId": "search_zoning_sources_desktop_v1_zoning_sources_search_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MeetingsSearch" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/zoning/imports": { + "post": { + "tags": [ + "native-zoning" + ], + "summary": "Imports", + "operationId": "imports_desktop_v1_zoning_imports_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": true, + "title": "Payload" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/zoning/parcels/lookup": { + "post": { + "tags": [ + "native-zoning" + ], + "summary": "Parcel Lookup", + "operationId": "parcel_lookup_desktop_v1_zoning_parcels_lookup_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/_ParcelLookupIn" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/zoning/questions/{question_id}/history": { + "get": { + "tags": [ + "native-zoning" + ], + "summary": "Question History", + "operationId": "question_history_desktop_v1_zoning_questions__question_id__history_get", + "parameters": [ + { + "name": "question_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Question Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/zoning/meetings/search": { + "post": { + "tags": [ + "native-zoning" + ], + "summary": "Search Meetings", + "operationId": "search_meetings_desktop_v1_zoning_meetings_search_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MeetingSearch" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/zoning/questions/{question_id}/meetings": { + "post": { + "tags": [ + "native-zoning" + ], + "summary": "Link Meeting", + "operationId": "link_meeting_desktop_v1_zoning_questions__question_id__meetings_post", + "parameters": [ + { + "name": "question_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Question Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MeetingLink" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/zoning/questions/{question_id}/snapshots": { + "post": { + "tags": [ + "native-zoning" + ], + "summary": "Create Snapshot", + "operationId": "create_snapshot_desktop_v1_zoning_questions__question_id__snapshots_post", + "parameters": [ + { + "name": "question_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Question Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SourceSnapshot" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/zoning/rules": { + "post": { + "tags": [ + "native-zoning" + ], + "summary": "Create Rule", + "operationId": "create_rule_desktop_v1_zoning_rules_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Rule" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/zoning/questions": { + "post": { + "tags": [ + "native-zoning" + ], + "summary": "Create Question", + "operationId": "create_question_desktop_v1_zoning_questions_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Question" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/zoning/workspace": { + "get": { + "tags": [ + "native-zoning" + ], + "summary": "Get Workspace", + "operationId": "get_workspace_desktop_v1_zoning_workspace_get", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/zoning/questions/{question_id}/reviews": { + "post": { + "tags": [ + "native-zoning" + ], + "summary": "Create Review", + "operationId": "create_review_desktop_v1_zoning_questions__question_id__reviews_post", + "parameters": [ + { + "name": "question_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Question Id" + } + }, + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/townlight_runtime__zoning_bridge__Review" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/zoning/outlines": { + "post": { + "tags": [ + "native-zoning" + ], + "summary": "Create Outline", + "operationId": "create_outline_desktop_v1_zoning_outlines_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Outline" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/zoning/code-context": { + "post": { + "tags": [ + "native-zoning" + ], + "summary": "Create Code Context", + "operationId": "create_code_context_desktop_v1_zoning_code_context_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CodeContext" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/desktop/v1/zoning/standards/process-explanation": { + "post": { + "tags": [ + "native-zoning" + ], + "summary": "Standards Explanation", + "description": "Cited variance/CUP/nonconformity process; never a determination.", + "operationId": "standards_explanation_desktop_v1_zoning_standards_process_explanation_post", + "parameters": [ + { + "name": "X-Townlight-Session", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Townlight-Session" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StandardsExplanation" + } + } + } + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "ActionItemInput": { + "properties": { + "description": { + "type": "string", + "minLength": 1, + "title": "Description" + }, + "assigned_to": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "source_motion_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Source Motion Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "description" + ], + "title": "ActionItemInput" + }, + "AdaPlan": { + "properties": { + "action": { + "type": "string", + "const": "ada-title-ii", + "title": "Action" + }, + "serviceArea": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Servicearea" + }, + "hasCoordinatorReview": { + "type": "boolean", + "title": "Hascoordinatorreview", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "serviceArea" + ], + "title": "AdaPlan" + }, + "AdminUserCreateRequest": { + "properties": { + "email": { + "type": "string", + "title": "Email" + }, + "password": { + "type": "string", + "title": "Password" + }, + "full_name": { + "type": "string", + "title": "Full Name", + "default": "" + }, + "role": { + "type": "string", + "title": "Role", + "default": "staff" + } + }, + "type": "object", + "required": [ + "email", + "password" + ], + "title": "AdminUserCreateRequest" + }, + "AdminUserCreateResponse": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "email": { + "type": "string", + "title": "Email" + }, + "full_name": { + "type": "string", + "title": "Full Name" + }, + "role": { + "type": "string", + "title": "Role" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + } + }, + "type": "object", + "required": [ + "id", + "email", + "full_name", + "role", + "is_active" + ], + "title": "AdminUserCreateResponse" + }, + "AgendaAssignment": { + "properties": { + "meeting_id": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "meeting_id" + ], + "title": "AgendaAssignment" + }, + "AgendaInput": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "department_name": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Department Name" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "department_name" + ], + "title": "AgendaInput" + }, + "AgendaReviewInput": { + "properties": { + "to_status": { + "type": "string", + "enum": [ + "DRAFTED", + "SUBMITTED", + "DEPT_APPROVED", + "LEGAL_REVIEWED", + "CLERK_ACCEPTED", + "ON_AGENDA", + "IN_PACKET", + "POSTED", + "HEARD", + "DISPOSED", + "ARCHIVED" + ], + "title": "To Status" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "to_status" + ], + "title": "AgendaReviewInput" + }, + "AmendmentInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "policy": { + "$ref": "#/components/schemas/PolicySelection" + }, + "proposal": { + "type": "string", + "maxLength": 20000, + "minLength": 1, + "title": "Proposal" + }, + "responsible_staff": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Responsible Staff" + }, + "status": { + "type": "string", + "enum": [ + "draft", + "review", + "adopted", + "withdrawn" + ], + "title": "Status", + "default": "draft" + }, + "review_note": { + "type": "string", + "maxLength": 5000, + "title": "Review Note", + "default": "" + }, + "adoption_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Adoption Revision" + }, + "note": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "policy", + "proposal", + "responsible_staff", + "note" + ], + "title": "AmendmentInput" + }, + "AnalysisObservation": { + "properties": { + "source": { + "type": "string", + "maxLength": 64, + "minLength": 1, + "title": "Source" + }, + "filename": { + "type": "string", + "maxLength": 160, + "title": "Filename", + "default": "" + }, + "media_type": { + "type": "string", + "maxLength": 80, + "title": "Media Type", + "default": "" + }, + "text": { + "type": "string", + "maxLength": 4000, + "minLength": 1, + "title": "Text" + }, + "adapter": { + "type": "string", + "maxLength": 120, + "title": "Adapter", + "default": "" + }, + "citation_source_ids": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 30, + "title": "Citation Source Ids" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source", + "text" + ], + "title": "AnalysisObservation", + "description": "One draft observation, named with the adapter that actually produced it." + }, + "AnalysisRecord": { + "properties": { + "observations": { + "items": { + "$ref": "#/components/schemas/AnalysisObservation" + }, + "type": "array", + "maxItems": 30, + "title": "Observations" + }, + "cited_sections": { + "items": { + "$ref": "#/components/schemas/CitedSection" + }, + "type": "array", + "maxItems": 30, + "title": "Cited Sections" + }, + "unavailable": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 30, + "title": "Unavailable" + }, + "runtime": { + "additionalProperties": true, + "type": "object", + "title": "Runtime" + }, + "review_required": { + "type": "boolean", + "title": "Review Required", + "default": true + } + }, + "additionalProperties": false, + "type": "object", + "title": "AnalysisRecord", + "description": "The adapter output that accompanies a saved inspection draft." + }, + "ApprovalCommand": { + "properties": { + "action": { + "type": "string", + "const": "approve-records-response", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ApprovalPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "ApprovalCommand" + }, + "ApprovalPayload": { + "properties": { + "approvalNote": { + "type": "string", + "title": "Approvalnote", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "title": "ApprovalPayload" + }, + "ArchiveInput": { + "properties": { + "visibility": { + "type": "string", + "enum": [ + "public", + "closed_session" + ], + "title": "Visibility" + }, + "packet_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Packet Id" + }, + "minutes_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Minutes Id" + }, + "plain_language_summary": { + "type": "string", + "title": "Plain Language Summary", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "visibility" + ], + "title": "ArchiveInput" + }, + "ArtifactPlan": { + "properties": { + "artifact_id": { + "type": "string", + "title": "Artifact Id" + }, + "file_name": { + "type": "string", + "title": "File Name" + }, + "content": { + "type": "string", + "title": "Content" + }, + "sha256": { + "type": "string", + "title": "Sha256" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "artifact_id", + "file_name", + "content", + "sha256", + "created_at_unix_seconds" + ], + "title": "ArtifactPlan" + }, + "AssignCommand": { + "properties": { + "action": { + "type": "string", + "const": "assign-records-request", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/AssignmentPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "AssignCommand" + }, + "AssignmentPayload": { + "properties": { + "assignedTo": { + "type": "string", + "minLength": 1, + "title": "Assignedto" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "assignedTo" + ], + "title": "AssignmentPayload" + }, + "AttachDocument": { + "properties": { + "title": { + "type": "string", + "minLength": 1, + "title": "Title" + }, + "citation": { + "type": "string", + "title": "Citation", + "default": "" + }, + "file": { + "$ref": "#/components/schemas/ManagedFileReceipt" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "file" + ], + "title": "AttachDocument" + }, + "AttachReleaseCopy": { + "properties": { + "status": { + "type": "string", + "enum": [ + "release-ready copy", + "redacted copy" + ], + "title": "Status" + }, + "note": { + "type": "string", + "title": "Note", + "default": "" + }, + "added_by": { + "type": "string", + "title": "Added By", + "default": "" + }, + "file": { + "$ref": "#/components/schemas/ManagedFileReceipt" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "status", + "file" + ], + "title": "AttachReleaseCopy" + }, + "AuditChainVerification": { + "properties": { + "is_valid": { + "type": "boolean", + "title": "Is Valid" + }, + "entries_checked": { + "type": "integer", + "title": "Entries Checked" + }, + "error_message": { + "type": "string", + "title": "Error Message" + } + }, + "type": "object", + "required": [ + "is_valid", + "entries_checked", + "error_message" + ], + "title": "AuditChainVerification" + }, + "AuditLogRead": { + "properties": { + "id": { + "type": "integer", + "title": "Id" + }, + "prev_hash": { + "type": "string", + "title": "Prev Hash" + }, + "entry_hash": { + "type": "string", + "title": "Entry Hash" + }, + "timestamp": { + "type": "string", + "format": "date-time", + "title": "Timestamp" + }, + "user_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "User Id" + }, + "action": { + "type": "string", + "title": "Action" + }, + "resource_type": { + "type": "string", + "title": "Resource Type" + }, + "resource_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Resource Id" + }, + "details": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Details" + }, + "ai_generated": { + "type": "boolean", + "title": "Ai Generated" + } + }, + "type": "object", + "required": [ + "id", + "prev_hash", + "entry_hash", + "timestamp", + "user_id", + "action", + "resource_type", + "resource_id", + "details", + "ai_generated" + ], + "title": "AuditLogRead" + }, + "AuditView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "module_id": { + "type": "string", + "title": "Module Id" + }, + "action": { + "type": "string", + "title": "Action" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + }, + "previous_hash": { + "type": "string", + "title": "Previous Hash" + }, + "entry_hash": { + "type": "string", + "title": "Entry Hash" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "module_id", + "action", + "summary", + "created_at_unix_seconds", + "previous_hash", + "entry_hash" + ], + "title": "AuditView" + }, + "BearerResponse": { + "properties": { + "access_token": { + "type": "string", + "title": "Access Token" + }, + "token_type": { + "type": "string", + "title": "Token Type" + } + }, + "type": "object", + "required": [ + "access_token", + "token_type" + ], + "title": "BearerResponse" + }, + "Body_auth_jwt_login_auth_jwt_login_post": { + "properties": { + "grant_type": { + "anyOf": [ + { + "type": "string", + "pattern": "^password$" + }, + { + "type": "null" + } + ], + "title": "Grant Type" + }, + "username": { + "type": "string", + "title": "Username" + }, + "password": { + "type": "string", + "format": "password", + "title": "Password" + }, + "scope": { + "type": "string", + "title": "Scope", + "default": "" + }, + "client_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Client Id" + }, + "client_secret": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "format": "password", + "title": "Client Secret" + } + }, + "type": "object", + "required": [ + "username", + "password" + ], + "title": "Body_auth_jwt_login_auth_jwt_login_post" + }, + "Body_upload_file_datasources_upload_post": { + "properties": { + "file": { + "type": "string", + "contentMediaType": "application/octet-stream", + "title": "File" + } + }, + "type": "object", + "required": [ + "file" + ], + "title": "Body_upload_file_datasources_upload_post" + }, + "CalculateDeadlineCommand": { + "properties": { + "action": { + "type": "string", + "const": "calculate-records-deadline", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/CalculateDeadlinePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "CalculateDeadlineCommand" + }, + "CalculateDeadlinePayload": { + "properties": { + "deadlineReceivedDate": { + "type": "string", + "title": "Deadlinereceiveddate" + }, + "deadlineRuleName": { + "type": "string", + "minLength": 1, + "title": "Deadlinerulename" + }, + "deadlineDayCount": { + "type": "string", + "title": "Deadlinedaycount" + }, + "deadlineDayType": { + "type": "string", + "title": "Deadlinedaytype" + }, + "deadlineBasis": { + "type": "string", + "minLength": 1, + "title": "Deadlinebasis" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "deadlineReceivedDate", + "deadlineRuleName", + "deadlineDayCount", + "deadlineDayType", + "deadlineBasis" + ], + "title": "CalculateDeadlinePayload" + }, + "ChapterCreate": { + "properties": { + "chapter_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Chapter Id" + }, + "title_id": { + "type": "string", + "minLength": 1, + "title": "Title Id" + }, + "chapter_number": { + "type": "string", + "minLength": 1, + "title": "Chapter Number" + }, + "chapter_name": { + "type": "string", + "minLength": 1, + "title": "Chapter Name" + }, + "sort_order": { + "type": "integer", + "title": "Sort Order", + "default": 0 + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title_id", + "chapter_number", + "chapter_name" + ], + "title": "ChapterCreate", + "description": "Request body for creating a code chapter." + }, + "CitedSection": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "citation": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Citation" + }, + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "version": { + "type": "string", + "maxLength": 80, + "title": "Version", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "citation" + ], + "title": "CitedSection", + "description": "One resolved public Code section; never a caller-supplied quotation." + }, + "CityProfileCreate": { + "properties": { + "city_name": { + "type": "string", + "title": "City Name" + }, + "state": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State" + }, + "county": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "County" + }, + "population_band": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Population Band" + }, + "email_platform": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Email Platform" + }, + "has_dedicated_it": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Has Dedicated It" + }, + "monthly_request_volume": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Monthly Request Volume" + }, + "profile_data": { + "additionalProperties": true, + "type": "object", + "title": "Profile Data", + "default": {} + }, + "gap_map": { + "additionalProperties": true, + "type": "object", + "title": "Gap Map", + "default": {} + } + }, + "type": "object", + "required": [ + "city_name" + ], + "title": "CityProfileCreate" + }, + "CityProfileRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "city_name": { + "type": "string", + "title": "City Name" + }, + "state": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State" + }, + "county": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "County" + }, + "population_band": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Population Band" + }, + "email_platform": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Email Platform" + }, + "has_dedicated_it": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Has Dedicated It" + }, + "monthly_request_volume": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Monthly Request Volume" + }, + "onboarding_status": { + "type": "string", + "title": "Onboarding Status" + }, + "profile_data": { + "additionalProperties": true, + "type": "object", + "title": "Profile Data" + }, + "gap_map": { + "additionalProperties": true, + "type": "object", + "title": "Gap Map" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "city_name", + "state", + "county", + "population_band", + "email_platform", + "has_dedicated_it", + "monthly_request_volume", + "onboarding_status", + "profile_data", + "gap_map", + "created_at", + "updated_at" + ], + "title": "CityProfileRead" + }, + "CityProfileUpdate": { + "properties": { + "city_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "City Name" + }, + "state": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State" + }, + "county": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "County" + }, + "population_band": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Population Band" + }, + "email_platform": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Email Platform" + }, + "has_dedicated_it": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Has Dedicated It" + }, + "monthly_request_volume": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Monthly Request Volume" + }, + "onboarding_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Onboarding Status" + }, + "profile_data": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Profile Data" + }, + "gap_map": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Gap Map" + } + }, + "type": "object", + "title": "CityProfileUpdate" + }, + "ClarificationCommand": { + "properties": { + "action": { + "type": "string", + "const": "request-records-clarification", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ClarificationPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "ClarificationCommand" + }, + "ClarificationPayload": { + "properties": { + "clarificationNote": { + "type": "string", + "minLength": 1, + "title": "Clarificationnote" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "clarificationNote" + ], + "title": "ClarificationPayload" + }, + "Closeout": { + "properties": { + "decision_id": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Decision Id" + }, + "version_id": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Version Id" + }, + "source_id": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Source Id" + }, + "version_label": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Version Label" + }, + "body": { + "type": "string", + "maxLength": 1000000, + "minLength": 1, + "title": "Body" + }, + "effective_start": { + "type": "string", + "format": "date", + "title": "Effective Start" + }, + "effective_end": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective End" + }, + "is_current": { + "type": "boolean", + "title": "Is Current" + }, + "reconciliation_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reconciliation Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "decision_id", + "version_id", + "source_id", + "version_label", + "body", + "effective_start", + "is_current" + ], + "title": "Closeout" + }, + "CodeContext": { + "properties": { + "section_number": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Section Number" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "section_number" + ], + "title": "CodeContext" + }, + "CodeLink": { + "properties": { + "provider": { + "type": "string", + "const": "code", + "title": "Provider", + "default": "code" + }, + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "CodeLink" + }, + "CodeSearch": { + "properties": { + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "CodeSearch" + }, + "CodeSourceSelection": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "CodeSourceSelection" + }, + "CompleteArtifact": { + "properties": { + "export_path": { + "type": "string", + "minLength": 1, + "title": "Export Path" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "export_path" + ], + "title": "CompleteArtifact" + }, + "ConnectionSearch": { + "properties": { + "provider": { + "type": "string", + "enum": [ + "meetings", + "zoning" + ], + "title": "Provider" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "query" + ], + "title": "ConnectionSearch" + }, + "CoverageGapResponse": { + "properties": { + "jurisdictions_without_rules": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Jurisdictions Without Rules" + }, + "departments_without_staff": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array", + "title": "Departments Without Staff" + }, + "uncovered_categories": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Uncovered Categories" + }, + "total_gaps": { + "type": "integer", + "title": "Total Gaps" + } + }, + "type": "object", + "required": [ + "jurisdictions_without_rules", + "departments_without_staff", + "uncovered_categories", + "total_gaps" + ], + "title": "CoverageGapResponse" + }, + "DataSourceAdminRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "source_type": { + "$ref": "#/components/schemas/SourceType" + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "type": "boolean", + "title": "Schedule Enabled", + "default": true + }, + "next_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Next Sync At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "last_ingestion_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Ingestion At" + }, + "last_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Sync At" + }, + "last_sync_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Sync Status" + }, + "last_error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Error Message" + }, + "consecutive_failure_count": { + "type": "integer", + "title": "Consecutive Failure Count", + "default": 0 + }, + "sync_paused": { + "type": "boolean", + "title": "Sync Paused", + "default": false + }, + "health_status": { + "type": "string", + "title": "Health Status", + "default": "healthy" + }, + "active_failure_count": { + "type": "integer", + "title": "Active Failure Count", + "default": 0 + }, + "connector_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Connector Type" + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At" + }, + "connection_config": { + "additionalProperties": true, + "type": "object", + "title": "Connection Config" + } + }, + "type": "object", + "required": [ + "id", + "name", + "source_type", + "is_active", + "created_by", + "created_at", + "last_ingestion_at", + "connection_config" + ], + "title": "DataSourceAdminRead", + "description": "Full datasource shape including connection_config. Returned only by admin-gated endpoints." + }, + "DataSourceCreate": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "source_type": { + "$ref": "#/components/schemas/SourceType" + }, + "connection_config": { + "additionalProperties": true, + "type": "object", + "title": "Connection Config", + "default": {} + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "type": "boolean", + "title": "Schedule Enabled", + "default": true + } + }, + "type": "object", + "required": [ + "name", + "source_type" + ], + "title": "DataSourceCreate" + }, + "DataSourceRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "source_type": { + "$ref": "#/components/schemas/SourceType" + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "type": "boolean", + "title": "Schedule Enabled", + "default": true + }, + "next_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Next Sync At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "last_ingestion_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Ingestion At" + }, + "last_sync_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Sync At" + }, + "last_sync_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Sync Status" + }, + "last_error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Error Message" + }, + "consecutive_failure_count": { + "type": "integer", + "title": "Consecutive Failure Count", + "default": 0 + }, + "sync_paused": { + "type": "boolean", + "title": "Sync Paused", + "default": false + }, + "health_status": { + "type": "string", + "title": "Health Status", + "default": "healthy" + }, + "active_failure_count": { + "type": "integer", + "title": "Active Failure Count", + "default": 0 + }, + "connector_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Connector Type" + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "name", + "source_type", + "is_active", + "created_by", + "created_at", + "last_ingestion_at" + ], + "title": "DataSourceRead", + "description": "Redacted datasource shape — safe for non-admin roles. connection_config omitted." + }, + "DataSourceUpdate": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "connection_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Connection Config" + }, + "sync_schedule": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Sync Schedule" + }, + "schedule_enabled": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Schedule Enabled" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "DataSourceUpdate" + }, + "DeadlineCommand": { + "properties": { + "action": { + "type": "string", + "const": "set-records-deadline", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/DeadlinePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "DeadlineCommand" + }, + "DeadlinePayload": { + "properties": { + "deadline": { + "type": "string", + "title": "Deadline" + }, + "deadlineBasis": { + "type": "string", + "minLength": 1, + "title": "Deadlinebasis" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "deadline", + "deadlineBasis" + ], + "title": "DeadlinePayload" + }, + "Decision": { + "properties": { + "id": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Id" + }, + "outcome": { + "type": "string", + "enum": [ + "adopted", + "not_adopted", + "deferred", + "withdrawn" + ], + "title": "Outcome" + }, + "decided_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Decided At" + }, + "decision_text": { + "type": "string", + "maxLength": 1000000, + "minLength": 1, + "title": "Decision Text" + }, + "supporting_references": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Supporting References" + }, + "supersedes_decision_id": { + "anyOf": [ + { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$" + }, + { + "type": "null" + } + ], + "title": "Supersedes Decision Id" + }, + "reconciliation_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reconciliation Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "outcome", + "decision_text" + ], + "title": "Decision" + }, + "DepartmentCreate": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "code": { + "type": "string", + "title": "Code" + }, + "contact_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Contact Email" + } + }, + "type": "object", + "required": [ + "name", + "code" + ], + "title": "DepartmentCreate" + }, + "DepartmentRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "code": { + "type": "string", + "title": "Code" + }, + "contact_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Contact Email" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "name", + "code", + "contact_email", + "created_at" + ], + "title": "DepartmentRead" + }, + "DepartmentUpdate": { + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, + "code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Code" + }, + "contact_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Contact Email" + } + }, + "type": "object", + "title": "DepartmentUpdate" + }, + "DisclosureTemplateCreate": { + "properties": { + "template_type": { + "type": "string", + "title": "Template Type" + }, + "state_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State Code" + }, + "content": { + "type": "string", + "title": "Content" + } + }, + "type": "object", + "required": [ + "template_type", + "content" + ], + "title": "DisclosureTemplateCreate" + }, + "DisclosureTemplateRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "template_type": { + "type": "string", + "title": "Template Type" + }, + "state_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State Code" + }, + "content": { + "type": "string", + "title": "Content" + }, + "version": { + "type": "integer", + "title": "Version" + }, + "updated_by": { + "type": "string", + "format": "uuid", + "title": "Updated By" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "template_type", + "state_code", + "content", + "version", + "updated_by", + "updated_at" + ], + "title": "DisclosureTemplateRead" + }, + "DisclosureTemplateRendered": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "template_type": { + "type": "string", + "title": "Template Type" + }, + "rendered_content": { + "type": "string", + "title": "Rendered Content" + }, + "has_unresolved_variables": { + "type": "boolean", + "title": "Has Unresolved Variables" + } + }, + "type": "object", + "required": [ + "id", + "template_type", + "rendered_content", + "has_unresolved_variables" + ], + "title": "DisclosureTemplateRendered" + }, + "DisclosureTemplateUpdate": { + "properties": { + "content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Content" + }, + "state_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "State Code" + } + }, + "type": "object", + "title": "DisclosureTemplateUpdate" + }, + "DocumentChunkRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "chunk_index": { + "type": "integer", + "title": "Chunk Index" + }, + "content_text": { + "type": "string", + "title": "Content Text" + }, + "token_count": { + "type": "integer", + "title": "Token Count" + }, + "page_number": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Page Number" + } + }, + "type": "object", + "required": [ + "id", + "document_id", + "chunk_index", + "content_text", + "token_count", + "page_number" + ], + "title": "DocumentChunkRead" + }, + "DocumentRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "source_id": { + "type": "string", + "format": "uuid", + "title": "Source Id" + }, + "source_path": { + "type": "string", + "title": "Source Path" + }, + "filename": { + "type": "string", + "title": "Filename" + }, + "file_type": { + "type": "string", + "title": "File Type" + }, + "file_hash": { + "type": "string", + "title": "File Hash" + }, + "file_size": { + "type": "integer", + "title": "File Size" + }, + "ingestion_status": { + "$ref": "#/components/schemas/IngestionStatus" + }, + "ingestion_error": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Ingestion Error" + }, + "chunk_count": { + "type": "integer", + "title": "Chunk Count" + }, + "ingested_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Ingested At" + }, + "connector_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Connector Type" + }, + "updated_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Updated At" + } + }, + "type": "object", + "required": [ + "id", + "source_id", + "source_path", + "filename", + "file_type", + "file_hash", + "file_size", + "ingestion_status", + "ingestion_error", + "chunk_count", + "ingested_at" + ], + "title": "DocumentRead" + }, + "DraftCommand": { + "properties": { + "action": { + "type": "string", + "const": "draft-records-response", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/DraftPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "DraftCommand" + }, + "DraftInput": { + "properties": { + "source_materials": { + "items": { + "$ref": "#/components/schemas/SourceInput" + }, + "type": "array", + "title": "Source Materials" + }, + "sentences": { + "items": { + "$ref": "#/components/schemas/SentenceInput" + }, + "type": "array", + "minItems": 1, + "title": "Sentences" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sentences" + ], + "title": "DraftInput" + }, + "DraftPayload": { + "properties": { + "responseDraft": { + "type": "string", + "minLength": 1, + "title": "Responsedraft" + }, + "citation": { + "type": "string", + "title": "Citation", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "responseDraft" + ], + "title": "DraftPayload" + }, + "ErrorModel": { + "properties": { + "detail": { + "anyOf": [ + { + "type": "string" + }, + { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + ], + "title": "Detail" + } + }, + "type": "object", + "required": [ + "detail" + ], + "title": "ErrorModel" + }, + "Evidence": { + "properties": { + "filename": { + "type": "string", + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$", + "title": "Filename" + }, + "description": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Description" + }, + "media_type": { + "type": "string", + "enum": [ + "text/plain", + "image/jpeg", + "image/png", + "image/webp", + "application/pdf", + "audio/webm", + "audio/ogg", + "audio/wav", + "audio/mpeg", + "audio/mp4" + ], + "title": "Media Type" + }, + "content_base64": { + "type": "string", + "maxLength": 14000000, + "minLength": 1, + "title": "Content Base64" + }, + "sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "filename", + "description", + "media_type", + "content_base64", + "sha256" + ], + "title": "Evidence" + }, + "EvidenceItem": { + "properties": { + "filename": { + "type": "string", + "maxLength": 151, + "minLength": 1, + "title": "Filename" + }, + "media_type": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Media Type" + }, + "description": { + "type": "string", + "maxLength": 2000, + "title": "Description", + "default": "" + }, + "content_base64": { + "type": "string", + "maxLength": 14000000, + "minLength": 1, + "title": "Content Base64" + }, + "sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "filename", + "media_type", + "content_base64", + "sha256" + ], + "title": "EvidenceItem" + }, + "EvidenceItems": { + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/EvidenceItem" + }, + "type": "array", + "maxItems": 10, + "minItems": 1, + "title": "Items" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "items" + ], + "title": "EvidenceItems" + }, + "ExemptionAccuracyReport": { + "properties": { + "category": { + "type": "string", + "title": "Category" + }, + "total_flags": { + "type": "integer", + "title": "Total Flags" + }, + "accepted": { + "type": "integer", + "title": "Accepted" + }, + "rejected": { + "type": "integer", + "title": "Rejected" + }, + "pending": { + "type": "integer", + "title": "Pending" + }, + "acceptance_rate": { + "type": "number", + "title": "Acceptance Rate" + } + }, + "type": "object", + "required": [ + "category", + "total_flags", + "accepted", + "rejected", + "pending", + "acceptance_rate" + ], + "title": "ExemptionAccuracyReport" + }, + "ExemptionDashboard": { + "properties": { + "total_flags": { + "type": "integer", + "title": "Total Flags" + }, + "by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "By Status" + }, + "by_category": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "By Category" + }, + "acceptance_rate": { + "type": "number", + "title": "Acceptance Rate" + }, + "total_rules": { + "type": "integer", + "title": "Total Rules" + }, + "active_rules": { + "type": "integer", + "title": "Active Rules" + } + }, + "type": "object", + "required": [ + "total_flags", + "by_status", + "by_category", + "acceptance_rate", + "total_rules", + "active_rules" + ], + "title": "ExemptionDashboard" + }, + "ExemptionDecisionCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-exemption-decision", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ExemptionDecisionPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "ExemptionDecisionCommand" + }, + "ExemptionDecisionPayload": { + "properties": { + "exemptionSource": { + "type": "string", + "minLength": 1, + "title": "Exemptionsource" + }, + "exemptionKind": { + "type": "string", + "minLength": 1, + "title": "Exemptionkind" + }, + "exemptionFinding": { + "type": "string", + "minLength": 1, + "title": "Exemptionfinding" + }, + "exemptionDecision": { + "type": "string", + "enum": [ + "release", + "redact", + "exempt" + ], + "title": "Exemptiondecision" + }, + "exemptionBasis": { + "type": "string", + "minLength": 1, + "title": "Exemptionbasis" + }, + "exemptionReviewer": { + "type": "string", + "title": "Exemptionreviewer", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "exemptionSource", + "exemptionKind", + "exemptionFinding", + "exemptionDecision", + "exemptionBasis" + ], + "title": "ExemptionDecisionPayload" + }, + "ExemptionDecisionView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "source": { + "type": "string", + "title": "Source" + }, + "kind": { + "type": "string", + "title": "Kind" + }, + "finding": { + "type": "string", + "title": "Finding" + }, + "decision": { + "type": "string", + "enum": [ + "release", + "redact", + "exempt" + ], + "title": "Decision" + }, + "basis": { + "type": "string", + "title": "Basis" + }, + "reviewer": { + "type": "string", + "title": "Reviewer" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "source", + "kind", + "finding", + "decision", + "basis", + "reviewer", + "created_at_unix_seconds" + ], + "title": "ExemptionDecisionView" + }, + "ExemptionFlagRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "chunk_id": { + "type": "string", + "format": "uuid", + "title": "Chunk Id" + }, + "rule_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Rule Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "category": { + "type": "string", + "title": "Category" + }, + "matched_text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Matched Text" + }, + "confidence": { + "type": "number", + "title": "Confidence" + }, + "status": { + "$ref": "#/components/schemas/FlagStatus" + }, + "reviewed_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Reviewed By" + }, + "reviewed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Reviewed At" + }, + "review_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Reason" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "chunk_id", + "rule_id", + "request_id", + "category", + "matched_text", + "confidence", + "status", + "reviewed_by", + "reviewed_at", + "review_reason", + "created_at" + ], + "title": "ExemptionFlagRead" + }, + "ExemptionFlagReview": { + "properties": { + "status": { + "$ref": "#/components/schemas/FlagStatus" + }, + "review_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Reason" + } + }, + "type": "object", + "required": [ + "status" + ], + "title": "ExemptionFlagReview" + }, + "ExemptionNoteCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-exemption-review", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/ExemptionNotePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "ExemptionNoteCommand" + }, + "ExemptionNotePayload": { + "properties": { + "exemptionNote": { + "type": "string", + "minLength": 1, + "title": "Exemptionnote" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "exemptionNote" + ], + "title": "ExemptionNotePayload" + }, + "ExemptionRuleCreate": { + "properties": { + "state_code": { + "type": "string", + "title": "State Code" + }, + "category": { + "type": "string", + "title": "Category" + }, + "rule_type": { + "$ref": "#/components/schemas/RuleType" + }, + "rule_definition": { + "type": "string", + "title": "Rule Definition" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "enabled": { + "type": "boolean", + "title": "Enabled", + "default": true + } + }, + "type": "object", + "required": [ + "state_code", + "category", + "rule_type", + "rule_definition" + ], + "title": "ExemptionRuleCreate" + }, + "ExemptionRuleRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "state_code": { + "type": "string", + "title": "State Code" + }, + "category": { + "type": "string", + "title": "Category" + }, + "rule_type": { + "$ref": "#/components/schemas/RuleType" + }, + "rule_definition": { + "type": "string", + "title": "Rule Definition" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "enabled": { + "type": "boolean", + "title": "Enabled" + }, + "version": { + "type": "integer", + "title": "Version", + "default": 1 + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "state_code", + "category", + "rule_type", + "rule_definition", + "description", + "enabled", + "created_by", + "created_at" + ], + "title": "ExemptionRuleRead" + }, + "ExemptionRuleUpdate": { + "properties": { + "rule_definition": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Rule Definition" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "enabled": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Enabled" + } + }, + "type": "object", + "title": "ExemptionRuleUpdate" + }, + "ExportReceipt": { + "properties": { + "export_path": { + "type": "string", + "maxLength": 32768, + "minLength": 1, + "title": "Export Path" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "export_path" + ], + "title": "ExportReceipt" + }, + "FeeEstimateCommand": { + "properties": { + "action": { + "type": "string", + "const": "estimate-records-fee", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/FeeEstimatePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "FeeEstimateCommand" + }, + "FeeEstimatePayload": { + "properties": { + "feeEstimate": { + "type": "string", + "minLength": 1, + "title": "Feeestimate" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "feeEstimate" + ], + "title": "FeeEstimatePayload" + }, + "FeeEstimateRequest": { + "properties": { + "page_count": { + "type": "integer", + "title": "Page Count" + }, + "fee_schedule_id": { + "type": "string", + "format": "uuid", + "title": "Fee Schedule Id" + } + }, + "type": "object", + "required": [ + "page_count", + "fee_schedule_id" + ], + "title": "FeeEstimateRequest" + }, + "FeeEstimateResponse": { + "properties": { + "page_count": { + "type": "integer", + "title": "Page Count" + }, + "unit_price": { + "type": "number", + "title": "Unit Price" + }, + "total": { + "type": "number", + "title": "Total" + }, + "fee_type": { + "type": "string", + "title": "Fee Type" + }, + "description": { + "type": "string", + "title": "Description" + } + }, + "type": "object", + "required": [ + "page_count", + "unit_price", + "total", + "fee_type", + "description" + ], + "title": "FeeEstimateResponse" + }, + "FeeLineCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-fee-line", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/FeeLinePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "FeeLineCommand" + }, + "FeeLineItemCreate": { + "properties": { + "description": { + "type": "string", + "title": "Description" + }, + "quantity": { + "type": "integer", + "title": "Quantity", + "default": 1 + }, + "unit_price": { + "type": "number", + "title": "Unit Price" + }, + "fee_schedule_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Fee Schedule Id" + } + }, + "type": "object", + "required": [ + "description", + "unit_price" + ], + "title": "FeeLineItemCreate" + }, + "FeeLineItemRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "fee_schedule_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Fee Schedule Id" + }, + "description": { + "type": "string", + "title": "Description" + }, + "quantity": { + "type": "integer", + "title": "Quantity" + }, + "unit_price": { + "type": "number", + "title": "Unit Price" + }, + "total": { + "type": "number", + "title": "Total" + }, + "status": { + "type": "string", + "title": "Status" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "fee_schedule_id", + "description", + "quantity", + "unit_price", + "total", + "status", + "created_at" + ], + "title": "FeeLineItemRead" + }, + "FeeLinePayload": { + "properties": { + "feeLineDescription": { + "type": "string", + "minLength": 1, + "title": "Feelinedescription" + }, + "feeScheduleBasis": { + "type": "string", + "minLength": 1, + "title": "Feeschedulebasis" + }, + "feeLineAmount": { + "type": "string", + "title": "Feelineamount" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "feeLineDescription", + "feeScheduleBasis", + "feeLineAmount" + ], + "title": "FeeLinePayload" + }, + "FeeLineView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "description": { + "type": "string", + "title": "Description" + }, + "schedule_basis": { + "type": "string", + "title": "Schedule Basis" + }, + "amount_cents": { + "type": "integer", + "title": "Amount Cents" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "description", + "schedule_basis", + "amount_cents", + "created_at_unix_seconds" + ], + "title": "FeeLineView" + }, + "FeeScheduleCreate": { + "properties": { + "jurisdiction": { + "type": "string", + "title": "Jurisdiction" + }, + "fee_type": { + "type": "string", + "title": "Fee Type" + }, + "amount": { + "type": "number", + "title": "Amount" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "effective_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective Date" + } + }, + "type": "object", + "required": [ + "jurisdiction", + "fee_type", + "amount" + ], + "title": "FeeScheduleCreate" + }, + "FeeScheduleRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "jurisdiction": { + "type": "string", + "title": "Jurisdiction" + }, + "fee_type": { + "type": "string", + "title": "Fee Type" + }, + "amount": { + "type": "number", + "title": "Amount" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "effective_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective Date" + }, + "created_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "jurisdiction", + "fee_type", + "amount", + "description", + "effective_date", + "created_by", + "created_at" + ], + "title": "FeeScheduleRead" + }, + "FeeScheduleUpdate": { + "properties": { + "fee_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Fee Type" + }, + "amount": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Amount" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "effective_date": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective Date" + } + }, + "type": "object", + "title": "FeeScheduleUpdate" + }, + "FeeWaiverCommand": { + "properties": { + "action": { + "type": "string", + "const": "waive-records-fee", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/FeeWaiverPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "FeeWaiverCommand" + }, + "FeeWaiverCreateRequest": { + "properties": { + "waiver_type": { + "type": "string", + "title": "Waiver Type" + }, + "reason": { + "type": "string", + "title": "Reason" + } + }, + "type": "object", + "required": [ + "waiver_type", + "reason" + ], + "title": "FeeWaiverCreateRequest" + }, + "FeeWaiverPayload": { + "properties": { + "feeWaiverReason": { + "type": "string", + "minLength": 1, + "title": "Feewaiverreason" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "feeWaiverReason" + ], + "title": "FeeWaiverPayload" + }, + "FeeWaiverReadResponse": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "waiver_type": { + "type": "string", + "title": "Waiver Type" + }, + "reason": { + "type": "string", + "title": "Reason" + }, + "status": { + "type": "string", + "title": "Status" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + }, + "created_at": { + "type": "string", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "waiver_type", + "reason", + "status", + "created_at" + ], + "title": "FeeWaiverReadResponse" + }, + "FeeWaiverReviewRequest": { + "properties": { + "status": { + "type": "string", + "title": "Status" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + } + }, + "type": "object", + "required": [ + "status" + ], + "title": "FeeWaiverReviewRequest" + }, + "FinishCommand": { + "properties": { + "action": { + "type": "string", + "enum": [ + "fulfill-records-request", + "close-records-request" + ], + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/NativePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "FinishCommand" + }, + "FlagStatus": { + "type": "string", + "enum": [ + "flagged", + "reviewed", + "accepted", + "rejected" + ], + "title": "FlagStatus" + }, + "FormPlan": { + "properties": { + "action": { + "type": "string", + "const": "form-plan", + "title": "Action" + }, + "formName": { + "type": "string", + "maxLength": 500, + "title": "Formname", + "default": "" + }, + "fields": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 50, + "title": "Fields" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "FormPlan" + }, + "GeneratedDraft": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "model": { + "type": "string", + "minLength": 1, + "title": "Model" + }, + "previous_response_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Previous Response Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text", + "model", + "previous_response_sha256" + ], + "title": "GeneratedDraft" + }, + "HTTPValidationError": { + "properties": { + "detail": { + "items": { + "$ref": "#/components/schemas/ValidationError" + }, + "type": "array", + "title": "Detail" + } + }, + "type": "object", + "title": "HTTPValidationError" + }, + "Handoff": { + "properties": { + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "request_id" + ], + "title": "Handoff" + }, + "ImportBundleCreate": { + "properties": { + "job_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Job Id" + }, + "connector_type": { + "type": "string", + "minLength": 1, + "title": "Connector Type" + }, + "source": { + "$ref": "#/components/schemas/SourceCreate" + }, + "sources": { + "items": { + "$ref": "#/components/schemas/SourceCreate" + }, + "type": "array", + "title": "Sources" + }, + "titles": { + "items": { + "$ref": "#/components/schemas/TitleCreate" + }, + "type": "array", + "title": "Titles" + }, + "chapters": { + "items": { + "$ref": "#/components/schemas/ChapterCreate" + }, + "type": "array", + "title": "Chapters" + }, + "sections": { + "items": { + "$ref": "#/components/schemas/SectionCreate" + }, + "type": "array", + "title": "Sections" + }, + "versions": { + "items": { + "$ref": "#/components/schemas/SectionVersionCreate" + }, + "type": "array", + "title": "Versions" + }, + "provenance": { + "additionalProperties": true, + "type": "object", + "title": "Provenance" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "connector_type", + "source" + ], + "title": "ImportBundleCreate", + "description": "Request body for local fixture/file-drop import jobs." + }, + "InclusionStatus": { + "type": "string", + "enum": [ + "included", + "excluded", + "pending" + ], + "title": "InclusionStatus" + }, + "IngestionStats": { + "properties": { + "total_sources": { + "type": "integer", + "title": "Total Sources" + }, + "active_sources": { + "type": "integer", + "title": "Active Sources" + }, + "total_documents": { + "type": "integer", + "title": "Total Documents" + }, + "documents_by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Documents By Status" + }, + "total_chunks": { + "type": "integer", + "title": "Total Chunks" + } + }, + "type": "object", + "required": [ + "total_sources", + "active_sources", + "total_documents", + "documents_by_status", + "total_chunks" + ], + "title": "IngestionStats" + }, + "IngestionStatus": { + "type": "string", + "enum": [ + "pending", + "processing", + "completed", + "failed" + ], + "title": "IngestionStatus" + }, + "InitiativeInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "policy": { + "$ref": "#/components/schemas/PolicySelection" + }, + "responsible_staff": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Responsible Staff" + }, + "target": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "title": "Target" + }, + "unit": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Unit" + }, + "due_on": { + "type": "string", + "format": "date", + "title": "Due On" + }, + "status": { + "type": "string", + "enum": [ + "planned", + "active", + "completed", + "cancelled" + ], + "title": "Status", + "default": "planned" + }, + "milestones": { + "items": { + "$ref": "#/components/schemas/Milestone" + }, + "type": "array", + "maxItems": 100, + "title": "Milestones" + }, + "measurements": { + "items": { + "$ref": "#/components/schemas/Measurement" + }, + "type": "array", + "maxItems": 1000, + "title": "Measurements" + }, + "note": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "policy", + "responsible_staff", + "target", + "unit", + "due_on", + "note" + ], + "title": "InitiativeInput" + }, + "InspectionInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "property_reference": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Property Reference" + }, + "inspection_reference": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Inspection Reference" + }, + "dataset_kind": { + "type": "string", + "enum": [ + "municipal", + "fictional" + ], + "title": "Dataset Kind" + }, + "inspector_notes": { + "type": "string", + "maxLength": 10000, + "minLength": 1, + "title": "Inspector Notes" + }, + "photo_observations": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 30, + "title": "Photo Observations" + }, + "voice_notes": { + "type": "string", + "maxLength": 10000, + "title": "Voice Notes", + "default": "" + }, + "evidence": { + "items": { + "$ref": "#/components/schemas/Evidence" + }, + "type": "array", + "maxItems": 10, + "title": "Evidence" + }, + "linked_sources": { + "items": { + "$ref": "#/components/schemas/townlight_inspections__workflow_models__SourceLink" + }, + "type": "array", + "maxItems": 30, + "title": "Linked Sources" + }, + "assigned_to": { + "type": "string", + "maxLength": 255, + "title": "Assigned To", + "default": "" + }, + "staff_notes": { + "type": "string", + "maxLength": 10000, + "title": "Staff Notes", + "default": "" + }, + "notice_draft": { + "type": "string", + "maxLength": 10000, + "title": "Notice Draft", + "default": "" + }, + "review_state": { + "type": "string", + "enum": [ + "draft", + "follow_up", + "reviewed" + ], + "title": "Review State", + "default": "draft" + }, + "review_notes": { + "type": "string", + "maxLength": 4000, + "title": "Review Notes", + "default": "" + }, + "public_summary": { + "type": "string", + "maxLength": 10000, + "title": "Public Summary", + "default": "" + }, + "analysis": { + "anyOf": [ + { + "$ref": "#/components/schemas/AnalysisRecord" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "property_reference", + "inspection_reference", + "dataset_kind", + "inspector_notes" + ], + "title": "InspectionInput" + }, + "IntakeInput": { + "properties": { + "expected_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + }, + "project_name": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Project Name" + }, + "project_description": { + "type": "string", + "maxLength": 10000, + "minLength": 1, + "title": "Project Description" + }, + "location": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Location" + }, + "applicant_contact": { + "type": "string", + "maxLength": 2000, + "title": "Applicant Contact", + "default": "" + }, + "requirement_revision": { + "type": "string", + "format": "uuid", + "title": "Requirement Revision" + }, + "materials": { + "items": { + "$ref": "#/components/schemas/MaterialReview" + }, + "type": "array", + "maxItems": 100, + "minItems": 1, + "title": "Materials" + }, + "linked_sources": { + "items": { + "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink" + }, + "type": "array", + "maxItems": 30, + "title": "Linked Sources" + }, + "staff_notes": { + "type": "string", + "maxLength": 10000, + "title": "Staff Notes", + "default": "" + }, + "assigned_to": { + "type": "string", + "maxLength": 255, + "title": "Assigned To", + "default": "" + }, + "review_state": { + "type": "string", + "enum": [ + "draft", + "follow_up", + "reviewed" + ], + "title": "Review State", + "default": "draft" + }, + "review_notes": { + "type": "string", + "maxLength": 4000, + "title": "Review Notes", + "default": "" + }, + "public_summary": { + "type": "string", + "maxLength": 10000, + "title": "Public Summary", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "project_name", + "project_description", + "location", + "requirement_revision", + "materials" + ], + "title": "IntakeInput" + }, + "InterpretationNoteCreate": { + "properties": { + "note_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Note Id" + }, + "note_text": { + "type": "string", + "minLength": 1, + "title": "Note Text" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "note_text" + ], + "title": "InterpretationNoteCreate", + "description": "Request body for staff-only interpretation notes." + }, + "InterviewRequest": { + "properties": { + "last_answer": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Answer" + }, + "last_field": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last Field" + }, + "skipped_fields": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Skipped Fields" + } + }, + "type": "object", + "title": "InterviewRequest" + }, + "InterviewResponse": { + "properties": { + "question": { + "type": "string", + "title": "Question" + }, + "target_field": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Target Field" + }, + "all_complete": { + "type": "boolean", + "title": "All Complete" + }, + "completed_fields": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Completed Fields" + }, + "onboarding_status": { + "type": "string", + "title": "Onboarding Status" + }, + "skipped_fields": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Skipped Fields" + } + }, + "type": "object", + "required": [ + "question", + "target_field", + "all_complete", + "completed_fields", + "onboarding_status", + "skipped_fields" + ], + "title": "InterviewResponse" + }, + "ManagedFileReceipt": { + "properties": { + "original_path": { + "type": "string", + "minLength": 1, + "title": "Original Path" + }, + "stored_path": { + "type": "string", + "minLength": 1, + "title": "Stored Path" + }, + "file_name": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "File Name" + }, + "sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Sha256" + }, + "size_bytes": { + "type": "integer", + "maximum": 2147483647.0, + "minimum": 0.0, + "title": "Size Bytes" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "original_path", + "stored_path", + "file_name", + "sha256", + "size_bytes" + ], + "title": "ManagedFileReceipt" + }, + "ManagedSource": { + "properties": { + "original_path": { + "type": "string", + "title": "Original Path" + }, + "stored_path": { + "type": "string", + "title": "Stored Path" + }, + "file_name": { + "type": "string", + "title": "File Name" + }, + "sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Sha256" + }, + "size_bytes": { + "type": "integer", + "minimum": 0.0, + "title": "Size Bytes" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "original_path", + "stored_path", + "file_name", + "sha256", + "size_bytes" + ], + "title": "ManagedSource" + }, + "Material": { + "properties": { + "material_id": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]{1,80}$", + "title": "Material Id" + }, + "description": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Description" + }, + "citation": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Citation" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "material_id", + "description", + "citation" + ], + "title": "Material" + }, + "MaterialReview": { + "properties": { + "material_id": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Material Id" + }, + "status": { + "type": "string", + "enum": [ + "not_reviewed", + "provided", + "missing", + "unclear" + ], + "title": "Status", + "default": "not_reviewed" + }, + "note": { + "type": "string", + "maxLength": 2000, + "title": "Note", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "material_id" + ], + "title": "MaterialReview" + }, + "Measurement": { + "properties": { + "recorded_on": { + "type": "string", + "format": "date", + "title": "Recorded On" + }, + "value": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + } + ], + "title": "Value" + }, + "evidence": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Evidence" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "recorded_on", + "value", + "evidence" + ], + "title": "Measurement" + }, + "MediaAnalysis": { + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/EvidenceItem" + }, + "type": "array", + "maxItems": 10, + "minItems": 1, + "title": "Items" + }, + "code_links": { + "items": { + "$ref": "#/components/schemas/CodeLink" + }, + "type": "array", + "maxItems": 30, + "title": "Code Links" + }, + "inspector_supplied_text": { + "type": "string", + "maxLength": 10000, + "title": "Inspector Supplied Text", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "items" + ], + "title": "MediaAnalysis" + }, + "MeetingInput": { + "properties": { + "title": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Title" + }, + "scheduled_start": { + "type": "string", + "format": "date-time", + "title": "Scheduled Start" + }, + "location": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Location" + }, + "meeting_type": { + "type": "string", + "enum": [ + "regular", + "special", + "emergency", + "closed_session", + "executive" + ], + "title": "Meeting Type", + "default": "regular" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "scheduled_start", + "location" + ], + "title": "MeetingInput" + }, + "MeetingLink": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + }, + "relation": { + "type": "string", + "enum": [ + "hearing", + "context", + "precedent" + ], + "title": "Relation" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256", + "relation" + ], + "title": "MeetingLink" + }, + "MeetingSearch": { + "properties": { + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "MeetingSearch" + }, + "MeetingStageInput": { + "properties": { + "to_status": { + "type": "string", + "enum": [ + "SCHEDULED", + "NOTICED", + "PACKET_POSTED", + "IN_PROGRESS", + "RECESSED", + "ADJOURNED", + "TRANSCRIPT_READY", + "MINUTES_DRAFTED", + "MINUTES_POSTED", + "MINUTES_ADOPTED", + "MINUTES_SIGNED", + "ARCHIVED", + "CANCELLED" + ], + "title": "To Status" + }, + "statutory_basis": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Statutory Basis" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "to_status" + ], + "title": "MeetingStageInput" + }, + "MeetingsSearch": { + "properties": { + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "MeetingsSearch" + }, + "MeetingsSourceSelection": { + "properties": { + "source_id": { + "type": "string", + "maxLength": 200, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "MeetingsSourceSelection" + }, + "MessageCommand": { + "properties": { + "action": { + "type": "string", + "const": "add-records-message", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/MessagePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "MessageCommand" + }, + "MessageCreate": { + "properties": { + "message_text": { + "type": "string", + "title": "Message Text" + }, + "is_internal": { + "type": "boolean", + "title": "Is Internal", + "default": false + } + }, + "type": "object", + "required": [ + "message_text" + ], + "title": "MessageCreate" + }, + "MessagePayload": { + "properties": { + "requestMessageBody": { + "type": "string", + "minLength": 1, + "title": "Requestmessagebody" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requestMessageBody" + ], + "title": "MessagePayload" + }, + "MessageRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "sender_type": { + "type": "string", + "title": "Sender Type" + }, + "sender_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Sender Id" + }, + "message_text": { + "type": "string", + "title": "Message Text" + }, + "is_internal": { + "type": "boolean", + "title": "Is Internal" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "sender_type", + "sender_id", + "message_text", + "is_internal", + "created_at" + ], + "title": "MessageRead" + }, + "MessageView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "author": { + "type": "string", + "title": "Author" + }, + "author_role": { + "type": "string", + "title": "Author Role" + }, + "body": { + "type": "string", + "title": "Body" + }, + "visibility": { + "type": "string", + "title": "Visibility" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "author", + "author_role", + "body", + "visibility", + "created_at_unix_seconds" + ], + "title": "MessageView" + }, + "Milestone": { + "properties": { + "title": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Title" + }, + "due_on": { + "type": "string", + "format": "date", + "title": "Due On" + }, + "completed_on": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Completed On" + }, + "evidence": { + "type": "string", + "maxLength": 2000, + "title": "Evidence", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "due_on" + ], + "title": "Milestone" + }, + "MinutesDecision": { + "properties": { + "action": { + "type": "string", + "enum": [ + "post", + "adopt", + "sign" + ], + "title": "Action" + }, + "note": { + "type": "string", + "title": "Note", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "MinutesDecision" + }, + "ModelRegistryCreate": { + "properties": { + "model_name": { + "type": "string", + "title": "Model Name" + }, + "model_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Version" + }, + "parameter_count": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parameter Count" + }, + "license": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License" + }, + "model_card_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Card Url" + }, + "is_active": { + "type": "boolean", + "title": "Is Active", + "default": false + }, + "context_window_size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Context Window Size" + }, + "supports_ner": { + "type": "boolean", + "title": "Supports Ner", + "default": false + }, + "supports_vision": { + "type": "boolean", + "title": "Supports Vision", + "default": false + } + }, + "type": "object", + "required": [ + "model_name" + ], + "title": "ModelRegistryCreate", + "description": "Schema for creating a new model_registry record (POST body)." + }, + "ModelRegistryRead": { + "properties": { + "id": { + "type": "integer", + "title": "Id" + }, + "model_name": { + "type": "string", + "title": "Model Name" + }, + "model_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Version" + }, + "parameter_count": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parameter Count" + }, + "license": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License" + }, + "model_card_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Card Url" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "added_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Added At" + }, + "context_window_size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Context Window Size" + }, + "supports_ner": { + "type": "boolean", + "title": "Supports Ner" + }, + "supports_vision": { + "type": "boolean", + "title": "Supports Vision" + } + }, + "type": "object", + "required": [ + "id", + "model_name", + "is_active", + "supports_ner", + "supports_vision" + ], + "title": "ModelRegistryRead", + "description": "Schema for returning a model_registry record (GET response).\n\n``from_attributes=True`` allows construction directly from an ORM instance." + }, + "ModelRegistryUpdate": { + "properties": { + "model_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Name" + }, + "model_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Version" + }, + "parameter_count": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parameter Count" + }, + "license": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "License" + }, + "model_card_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Model Card Url" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + }, + "context_window_size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Context Window Size" + }, + "supports_ner": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Supports Ner" + }, + "supports_vision": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Supports Vision" + } + }, + "type": "object", + "title": "ModelRegistryUpdate", + "description": "Schema for partially updating a model_registry record (PATCH body).\n\nEvery field is optional so callers can send only the fields they want to\nchange." + }, + "MotionCorrection": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "reason": { + "type": "string", + "minLength": 1, + "title": "Reason" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text", + "reason" + ], + "title": "MotionCorrection" + }, + "MotionInput": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "seconded_by": { + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "type": "null" + } + ], + "title": "Seconded By" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text" + ], + "title": "MotionInput" + }, + "NativePayload": { + "properties": {}, + "additionalProperties": false, + "type": "object", + "title": "NativePayload" + }, + "NativeRequestRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "requester_name": { + "type": "string", + "title": "Requester Name" + }, + "requester_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Email" + }, + "requester_phone": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Phone" + }, + "requester_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Type" + }, + "date_received": { + "type": "string", + "format": "date-time", + "title": "Date Received" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "description": { + "type": "string", + "title": "Description" + }, + "status": { + "$ref": "#/components/schemas/RequestStatus" + }, + "assigned_to": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "created_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "response_draft": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Response Draft" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + }, + "estimated_fee": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Estimated Fee" + }, + "fee_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Fee Status" + }, + "fee_waiver_requested": { + "type": "boolean", + "title": "Fee Waiver Requested", + "default": false + }, + "priority": { + "type": "string", + "title": "Priority", + "default": "normal" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + }, + "closed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Closed At" + }, + "closure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Closure Reason" + }, + "desktop_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Desktop Id" + }, + "public_tracking_number": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Public Tracking Number" + }, + "submitted_via": { + "type": "string", + "title": "Submitted Via" + }, + "deadline_label": { + "type": "string", + "title": "Deadline Label" + }, + "deadline_basis": { + "type": "string", + "title": "Deadline Basis" + }, + "deadline_reviewed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Deadline Reviewed At" + } + }, + "type": "object", + "required": [ + "id", + "requester_name", + "requester_email", + "date_received", + "statutory_deadline", + "description", + "status", + "assigned_to", + "created_by", + "created_at", + "response_draft", + "review_notes", + "desktop_id", + "public_tracking_number", + "submitted_via", + "deadline_label", + "deadline_basis", + "deadline_reviewed_at" + ], + "title": "NativeRequestRead" + }, + "NoticeDocumentInput": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text" + ], + "title": "NoticeDocumentInput" + }, + "NoticeDraft": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "body": { + "type": "string", + "maxLength": 100000, + "minLength": 1, + "title": "Body" + }, + "notice_type": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Notice Type" + }, + "statutory_basis": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Statutory Basis" + }, + "event_date": { + "type": "string", + "format": "date", + "title": "Event Date" + }, + "lead_days": { + "type": "integer", + "maximum": 365.0, + "minimum": 0.0, + "title": "Lead Days" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "body", + "notice_type", + "statutory_basis", + "event_date", + "lead_days" + ], + "title": "NoticeDraft" + }, + "NoticeInput": { + "properties": { + "notice_type": { + "type": "string", + "enum": [ + "regular", + "special", + "emergency", + "closed_session", + "executive" + ], + "title": "Notice Type" + }, + "posted_at": { + "type": "string", + "format": "date-time", + "title": "Posted At" + }, + "minimum_notice_hours": { + "type": "integer", + "minimum": 0.0, + "title": "Minimum Notice Hours" + }, + "statutory_basis": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Statutory Basis" + }, + "approved_by": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Approved By" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "notice_type", + "posted_at", + "minimum_notice_hours" + ], + "title": "NoticeInput" + }, + "NoticeProofInput": { + "properties": { + "location": { + "type": "string", + "minLength": 1, + "title": "Location" + }, + "note": { + "type": "string", + "title": "Note", + "default": "" + }, + "document_delivery_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Document Delivery Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "location" + ], + "title": "NoticeProofInput" + }, + "NotificationLogRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "template_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Template Id" + }, + "recipient_email": { + "type": "string", + "title": "Recipient Email" + }, + "request_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Request Id" + }, + "channel": { + "type": "string", + "title": "Channel" + }, + "status": { + "type": "string", + "title": "Status" + }, + "sent_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Sent At" + }, + "error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Message" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "template_id", + "recipient_email", + "request_id", + "channel", + "status", + "sent_at", + "error_message", + "created_at" + ], + "title": "NotificationLogRead" + }, + "NotificationTemplateCreate": { + "properties": { + "event_type": { + "type": "string", + "title": "Event Type" + }, + "channel": { + "type": "string", + "title": "Channel", + "default": "email" + }, + "subject_template": { + "type": "string", + "title": "Subject Template" + }, + "body_template": { + "type": "string", + "title": "Body Template" + } + }, + "type": "object", + "required": [ + "event_type", + "subject_template", + "body_template" + ], + "title": "NotificationTemplateCreate" + }, + "NotificationTemplateRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "event_type": { + "type": "string", + "title": "Event Type" + }, + "channel": { + "type": "string", + "title": "Channel" + }, + "subject_template": { + "type": "string", + "title": "Subject Template" + }, + "body_template": { + "type": "string", + "title": "Body Template" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "event_type", + "channel", + "subject_template", + "body_template", + "is_active", + "created_at" + ], + "title": "NotificationTemplateRead" + }, + "NotificationTemplateUpdate": { + "properties": { + "subject_template": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Subject Template" + }, + "body_template": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Body Template" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "NotificationTemplateUpdate" + }, + "NotificationView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "notification_id": { + "type": "string", + "title": "Notification Id" + }, + "module_id": { + "type": "string", + "title": "Module Id" + }, + "record_id": { + "type": "string", + "title": "Record Id" + }, + "audience": { + "type": "string", + "title": "Audience" + }, + "channel": { + "type": "string", + "title": "Channel" + }, + "subject": { + "type": "string", + "title": "Subject" + }, + "body": { + "type": "string", + "title": "Body" + }, + "status": { + "type": "string", + "title": "Status" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + }, + "sent_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Sent At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "notification_id", + "module_id", + "record_id", + "audience", + "channel", + "subject", + "body", + "status", + "created_at_unix_seconds", + "sent_at_unix_seconds" + ], + "title": "NotificationView" + }, + "OllamaModelInfo": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "size": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Size" + }, + "details": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Details" + } + }, + "type": "object", + "required": [ + "name" + ], + "title": "OllamaModelInfo" + }, + "OllamaStatus": { + "properties": { + "status": { + "type": "string", + "title": "Status" + }, + "models": { + "items": { + "$ref": "#/components/schemas/OllamaModelInfo" + }, + "type": "array", + "title": "Models" + } + }, + "type": "object", + "required": [ + "status", + "models" + ], + "title": "OllamaStatus" + }, + "OperationalMetrics": { + "properties": { + "average_response_time_days": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Average Response Time Days" + }, + "median_response_time_days": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Median Response Time Days" + }, + "requests_by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Requests By Status" + }, + "requests_by_department": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "Requests By Department" + }, + "deadline_compliance_rate": { + "type": "number", + "title": "Deadline Compliance Rate" + }, + "total_open": { + "type": "integer", + "title": "Total Open" + }, + "total_closed": { + "type": "integer", + "title": "Total Closed" + }, + "total_overdue": { + "type": "integer", + "title": "Total Overdue" + }, + "clarification_frequency": { + "type": "number", + "title": "Clarification Frequency" + }, + "top_request_topics": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Top Request Topics" + } + }, + "type": "object", + "required": [ + "average_response_time_days", + "median_response_time_days", + "requests_by_status", + "requests_by_department", + "deadline_compliance_rate", + "total_open", + "total_closed", + "total_overdue", + "clarification_frequency", + "top_request_topics" + ], + "title": "OperationalMetrics" + }, + "Outline": { + "properties": { + "title": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Title" + }, + "question_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "maxItems": 50, + "minItems": 1, + "title": "Question Ids" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title", + "question_ids" + ], + "title": "Outline" + }, + "Packet": { + "properties": { + "expected_revision": { + "type": "string", + "format": "uuid", + "title": "Expected Revision" + }, + "visibility": { + "type": "string", + "enum": [ + "staff_only", + "records_copy" + ], + "title": "Visibility" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "expected_revision", + "visibility" + ], + "title": "Packet" + }, + "PacketInput": { + "properties": { + "agenda_item_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "title": "Agenda Item Ids" + }, + "source_files": { + "items": { + "$ref": "#/components/schemas/ManagedSource" + }, + "type": "array", + "title": "Source Files" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "agenda_item_ids" + ], + "title": "PacketInput" + }, + "Pathway": { + "properties": { + "project_type": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Project Type" + }, + "proposal": { + "type": "string", + "maxLength": 4000, + "title": "Proposal", + "default": "" + }, + "location_context": { + "type": "string", + "maxLength": 1000, + "title": "Location Context", + "default": "" + }, + "requirement_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Requirement Revision" + }, + "fee_link": { + "anyOf": [ + { + "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "project_type" + ], + "title": "Pathway" + }, + "PathwayStep": { + "properties": { + "step": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Step" + }, + "citation": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Citation" + }, + "typical_time": { + "type": "string", + "maxLength": 1000, + "title": "Typical Time", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "step", + "citation" + ], + "title": "PathwayStep" + }, + "PlainLanguageSummaryCreate": { + "properties": { + "summary_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Summary Id" + }, + "section_version_id": { + "type": "string", + "minLength": 1, + "title": "Section Version Id" + }, + "summary_text": { + "type": "string", + "minLength": 1, + "title": "Summary Text" + }, + "language_code": { + "type": "string", + "title": "Language Code", + "default": "en" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "section_version_id", + "summary_text" + ], + "title": "PlainLanguageSummaryCreate", + "description": "Request body for staff-drafted plain-language summaries." + }, + "PolicySelection": { + "properties": { + "plan_id": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Plan Id" + }, + "revision_id": { + "type": "string", + "maxLength": 36, + "minLength": 36, + "title": "Revision Id" + }, + "policy_id": { + "type": "string", + "maxLength": 160, + "minLength": 1, + "title": "Policy Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "plan_id", + "revision_id", + "policy_id" + ], + "title": "PolicySelection" + }, + "PortalModeResponse": { + "properties": { + "mode": { + "type": "string", + "enum": [ + "public", + "private" + ], + "title": "Mode", + "description": "Active portal posture for this deployment. ``public`` = minimal resident surface (landing + authenticated records-request submission + resident registration) reachable without staff auth. ``private`` = staff-only; no public routes, no resident self-registration." + } + }, + "type": "object", + "required": [ + "mode" + ], + "title": "PortalModeResponse", + "description": "T5D — schema for ``GET /config/portal-mode``.\n\nExposed to the frontend on boot so it can branch routing without a\nuser-identity lookup. The payload is intentionally the single field\nbelow — no staff config, no user state, no schema version." + }, + "PrepareArtifact": { + "properties": { + "kind": { + "type": "string", + "enum": [ + "response", + "release-package" + ], + "title": "Kind" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "kind" + ], + "title": "PrepareArtifact" + }, + "Proof": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + }, + "filename": { + "type": "string", + "maxLength": 150, + "minLength": 1, + "title": "Filename" + }, + "content_base64": { + "type": "string", + "maxLength": 7000000, + "minLength": 1, + "title": "Content Base64" + }, + "location": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Location" + }, + "published_at": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Published At" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence", + "filename", + "content_base64", + "location", + "published_at" + ], + "title": "Proof" + }, + "Proposal": { + "properties": { + "id": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$", + "title": "Id" + }, + "version_id": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Version Id" + }, + "meeting_id": { + "type": "string", + "format": "uuid", + "title": "Meeting Id" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "ordinance_number": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Ordinance Number" + }, + "proposed_text": { + "type": "string", + "maxLength": 1000000, + "minLength": 1, + "title": "Proposed Text" + }, + "supersedes_id": { + "anyOf": [ + { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,64}$" + }, + { + "type": "null" + } + ], + "title": "Supersedes Id" + }, + "reconciliation_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reconciliation Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "version_id", + "meeting_id", + "title", + "ordinance_number", + "proposed_text" + ], + "title": "Proposal" + }, + "PublicExplore": { + "properties": { + "goal": { + "type": "string", + "maxLength": 500, + "title": "Goal", + "default": "" + }, + "topic": { + "type": "string", + "maxLength": 160, + "title": "Topic", + "default": "" + }, + "neighborhood": { + "type": "string", + "maxLength": 255, + "title": "Neighborhood", + "default": "" + }, + "plan_type": { + "type": "string", + "maxLength": 120, + "title": "Plan Type", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "title": "PublicExplore" + }, + "PublicIntake": { + "properties": { + "requester": { + "type": "string", + "minLength": 1, + "title": "Requester" + }, + "requesterContact": { + "type": "string", + "minLength": 1, + "title": "Requestercontact" + }, + "summary": { + "type": "string", + "minLength": 1, + "title": "Summary" + }, + "deadline": { + "type": "string", + "title": "Deadline", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requester", + "requesterContact", + "summary" + ], + "title": "PublicIntake" + }, + "PublicLookup": { + "properties": { + "trackingNumber": { + "type": "string", + "minLength": 1, + "title": "Trackingnumber" + }, + "requesterContact": { + "type": "string", + "minLength": 1, + "title": "Requestercontact" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "trackingNumber", + "requesterContact" + ], + "title": "PublicLookup" + }, + "PublicMessage": { + "properties": { + "trackingNumber": { + "type": "string", + "minLength": 1, + "title": "Trackingnumber" + }, + "requesterContact": { + "type": "string", + "minLength": 1, + "title": "Requestercontact" + }, + "publicRequestMessage": { + "type": "string", + "minLength": 1, + "title": "Publicrequestmessage" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "trackingNumber", + "requesterContact", + "publicRequestMessage" + ], + "title": "PublicMessage" + }, + "PublicStatusView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "label": { + "type": "string", + "title": "Label" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "status": { + "type": "string", + "title": "Status" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "label", + "summary", + "status", + "created_at_unix_seconds" + ], + "title": "PublicStatusView" + }, + "PublicationView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "source_module": { + "type": "string", + "title": "Source Module" + }, + "source_record_id": { + "type": "string", + "title": "Source Record Id" + }, + "record_type": { + "type": "string", + "title": "Record Type" + }, + "public_payload": { + "type": "string", + "title": "Public Payload" + }, + "payload_hash": { + "type": "string", + "title": "Payload Hash" + }, + "published_at_unix_seconds": { + "type": "integer", + "title": "Published At Unix Seconds" + }, + "retracted_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Retracted At Unix Seconds" + }, + "retracted_by": { + "type": "string", + "title": "Retracted By", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "source_module", + "source_record_id", + "record_type", + "public_payload", + "payload_hash", + "published_at_unix_seconds" + ], + "title": "PublicationView" + }, + "PublishingPlan": { + "properties": { + "action": { + "type": "string", + "const": "publishing-workflow", + "title": "Action" + }, + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "hasReview": { + "type": "boolean", + "title": "Hasreview", + "default": false + }, + "hasPlainLanguage": { + "type": "boolean", + "title": "Hasplainlanguage", + "default": false + }, + "hasTranslationReview": { + "type": "boolean", + "title": "Hastranslationreview", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "PublishingPlan" + }, + "Question": { + "properties": { + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + }, + "question": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Question" + }, + "kind": { + "type": "string", + "enum": [ + "use", + "dimension" + ], + "title": "Kind" + }, + "key": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Key" + }, + "audience": { + "type": "string", + "enum": [ + "resident", + "staff" + ], + "title": "Audience", + "default": "resident" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "jurisdiction", + "query", + "question", + "kind", + "key" + ], + "title": "Question" + }, + "QuestionAnswerRequest": { + "properties": { + "question": { + "type": "string", + "minLength": 1, + "title": "Question" + }, + "section_number": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Section Number" + }, + "as_of": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "As Of" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "question" + ], + "title": "QuestionAnswerRequest", + "description": "Request body for citation-grounded code Q&A." + }, + "RecordsDocumentView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "attachment_id": { + "type": "string", + "title": "Attachment Id" + }, + "title": { + "type": "string", + "title": "Title" + }, + "original_path": { + "type": "string", + "title": "Original Path" + }, + "stored_path": { + "type": "string", + "title": "Stored Path" + }, + "citation": { + "type": "string", + "title": "Citation" + }, + "sha256": { + "type": "string", + "title": "Sha256" + }, + "size_bytes": { + "type": "integer", + "title": "Size Bytes" + }, + "status": { + "type": "string", + "title": "Status" + }, + "added_by": { + "type": "string", + "title": "Added By" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + }, + "release_original_path": { + "type": "string", + "title": "Release Original Path", + "default": "" + }, + "release_stored_path": { + "type": "string", + "title": "Release Stored Path", + "default": "" + }, + "release_file_name": { + "type": "string", + "title": "Release File Name", + "default": "" + }, + "release_sha256": { + "type": "string", + "title": "Release Sha256", + "default": "" + }, + "release_size_bytes": { + "type": "integer", + "title": "Release Size Bytes", + "default": 0 + }, + "release_status": { + "type": "string", + "title": "Release Status", + "default": "" + }, + "release_note": { + "type": "string", + "title": "Release Note", + "default": "" + }, + "release_added_by": { + "type": "string", + "title": "Release Added By", + "default": "" + }, + "release_added_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Release Added At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "attachment_id", + "title", + "original_path", + "stored_path", + "citation", + "sha256", + "size_bytes", + "status", + "added_by", + "created_at_unix_seconds" + ], + "title": "RecordsDocumentView" + }, + "RecordsOperationRead": { + "properties": { + "action": { + "type": "string", + "title": "Action" + }, + "message": { + "type": "string", + "title": "Message" + }, + "request": { + "$ref": "#/components/schemas/RecordsView" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "message", + "request" + ], + "title": "RecordsOperationRead" + }, + "RecordsStateRead": { + "properties": { + "demo_fixture": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Demo Fixture" + }, + "records_requests": { + "items": { + "$ref": "#/components/schemas/RecordsView" + }, + "type": "array", + "title": "Records Requests" + }, + "notification_events": { + "items": { + "$ref": "#/components/schemas/NotificationView" + }, + "type": "array", + "title": "Notification Events" + }, + "publication_events": { + "items": { + "$ref": "#/components/schemas/PublicationView" + }, + "type": "array", + "title": "Publication Events" + }, + "audit_entries": { + "items": { + "$ref": "#/components/schemas/AuditView" + }, + "type": "array", + "title": "Audit Entries" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "records_requests" + ], + "title": "RecordsStateRead" + }, + "RecordsView": { + "properties": { + "request_id": { + "type": "string", + "title": "Request Id" + }, + "id": { + "type": "string", + "title": "Id" + }, + "public_tracking_number": { + "type": "string", + "title": "Public Tracking Number" + }, + "requester": { + "type": "string", + "title": "Requester" + }, + "requester_contact": { + "type": "string", + "title": "Requester Contact" + }, + "submitted_via": { + "type": "string", + "title": "Submitted Via" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "deadline": { + "type": "string", + "title": "Deadline" + }, + "deadline_basis": { + "type": "string", + "title": "Deadline Basis" + }, + "status": { + "type": "string", + "title": "Status" + }, + "assigned_to": { + "type": "string", + "title": "Assigned To" + }, + "clarification_notes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Clarification Notes" + }, + "search_notes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Search Notes" + }, + "search_sessions": { + "items": { + "$ref": "#/components/schemas/SearchReceiptView" + }, + "type": "array", + "title": "Search Sessions" + }, + "exemption_reviews": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Exemption Reviews" + }, + "exemption_decisions": { + "items": { + "$ref": "#/components/schemas/ExemptionDecisionView" + }, + "type": "array", + "title": "Exemption Decisions" + }, + "fee_estimate": { + "type": "string", + "title": "Fee Estimate" + }, + "fee_line_items": { + "items": { + "$ref": "#/components/schemas/FeeLineView" + }, + "type": "array", + "title": "Fee Line Items" + }, + "fee_waiver_reason": { + "type": "string", + "title": "Fee Waiver Reason" + }, + "citations": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Citations" + }, + "response_draft": { + "type": "string", + "title": "Response Draft" + }, + "approval_notes": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Approval Notes" + }, + "exports": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Exports" + }, + "documents": { + "items": { + "$ref": "#/components/schemas/RecordsDocumentView" + }, + "type": "array", + "title": "Documents" + }, + "release_packages": { + "items": { + "$ref": "#/components/schemas/ReleasePackageView" + }, + "type": "array", + "title": "Release Packages" + }, + "timeline": { + "items": { + "$ref": "#/components/schemas/TimelineView" + }, + "type": "array", + "title": "Timeline" + }, + "public_status_events": { + "items": { + "$ref": "#/components/schemas/PublicStatusView" + }, + "type": "array", + "title": "Public Status Events" + }, + "messages": { + "items": { + "$ref": "#/components/schemas/MessageView" + }, + "type": "array", + "title": "Messages" + }, + "deadline_reviewed_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Deadline Reviewed At Unix Seconds" + }, + "approved_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Approved At Unix Seconds" + }, + "fulfilled_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Fulfilled At Unix Seconds" + }, + "closed_at_unix_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Closed At Unix Seconds" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "request_id", + "id", + "public_tracking_number", + "requester", + "requester_contact", + "submitted_via", + "summary", + "deadline", + "deadline_basis", + "status", + "assigned_to", + "clarification_notes", + "search_notes", + "search_sessions", + "exemption_reviews", + "exemption_decisions", + "fee_estimate", + "fee_line_items", + "fee_waiver_reason", + "citations", + "response_draft", + "approval_notes", + "exports", + "timeline", + "public_status_events", + "messages", + "deadline_reviewed_at_unix_seconds", + "approved_at_unix_seconds", + "fulfilled_at_unix_seconds", + "closed_at_unix_seconds", + "created_at_unix_seconds" + ], + "title": "RecordsView" + }, + "ReleasePackageView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "export_path": { + "type": "string", + "title": "Export Path" + }, + "package_hash": { + "type": "string", + "title": "Package Hash" + }, + "document_count": { + "type": "integer", + "title": "Document Count" + }, + "release_artifact_count": { + "type": "integer", + "title": "Release Artifact Count" + }, + "search_session_count": { + "type": "integer", + "title": "Search Session Count" + }, + "release_count": { + "type": "integer", + "title": "Release Count" + }, + "redacted_count": { + "type": "integer", + "title": "Redacted Count" + }, + "exempt_count": { + "type": "integer", + "title": "Exempt Count" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "export_path", + "package_hash", + "document_count", + "release_artifact_count", + "search_session_count", + "release_count", + "redacted_count", + "exempt_count", + "created_at_unix_seconds" + ], + "title": "ReleasePackageView" + }, + "RepeatLookup": { + "properties": { + "property_reference": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Property Reference" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "property_reference" + ], + "title": "RepeatLookup" + }, + "RequestCreate": { + "properties": { + "requester_name": { + "type": "string", + "maxLength": 255, + "title": "Requester Name" + }, + "requester_email": { + "anyOf": [ + { + "type": "string", + "maxLength": 255 + }, + { + "type": "null" + } + ], + "title": "Requester Email" + }, + "requester_phone": { + "anyOf": [ + { + "type": "string", + "maxLength": 50 + }, + { + "type": "null" + } + ], + "title": "Requester Phone" + }, + "requester_type": { + "anyOf": [ + { + "type": "string", + "maxLength": 100 + }, + { + "type": "null" + } + ], + "title": "Requester Type" + }, + "description": { + "type": "string", + "maxLength": 10000, + "title": "Description" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "priority": { + "type": "string", + "title": "Priority", + "default": "normal" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string", + "pattern": "^(narrow|moderate|broad)$" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + } + }, + "type": "object", + "required": [ + "requester_name", + "description" + ], + "title": "RequestCreate" + }, + "RequestDocumentAdd": { + "properties": { + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "relevance_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Relevance Note" + } + }, + "type": "object", + "required": [ + "document_id" + ], + "title": "RequestDocumentAdd" + }, + "RequestDocumentRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "relevance_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Relevance Note" + }, + "exemption_flags": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Exemption Flags" + }, + "inclusion_status": { + "$ref": "#/components/schemas/InclusionStatus" + }, + "attached_at": { + "type": "string", + "format": "date-time", + "title": "Attached At" + }, + "attached_by": { + "type": "string", + "format": "uuid", + "title": "Attached By" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "document_id", + "relevance_note", + "exemption_flags", + "inclusion_status", + "attached_at", + "attached_by" + ], + "title": "RequestDocumentRead" + }, + "RequestRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "requester_name": { + "type": "string", + "title": "Requester Name" + }, + "requester_email": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Email" + }, + "requester_phone": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Phone" + }, + "requester_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requester Type" + }, + "date_received": { + "type": "string", + "format": "date-time", + "title": "Date Received" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "description": { + "type": "string", + "title": "Description" + }, + "status": { + "$ref": "#/components/schemas/RequestStatus" + }, + "assigned_to": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "created_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "response_draft": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Response Draft" + }, + "review_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Review Notes" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + }, + "estimated_fee": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "title": "Estimated Fee" + }, + "fee_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Fee Status" + }, + "fee_waiver_requested": { + "type": "boolean", + "title": "Fee Waiver Requested", + "default": false + }, + "priority": { + "type": "string", + "title": "Priority", + "default": "normal" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + }, + "closed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Closed At" + }, + "closure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Closure Reason" + } + }, + "type": "object", + "required": [ + "id", + "requester_name", + "requester_email", + "date_received", + "statutory_deadline", + "description", + "status", + "assigned_to", + "created_by", + "created_at", + "response_draft", + "review_notes" + ], + "title": "RequestRead" + }, + "RequestStats": { + "properties": { + "total_requests": { + "type": "integer", + "title": "Total Requests" + }, + "by_status": { + "additionalProperties": { + "type": "integer" + }, + "type": "object", + "title": "By Status" + }, + "approaching_deadline": { + "type": "integer", + "title": "Approaching Deadline" + }, + "overdue": { + "type": "integer", + "title": "Overdue" + } + }, + "type": "object", + "required": [ + "total_requests", + "by_status", + "approaching_deadline", + "overdue" + ], + "title": "RequestStats" + }, + "RequestStatus": { + "type": "string", + "enum": [ + "received", + "clarification_needed", + "assigned", + "searching", + "in_review", + "ready_for_release", + "drafted", + "approved", + "fulfilled", + "closed" + ], + "title": "RequestStatus" + }, + "RequestUpdate": { + "properties": { + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Description" + }, + "status": { + "anyOf": [ + { + "$ref": "#/components/schemas/RequestStatus" + }, + { + "type": "null" + } + ] + }, + "assigned_to": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Assigned To" + }, + "response_draft": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Response Draft" + }, + "statutory_deadline": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Statutory Deadline" + }, + "scope_assessment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Scope Assessment" + } + }, + "type": "object", + "title": "RequestUpdate" + }, + "RequirementBundle": { + "properties": { + "requirement_id": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]{1,100}$", + "title": "Requirement Id" + }, + "title": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Title" + }, + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "project_type": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Project Type" + }, + "source_reference": { + "type": "string", + "maxLength": 1000, + "minLength": 1, + "title": "Source Reference" + }, + "source_date": { + "type": "string", + "format": "date", + "title": "Source Date" + }, + "effective_on": { + "type": "string", + "format": "date", + "title": "Effective On" + }, + "dataset_kind": { + "type": "string", + "enum": [ + "municipal", + "fictional" + ], + "title": "Dataset Kind" + }, + "filename": { + "type": "string", + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$", + "title": "Filename" + }, + "content_base64": { + "type": "string", + "maxLength": 14000000, + "minLength": 1, + "title": "Content Base64" + }, + "sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Sha256" + }, + "materials": { + "items": { + "$ref": "#/components/schemas/Material" + }, + "type": "array", + "maxItems": 100, + "minItems": 1, + "title": "Materials" + }, + "pathway": { + "items": { + "$ref": "#/components/schemas/PathwayStep" + }, + "type": "array", + "maxItems": 100, + "title": "Pathway" + }, + "fee_link": { + "anyOf": [ + { + "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink" + }, + { + "type": "null" + } + ] + }, + "staff_note": { + "type": "string", + "maxLength": 4000, + "title": "Staff Note", + "default": "" + }, + "change_note": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Change Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requirement_id", + "title", + "jurisdiction", + "project_type", + "source_reference", + "source_date", + "effective_on", + "dataset_kind", + "filename", + "content_base64", + "sha256", + "materials", + "change_note" + ], + "title": "RequirementBundle" + }, + "ResponseLetterCreate": { + "properties": { + "template_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Template Id" + } + }, + "type": "object", + "title": "ResponseLetterCreate" + }, + "ResponseLetterRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "template_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Template Id" + }, + "generated_content": { + "type": "string", + "title": "Generated Content" + }, + "edited_content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Edited Content" + }, + "status": { + "type": "string", + "title": "Status" + }, + "generated_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Generated By" + }, + "approved_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Approved By" + }, + "sent_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Sent At" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "template_id", + "generated_content", + "edited_content", + "status", + "generated_by", + "approved_by", + "sent_at", + "created_at" + ], + "title": "ResponseLetterRead" + }, + "ResponseLetterUpdate": { + "properties": { + "edited_content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Edited Content" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + } + }, + "type": "object", + "title": "ResponseLetterUpdate" + }, + "ReviewInput": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "body": { + "type": "string", + "maxLength": 5000, + "title": "Body", + "default": "" + }, + "hasAltText": { + "type": "boolean", + "title": "Hasalttext", + "default": false + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "en" + } + }, + "additionalProperties": false, + "type": "object", + "title": "ReviewInput" + }, + "Revision": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + }, + "document": { + "$ref": "#/components/schemas/NoticeDraft" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence", + "document" + ], + "title": "Revision" + }, + "RewriteInput": { + "properties": { + "action": { + "type": "string", + "enum": [ + "plain-language", + "language-variant" + ], + "title": "Action" + }, + "text": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Text" + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "text" + ], + "title": "RewriteInput" + }, + "RewriteResult": { + "properties": { + "action": { + "type": "string", + "enum": [ + "plain-language", + "language-variant" + ], + "title": "Action" + }, + "text": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Text" + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "" + }, + "outcome": { + "type": "string", + "enum": [ + "generated", + "unavailable" + ], + "title": "Outcome" + }, + "generated": { + "anyOf": [ + { + "type": "string", + "maxLength": 100000 + }, + { + "type": "null" + } + ], + "title": "Generated" + }, + "model": { + "anyOf": [ + { + "type": "string", + "maxLength": 200 + }, + { + "type": "null" + } + ], + "title": "Model" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "text", + "outcome" + ], + "title": "RewriteResult" + }, + "Rule": { + "properties": { + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "zone_code": { + "type": "string", + "maxLength": 80, + "minLength": 1, + "title": "Zone Code" + }, + "key": { + "type": "string", + "maxLength": 120, + "minLength": 1, + "title": "Key" + }, + "section_number": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Section Number" + }, + "kind": { + "type": "string", + "enum": [ + "use", + "dimension" + ], + "title": "Kind" + }, + "value": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Value" + }, + "overlay_code": { + "anyOf": [ + { + "type": "string", + "maxLength": 255 + }, + { + "type": "null" + } + ], + "title": "Overlay Code" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "jurisdiction", + "zone_code", + "key", + "section_number", + "kind", + "value" + ], + "title": "Rule" + }, + "RuleTestMatch": { + "properties": { + "matched_text": { + "type": "string", + "title": "Matched Text" + }, + "start": { + "type": "integer", + "title": "Start" + }, + "end": { + "type": "integer", + "title": "End" + } + }, + "type": "object", + "required": [ + "matched_text", + "start", + "end" + ], + "title": "RuleTestMatch" + }, + "RuleTestRequest": { + "properties": { + "sample_text": { + "type": "string", + "title": "Sample Text" + } + }, + "type": "object", + "required": [ + "sample_text" + ], + "title": "RuleTestRequest" + }, + "RuleTestResponse": { + "properties": { + "rule_id": { + "type": "string", + "format": "uuid", + "title": "Rule Id" + }, + "rule_type": { + "type": "string", + "title": "Rule Type" + }, + "matched": { + "type": "boolean", + "title": "Matched" + }, + "matches": { + "items": { + "$ref": "#/components/schemas/RuleTestMatch" + }, + "type": "array", + "title": "Matches" + } + }, + "type": "object", + "required": [ + "rule_id", + "rule_type", + "matched", + "matches" + ], + "title": "RuleTestResponse" + }, + "RuleType": { + "type": "string", + "enum": [ + "regex", + "keyword", + "llm_prompt" + ], + "title": "RuleType" + }, + "SaveReview": { + "properties": { + "title": { + "type": "string", + "maxLength": 500, + "title": "Title", + "default": "" + }, + "body": { + "type": "string", + "maxLength": 5000, + "title": "Body", + "default": "" + }, + "hasAltText": { + "type": "boolean", + "title": "Hasalttext", + "default": false + }, + "language": { + "type": "string", + "maxLength": 80, + "title": "Language", + "default": "en" + }, + "ai_analysis": { + "anyOf": [ + { + "type": "string", + "maxLength": 100000 + }, + { + "type": "null" + } + ], + "title": "Ai Analysis" + }, + "ai_analysis_model": { + "anyOf": [ + { + "type": "string", + "maxLength": 200 + }, + { + "type": "null" + } + ], + "title": "Ai Analysis Model" + }, + "ai_outcome": { + "type": "string", + "enum": [ + "generated", + "unavailable", + "failed" + ], + "title": "Ai Outcome" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "ai_outcome" + ], + "title": "SaveReview" + }, + "SearchFilterOptions": { + "properties": { + "file_types": { + "items": { + "type": "string" + }, + "type": "array", + "title": "File Types" + }, + "source_names": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Source Names" + }, + "departments": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array", + "title": "Departments", + "default": [] + }, + "date_range": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Date Range" + } + }, + "type": "object", + "required": [ + "file_types", + "source_names" + ], + "title": "SearchFilterOptions" + }, + "SearchInput": { + "properties": { + "query": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "SearchInput" + }, + "SearchNoteCommand": { + "properties": { + "action": { + "type": "string", + "const": "record-records-search", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/SearchNotePayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "SearchNoteCommand" + }, + "SearchNotePayload": { + "properties": { + "sourceNote": { + "type": "string", + "minLength": 1, + "title": "Sourcenote" + }, + "citation": { + "type": "string", + "title": "Citation", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sourceNote" + ], + "title": "SearchNotePayload" + }, + "SearchReceiptCommand": { + "properties": { + "action": { + "type": "string", + "const": "record-records-search-session", + "title": "Action" + }, + "payload": { + "$ref": "#/components/schemas/SearchReceiptPayload" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action", + "payload" + ], + "title": "SearchReceiptCommand" + }, + "SearchReceiptPayload": { + "properties": { + "searchQuery": { + "type": "string", + "minLength": 1, + "title": "Searchquery" + }, + "searchLocations": { + "type": "string", + "minLength": 1, + "title": "Searchlocations" + }, + "searchResultTitle": { + "type": "string", + "minLength": 1, + "title": "Searchresulttitle" + }, + "searchResultCitation": { + "type": "string", + "minLength": 1, + "title": "Searchresultcitation" + }, + "searchResultSummary": { + "type": "string", + "minLength": 1, + "title": "Searchresultsummary" + }, + "searchResultStatus": { + "type": "string", + "title": "Searchresultstatus", + "default": "" + }, + "searchReviewer": { + "type": "string", + "title": "Searchreviewer", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "searchQuery", + "searchLocations", + "searchResultTitle", + "searchResultCitation", + "searchResultSummary" + ], + "title": "SearchReceiptPayload" + }, + "SearchReceiptView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "query": { + "type": "string", + "title": "Query" + }, + "locations": { + "type": "string", + "title": "Locations" + }, + "reviewer": { + "type": "string", + "title": "Reviewer" + }, + "results": { + "items": { + "$ref": "#/components/schemas/SearchResultView" + }, + "type": "array", + "title": "Results" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "query", + "locations", + "reviewer", + "results", + "created_at_unix_seconds" + ], + "title": "SearchReceiptView" + }, + "SearchRequest": { + "properties": { + "query": { + "type": "string", + "title": "Query" + }, + "session_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Session Id" + }, + "filters": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Filters" + }, + "limit": { + "type": "integer", + "maximum": 50.0, + "title": "Limit", + "default": 10 + }, + "synthesize": { + "type": "boolean", + "title": "Synthesize", + "default": false + } + }, + "type": "object", + "required": [ + "query" + ], + "title": "SearchRequest" + }, + "SearchResponse": { + "properties": { + "query_id": { + "type": "string", + "format": "uuid", + "title": "Query Id" + }, + "session_id": { + "type": "string", + "format": "uuid", + "title": "Session Id" + }, + "query_text": { + "type": "string", + "title": "Query Text" + }, + "results": { + "items": { + "$ref": "#/components/schemas/SearchResultItem" + }, + "type": "array", + "title": "Results" + }, + "results_count": { + "type": "integer", + "title": "Results Count" + }, + "synthesized_answer": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Synthesized Answer" + }, + "ai_generated": { + "type": "boolean", + "title": "Ai Generated", + "default": false + } + }, + "type": "object", + "required": [ + "query_id", + "session_id", + "query_text", + "results", + "results_count" + ], + "title": "SearchResponse" + }, + "SearchResultItem": { + "properties": { + "chunk_id": { + "type": "string", + "format": "uuid", + "title": "Chunk Id" + }, + "document_id": { + "type": "string", + "format": "uuid", + "title": "Document Id" + }, + "filename": { + "type": "string", + "title": "Filename" + }, + "file_type": { + "type": "string", + "title": "File Type" + }, + "source_path": { + "type": "string", + "title": "Source Path" + }, + "page_number": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Page Number" + }, + "content_text": { + "type": "string", + "title": "Content Text" + }, + "similarity_score": { + "type": "number", + "title": "Similarity Score" + }, + "rank": { + "type": "integer", + "title": "Rank" + } + }, + "type": "object", + "required": [ + "chunk_id", + "document_id", + "filename", + "file_type", + "source_path", + "page_number", + "content_text", + "similarity_score", + "rank" + ], + "title": "SearchResultItem" + }, + "SearchResultView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "title": { + "type": "string", + "title": "Title" + }, + "citation": { + "type": "string", + "title": "Citation" + }, + "summary": { + "type": "string", + "title": "Summary" + }, + "status": { + "type": "string", + "title": "Status" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "title", + "citation", + "summary", + "status" + ], + "title": "SearchResultView" + }, + "SearchSessionRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "user_id": { + "type": "string", + "format": "uuid", + "title": "User Id" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "queries": { + "items": { + "additionalProperties": true, + "type": "object" + }, + "type": "array", + "title": "Queries", + "default": [] + } + }, + "type": "object", + "required": [ + "id", + "user_id", + "created_at" + ], + "title": "SearchSessionRead" + }, + "SectionCreate": { + "properties": { + "section_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Section Id" + }, + "chapter_id": { + "type": "string", + "minLength": 1, + "title": "Chapter Id" + }, + "section_number": { + "type": "string", + "minLength": 1, + "title": "Section Number" + }, + "section_heading": { + "type": "string", + "minLength": 1, + "title": "Section Heading" + }, + "parent_section_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Parent Section Id" + }, + "sort_order": { + "type": "integer", + "title": "Sort Order", + "default": 0 + }, + "administrative_regulation_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Administrative Regulation Refs" + }, + "resolution_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Resolution Refs" + }, + "policy_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Policy Refs" + }, + "approved_summary_refs": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Approved Summary Refs" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "chapter_id", + "section_number", + "section_heading" + ], + "title": "SectionCreate", + "description": "Request body for creating a code section or subsection." + }, + "SectionVersionCreate": { + "properties": { + "version_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Version Id" + }, + "section_id": { + "type": "string", + "minLength": 1, + "title": "Section Id" + }, + "source_id": { + "type": "string", + "minLength": 1, + "title": "Source Id" + }, + "version_label": { + "type": "string", + "minLength": 1, + "title": "Version Label" + }, + "body": { + "type": "string", + "minLength": 1, + "title": "Body" + }, + "effective_start": { + "type": "string", + "format": "date", + "title": "Effective Start" + }, + "effective_end": { + "anyOf": [ + { + "type": "string", + "format": "date" + }, + { + "type": "null" + } + ], + "title": "Effective End" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + }, + "is_current": { + "type": "boolean", + "title": "Is Current", + "default": false + }, + "adoption_event_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Adoption Event Id" + }, + "amendment_event_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Amendment Event Id" + }, + "amendment_summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Amendment Summary" + }, + "prior_version_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Prior Version Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "section_id", + "source_id", + "version_label", + "body", + "effective_start" + ], + "title": "SectionVersionCreate", + "description": "Request body for adding an immutable section version." + }, + "Selection": { + "properties": { + "recording_id": { + "type": "string", + "format": "uuid", + "title": "Recording Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[0-9a-f]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "recording_id", + "expected_sha256" + ], + "title": "Selection" + }, + "SentenceInput": { + "properties": { + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + }, + "citations": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Citations" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "text" + ], + "title": "SentenceInput" + }, + "ServiceAccountCreate": { + "properties": { + "name": { + "type": "string", + "title": "Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole", + "default": "read_only" + } + }, + "type": "object", + "required": [ + "name" + ], + "title": "ServiceAccountCreate" + }, + "ServiceAccountCreated": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + }, + "api_key": { + "type": "string", + "title": "Api Key" + } + }, + "type": "object", + "required": [ + "id", + "name", + "role", + "created_by", + "created_at", + "is_active", + "api_key" + ], + "title": "ServiceAccountCreated", + "description": "Returned only on creation — includes the plaintext API key (shown once)." + }, + "ServiceAccountRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "name": { + "type": "string", + "title": "Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole" + }, + "created_by": { + "type": "string", + "format": "uuid", + "title": "Created By" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "is_active": { + "type": "boolean", + "title": "Is Active" + } + }, + "type": "object", + "required": [ + "id", + "name", + "role", + "created_by", + "created_at", + "is_active" + ], + "title": "ServiceAccountRead" + }, + "ServiceAccountUpdate": { + "properties": { + "role": { + "anyOf": [ + { + "$ref": "#/components/schemas/UserRole" + }, + { + "type": "null" + } + ] + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "ServiceAccountUpdate" + }, + "Snapshot": { + "properties": { + "expected_revision": { + "type": "string", + "format": "uuid", + "title": "Expected Revision" + }, + "visibility": { + "type": "string", + "enum": [ + "staff_only", + "public" + ], + "title": "Visibility" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "expected_revision", + "visibility" + ], + "title": "Snapshot" + }, + "SourceCreate": { + "properties": { + "source_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Id" + }, + "name": { + "type": "string", + "minLength": 1, + "title": "Name" + }, + "publisher": { + "type": "string", + "minLength": 1, + "title": "Publisher" + }, + "source_type": { + "type": "string", + "minLength": 1, + "title": "Source Type" + }, + "source_category": { + "type": "string", + "minLength": 1, + "title": "Source Category" + }, + "source_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Url" + }, + "file_reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "File Reference" + }, + "retrieved_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Retrieved At" + }, + "retrieval_method": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Retrieval Method" + }, + "checksum": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Checksum" + }, + "source_owner": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source Owner" + }, + "is_official": { + "type": "boolean", + "title": "Is Official", + "default": true + }, + "official_status_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Official Status Note" + }, + "status": { + "type": "string", + "title": "Status", + "default": "draft" + }, + "staff_notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Staff Notes" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "name", + "publisher", + "source_type", + "source_category" + ], + "title": "SourceCreate", + "description": "Request body for registering an official or explicitly labeled source." + }, + "SourceInput": { + "properties": { + "source_id": { + "type": "string", + "minLength": 1, + "title": "Source Id" + }, + "label": { + "type": "string", + "minLength": 1, + "title": "Label" + }, + "text": { + "type": "string", + "minLength": 1, + "title": "Text" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "label", + "text" + ], + "title": "SourceInput" + }, + "SourceSnapshot": { + "properties": { + "visibility": { + "type": "string", + "enum": [ + "public", + "staff_only" + ], + "title": "Visibility" + }, + "meeting_event_ids": { + "items": { + "type": "string", + "format": "uuid" + }, + "type": "array", + "maxItems": 50, + "title": "Meeting Event Ids" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "visibility" + ], + "title": "SourceSnapshot" + }, + "SourceType": { + "type": "string", + "enum": [ + "manual_drop", + "file_system", + "rest_api", + "odbc" + ], + "title": "SourceType" + }, + "StaffRecordsIntake": { + "properties": { + "requester": { + "type": "string", + "minLength": 1, + "title": "Requester" + }, + "summary": { + "type": "string", + "minLength": 1, + "title": "Summary" + }, + "deadline": { + "type": "string", + "title": "Deadline" + }, + "deadlineBasis": { + "type": "string", + "title": "Deadlinebasis", + "default": "" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "requester", + "summary", + "deadline" + ], + "title": "StaffRecordsIntake", + "description": "Existing native create-records-request input; no caller-supplied actor." + }, + "StandardsExplanation": { + "properties": { + "question": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Question" + }, + "process_section": { + "type": "string", + "maxLength": 255, + "title": "Process Section", + "default": "" + }, + "zone_code": { + "type": "string", + "maxLength": 40, + "title": "Zone Code", + "default": "" + }, + "rule_types": { + "items": { + "type": "string" + }, + "type": "array", + "maxItems": 10, + "title": "Rule Types" + }, + "observed": { + "additionalProperties": { + "type": "string" + }, + "type": "object", + "title": "Observed" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "question" + ], + "title": "StandardsExplanation" + }, + "SyncFailureRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "source_id": { + "type": "string", + "format": "uuid", + "title": "Source Id" + }, + "source_path": { + "type": "string", + "title": "Source Path" + }, + "error_message": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Message" + }, + "error_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Class" + }, + "http_status_code": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Http Status Code" + }, + "retry_count": { + "type": "integer", + "title": "Retry Count" + }, + "status": { + "type": "string", + "title": "Status" + }, + "first_failed_at": { + "type": "string", + "format": "date-time", + "title": "First Failed At" + }, + "last_retried_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Retried At" + }, + "dismissed_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Dismissed At" + }, + "dismissed_by": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Dismissed By" + } + }, + "type": "object", + "required": [ + "id", + "source_id", + "source_path", + "error_message", + "error_class", + "http_status_code", + "retry_count", + "status", + "first_failed_at", + "last_retried_at", + "dismissed_at", + "dismissed_by" + ], + "title": "SyncFailureRead" + }, + "SyncRunLogRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "source_id": { + "type": "string", + "format": "uuid", + "title": "Source Id" + }, + "started_at": { + "type": "string", + "format": "date-time", + "title": "Started At" + }, + "finished_at": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Finished At" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + }, + "records_attempted": { + "type": "integer", + "title": "Records Attempted" + }, + "records_succeeded": { + "type": "integer", + "title": "Records Succeeded" + }, + "records_failed": { + "type": "integer", + "title": "Records Failed" + }, + "error_summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error Summary" + } + }, + "type": "object", + "required": [ + "id", + "source_id", + "started_at", + "finished_at", + "status", + "records_attempted", + "records_succeeded", + "records_failed", + "error_summary" + ], + "title": "SyncRunLogRead" + }, + "SystemStatus": { + "properties": { + "version": { + "type": "string", + "title": "Version" + }, + "database": { + "type": "string", + "title": "Database" + }, + "ollama": { + "type": "string", + "title": "Ollama" + }, + "redis": { + "type": "string", + "title": "Redis" + }, + "user_count": { + "type": "integer", + "title": "User Count" + }, + "audit_log_count": { + "type": "integer", + "title": "Audit Log Count" + }, + "suite_session": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Suite Session" + } + }, + "type": "object", + "required": [ + "version", + "database", + "ollama", + "redis", + "user_count", + "audit_log_count" + ], + "title": "SystemStatus" + }, + "TaggedPlan": { + "properties": { + "action": { + "type": "string", + "const": "tagged-pdf", + "title": "Action" + }, + "headingLevels": { + "items": { + "type": "integer", + "maximum": 4294967295.0, + "minimum": 0.0 + }, + "type": "array", + "maxItems": 50, + "title": "Headinglevels" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "action" + ], + "title": "TaggedPlan" + }, + "TestConnectionRequest": { + "properties": { + "source_type": { + "type": "string", + "title": "Source Type" + }, + "host": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Host" + }, + "port": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Port" + }, + "path": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Path" + }, + "username": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Username" + }, + "password": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Password" + }, + "rest_api_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Rest Api Config" + }, + "odbc_config": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Odbc Config" + } + }, + "type": "object", + "required": [ + "source_type" + ], + "title": "TestConnectionRequest", + "description": "Dedicated schema for test-connection. NOT the create schema.\n\nSecurity: credentials in this request body are never persisted, never\nwritten to audit logs, and never returned in the response." + }, + "TestConnectionResponse": { + "properties": { + "success": { + "type": "boolean", + "title": "Success" + }, + "message": { + "type": "string", + "title": "Message" + }, + "latency_ms": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Latency Ms" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + }, + "warning": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Warning" + }, + "differing_keys": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Differing Keys" + } + }, + "type": "object", + "required": [ + "success", + "message" + ], + "title": "TestConnectionResponse" + }, + "TimelineEventCreate": { + "properties": { + "event_type": { + "type": "string", + "title": "Event Type" + }, + "description": { + "type": "string", + "title": "Description" + }, + "internal_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Internal Note" + } + }, + "type": "object", + "required": [ + "event_type", + "description" + ], + "title": "TimelineEventCreate" + }, + "TimelineEventRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "request_id": { + "type": "string", + "format": "uuid", + "title": "Request Id" + }, + "event_type": { + "type": "string", + "title": "Event Type" + }, + "actor_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Actor Id" + }, + "actor_role": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Actor Role" + }, + "description": { + "type": "string", + "title": "Description" + }, + "internal_note": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Internal Note" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + } + }, + "type": "object", + "required": [ + "id", + "request_id", + "event_type", + "actor_id", + "actor_role", + "description", + "internal_note", + "created_at" + ], + "title": "TimelineEventRead" + }, + "TimelineView": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "action": { + "type": "string", + "title": "Action" + }, + "actor": { + "type": "string", + "title": "Actor" + }, + "note": { + "type": "string", + "title": "Note" + }, + "created_at_unix_seconds": { + "type": "integer", + "title": "Created At Unix Seconds" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "action", + "actor", + "note", + "created_at_unix_seconds" + ], + "title": "TimelineView" + }, + "TitleCreate": { + "properties": { + "title_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Title Id" + }, + "title_number": { + "type": "string", + "minLength": 1, + "title": "Title Number" + }, + "title_name": { + "type": "string", + "minLength": 1, + "title": "Title Name" + }, + "sort_order": { + "type": "integer", + "title": "Sort Order", + "default": 0 + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "title_number", + "title_name" + ], + "title": "TitleCreate", + "description": "Request body for creating a code title." + }, + "TranscriptInput": { + "properties": { + "source_label": { + "type": "string", + "minLength": 1, + "title": "Source Label" + }, + "transcript_text": { + "type": "string", + "minLength": 1, + "title": "Transcript Text" + }, + "correction_of_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Correction Of Id" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_label", + "transcript_text" + ], + "title": "TranscriptInput" + }, + "UserRead": { + "properties": { + "id": { + "type": "string", + "format": "uuid", + "title": "Id" + }, + "email": { + "type": "string", + "format": "email", + "title": "Email" + }, + "is_active": { + "type": "boolean", + "title": "Is Active", + "default": true + }, + "is_superuser": { + "type": "boolean", + "title": "Is Superuser", + "default": false + }, + "is_verified": { + "type": "boolean", + "title": "Is Verified", + "default": false + }, + "full_name": { + "type": "string", + "title": "Full Name" + }, + "role": { + "$ref": "#/components/schemas/UserRole" + }, + "created_at": { + "type": "string", + "format": "date-time", + "title": "Created At" + }, + "last_login": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "null" + } + ], + "title": "Last Login" + }, + "must_change_password": { + "type": "boolean", + "title": "Must Change Password", + "default": false + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + } + }, + "type": "object", + "required": [ + "id", + "email", + "full_name", + "role", + "created_at", + "last_login" + ], + "title": "UserRead" + }, + "UserRole": { + "type": "string", + "enum": [ + "admin", + "staff", + "reviewer", + "read_only", + "liaison", + "public" + ], + "title": "UserRole" + }, + "UserSelfUpdate": { + "properties": { + "password": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Password" + }, + "email": { + "anyOf": [ + { + "type": "string", + "format": "email" + }, + { + "type": "null" + } + ], + "title": "Email" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + }, + "is_superuser": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Superuser" + }, + "is_verified": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Verified" + }, + "full_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Full Name" + } + }, + "type": "object", + "title": "UserSelfUpdate", + "description": "Schema for user self-update via PATCH /users/me.\n\nExcludes role and department_id. Any payload containing those fields is\nrejected at parse time (HTTP 422). Role and department changes require\nadmin privileges via /admin/users/{id}." + }, + "UserUpdateRequest": { + "properties": { + "full_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Full Name" + }, + "role": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Role" + }, + "department_id": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Department Id" + }, + "is_active": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Is Active" + } + }, + "type": "object", + "title": "UserUpdateRequest" + }, + "ValidationError": { + "properties": { + "loc": { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "integer" + } + ] + }, + "type": "array", + "title": "Location" + }, + "msg": { + "type": "string", + "title": "Message" + }, + "type": { + "type": "string", + "title": "Error Type" + }, + "input": { + "title": "Input" + }, + "ctx": { + "type": "object", + "title": "Context" + } + }, + "type": "object", + "required": [ + "loc", + "msg", + "type" + ], + "title": "ValidationError" + }, + "Version": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence" + ], + "title": "Version" + }, + "VoteCorrection": { + "properties": { + "vote": { + "type": "string", + "minLength": 1, + "title": "Vote" + }, + "reason": { + "type": "string", + "minLength": 1, + "title": "Reason" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "vote", + "reason" + ], + "title": "VoteCorrection" + }, + "VoteInput": { + "properties": { + "voter_name": { + "type": "string", + "minLength": 1, + "title": "Voter Name" + }, + "vote": { + "type": "string", + "minLength": 1, + "title": "Vote" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "voter_name", + "vote" + ], + "title": "VoteInput" + }, + "_ParcelLookupIn": { + "properties": { + "jurisdiction": { + "type": "string", + "maxLength": 255, + "minLength": 1, + "title": "Jurisdiction" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "jurisdiction", + "query" + ], + "title": "_ParcelLookupIn" + }, + "townlight_inspections__workflow_models__SourceLink": { + "properties": { + "provider": { + "type": "string", + "const": "code", + "title": "Provider", + "default": "code" + }, + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "source_id", + "expected_sha256" + ], + "title": "SourceLink" + }, + "townlight_permitting__workflow_models__SourceLink": { + "properties": { + "provider": { + "type": "string", + "enum": [ + "code", + "zoning" + ], + "title": "Provider" + }, + "source_id": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Source Id" + }, + "expected_sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "title": "Expected Sha256" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "source_id", + "expected_sha256" + ], + "title": "SourceLink" + }, + "townlight_runtime__inspections_bridge__Search": { + "properties": { + "provider": { + "type": "string", + "const": "code", + "title": "Provider" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "query" + ], + "title": "Search" + }, + "townlight_runtime__notice_bridge__Review": { + "properties": { + "sequence": { + "type": "integer", + "minimum": 1.0, + "title": "Sequence" + }, + "note": { + "type": "string", + "maxLength": 5000, + "minLength": 1, + "title": "Note" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "sequence", + "note" + ], + "title": "Review" + }, + "townlight_runtime__permitting_bridge__Import": { + "properties": { + "bundle": { + "$ref": "#/components/schemas/RequirementBundle" + }, + "expected_revision": { + "anyOf": [ + { + "type": "string", + "format": "uuid" + }, + { + "type": "null" + } + ], + "title": "Expected Revision" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "bundle" + ], + "title": "Import" + }, + "townlight_runtime__permitting_bridge__Search": { + "properties": { + "provider": { + "type": "string", + "enum": [ + "code", + "zoning" + ], + "title": "Provider" + }, + "query": { + "type": "string", + "maxLength": 500, + "minLength": 1, + "title": "Query" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "provider", + "query" + ], + "title": "Search" + }, + "townlight_runtime__planning_bridge__Import": { + "properties": { + "bundle": { + "additionalProperties": true, + "type": "object", + "title": "Bundle" + }, + "expected_previous_revision": { + "anyOf": [ + { + "type": "string", + "maxLength": 36, + "minLength": 36 + }, + { + "type": "null" + } + ], + "title": "Expected Previous Revision" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "bundle" + ], + "title": "Import" + }, + "townlight_runtime__planning_bridge__Search": { + "properties": { + "query": { + "type": "string", + "maxLength": 2000, + "minLength": 1, + "title": "Query" + }, + "plan_type": { + "anyOf": [ + { + "type": "string", + "maxLength": 40 + }, + { + "type": "null" + } + ], + "title": "Plan Type" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "query" + ], + "title": "Search" + }, + "townlight_runtime__zoning_bridge__Review": { + "properties": { + "answer": { + "type": "string", + "maxLength": 10000, + "title": "Answer", + "default": "" + }, + "notes": { + "type": "string", + "maxLength": 10000, + "title": "Notes", + "default": "" + }, + "queue_status": { + "type": "string", + "enum": [ + "open", + "in_review", + "resolved", + "closed" + ], + "title": "Queue Status", + "default": "resolved" + } + }, + "additionalProperties": false, + "type": "object", + "title": "Review" + } + }, + "securitySchemes": { + "OAuth2PasswordBearer": { + "type": "oauth2", + "flows": { + "password": { + "scopes": {}, + "tokenUrl": "auth/jwt/login" + } + } + } + } + }, + "x-townlight-component": { + "view": "zoning", + "identity": "Townlight Zoning 0.2.3", + "evidence": "source-schema-only" + } +} diff --git a/docs/beta-1/api/zoning.html b/docs/beta-1/api/zoning.html new file mode 100644 index 0000000..e5ee5ce --- /dev/null +++ b/docs/beta-1/api/zoning.html @@ -0,0 +1,12297 @@ +Townlight Zoning API reference
Townlight

Townlight Zoning API reference

+

Prepared source candidate, November 2, 2026. New signed Windows installed acceptance and publication remain pending.

+

Townlight Zoning 0.2.3. The HTTP host is Townlight Records 1.8.0.dev2. Component package versions and the host API version are separate identities.

+

Generated from the actual native inspections-preview composition without application lifespan, migrations or database/network access. It describes route and validation contracts; it does not establish endpoint behavior, individual authorization or installed acceptance. Standalone product applications have separate deployment boundaries.

+

Machine-readable OpenAPI schema · Operating manual and limits

+

HTTP operations

+
POST /desktop/v1/zoning-sources/search +
{
+  "tags": [
+    "native-desktop"
+  ],
+  "summary": "Search Zoning Sources",
+  "operationId": "search_zoning_sources_desktop_v1_zoning_sources_search_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MeetingsSearch"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/zoning/code-context +
{
+  "tags": [
+    "native-zoning"
+  ],
+  "summary": "Create Code Context",
+  "operationId": "create_code_context_desktop_v1_zoning_code_context_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/CodeContext"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/zoning/imports +
{
+  "tags": [
+    "native-zoning"
+  ],
+  "summary": "Imports",
+  "operationId": "imports_desktop_v1_zoning_imports_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "type": "object",
+          "additionalProperties": true,
+          "title": "Payload"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/zoning/meetings/search +
{
+  "tags": [
+    "native-zoning"
+  ],
+  "summary": "Search Meetings",
+  "operationId": "search_meetings_desktop_v1_zoning_meetings_search_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MeetingSearch"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/zoning/outlines +
{
+  "tags": [
+    "native-zoning"
+  ],
+  "summary": "Create Outline",
+  "operationId": "create_outline_desktop_v1_zoning_outlines_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/Outline"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/zoning/parcels/lookup +
{
+  "tags": [
+    "native-zoning"
+  ],
+  "summary": "Parcel Lookup",
+  "operationId": "parcel_lookup_desktop_v1_zoning_parcels_lookup_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/_ParcelLookupIn"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/zoning/questions +
{
+  "tags": [
+    "native-zoning"
+  ],
+  "summary": "Create Question",
+  "operationId": "create_question_desktop_v1_zoning_questions_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/Question"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/zoning/questions/{question_id}/history +
{
+  "tags": [
+    "native-zoning"
+  ],
+  "summary": "Question History",
+  "operationId": "question_history_desktop_v1_zoning_questions__question_id__history_get",
+  "parameters": [
+    {
+      "name": "question_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Question Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/zoning/questions/{question_id}/meetings +
{
+  "tags": [
+    "native-zoning"
+  ],
+  "summary": "Link Meeting",
+  "operationId": "link_meeting_desktop_v1_zoning_questions__question_id__meetings_post",
+  "parameters": [
+    {
+      "name": "question_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Question Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/MeetingLink"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/zoning/questions/{question_id}/reviews +
{
+  "tags": [
+    "native-zoning"
+  ],
+  "summary": "Create Review",
+  "operationId": "create_review_desktop_v1_zoning_questions__question_id__reviews_post",
+  "parameters": [
+    {
+      "name": "question_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Question Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/townlight_runtime__zoning_bridge__Review"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/zoning/questions/{question_id}/snapshots +
{
+  "tags": [
+    "native-zoning"
+  ],
+  "summary": "Create Snapshot",
+  "operationId": "create_snapshot_desktop_v1_zoning_questions__question_id__snapshots_post",
+  "parameters": [
+    {
+      "name": "question_id",
+      "in": "path",
+      "required": true,
+      "schema": {
+        "type": "string",
+        "format": "uuid",
+        "title": "Question Id"
+      }
+    },
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/SourceSnapshot"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/zoning/rules +
{
+  "tags": [
+    "native-zoning"
+  ],
+  "summary": "Create Rule",
+  "operationId": "create_rule_desktop_v1_zoning_rules_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/Rule"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
POST /desktop/v1/zoning/standards/process-explanation +
{
+  "tags": [
+    "native-zoning"
+  ],
+  "summary": "Standards Explanation",
+  "description": "Cited variance/CUP/nonconformity process; never a determination.",
+  "operationId": "standards_explanation_desktop_v1_zoning_standards_process_explanation_post",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "requestBody": {
+    "required": true,
+    "content": {
+      "application/json": {
+        "schema": {
+          "$ref": "#/components/schemas/StandardsExplanation"
+        }
+      }
+    }
+  },
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+
GET /desktop/v1/zoning/workspace +
{
+  "tags": [
+    "native-zoning"
+  ],
+  "summary": "Get Workspace",
+  "operationId": "get_workspace_desktop_v1_zoning_workspace_get",
+  "parameters": [
+    {
+      "name": "X-Townlight-Session",
+      "in": "header",
+      "required": false,
+      "schema": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "null"
+          }
+        ],
+        "title": "X-Townlight-Session"
+      }
+    }
+  ],
+  "responses": {
+    "200": {
+      "description": "Successful Response",
+      "content": {
+        "application/json": {
+          "schema": {}
+        }
+      }
+    },
+    "422": {
+      "description": "Validation Error",
+      "content": {
+        "application/json": {
+          "schema": {
+            "$ref": "#/components/schemas/HTTPValidationError"
+          }
+        }
+      }
+    }
+  }
+}
+

Request and response data dictionary

+

Each schema includes the actual required fields, types, constraints and descriptions. References resolve against the machine-readable document.

+
ActionItemInput
+{
+  "properties": {
+    "description": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Description"
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "source_motion_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Motion Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "description"
+  ],
+  "title": "ActionItemInput"
+}
+
+
AdaPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "ada-title-ii",
+      "title": "Action"
+    },
+    "serviceArea": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Servicearea"
+    },
+    "hasCoordinatorReview": {
+      "type": "boolean",
+      "title": "Hascoordinatorreview",
+      "default": false
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "serviceArea"
+  ],
+  "title": "AdaPlan"
+}
+
+
AdminUserCreateRequest
+{
+  "properties": {
+    "email": {
+      "type": "string",
+      "title": "Email"
+    },
+    "password": {
+      "type": "string",
+      "title": "Password"
+    },
+    "full_name": {
+      "type": "string",
+      "title": "Full Name",
+      "default": ""
+    },
+    "role": {
+      "type": "string",
+      "title": "Role",
+      "default": "staff"
+    }
+  },
+  "type": "object",
+  "required": [
+    "email",
+    "password"
+  ],
+  "title": "AdminUserCreateRequest"
+}
+
+
AdminUserCreateResponse
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "email": {
+      "type": "string",
+      "title": "Email"
+    },
+    "full_name": {
+      "type": "string",
+      "title": "Full Name"
+    },
+    "role": {
+      "type": "string",
+      "title": "Role"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "email",
+    "full_name",
+    "role",
+    "is_active"
+  ],
+  "title": "AdminUserCreateResponse"
+}
+
+
AgendaAssignment
+{
+  "properties": {
+    "meeting_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Meeting Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "meeting_id"
+  ],
+  "title": "AgendaAssignment"
+}
+
+
AgendaInput
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "department_name": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Department Name"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "department_name"
+  ],
+  "title": "AgendaInput"
+}
+
+
AgendaReviewInput
+{
+  "properties": {
+    "to_status": {
+      "type": "string",
+      "enum": [
+        "DRAFTED",
+        "SUBMITTED",
+        "DEPT_APPROVED",
+        "LEGAL_REVIEWED",
+        "CLERK_ACCEPTED",
+        "ON_AGENDA",
+        "IN_PACKET",
+        "POSTED",
+        "HEARD",
+        "DISPOSED",
+        "ARCHIVED"
+      ],
+      "title": "To Status"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "to_status"
+  ],
+  "title": "AgendaReviewInput"
+}
+
+
AmendmentInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "policy": {
+      "$ref": "#/components/schemas/PolicySelection"
+    },
+    "proposal": {
+      "type": "string",
+      "maxLength": 20000,
+      "minLength": 1,
+      "title": "Proposal"
+    },
+    "responsible_staff": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Responsible Staff"
+    },
+    "status": {
+      "type": "string",
+      "enum": [
+        "draft",
+        "review",
+        "adopted",
+        "withdrawn"
+      ],
+      "title": "Status",
+      "default": "draft"
+    },
+    "review_note": {
+      "type": "string",
+      "maxLength": 5000,
+      "title": "Review Note",
+      "default": ""
+    },
+    "adoption_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Adoption Revision"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "policy",
+    "proposal",
+    "responsible_staff",
+    "note"
+  ],
+  "title": "AmendmentInput"
+}
+
+
AnalysisObservation
+{
+  "properties": {
+    "source": {
+      "type": "string",
+      "maxLength": 64,
+      "minLength": 1,
+      "title": "Source"
+    },
+    "filename": {
+      "type": "string",
+      "maxLength": 160,
+      "title": "Filename",
+      "default": ""
+    },
+    "media_type": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Media Type",
+      "default": ""
+    },
+    "text": {
+      "type": "string",
+      "maxLength": 4000,
+      "minLength": 1,
+      "title": "Text"
+    },
+    "adapter": {
+      "type": "string",
+      "maxLength": 120,
+      "title": "Adapter",
+      "default": ""
+    },
+    "citation_source_ids": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Citation Source Ids"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source",
+    "text"
+  ],
+  "title": "AnalysisObservation",
+  "description": "One draft observation, named with the adapter that actually produced it."
+}
+
+
AnalysisRecord
+{
+  "properties": {
+    "observations": {
+      "items": {
+        "$ref": "#/components/schemas/AnalysisObservation"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Observations"
+    },
+    "cited_sections": {
+      "items": {
+        "$ref": "#/components/schemas/CitedSection"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Cited Sections"
+    },
+    "unavailable": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Unavailable"
+    },
+    "runtime": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Runtime"
+    },
+    "review_required": {
+      "type": "boolean",
+      "title": "Review Required",
+      "default": true
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "AnalysisRecord",
+  "description": "The adapter output that accompanies a saved inspection draft."
+}
+
+
ApprovalCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "approve-records-response",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ApprovalPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "ApprovalCommand"
+}
+
+
ApprovalPayload
+{
+  "properties": {
+    "approvalNote": {
+      "type": "string",
+      "title": "Approvalnote",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "ApprovalPayload"
+}
+
+
ArchiveInput
+{
+  "properties": {
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "public",
+        "closed_session"
+      ],
+      "title": "Visibility"
+    },
+    "packet_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Packet Id"
+    },
+    "minutes_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Minutes Id"
+    },
+    "plain_language_summary": {
+      "type": "string",
+      "title": "Plain Language Summary",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "visibility"
+  ],
+  "title": "ArchiveInput"
+}
+
+
ArtifactPlan
+{
+  "properties": {
+    "artifact_id": {
+      "type": "string",
+      "title": "Artifact Id"
+    },
+    "file_name": {
+      "type": "string",
+      "title": "File Name"
+    },
+    "content": {
+      "type": "string",
+      "title": "Content"
+    },
+    "sha256": {
+      "type": "string",
+      "title": "Sha256"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "artifact_id",
+    "file_name",
+    "content",
+    "sha256",
+    "created_at_unix_seconds"
+  ],
+  "title": "ArtifactPlan"
+}
+
+
AssignCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "assign-records-request",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/AssignmentPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "AssignCommand"
+}
+
+
AssignmentPayload
+{
+  "properties": {
+    "assignedTo": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Assignedto"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "assignedTo"
+  ],
+  "title": "AssignmentPayload"
+}
+
+
AttachDocument
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation",
+      "default": ""
+    },
+    "file": {
+      "$ref": "#/components/schemas/ManagedFileReceipt"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "file"
+  ],
+  "title": "AttachDocument"
+}
+
+
AttachReleaseCopy
+{
+  "properties": {
+    "status": {
+      "type": "string",
+      "enum": [
+        "release-ready copy",
+        "redacted copy"
+      ],
+      "title": "Status"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note",
+      "default": ""
+    },
+    "added_by": {
+      "type": "string",
+      "title": "Added By",
+      "default": ""
+    },
+    "file": {
+      "$ref": "#/components/schemas/ManagedFileReceipt"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "status",
+    "file"
+  ],
+  "title": "AttachReleaseCopy"
+}
+
+
AuditChainVerification
+{
+  "properties": {
+    "is_valid": {
+      "type": "boolean",
+      "title": "Is Valid"
+    },
+    "entries_checked": {
+      "type": "integer",
+      "title": "Entries Checked"
+    },
+    "error_message": {
+      "type": "string",
+      "title": "Error Message"
+    }
+  },
+  "type": "object",
+  "required": [
+    "is_valid",
+    "entries_checked",
+    "error_message"
+  ],
+  "title": "AuditChainVerification"
+}
+
+
AuditLogRead
+{
+  "properties": {
+    "id": {
+      "type": "integer",
+      "title": "Id"
+    },
+    "prev_hash": {
+      "type": "string",
+      "title": "Prev Hash"
+    },
+    "entry_hash": {
+      "type": "string",
+      "title": "Entry Hash"
+    },
+    "timestamp": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Timestamp"
+    },
+    "user_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "User Id"
+    },
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "resource_type": {
+      "type": "string",
+      "title": "Resource Type"
+    },
+    "resource_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Resource Id"
+    },
+    "details": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Details"
+    },
+    "ai_generated": {
+      "type": "boolean",
+      "title": "Ai Generated"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "prev_hash",
+    "entry_hash",
+    "timestamp",
+    "user_id",
+    "action",
+    "resource_type",
+    "resource_id",
+    "details",
+    "ai_generated"
+  ],
+  "title": "AuditLogRead"
+}
+
+
AuditView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "module_id": {
+      "type": "string",
+      "title": "Module Id"
+    },
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    },
+    "previous_hash": {
+      "type": "string",
+      "title": "Previous Hash"
+    },
+    "entry_hash": {
+      "type": "string",
+      "title": "Entry Hash"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "module_id",
+    "action",
+    "summary",
+    "created_at_unix_seconds",
+    "previous_hash",
+    "entry_hash"
+  ],
+  "title": "AuditView"
+}
+
+
BearerResponse
+{
+  "properties": {
+    "access_token": {
+      "type": "string",
+      "title": "Access Token"
+    },
+    "token_type": {
+      "type": "string",
+      "title": "Token Type"
+    }
+  },
+  "type": "object",
+  "required": [
+    "access_token",
+    "token_type"
+  ],
+  "title": "BearerResponse"
+}
+
+
Body_auth_jwt_login_auth_jwt_login_post
+{
+  "properties": {
+    "grant_type": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^password$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Grant Type"
+    },
+    "username": {
+      "type": "string",
+      "title": "Username"
+    },
+    "password": {
+      "type": "string",
+      "format": "password",
+      "title": "Password"
+    },
+    "scope": {
+      "type": "string",
+      "title": "Scope",
+      "default": ""
+    },
+    "client_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Client Id"
+    },
+    "client_secret": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "format": "password",
+      "title": "Client Secret"
+    }
+  },
+  "type": "object",
+  "required": [
+    "username",
+    "password"
+  ],
+  "title": "Body_auth_jwt_login_auth_jwt_login_post"
+}
+
+
Body_upload_file_datasources_upload_post
+{
+  "properties": {
+    "file": {
+      "type": "string",
+      "contentMediaType": "application/octet-stream",
+      "title": "File"
+    }
+  },
+  "type": "object",
+  "required": [
+    "file"
+  ],
+  "title": "Body_upload_file_datasources_upload_post"
+}
+
+
CalculateDeadlineCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "calculate-records-deadline",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/CalculateDeadlinePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "CalculateDeadlineCommand"
+}
+
+
CalculateDeadlinePayload
+{
+  "properties": {
+    "deadlineReceivedDate": {
+      "type": "string",
+      "title": "Deadlinereceiveddate"
+    },
+    "deadlineRuleName": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Deadlinerulename"
+    },
+    "deadlineDayCount": {
+      "type": "string",
+      "title": "Deadlinedaycount"
+    },
+    "deadlineDayType": {
+      "type": "string",
+      "title": "Deadlinedaytype"
+    },
+    "deadlineBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Deadlinebasis"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "deadlineReceivedDate",
+    "deadlineRuleName",
+    "deadlineDayCount",
+    "deadlineDayType",
+    "deadlineBasis"
+  ],
+  "title": "CalculateDeadlinePayload"
+}
+
+
ChapterCreate
+{
+  "properties": {
+    "chapter_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Chapter Id"
+    },
+    "title_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title Id"
+    },
+    "chapter_number": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Chapter Number"
+    },
+    "chapter_name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Chapter Name"
+    },
+    "sort_order": {
+      "type": "integer",
+      "title": "Sort Order",
+      "default": 0
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title_id",
+    "chapter_number",
+    "chapter_name"
+  ],
+  "title": "ChapterCreate",
+  "description": "Request body for creating a code chapter."
+}
+
+
CitedSection
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "citation": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Citation"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "version": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Version",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "citation"
+  ],
+  "title": "CitedSection",
+  "description": "One resolved public Code section; never a caller-supplied quotation."
+}
+
+
CityProfileCreate
+{
+  "properties": {
+    "city_name": {
+      "type": "string",
+      "title": "City Name"
+    },
+    "state": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State"
+    },
+    "county": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "County"
+    },
+    "population_band": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Population Band"
+    },
+    "email_platform": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email Platform"
+    },
+    "has_dedicated_it": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Has Dedicated It"
+    },
+    "monthly_request_volume": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Monthly Request Volume"
+    },
+    "profile_data": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Profile Data",
+      "default": {}
+    },
+    "gap_map": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Gap Map",
+      "default": {}
+    }
+  },
+  "type": "object",
+  "required": [
+    "city_name"
+  ],
+  "title": "CityProfileCreate"
+}
+
+
CityProfileRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "city_name": {
+      "type": "string",
+      "title": "City Name"
+    },
+    "state": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State"
+    },
+    "county": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "County"
+    },
+    "population_band": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Population Band"
+    },
+    "email_platform": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email Platform"
+    },
+    "has_dedicated_it": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Has Dedicated It"
+    },
+    "monthly_request_volume": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Monthly Request Volume"
+    },
+    "onboarding_status": {
+      "type": "string",
+      "title": "Onboarding Status"
+    },
+    "profile_data": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Profile Data"
+    },
+    "gap_map": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Gap Map"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "updated_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "city_name",
+    "state",
+    "county",
+    "population_band",
+    "email_platform",
+    "has_dedicated_it",
+    "monthly_request_volume",
+    "onboarding_status",
+    "profile_data",
+    "gap_map",
+    "created_at",
+    "updated_at"
+  ],
+  "title": "CityProfileRead"
+}
+
+
CityProfileUpdate
+{
+  "properties": {
+    "city_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "City Name"
+    },
+    "state": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State"
+    },
+    "county": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "County"
+    },
+    "population_band": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Population Band"
+    },
+    "email_platform": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email Platform"
+    },
+    "has_dedicated_it": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Has Dedicated It"
+    },
+    "monthly_request_volume": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Monthly Request Volume"
+    },
+    "onboarding_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Onboarding Status"
+    },
+    "profile_data": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Profile Data"
+    },
+    "gap_map": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Gap Map"
+    }
+  },
+  "type": "object",
+  "title": "CityProfileUpdate"
+}
+
+
ClarificationCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "request-records-clarification",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ClarificationPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "ClarificationCommand"
+}
+
+
ClarificationPayload
+{
+  "properties": {
+    "clarificationNote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Clarificationnote"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "clarificationNote"
+  ],
+  "title": "ClarificationPayload"
+}
+
+
Closeout
+{
+  "properties": {
+    "decision_id": {
+      "type": "string",
+      "pattern": "^[A-Za-z0-9_-]{1,64}$",
+      "title": "Decision Id"
+    },
+    "version_id": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Version Id"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "version_label": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Version Label"
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 1000000,
+      "minLength": 1,
+      "title": "Body"
+    },
+    "effective_start": {
+      "type": "string",
+      "format": "date",
+      "title": "Effective Start"
+    },
+    "effective_end": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective End"
+    },
+    "is_current": {
+      "type": "boolean",
+      "title": "Is Current"
+    },
+    "reconciliation_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reconciliation Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "decision_id",
+    "version_id",
+    "source_id",
+    "version_label",
+    "body",
+    "effective_start",
+    "is_current"
+  ],
+  "title": "Closeout"
+}
+
+
CodeContext
+{
+  "properties": {
+    "section_number": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Section Number"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "section_number"
+  ],
+  "title": "CodeContext"
+}
+
+
CodeLink
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "const": "code",
+      "title": "Provider",
+      "default": "code"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "CodeLink"
+}
+
+
CodeSearch
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "CodeSearch"
+}
+
+
CodeSourceSelection
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 200,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "CodeSourceSelection"
+}
+
+
CompleteArtifact
+{
+  "properties": {
+    "export_path": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Export Path"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "export_path"
+  ],
+  "title": "CompleteArtifact"
+}
+
+
ConnectionSearch
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "enum": [
+        "meetings",
+        "zoning"
+      ],
+      "title": "Provider"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "query"
+  ],
+  "title": "ConnectionSearch"
+}
+
+
CoverageGapResponse
+{
+  "properties": {
+    "jurisdictions_without_rules": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Jurisdictions Without Rules"
+    },
+    "departments_without_staff": {
+      "items": {
+        "additionalProperties": true,
+        "type": "object"
+      },
+      "type": "array",
+      "title": "Departments Without Staff"
+    },
+    "uncovered_categories": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Uncovered Categories"
+    },
+    "total_gaps": {
+      "type": "integer",
+      "title": "Total Gaps"
+    }
+  },
+  "type": "object",
+  "required": [
+    "jurisdictions_without_rules",
+    "departments_without_staff",
+    "uncovered_categories",
+    "total_gaps"
+  ],
+  "title": "CoverageGapResponse"
+}
+
+
DataSourceAdminRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "source_type": {
+      "$ref": "#/components/schemas/SourceType"
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "type": "boolean",
+      "title": "Schedule Enabled",
+      "default": true
+    },
+    "next_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Next Sync At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "last_ingestion_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Ingestion At"
+    },
+    "last_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync At"
+    },
+    "last_sync_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync Status"
+    },
+    "last_error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Error Message"
+    },
+    "consecutive_failure_count": {
+      "type": "integer",
+      "title": "Consecutive Failure Count",
+      "default": 0
+    },
+    "sync_paused": {
+      "type": "boolean",
+      "title": "Sync Paused",
+      "default": false
+    },
+    "health_status": {
+      "type": "string",
+      "title": "Health Status",
+      "default": "healthy"
+    },
+    "active_failure_count": {
+      "type": "integer",
+      "title": "Active Failure Count",
+      "default": 0
+    },
+    "connector_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connector Type"
+    },
+    "updated_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Updated At"
+    },
+    "connection_config": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Connection Config"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "source_type",
+    "is_active",
+    "created_by",
+    "created_at",
+    "last_ingestion_at",
+    "connection_config"
+  ],
+  "title": "DataSourceAdminRead",
+  "description": "Full datasource shape including connection_config. Returned only by admin-gated endpoints."
+}
+
+
DataSourceCreate
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "source_type": {
+      "$ref": "#/components/schemas/SourceType"
+    },
+    "connection_config": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Connection Config",
+      "default": {}
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "type": "boolean",
+      "title": "Schedule Enabled",
+      "default": true
+    }
+  },
+  "type": "object",
+  "required": [
+    "name",
+    "source_type"
+  ],
+  "title": "DataSourceCreate"
+}
+
+
DataSourceRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "source_type": {
+      "$ref": "#/components/schemas/SourceType"
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "type": "boolean",
+      "title": "Schedule Enabled",
+      "default": true
+    },
+    "next_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Next Sync At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "last_ingestion_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Ingestion At"
+    },
+    "last_sync_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync At"
+    },
+    "last_sync_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Sync Status"
+    },
+    "last_error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Error Message"
+    },
+    "consecutive_failure_count": {
+      "type": "integer",
+      "title": "Consecutive Failure Count",
+      "default": 0
+    },
+    "sync_paused": {
+      "type": "boolean",
+      "title": "Sync Paused",
+      "default": false
+    },
+    "health_status": {
+      "type": "string",
+      "title": "Health Status",
+      "default": "healthy"
+    },
+    "active_failure_count": {
+      "type": "integer",
+      "title": "Active Failure Count",
+      "default": 0
+    },
+    "connector_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connector Type"
+    },
+    "updated_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "source_type",
+    "is_active",
+    "created_by",
+    "created_at",
+    "last_ingestion_at"
+  ],
+  "title": "DataSourceRead",
+  "description": "Redacted datasource shape — safe for non-admin roles. connection_config omitted."
+}
+
+
DataSourceUpdate
+{
+  "properties": {
+    "name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Name"
+    },
+    "connection_config": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connection Config"
+    },
+    "sync_schedule": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sync Schedule"
+    },
+    "schedule_enabled": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Schedule Enabled"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "DataSourceUpdate"
+}
+
+
DeadlineCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "set-records-deadline",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/DeadlinePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "DeadlineCommand"
+}
+
+
DeadlinePayload
+{
+  "properties": {
+    "deadline": {
+      "type": "string",
+      "title": "Deadline"
+    },
+    "deadlineBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Deadlinebasis"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "deadline",
+    "deadlineBasis"
+  ],
+  "title": "DeadlinePayload"
+}
+
+
Decision
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "pattern": "^[A-Za-z0-9_-]{1,64}$",
+      "title": "Id"
+    },
+    "outcome": {
+      "type": "string",
+      "enum": [
+        "adopted",
+        "not_adopted",
+        "deferred",
+        "withdrawn"
+      ],
+      "title": "Outcome"
+    },
+    "decided_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Decided At"
+    },
+    "decision_text": {
+      "type": "string",
+      "maxLength": 1000000,
+      "minLength": 1,
+      "title": "Decision Text"
+    },
+    "supporting_references": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Supporting References"
+    },
+    "supersedes_decision_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^[A-Za-z0-9_-]{1,64}$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supersedes Decision Id"
+    },
+    "reconciliation_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reconciliation Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "outcome",
+    "decision_text"
+  ],
+  "title": "Decision"
+}
+
+
DepartmentCreate
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "code": {
+      "type": "string",
+      "title": "Code"
+    },
+    "contact_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Contact Email"
+    }
+  },
+  "type": "object",
+  "required": [
+    "name",
+    "code"
+  ],
+  "title": "DepartmentCreate"
+}
+
+
DepartmentRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "code": {
+      "type": "string",
+      "title": "Code"
+    },
+    "contact_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Contact Email"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "code",
+    "contact_email",
+    "created_at"
+  ],
+  "title": "DepartmentRead"
+}
+
+
DepartmentUpdate
+{
+  "properties": {
+    "name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Name"
+    },
+    "code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Code"
+    },
+    "contact_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Contact Email"
+    }
+  },
+  "type": "object",
+  "title": "DepartmentUpdate"
+}
+
+
DisclosureTemplateCreate
+{
+  "properties": {
+    "template_type": {
+      "type": "string",
+      "title": "Template Type"
+    },
+    "state_code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State Code"
+    },
+    "content": {
+      "type": "string",
+      "title": "Content"
+    }
+  },
+  "type": "object",
+  "required": [
+    "template_type",
+    "content"
+  ],
+  "title": "DisclosureTemplateCreate"
+}
+
+
DisclosureTemplateRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "template_type": {
+      "type": "string",
+      "title": "Template Type"
+    },
+    "state_code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State Code"
+    },
+    "content": {
+      "type": "string",
+      "title": "Content"
+    },
+    "version": {
+      "type": "integer",
+      "title": "Version"
+    },
+    "updated_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Updated By"
+    },
+    "updated_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "template_type",
+    "state_code",
+    "content",
+    "version",
+    "updated_by",
+    "updated_at"
+  ],
+  "title": "DisclosureTemplateRead"
+}
+
+
DisclosureTemplateRendered
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "template_type": {
+      "type": "string",
+      "title": "Template Type"
+    },
+    "rendered_content": {
+      "type": "string",
+      "title": "Rendered Content"
+    },
+    "has_unresolved_variables": {
+      "type": "boolean",
+      "title": "Has Unresolved Variables"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "template_type",
+    "rendered_content",
+    "has_unresolved_variables"
+  ],
+  "title": "DisclosureTemplateRendered"
+}
+
+
DisclosureTemplateUpdate
+{
+  "properties": {
+    "content": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Content"
+    },
+    "state_code": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "State Code"
+    }
+  },
+  "type": "object",
+  "title": "DisclosureTemplateUpdate"
+}
+
+
DocumentChunkRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "chunk_index": {
+      "type": "integer",
+      "title": "Chunk Index"
+    },
+    "content_text": {
+      "type": "string",
+      "title": "Content Text"
+    },
+    "token_count": {
+      "type": "integer",
+      "title": "Token Count"
+    },
+    "page_number": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Page Number"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "document_id",
+    "chunk_index",
+    "content_text",
+    "token_count",
+    "page_number"
+  ],
+  "title": "DocumentChunkRead"
+}
+
+
DocumentRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "source_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Source Id"
+    },
+    "source_path": {
+      "type": "string",
+      "title": "Source Path"
+    },
+    "filename": {
+      "type": "string",
+      "title": "Filename"
+    },
+    "file_type": {
+      "type": "string",
+      "title": "File Type"
+    },
+    "file_hash": {
+      "type": "string",
+      "title": "File Hash"
+    },
+    "file_size": {
+      "type": "integer",
+      "title": "File Size"
+    },
+    "ingestion_status": {
+      "$ref": "#/components/schemas/IngestionStatus"
+    },
+    "ingestion_error": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ingestion Error"
+    },
+    "chunk_count": {
+      "type": "integer",
+      "title": "Chunk Count"
+    },
+    "ingested_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ingested At"
+    },
+    "connector_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Connector Type"
+    },
+    "updated_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Updated At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "source_id",
+    "source_path",
+    "filename",
+    "file_type",
+    "file_hash",
+    "file_size",
+    "ingestion_status",
+    "ingestion_error",
+    "chunk_count",
+    "ingested_at"
+  ],
+  "title": "DocumentRead"
+}
+
+
DraftCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "draft-records-response",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/DraftPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "DraftCommand"
+}
+
+
DraftInput
+{
+  "properties": {
+    "source_materials": {
+      "items": {
+        "$ref": "#/components/schemas/SourceInput"
+      },
+      "type": "array",
+      "title": "Source Materials"
+    },
+    "sentences": {
+      "items": {
+        "$ref": "#/components/schemas/SentenceInput"
+      },
+      "type": "array",
+      "minItems": 1,
+      "title": "Sentences"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sentences"
+  ],
+  "title": "DraftInput"
+}
+
+
DraftPayload
+{
+  "properties": {
+    "responseDraft": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Responsedraft"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "responseDraft"
+  ],
+  "title": "DraftPayload"
+}
+
+
ErrorModel
+{
+  "properties": {
+    "detail": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "additionalProperties": {
+            "type": "string"
+          },
+          "type": "object"
+        }
+      ],
+      "title": "Detail"
+    }
+  },
+  "type": "object",
+  "required": [
+    "detail"
+  ],
+  "title": "ErrorModel"
+}
+
+
Evidence
+{
+  "properties": {
+    "filename": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$",
+      "title": "Filename"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Description"
+    },
+    "media_type": {
+      "type": "string",
+      "enum": [
+        "text/plain",
+        "image/jpeg",
+        "image/png",
+        "image/webp",
+        "application/pdf",
+        "audio/webm",
+        "audio/ogg",
+        "audio/wav",
+        "audio/mpeg",
+        "audio/mp4"
+      ],
+      "title": "Media Type"
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 14000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "filename",
+    "description",
+    "media_type",
+    "content_base64",
+    "sha256"
+  ],
+  "title": "Evidence"
+}
+
+
EvidenceItem
+{
+  "properties": {
+    "filename": {
+      "type": "string",
+      "maxLength": 151,
+      "minLength": 1,
+      "title": "Filename"
+    },
+    "media_type": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Media Type"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Description",
+      "default": ""
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 14000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "filename",
+    "media_type",
+    "content_base64",
+    "sha256"
+  ],
+  "title": "EvidenceItem"
+}
+
+
EvidenceItems
+{
+  "properties": {
+    "items": {
+      "items": {
+        "$ref": "#/components/schemas/EvidenceItem"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "minItems": 1,
+      "title": "Items"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "items"
+  ],
+  "title": "EvidenceItems"
+}
+
+
ExemptionAccuracyReport
+{
+  "properties": {
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "total_flags": {
+      "type": "integer",
+      "title": "Total Flags"
+    },
+    "accepted": {
+      "type": "integer",
+      "title": "Accepted"
+    },
+    "rejected": {
+      "type": "integer",
+      "title": "Rejected"
+    },
+    "pending": {
+      "type": "integer",
+      "title": "Pending"
+    },
+    "acceptance_rate": {
+      "type": "number",
+      "title": "Acceptance Rate"
+    }
+  },
+  "type": "object",
+  "required": [
+    "category",
+    "total_flags",
+    "accepted",
+    "rejected",
+    "pending",
+    "acceptance_rate"
+  ],
+  "title": "ExemptionAccuracyReport"
+}
+
+
ExemptionDashboard
+{
+  "properties": {
+    "total_flags": {
+      "type": "integer",
+      "title": "Total Flags"
+    },
+    "by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "By Status"
+    },
+    "by_category": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "By Category"
+    },
+    "acceptance_rate": {
+      "type": "number",
+      "title": "Acceptance Rate"
+    },
+    "total_rules": {
+      "type": "integer",
+      "title": "Total Rules"
+    },
+    "active_rules": {
+      "type": "integer",
+      "title": "Active Rules"
+    }
+  },
+  "type": "object",
+  "required": [
+    "total_flags",
+    "by_status",
+    "by_category",
+    "acceptance_rate",
+    "total_rules",
+    "active_rules"
+  ],
+  "title": "ExemptionDashboard"
+}
+
+
ExemptionDecisionCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-exemption-decision",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ExemptionDecisionPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "ExemptionDecisionCommand"
+}
+
+
ExemptionDecisionPayload
+{
+  "properties": {
+    "exemptionSource": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionsource"
+    },
+    "exemptionKind": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionkind"
+    },
+    "exemptionFinding": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionfinding"
+    },
+    "exemptionDecision": {
+      "type": "string",
+      "enum": [
+        "release",
+        "redact",
+        "exempt"
+      ],
+      "title": "Exemptiondecision"
+    },
+    "exemptionBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionbasis"
+    },
+    "exemptionReviewer": {
+      "type": "string",
+      "title": "Exemptionreviewer",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "exemptionSource",
+    "exemptionKind",
+    "exemptionFinding",
+    "exemptionDecision",
+    "exemptionBasis"
+  ],
+  "title": "ExemptionDecisionPayload"
+}
+
+
ExemptionDecisionView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "source": {
+      "type": "string",
+      "title": "Source"
+    },
+    "kind": {
+      "type": "string",
+      "title": "Kind"
+    },
+    "finding": {
+      "type": "string",
+      "title": "Finding"
+    },
+    "decision": {
+      "type": "string",
+      "enum": [
+        "release",
+        "redact",
+        "exempt"
+      ],
+      "title": "Decision"
+    },
+    "basis": {
+      "type": "string",
+      "title": "Basis"
+    },
+    "reviewer": {
+      "type": "string",
+      "title": "Reviewer"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "source",
+    "kind",
+    "finding",
+    "decision",
+    "basis",
+    "reviewer",
+    "created_at_unix_seconds"
+  ],
+  "title": "ExemptionDecisionView"
+}
+
+
ExemptionFlagRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "chunk_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Chunk Id"
+    },
+    "rule_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Rule Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "matched_text": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Matched Text"
+    },
+    "confidence": {
+      "type": "number",
+      "title": "Confidence"
+    },
+    "status": {
+      "$ref": "#/components/schemas/FlagStatus"
+    },
+    "reviewed_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reviewed By"
+    },
+    "reviewed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reviewed At"
+    },
+    "review_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Reason"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "chunk_id",
+    "rule_id",
+    "request_id",
+    "category",
+    "matched_text",
+    "confidence",
+    "status",
+    "reviewed_by",
+    "reviewed_at",
+    "review_reason",
+    "created_at"
+  ],
+  "title": "ExemptionFlagRead"
+}
+
+
ExemptionFlagReview
+{
+  "properties": {
+    "status": {
+      "$ref": "#/components/schemas/FlagStatus"
+    },
+    "review_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Reason"
+    }
+  },
+  "type": "object",
+  "required": [
+    "status"
+  ],
+  "title": "ExemptionFlagReview"
+}
+
+
ExemptionNoteCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-exemption-review",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/ExemptionNotePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "ExemptionNoteCommand"
+}
+
+
ExemptionNotePayload
+{
+  "properties": {
+    "exemptionNote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Exemptionnote"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "exemptionNote"
+  ],
+  "title": "ExemptionNotePayload"
+}
+
+
ExemptionRuleCreate
+{
+  "properties": {
+    "state_code": {
+      "type": "string",
+      "title": "State Code"
+    },
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "rule_type": {
+      "$ref": "#/components/schemas/RuleType"
+    },
+    "rule_definition": {
+      "type": "string",
+      "title": "Rule Definition"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "enabled": {
+      "type": "boolean",
+      "title": "Enabled",
+      "default": true
+    }
+  },
+  "type": "object",
+  "required": [
+    "state_code",
+    "category",
+    "rule_type",
+    "rule_definition"
+  ],
+  "title": "ExemptionRuleCreate"
+}
+
+
ExemptionRuleRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "state_code": {
+      "type": "string",
+      "title": "State Code"
+    },
+    "category": {
+      "type": "string",
+      "title": "Category"
+    },
+    "rule_type": {
+      "$ref": "#/components/schemas/RuleType"
+    },
+    "rule_definition": {
+      "type": "string",
+      "title": "Rule Definition"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "enabled": {
+      "type": "boolean",
+      "title": "Enabled"
+    },
+    "version": {
+      "type": "integer",
+      "title": "Version",
+      "default": 1
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "state_code",
+    "category",
+    "rule_type",
+    "rule_definition",
+    "description",
+    "enabled",
+    "created_by",
+    "created_at"
+  ],
+  "title": "ExemptionRuleRead"
+}
+
+
ExemptionRuleUpdate
+{
+  "properties": {
+    "rule_definition": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Rule Definition"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "enabled": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Enabled"
+    }
+  },
+  "type": "object",
+  "title": "ExemptionRuleUpdate"
+}
+
+
ExportReceipt
+{
+  "properties": {
+    "export_path": {
+      "type": "string",
+      "maxLength": 32768,
+      "minLength": 1,
+      "title": "Export Path"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "export_path"
+  ],
+  "title": "ExportReceipt"
+}
+
+
FeeEstimateCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "estimate-records-fee",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/FeeEstimatePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "FeeEstimateCommand"
+}
+
+
FeeEstimatePayload
+{
+  "properties": {
+    "feeEstimate": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feeestimate"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "feeEstimate"
+  ],
+  "title": "FeeEstimatePayload"
+}
+
+
FeeEstimateRequest
+{
+  "properties": {
+    "page_count": {
+      "type": "integer",
+      "title": "Page Count"
+    },
+    "fee_schedule_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Fee Schedule Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "page_count",
+    "fee_schedule_id"
+  ],
+  "title": "FeeEstimateRequest"
+}
+
+
FeeEstimateResponse
+{
+  "properties": {
+    "page_count": {
+      "type": "integer",
+      "title": "Page Count"
+    },
+    "unit_price": {
+      "type": "number",
+      "title": "Unit Price"
+    },
+    "total": {
+      "type": "number",
+      "title": "Total"
+    },
+    "fee_type": {
+      "type": "string",
+      "title": "Fee Type"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    }
+  },
+  "type": "object",
+  "required": [
+    "page_count",
+    "unit_price",
+    "total",
+    "fee_type",
+    "description"
+  ],
+  "title": "FeeEstimateResponse"
+}
+
+
FeeLineCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-fee-line",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/FeeLinePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "FeeLineCommand"
+}
+
+
FeeLineItemCreate
+{
+  "properties": {
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "quantity": {
+      "type": "integer",
+      "title": "Quantity",
+      "default": 1
+    },
+    "unit_price": {
+      "type": "number",
+      "title": "Unit Price"
+    },
+    "fee_schedule_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Schedule Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "description",
+    "unit_price"
+  ],
+  "title": "FeeLineItemCreate"
+}
+
+
FeeLineItemRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "fee_schedule_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Schedule Id"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "quantity": {
+      "type": "integer",
+      "title": "Quantity"
+    },
+    "unit_price": {
+      "type": "number",
+      "title": "Unit Price"
+    },
+    "total": {
+      "type": "number",
+      "title": "Total"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "fee_schedule_id",
+    "description",
+    "quantity",
+    "unit_price",
+    "total",
+    "status",
+    "created_at"
+  ],
+  "title": "FeeLineItemRead"
+}
+
+
FeeLinePayload
+{
+  "properties": {
+    "feeLineDescription": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feelinedescription"
+    },
+    "feeScheduleBasis": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feeschedulebasis"
+    },
+    "feeLineAmount": {
+      "type": "string",
+      "title": "Feelineamount"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "feeLineDescription",
+    "feeScheduleBasis",
+    "feeLineAmount"
+  ],
+  "title": "FeeLinePayload"
+}
+
+
FeeLineView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "schedule_basis": {
+      "type": "string",
+      "title": "Schedule Basis"
+    },
+    "amount_cents": {
+      "type": "integer",
+      "title": "Amount Cents"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "description",
+    "schedule_basis",
+    "amount_cents",
+    "created_at_unix_seconds"
+  ],
+  "title": "FeeLineView"
+}
+
+
FeeScheduleCreate
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "title": "Jurisdiction"
+    },
+    "fee_type": {
+      "type": "string",
+      "title": "Fee Type"
+    },
+    "amount": {
+      "type": "number",
+      "title": "Amount"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "effective_date": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective Date"
+    }
+  },
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "fee_type",
+    "amount"
+  ],
+  "title": "FeeScheduleCreate"
+}
+
+
FeeScheduleRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "jurisdiction": {
+      "type": "string",
+      "title": "Jurisdiction"
+    },
+    "fee_type": {
+      "type": "string",
+      "title": "Fee Type"
+    },
+    "amount": {
+      "type": "number",
+      "title": "Amount"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "effective_date": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective Date"
+    },
+    "created_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "jurisdiction",
+    "fee_type",
+    "amount",
+    "description",
+    "effective_date",
+    "created_by",
+    "created_at"
+  ],
+  "title": "FeeScheduleRead"
+}
+
+
FeeScheduleUpdate
+{
+  "properties": {
+    "fee_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Type"
+    },
+    "amount": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Amount"
+    },
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "effective_date": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective Date"
+    }
+  },
+  "type": "object",
+  "title": "FeeScheduleUpdate"
+}
+
+
FeeWaiverCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "waive-records-fee",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/FeeWaiverPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "FeeWaiverCommand"
+}
+
+
FeeWaiverCreateRequest
+{
+  "properties": {
+    "waiver_type": {
+      "type": "string",
+      "title": "Waiver Type"
+    },
+    "reason": {
+      "type": "string",
+      "title": "Reason"
+    }
+  },
+  "type": "object",
+  "required": [
+    "waiver_type",
+    "reason"
+  ],
+  "title": "FeeWaiverCreateRequest"
+}
+
+
FeeWaiverPayload
+{
+  "properties": {
+    "feeWaiverReason": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Feewaiverreason"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "feeWaiverReason"
+  ],
+  "title": "FeeWaiverPayload"
+}
+
+
FeeWaiverReadResponse
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "waiver_type": {
+      "type": "string",
+      "title": "Waiver Type"
+    },
+    "reason": {
+      "type": "string",
+      "title": "Reason"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    },
+    "created_at": {
+      "type": "string",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "waiver_type",
+    "reason",
+    "status",
+    "created_at"
+  ],
+  "title": "FeeWaiverReadResponse"
+}
+
+
FeeWaiverReviewRequest
+{
+  "properties": {
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    }
+  },
+  "type": "object",
+  "required": [
+    "status"
+  ],
+  "title": "FeeWaiverReviewRequest"
+}
+
+
FinishCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "fulfill-records-request",
+        "close-records-request"
+      ],
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/NativePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "FinishCommand"
+}
+
+
FlagStatus
+{
+  "type": "string",
+  "enum": [
+    "flagged",
+    "reviewed",
+    "accepted",
+    "rejected"
+  ],
+  "title": "FlagStatus"
+}
+
+
FormPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "form-plan",
+      "title": "Action"
+    },
+    "formName": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Formname",
+      "default": ""
+    },
+    "fields": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 50,
+      "title": "Fields"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "FormPlan"
+}
+
+
GeneratedDraft
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "model": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Model"
+    },
+    "previous_response_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Previous Response Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text",
+    "model",
+    "previous_response_sha256"
+  ],
+  "title": "GeneratedDraft"
+}
+
+
HTTPValidationError
+{
+  "properties": {
+    "detail": {
+      "items": {
+        "$ref": "#/components/schemas/ValidationError"
+      },
+      "type": "array",
+      "title": "Detail"
+    }
+  },
+  "type": "object",
+  "title": "HTTPValidationError"
+}
+
+
Handoff
+{
+  "properties": {
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "request_id"
+  ],
+  "title": "Handoff"
+}
+
+
ImportBundleCreate
+{
+  "properties": {
+    "job_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Job Id"
+    },
+    "connector_type": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Connector Type"
+    },
+    "source": {
+      "$ref": "#/components/schemas/SourceCreate"
+    },
+    "sources": {
+      "items": {
+        "$ref": "#/components/schemas/SourceCreate"
+      },
+      "type": "array",
+      "title": "Sources"
+    },
+    "titles": {
+      "items": {
+        "$ref": "#/components/schemas/TitleCreate"
+      },
+      "type": "array",
+      "title": "Titles"
+    },
+    "chapters": {
+      "items": {
+        "$ref": "#/components/schemas/ChapterCreate"
+      },
+      "type": "array",
+      "title": "Chapters"
+    },
+    "sections": {
+      "items": {
+        "$ref": "#/components/schemas/SectionCreate"
+      },
+      "type": "array",
+      "title": "Sections"
+    },
+    "versions": {
+      "items": {
+        "$ref": "#/components/schemas/SectionVersionCreate"
+      },
+      "type": "array",
+      "title": "Versions"
+    },
+    "provenance": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Provenance"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "connector_type",
+    "source"
+  ],
+  "title": "ImportBundleCreate",
+  "description": "Request body for local fixture/file-drop import jobs."
+}
+
+
InclusionStatus
+{
+  "type": "string",
+  "enum": [
+    "included",
+    "excluded",
+    "pending"
+  ],
+  "title": "InclusionStatus"
+}
+
+
IngestionStats
+{
+  "properties": {
+    "total_sources": {
+      "type": "integer",
+      "title": "Total Sources"
+    },
+    "active_sources": {
+      "type": "integer",
+      "title": "Active Sources"
+    },
+    "total_documents": {
+      "type": "integer",
+      "title": "Total Documents"
+    },
+    "documents_by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "Documents By Status"
+    },
+    "total_chunks": {
+      "type": "integer",
+      "title": "Total Chunks"
+    }
+  },
+  "type": "object",
+  "required": [
+    "total_sources",
+    "active_sources",
+    "total_documents",
+    "documents_by_status",
+    "total_chunks"
+  ],
+  "title": "IngestionStats"
+}
+
+
IngestionStatus
+{
+  "type": "string",
+  "enum": [
+    "pending",
+    "processing",
+    "completed",
+    "failed"
+  ],
+  "title": "IngestionStatus"
+}
+
+
InitiativeInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "policy": {
+      "$ref": "#/components/schemas/PolicySelection"
+    },
+    "responsible_staff": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Responsible Staff"
+    },
+    "target": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "string"
+        }
+      ],
+      "title": "Target"
+    },
+    "unit": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Unit"
+    },
+    "due_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Due On"
+    },
+    "status": {
+      "type": "string",
+      "enum": [
+        "planned",
+        "active",
+        "completed",
+        "cancelled"
+      ],
+      "title": "Status",
+      "default": "planned"
+    },
+    "milestones": {
+      "items": {
+        "$ref": "#/components/schemas/Milestone"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "title": "Milestones"
+    },
+    "measurements": {
+      "items": {
+        "$ref": "#/components/schemas/Measurement"
+      },
+      "type": "array",
+      "maxItems": 1000,
+      "title": "Measurements"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "policy",
+    "responsible_staff",
+    "target",
+    "unit",
+    "due_on",
+    "note"
+  ],
+  "title": "InitiativeInput"
+}
+
+
InspectionInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "property_reference": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Property Reference"
+    },
+    "inspection_reference": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Inspection Reference"
+    },
+    "dataset_kind": {
+      "type": "string",
+      "enum": [
+        "municipal",
+        "fictional"
+      ],
+      "title": "Dataset Kind"
+    },
+    "inspector_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "minLength": 1,
+      "title": "Inspector Notes"
+    },
+    "photo_observations": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Photo Observations"
+    },
+    "voice_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Voice Notes",
+      "default": ""
+    },
+    "evidence": {
+      "items": {
+        "$ref": "#/components/schemas/Evidence"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "title": "Evidence"
+    },
+    "linked_sources": {
+      "items": {
+        "$ref": "#/components/schemas/townlight_inspections__workflow_models__SourceLink"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Linked Sources"
+    },
+    "assigned_to": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Assigned To",
+      "default": ""
+    },
+    "staff_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Staff Notes",
+      "default": ""
+    },
+    "notice_draft": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Notice Draft",
+      "default": ""
+    },
+    "review_state": {
+      "type": "string",
+      "enum": [
+        "draft",
+        "follow_up",
+        "reviewed"
+      ],
+      "title": "Review State",
+      "default": "draft"
+    },
+    "review_notes": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Review Notes",
+      "default": ""
+    },
+    "public_summary": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Public Summary",
+      "default": ""
+    },
+    "analysis": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/AnalysisRecord"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "property_reference",
+    "inspection_reference",
+    "dataset_kind",
+    "inspector_notes"
+  ],
+  "title": "InspectionInput"
+}
+
+
IntakeInput
+{
+  "properties": {
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    },
+    "project_name": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Project Name"
+    },
+    "project_description": {
+      "type": "string",
+      "maxLength": 10000,
+      "minLength": 1,
+      "title": "Project Description"
+    },
+    "location": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Location"
+    },
+    "applicant_contact": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Applicant Contact",
+      "default": ""
+    },
+    "requirement_revision": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Requirement Revision"
+    },
+    "materials": {
+      "items": {
+        "$ref": "#/components/schemas/MaterialReview"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "minItems": 1,
+      "title": "Materials"
+    },
+    "linked_sources": {
+      "items": {
+        "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Linked Sources"
+    },
+    "staff_notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Staff Notes",
+      "default": ""
+    },
+    "assigned_to": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Assigned To",
+      "default": ""
+    },
+    "review_state": {
+      "type": "string",
+      "enum": [
+        "draft",
+        "follow_up",
+        "reviewed"
+      ],
+      "title": "Review State",
+      "default": "draft"
+    },
+    "review_notes": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Review Notes",
+      "default": ""
+    },
+    "public_summary": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Public Summary",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "project_name",
+    "project_description",
+    "location",
+    "requirement_revision",
+    "materials"
+  ],
+  "title": "IntakeInput"
+}
+
+
InterpretationNoteCreate
+{
+  "properties": {
+    "note_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Note Id"
+    },
+    "note_text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Note Text"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "note_text"
+  ],
+  "title": "InterpretationNoteCreate",
+  "description": "Request body for staff-only interpretation notes."
+}
+
+
InterviewRequest
+{
+  "properties": {
+    "last_answer": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Answer"
+    },
+    "last_field": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Field"
+    },
+    "skipped_fields": {
+      "anyOf": [
+        {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Skipped Fields"
+    }
+  },
+  "type": "object",
+  "title": "InterviewRequest"
+}
+
+
InterviewResponse
+{
+  "properties": {
+    "question": {
+      "type": "string",
+      "title": "Question"
+    },
+    "target_field": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Target Field"
+    },
+    "all_complete": {
+      "type": "boolean",
+      "title": "All Complete"
+    },
+    "completed_fields": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Completed Fields"
+    },
+    "onboarding_status": {
+      "type": "string",
+      "title": "Onboarding Status"
+    },
+    "skipped_fields": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Skipped Fields"
+    }
+  },
+  "type": "object",
+  "required": [
+    "question",
+    "target_field",
+    "all_complete",
+    "completed_fields",
+    "onboarding_status",
+    "skipped_fields"
+  ],
+  "title": "InterviewResponse"
+}
+
+
ManagedFileReceipt
+{
+  "properties": {
+    "original_path": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Original Path"
+    },
+    "stored_path": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Stored Path"
+    },
+    "file_name": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "File Name"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Sha256"
+    },
+    "size_bytes": {
+      "type": "integer",
+      "maximum": 2147483647.0,
+      "minimum": 0.0,
+      "title": "Size Bytes"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "original_path",
+    "stored_path",
+    "file_name",
+    "sha256",
+    "size_bytes"
+  ],
+  "title": "ManagedFileReceipt"
+}
+
+
ManagedSource
+{
+  "properties": {
+    "original_path": {
+      "type": "string",
+      "title": "Original Path"
+    },
+    "stored_path": {
+      "type": "string",
+      "title": "Stored Path"
+    },
+    "file_name": {
+      "type": "string",
+      "title": "File Name"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Sha256"
+    },
+    "size_bytes": {
+      "type": "integer",
+      "minimum": 0.0,
+      "title": "Size Bytes"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "original_path",
+    "stored_path",
+    "file_name",
+    "sha256",
+    "size_bytes"
+  ],
+  "title": "ManagedSource"
+}
+
+
Material
+{
+  "properties": {
+    "material_id": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9_-]{1,80}$",
+      "title": "Material Id"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Description"
+    },
+    "citation": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Citation"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "material_id",
+    "description",
+    "citation"
+  ],
+  "title": "Material"
+}
+
+
MaterialReview
+{
+  "properties": {
+    "material_id": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Material Id"
+    },
+    "status": {
+      "type": "string",
+      "enum": [
+        "not_reviewed",
+        "provided",
+        "missing",
+        "unclear"
+      ],
+      "title": "Status",
+      "default": "not_reviewed"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Note",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "material_id"
+  ],
+  "title": "MaterialReview"
+}
+
+
Measurement
+{
+  "properties": {
+    "recorded_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Recorded On"
+    },
+    "value": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "string"
+        }
+      ],
+      "title": "Value"
+    },
+    "evidence": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Evidence"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "recorded_on",
+    "value",
+    "evidence"
+  ],
+  "title": "Measurement"
+}
+
+
MediaAnalysis
+{
+  "properties": {
+    "items": {
+      "items": {
+        "$ref": "#/components/schemas/EvidenceItem"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "minItems": 1,
+      "title": "Items"
+    },
+    "code_links": {
+      "items": {
+        "$ref": "#/components/schemas/CodeLink"
+      },
+      "type": "array",
+      "maxItems": 30,
+      "title": "Code Links"
+    },
+    "inspector_supplied_text": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Inspector Supplied Text",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "items"
+  ],
+  "title": "MediaAnalysis"
+}
+
+
MeetingInput
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "scheduled_start": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Scheduled Start"
+    },
+    "location": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Location"
+    },
+    "meeting_type": {
+      "type": "string",
+      "enum": [
+        "regular",
+        "special",
+        "emergency",
+        "closed_session",
+        "executive"
+      ],
+      "title": "Meeting Type",
+      "default": "regular"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "scheduled_start",
+    "location"
+  ],
+  "title": "MeetingInput"
+}
+
+
MeetingLink
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 200,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    },
+    "relation": {
+      "type": "string",
+      "enum": [
+        "hearing",
+        "context",
+        "precedent"
+      ],
+      "title": "Relation"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256",
+    "relation"
+  ],
+  "title": "MeetingLink"
+}
+
+
MeetingSearch
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "MeetingSearch"
+}
+
+
MeetingStageInput
+{
+  "properties": {
+    "to_status": {
+      "type": "string",
+      "enum": [
+        "SCHEDULED",
+        "NOTICED",
+        "PACKET_POSTED",
+        "IN_PROGRESS",
+        "RECESSED",
+        "ADJOURNED",
+        "TRANSCRIPT_READY",
+        "MINUTES_DRAFTED",
+        "MINUTES_POSTED",
+        "MINUTES_ADOPTED",
+        "MINUTES_SIGNED",
+        "ARCHIVED",
+        "CANCELLED"
+      ],
+      "title": "To Status"
+    },
+    "statutory_basis": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Basis"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "to_status"
+  ],
+  "title": "MeetingStageInput"
+}
+
+
MeetingsSearch
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "MeetingsSearch"
+}
+
+
MeetingsSourceSelection
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "maxLength": 200,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "MeetingsSourceSelection"
+}
+
+
MessageCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "add-records-message",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/MessagePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "MessageCommand"
+}
+
+
MessageCreate
+{
+  "properties": {
+    "message_text": {
+      "type": "string",
+      "title": "Message Text"
+    },
+    "is_internal": {
+      "type": "boolean",
+      "title": "Is Internal",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "message_text"
+  ],
+  "title": "MessageCreate"
+}
+
+
MessagePayload
+{
+  "properties": {
+    "requestMessageBody": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestmessagebody"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requestMessageBody"
+  ],
+  "title": "MessagePayload"
+}
+
+
MessageRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "sender_type": {
+      "type": "string",
+      "title": "Sender Type"
+    },
+    "sender_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sender Id"
+    },
+    "message_text": {
+      "type": "string",
+      "title": "Message Text"
+    },
+    "is_internal": {
+      "type": "boolean",
+      "title": "Is Internal"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "sender_type",
+    "sender_id",
+    "message_text",
+    "is_internal",
+    "created_at"
+  ],
+  "title": "MessageRead"
+}
+
+
MessageView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "author": {
+      "type": "string",
+      "title": "Author"
+    },
+    "author_role": {
+      "type": "string",
+      "title": "Author Role"
+    },
+    "body": {
+      "type": "string",
+      "title": "Body"
+    },
+    "visibility": {
+      "type": "string",
+      "title": "Visibility"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "author",
+    "author_role",
+    "body",
+    "visibility",
+    "created_at_unix_seconds"
+  ],
+  "title": "MessageView"
+}
+
+
Milestone
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "due_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Due On"
+    },
+    "completed_on": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Completed On"
+    },
+    "evidence": {
+      "type": "string",
+      "maxLength": 2000,
+      "title": "Evidence",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "due_on"
+  ],
+  "title": "Milestone"
+}
+
+
MinutesDecision
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "post",
+        "adopt",
+        "sign"
+      ],
+      "title": "Action"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "MinutesDecision"
+}
+
+
ModelRegistryCreate
+{
+  "properties": {
+    "model_name": {
+      "type": "string",
+      "title": "Model Name"
+    },
+    "model_version": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Version"
+    },
+    "parameter_count": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parameter Count"
+    },
+    "license": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "License"
+    },
+    "model_card_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Card Url"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active",
+      "default": false
+    },
+    "context_window_size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Context Window Size"
+    },
+    "supports_ner": {
+      "type": "boolean",
+      "title": "Supports Ner",
+      "default": false
+    },
+    "supports_vision": {
+      "type": "boolean",
+      "title": "Supports Vision",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "model_name"
+  ],
+  "title": "ModelRegistryCreate",
+  "description": "Schema for creating a new model_registry record (POST body)."
+}
+
+
ModelRegistryRead
+{
+  "properties": {
+    "id": {
+      "type": "integer",
+      "title": "Id"
+    },
+    "model_name": {
+      "type": "string",
+      "title": "Model Name"
+    },
+    "model_version": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Version"
+    },
+    "parameter_count": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parameter Count"
+    },
+    "license": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "License"
+    },
+    "model_card_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Card Url"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "added_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Added At"
+    },
+    "context_window_size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Context Window Size"
+    },
+    "supports_ner": {
+      "type": "boolean",
+      "title": "Supports Ner"
+    },
+    "supports_vision": {
+      "type": "boolean",
+      "title": "Supports Vision"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "model_name",
+    "is_active",
+    "supports_ner",
+    "supports_vision"
+  ],
+  "title": "ModelRegistryRead",
+  "description": "Schema for returning a model_registry record (GET response).\n\n``from_attributes=True`` allows construction directly from an ORM instance."
+}
+
+
ModelRegistryUpdate
+{
+  "properties": {
+    "model_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Name"
+    },
+    "model_version": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Version"
+    },
+    "parameter_count": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parameter Count"
+    },
+    "license": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "License"
+    },
+    "model_card_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model Card Url"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    },
+    "context_window_size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Context Window Size"
+    },
+    "supports_ner": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supports Ner"
+    },
+    "supports_vision": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supports Vision"
+    }
+  },
+  "type": "object",
+  "title": "ModelRegistryUpdate",
+  "description": "Schema for partially updating a model_registry record (PATCH body).\n\nEvery field is optional so callers can send only the fields they want to\nchange."
+}
+
+
MotionCorrection
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "reason": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Reason"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text",
+    "reason"
+  ],
+  "title": "MotionCorrection"
+}
+
+
MotionInput
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "seconded_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "minLength": 1
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Seconded By"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text"
+  ],
+  "title": "MotionInput"
+}
+
+
NativePayload
+{
+  "properties": {},
+  "additionalProperties": false,
+  "type": "object",
+  "title": "NativePayload"
+}
+
+
NativeRequestRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "requester_name": {
+      "type": "string",
+      "title": "Requester Name"
+    },
+    "requester_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Email"
+    },
+    "requester_phone": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Phone"
+    },
+    "requester_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Type"
+    },
+    "date_received": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Date Received"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "status": {
+      "$ref": "#/components/schemas/RequestStatus"
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "created_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "response_draft": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Response Draft"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    },
+    "estimated_fee": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Estimated Fee"
+    },
+    "fee_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Status"
+    },
+    "fee_waiver_requested": {
+      "type": "boolean",
+      "title": "Fee Waiver Requested",
+      "default": false
+    },
+    "priority": {
+      "type": "string",
+      "title": "Priority",
+      "default": "normal"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    },
+    "closed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closed At"
+    },
+    "closure_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closure Reason"
+    },
+    "desktop_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Desktop Id"
+    },
+    "public_tracking_number": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Public Tracking Number"
+    },
+    "submitted_via": {
+      "type": "string",
+      "title": "Submitted Via"
+    },
+    "deadline_label": {
+      "type": "string",
+      "title": "Deadline Label"
+    },
+    "deadline_basis": {
+      "type": "string",
+      "title": "Deadline Basis"
+    },
+    "deadline_reviewed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Deadline Reviewed At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "requester_name",
+    "requester_email",
+    "date_received",
+    "statutory_deadline",
+    "description",
+    "status",
+    "assigned_to",
+    "created_by",
+    "created_at",
+    "response_draft",
+    "review_notes",
+    "desktop_id",
+    "public_tracking_number",
+    "submitted_via",
+    "deadline_label",
+    "deadline_basis",
+    "deadline_reviewed_at"
+  ],
+  "title": "NativeRequestRead"
+}
+
+
NoticeDocumentInput
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text"
+  ],
+  "title": "NoticeDocumentInput"
+}
+
+
NoticeDraft
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 100000,
+      "minLength": 1,
+      "title": "Body"
+    },
+    "notice_type": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Notice Type"
+    },
+    "statutory_basis": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Statutory Basis"
+    },
+    "event_date": {
+      "type": "string",
+      "format": "date",
+      "title": "Event Date"
+    },
+    "lead_days": {
+      "type": "integer",
+      "maximum": 365.0,
+      "minimum": 0.0,
+      "title": "Lead Days"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "body",
+    "notice_type",
+    "statutory_basis",
+    "event_date",
+    "lead_days"
+  ],
+  "title": "NoticeDraft"
+}
+
+
NoticeInput
+{
+  "properties": {
+    "notice_type": {
+      "type": "string",
+      "enum": [
+        "regular",
+        "special",
+        "emergency",
+        "closed_session",
+        "executive"
+      ],
+      "title": "Notice Type"
+    },
+    "posted_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Posted At"
+    },
+    "minimum_notice_hours": {
+      "type": "integer",
+      "minimum": 0.0,
+      "title": "Minimum Notice Hours"
+    },
+    "statutory_basis": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Basis"
+    },
+    "approved_by": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Approved By"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "notice_type",
+    "posted_at",
+    "minimum_notice_hours"
+  ],
+  "title": "NoticeInput"
+}
+
+
NoticeProofInput
+{
+  "properties": {
+    "location": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Location"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note",
+      "default": ""
+    },
+    "document_delivery_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Document Delivery Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "location"
+  ],
+  "title": "NoticeProofInput"
+}
+
+
NotificationLogRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "template_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Template Id"
+    },
+    "recipient_email": {
+      "type": "string",
+      "title": "Recipient Email"
+    },
+    "request_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Request Id"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "sent_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sent At"
+    },
+    "error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Message"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "template_id",
+    "recipient_email",
+    "request_id",
+    "channel",
+    "status",
+    "sent_at",
+    "error_message",
+    "created_at"
+  ],
+  "title": "NotificationLogRead"
+}
+
+
NotificationTemplateCreate
+{
+  "properties": {
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel",
+      "default": "email"
+    },
+    "subject_template": {
+      "type": "string",
+      "title": "Subject Template"
+    },
+    "body_template": {
+      "type": "string",
+      "title": "Body Template"
+    }
+  },
+  "type": "object",
+  "required": [
+    "event_type",
+    "subject_template",
+    "body_template"
+  ],
+  "title": "NotificationTemplateCreate"
+}
+
+
NotificationTemplateRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel"
+    },
+    "subject_template": {
+      "type": "string",
+      "title": "Subject Template"
+    },
+    "body_template": {
+      "type": "string",
+      "title": "Body Template"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "event_type",
+    "channel",
+    "subject_template",
+    "body_template",
+    "is_active",
+    "created_at"
+  ],
+  "title": "NotificationTemplateRead"
+}
+
+
NotificationTemplateUpdate
+{
+  "properties": {
+    "subject_template": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Subject Template"
+    },
+    "body_template": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Body Template"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "NotificationTemplateUpdate"
+}
+
+
NotificationView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "notification_id": {
+      "type": "string",
+      "title": "Notification Id"
+    },
+    "module_id": {
+      "type": "string",
+      "title": "Module Id"
+    },
+    "record_id": {
+      "type": "string",
+      "title": "Record Id"
+    },
+    "audience": {
+      "type": "string",
+      "title": "Audience"
+    },
+    "channel": {
+      "type": "string",
+      "title": "Channel"
+    },
+    "subject": {
+      "type": "string",
+      "title": "Subject"
+    },
+    "body": {
+      "type": "string",
+      "title": "Body"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    },
+    "sent_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sent At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "notification_id",
+    "module_id",
+    "record_id",
+    "audience",
+    "channel",
+    "subject",
+    "body",
+    "status",
+    "created_at_unix_seconds",
+    "sent_at_unix_seconds"
+  ],
+  "title": "NotificationView"
+}
+
+
OllamaModelInfo
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "size": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Size"
+    },
+    "details": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Details"
+    }
+  },
+  "type": "object",
+  "required": [
+    "name"
+  ],
+  "title": "OllamaModelInfo"
+}
+
+
OllamaStatus
+{
+  "properties": {
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "models": {
+      "items": {
+        "$ref": "#/components/schemas/OllamaModelInfo"
+      },
+      "type": "array",
+      "title": "Models"
+    }
+  },
+  "type": "object",
+  "required": [
+    "status",
+    "models"
+  ],
+  "title": "OllamaStatus"
+}
+
+
OperationalMetrics
+{
+  "properties": {
+    "average_response_time_days": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Average Response Time Days"
+    },
+    "median_response_time_days": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Median Response Time Days"
+    },
+    "requests_by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "Requests By Status"
+    },
+    "requests_by_department": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "Requests By Department"
+    },
+    "deadline_compliance_rate": {
+      "type": "number",
+      "title": "Deadline Compliance Rate"
+    },
+    "total_open": {
+      "type": "integer",
+      "title": "Total Open"
+    },
+    "total_closed": {
+      "type": "integer",
+      "title": "Total Closed"
+    },
+    "total_overdue": {
+      "type": "integer",
+      "title": "Total Overdue"
+    },
+    "clarification_frequency": {
+      "type": "number",
+      "title": "Clarification Frequency"
+    },
+    "top_request_topics": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Top Request Topics"
+    }
+  },
+  "type": "object",
+  "required": [
+    "average_response_time_days",
+    "median_response_time_days",
+    "requests_by_status",
+    "requests_by_department",
+    "deadline_compliance_rate",
+    "total_open",
+    "total_closed",
+    "total_overdue",
+    "clarification_frequency",
+    "top_request_topics"
+  ],
+  "title": "OperationalMetrics"
+}
+
+
Outline
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "question_ids": {
+      "items": {
+        "type": "string",
+        "format": "uuid"
+      },
+      "type": "array",
+      "maxItems": 50,
+      "minItems": 1,
+      "title": "Question Ids"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title",
+    "question_ids"
+  ],
+  "title": "Outline"
+}
+
+
Packet
+{
+  "properties": {
+    "expected_revision": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Expected Revision"
+    },
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "staff_only",
+        "records_copy"
+      ],
+      "title": "Visibility"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "expected_revision",
+    "visibility"
+  ],
+  "title": "Packet"
+}
+
+
PacketInput
+{
+  "properties": {
+    "agenda_item_ids": {
+      "items": {
+        "type": "string",
+        "format": "uuid"
+      },
+      "type": "array",
+      "title": "Agenda Item Ids"
+    },
+    "source_files": {
+      "items": {
+        "$ref": "#/components/schemas/ManagedSource"
+      },
+      "type": "array",
+      "title": "Source Files"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "agenda_item_ids"
+  ],
+  "title": "PacketInput"
+}
+
+
Pathway
+{
+  "properties": {
+    "project_type": {
+      "type": "string",
+      "maxLength": 120,
+      "minLength": 1,
+      "title": "Project Type"
+    },
+    "proposal": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Proposal",
+      "default": ""
+    },
+    "location_context": {
+      "type": "string",
+      "maxLength": 1000,
+      "title": "Location Context",
+      "default": ""
+    },
+    "requirement_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requirement Revision"
+    },
+    "fee_link": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "project_type"
+  ],
+  "title": "Pathway"
+}
+
+
PathwayStep
+{
+  "properties": {
+    "step": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Step"
+    },
+    "citation": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Citation"
+    },
+    "typical_time": {
+      "type": "string",
+      "maxLength": 1000,
+      "title": "Typical Time",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "step",
+    "citation"
+  ],
+  "title": "PathwayStep"
+}
+
+
PlainLanguageSummaryCreate
+{
+  "properties": {
+    "summary_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Summary Id"
+    },
+    "section_version_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Version Id"
+    },
+    "summary_text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Summary Text"
+    },
+    "language_code": {
+      "type": "string",
+      "title": "Language Code",
+      "default": "en"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "section_version_id",
+    "summary_text"
+  ],
+  "title": "PlainLanguageSummaryCreate",
+  "description": "Request body for staff-drafted plain-language summaries."
+}
+
+
PolicySelection
+{
+  "properties": {
+    "plan_id": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Plan Id"
+    },
+    "revision_id": {
+      "type": "string",
+      "maxLength": 36,
+      "minLength": 36,
+      "title": "Revision Id"
+    },
+    "policy_id": {
+      "type": "string",
+      "maxLength": 160,
+      "minLength": 1,
+      "title": "Policy Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "plan_id",
+    "revision_id",
+    "policy_id"
+  ],
+  "title": "PolicySelection"
+}
+
+
PortalModeResponse
+{
+  "properties": {
+    "mode": {
+      "type": "string",
+      "enum": [
+        "public",
+        "private"
+      ],
+      "title": "Mode",
+      "description": "Active portal posture for this deployment. ``public`` = minimal resident surface (landing + authenticated records-request submission + resident registration) reachable without staff auth. ``private`` = staff-only; no public routes, no resident self-registration."
+    }
+  },
+  "type": "object",
+  "required": [
+    "mode"
+  ],
+  "title": "PortalModeResponse",
+  "description": "T5D — schema for ``GET /config/portal-mode``.\n\nExposed to the frontend on boot so it can branch routing without a\nuser-identity lookup. The payload is intentionally the single field\nbelow — no staff config, no user state, no schema version."
+}
+
+
PrepareArtifact
+{
+  "properties": {
+    "kind": {
+      "type": "string",
+      "enum": [
+        "response",
+        "release-package"
+      ],
+      "title": "Kind"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "kind"
+  ],
+  "title": "PrepareArtifact"
+}
+
+
Proof
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    },
+    "filename": {
+      "type": "string",
+      "maxLength": 150,
+      "minLength": 1,
+      "title": "Filename"
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 7000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "location": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Location"
+    },
+    "published_at": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Published At"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence",
+    "filename",
+    "content_base64",
+    "location",
+    "published_at"
+  ],
+  "title": "Proof"
+}
+
+
Proposal
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "pattern": "^[A-Za-z0-9_-]{1,64}$",
+      "title": "Id"
+    },
+    "version_id": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Version Id"
+    },
+    "meeting_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Meeting Id"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "ordinance_number": {
+      "type": "string",
+      "maxLength": 120,
+      "minLength": 1,
+      "title": "Ordinance Number"
+    },
+    "proposed_text": {
+      "type": "string",
+      "maxLength": 1000000,
+      "minLength": 1,
+      "title": "Proposed Text"
+    },
+    "supersedes_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^[A-Za-z0-9_-]{1,64}$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Supersedes Id"
+    },
+    "reconciliation_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Reconciliation Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "version_id",
+    "meeting_id",
+    "title",
+    "ordinance_number",
+    "proposed_text"
+  ],
+  "title": "Proposal"
+}
+
+
PublicExplore
+{
+  "properties": {
+    "goal": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Goal",
+      "default": ""
+    },
+    "topic": {
+      "type": "string",
+      "maxLength": 160,
+      "title": "Topic",
+      "default": ""
+    },
+    "neighborhood": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Neighborhood",
+      "default": ""
+    },
+    "plan_type": {
+      "type": "string",
+      "maxLength": 120,
+      "title": "Plan Type",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "PublicExplore"
+}
+
+
PublicIntake
+{
+  "properties": {
+    "requester": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requester"
+    },
+    "requesterContact": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestercontact"
+    },
+    "summary": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Summary"
+    },
+    "deadline": {
+      "type": "string",
+      "title": "Deadline",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requester",
+    "requesterContact",
+    "summary"
+  ],
+  "title": "PublicIntake"
+}
+
+
PublicLookup
+{
+  "properties": {
+    "trackingNumber": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Trackingnumber"
+    },
+    "requesterContact": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestercontact"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "trackingNumber",
+    "requesterContact"
+  ],
+  "title": "PublicLookup"
+}
+
+
PublicMessage
+{
+  "properties": {
+    "trackingNumber": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Trackingnumber"
+    },
+    "requesterContact": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requestercontact"
+    },
+    "publicRequestMessage": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Publicrequestmessage"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "trackingNumber",
+    "requesterContact",
+    "publicRequestMessage"
+  ],
+  "title": "PublicMessage"
+}
+
+
PublicStatusView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "label": {
+      "type": "string",
+      "title": "Label"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "label",
+    "summary",
+    "status",
+    "created_at_unix_seconds"
+  ],
+  "title": "PublicStatusView"
+}
+
+
PublicationView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "source_module": {
+      "type": "string",
+      "title": "Source Module"
+    },
+    "source_record_id": {
+      "type": "string",
+      "title": "Source Record Id"
+    },
+    "record_type": {
+      "type": "string",
+      "title": "Record Type"
+    },
+    "public_payload": {
+      "type": "string",
+      "title": "Public Payload"
+    },
+    "payload_hash": {
+      "type": "string",
+      "title": "Payload Hash"
+    },
+    "published_at_unix_seconds": {
+      "type": "integer",
+      "title": "Published At Unix Seconds"
+    },
+    "retracted_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Retracted At Unix Seconds"
+    },
+    "retracted_by": {
+      "type": "string",
+      "title": "Retracted By",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "source_module",
+    "source_record_id",
+    "record_type",
+    "public_payload",
+    "payload_hash",
+    "published_at_unix_seconds"
+  ],
+  "title": "PublicationView"
+}
+
+
PublishingPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "publishing-workflow",
+      "title": "Action"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "hasReview": {
+      "type": "boolean",
+      "title": "Hasreview",
+      "default": false
+    },
+    "hasPlainLanguage": {
+      "type": "boolean",
+      "title": "Hasplainlanguage",
+      "default": false
+    },
+    "hasTranslationReview": {
+      "type": "boolean",
+      "title": "Hastranslationreview",
+      "default": false
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "PublishingPlan"
+}
+
+
Question
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    },
+    "question": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Question"
+    },
+    "kind": {
+      "type": "string",
+      "enum": [
+        "use",
+        "dimension"
+      ],
+      "title": "Kind"
+    },
+    "key": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Key"
+    },
+    "audience": {
+      "type": "string",
+      "enum": [
+        "resident",
+        "staff"
+      ],
+      "title": "Audience",
+      "default": "resident"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "query",
+    "question",
+    "kind",
+    "key"
+  ],
+  "title": "Question"
+}
+
+
QuestionAnswerRequest
+{
+  "properties": {
+    "question": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Question"
+    },
+    "section_number": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Section Number"
+    },
+    "as_of": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "As Of"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "question"
+  ],
+  "title": "QuestionAnswerRequest",
+  "description": "Request body for citation-grounded code Q&A."
+}
+
+
RecordsDocumentView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "attachment_id": {
+      "type": "string",
+      "title": "Attachment Id"
+    },
+    "title": {
+      "type": "string",
+      "title": "Title"
+    },
+    "original_path": {
+      "type": "string",
+      "title": "Original Path"
+    },
+    "stored_path": {
+      "type": "string",
+      "title": "Stored Path"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation"
+    },
+    "sha256": {
+      "type": "string",
+      "title": "Sha256"
+    },
+    "size_bytes": {
+      "type": "integer",
+      "title": "Size Bytes"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "added_by": {
+      "type": "string",
+      "title": "Added By"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    },
+    "release_original_path": {
+      "type": "string",
+      "title": "Release Original Path",
+      "default": ""
+    },
+    "release_stored_path": {
+      "type": "string",
+      "title": "Release Stored Path",
+      "default": ""
+    },
+    "release_file_name": {
+      "type": "string",
+      "title": "Release File Name",
+      "default": ""
+    },
+    "release_sha256": {
+      "type": "string",
+      "title": "Release Sha256",
+      "default": ""
+    },
+    "release_size_bytes": {
+      "type": "integer",
+      "title": "Release Size Bytes",
+      "default": 0
+    },
+    "release_status": {
+      "type": "string",
+      "title": "Release Status",
+      "default": ""
+    },
+    "release_note": {
+      "type": "string",
+      "title": "Release Note",
+      "default": ""
+    },
+    "release_added_by": {
+      "type": "string",
+      "title": "Release Added By",
+      "default": ""
+    },
+    "release_added_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Release Added At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "attachment_id",
+    "title",
+    "original_path",
+    "stored_path",
+    "citation",
+    "sha256",
+    "size_bytes",
+    "status",
+    "added_by",
+    "created_at_unix_seconds"
+  ],
+  "title": "RecordsDocumentView"
+}
+
+
RecordsOperationRead
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "message": {
+      "type": "string",
+      "title": "Message"
+    },
+    "request": {
+      "$ref": "#/components/schemas/RecordsView"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "message",
+    "request"
+  ],
+  "title": "RecordsOperationRead"
+}
+
+
RecordsStateRead
+{
+  "properties": {
+    "demo_fixture": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Demo Fixture"
+    },
+    "records_requests": {
+      "items": {
+        "$ref": "#/components/schemas/RecordsView"
+      },
+      "type": "array",
+      "title": "Records Requests"
+    },
+    "notification_events": {
+      "items": {
+        "$ref": "#/components/schemas/NotificationView"
+      },
+      "type": "array",
+      "title": "Notification Events"
+    },
+    "publication_events": {
+      "items": {
+        "$ref": "#/components/schemas/PublicationView"
+      },
+      "type": "array",
+      "title": "Publication Events"
+    },
+    "audit_entries": {
+      "items": {
+        "$ref": "#/components/schemas/AuditView"
+      },
+      "type": "array",
+      "title": "Audit Entries"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "records_requests"
+  ],
+  "title": "RecordsStateRead"
+}
+
+
RecordsView
+{
+  "properties": {
+    "request_id": {
+      "type": "string",
+      "title": "Request Id"
+    },
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "public_tracking_number": {
+      "type": "string",
+      "title": "Public Tracking Number"
+    },
+    "requester": {
+      "type": "string",
+      "title": "Requester"
+    },
+    "requester_contact": {
+      "type": "string",
+      "title": "Requester Contact"
+    },
+    "submitted_via": {
+      "type": "string",
+      "title": "Submitted Via"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "deadline": {
+      "type": "string",
+      "title": "Deadline"
+    },
+    "deadline_basis": {
+      "type": "string",
+      "title": "Deadline Basis"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "assigned_to": {
+      "type": "string",
+      "title": "Assigned To"
+    },
+    "clarification_notes": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Clarification Notes"
+    },
+    "search_notes": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Search Notes"
+    },
+    "search_sessions": {
+      "items": {
+        "$ref": "#/components/schemas/SearchReceiptView"
+      },
+      "type": "array",
+      "title": "Search Sessions"
+    },
+    "exemption_reviews": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Exemption Reviews"
+    },
+    "exemption_decisions": {
+      "items": {
+        "$ref": "#/components/schemas/ExemptionDecisionView"
+      },
+      "type": "array",
+      "title": "Exemption Decisions"
+    },
+    "fee_estimate": {
+      "type": "string",
+      "title": "Fee Estimate"
+    },
+    "fee_line_items": {
+      "items": {
+        "$ref": "#/components/schemas/FeeLineView"
+      },
+      "type": "array",
+      "title": "Fee Line Items"
+    },
+    "fee_waiver_reason": {
+      "type": "string",
+      "title": "Fee Waiver Reason"
+    },
+    "citations": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Citations"
+    },
+    "response_draft": {
+      "type": "string",
+      "title": "Response Draft"
+    },
+    "approval_notes": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Approval Notes"
+    },
+    "exports": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Exports"
+    },
+    "documents": {
+      "items": {
+        "$ref": "#/components/schemas/RecordsDocumentView"
+      },
+      "type": "array",
+      "title": "Documents"
+    },
+    "release_packages": {
+      "items": {
+        "$ref": "#/components/schemas/ReleasePackageView"
+      },
+      "type": "array",
+      "title": "Release Packages"
+    },
+    "timeline": {
+      "items": {
+        "$ref": "#/components/schemas/TimelineView"
+      },
+      "type": "array",
+      "title": "Timeline"
+    },
+    "public_status_events": {
+      "items": {
+        "$ref": "#/components/schemas/PublicStatusView"
+      },
+      "type": "array",
+      "title": "Public Status Events"
+    },
+    "messages": {
+      "items": {
+        "$ref": "#/components/schemas/MessageView"
+      },
+      "type": "array",
+      "title": "Messages"
+    },
+    "deadline_reviewed_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Deadline Reviewed At Unix Seconds"
+    },
+    "approved_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Approved At Unix Seconds"
+    },
+    "fulfilled_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fulfilled At Unix Seconds"
+    },
+    "closed_at_unix_seconds": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closed At Unix Seconds"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "request_id",
+    "id",
+    "public_tracking_number",
+    "requester",
+    "requester_contact",
+    "submitted_via",
+    "summary",
+    "deadline",
+    "deadline_basis",
+    "status",
+    "assigned_to",
+    "clarification_notes",
+    "search_notes",
+    "search_sessions",
+    "exemption_reviews",
+    "exemption_decisions",
+    "fee_estimate",
+    "fee_line_items",
+    "fee_waiver_reason",
+    "citations",
+    "response_draft",
+    "approval_notes",
+    "exports",
+    "timeline",
+    "public_status_events",
+    "messages",
+    "deadline_reviewed_at_unix_seconds",
+    "approved_at_unix_seconds",
+    "fulfilled_at_unix_seconds",
+    "closed_at_unix_seconds",
+    "created_at_unix_seconds"
+  ],
+  "title": "RecordsView"
+}
+
+
ReleasePackageView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "export_path": {
+      "type": "string",
+      "title": "Export Path"
+    },
+    "package_hash": {
+      "type": "string",
+      "title": "Package Hash"
+    },
+    "document_count": {
+      "type": "integer",
+      "title": "Document Count"
+    },
+    "release_artifact_count": {
+      "type": "integer",
+      "title": "Release Artifact Count"
+    },
+    "search_session_count": {
+      "type": "integer",
+      "title": "Search Session Count"
+    },
+    "release_count": {
+      "type": "integer",
+      "title": "Release Count"
+    },
+    "redacted_count": {
+      "type": "integer",
+      "title": "Redacted Count"
+    },
+    "exempt_count": {
+      "type": "integer",
+      "title": "Exempt Count"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "export_path",
+    "package_hash",
+    "document_count",
+    "release_artifact_count",
+    "search_session_count",
+    "release_count",
+    "redacted_count",
+    "exempt_count",
+    "created_at_unix_seconds"
+  ],
+  "title": "ReleasePackageView"
+}
+
+
RepeatLookup
+{
+  "properties": {
+    "property_reference": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Property Reference"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "property_reference"
+  ],
+  "title": "RepeatLookup"
+}
+
+
RequestCreate
+{
+  "properties": {
+    "requester_name": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Requester Name"
+    },
+    "requester_email": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 255
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Email"
+    },
+    "requester_phone": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 50
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Phone"
+    },
+    "requester_type": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 100
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Type"
+    },
+    "description": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Description"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "priority": {
+      "type": "string",
+      "title": "Priority",
+      "default": "normal"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string",
+          "pattern": "^(narrow|moderate|broad)$"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "requester_name",
+    "description"
+  ],
+  "title": "RequestCreate"
+}
+
+
RequestDocumentAdd
+{
+  "properties": {
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "relevance_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Relevance Note"
+    }
+  },
+  "type": "object",
+  "required": [
+    "document_id"
+  ],
+  "title": "RequestDocumentAdd"
+}
+
+
RequestDocumentRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "relevance_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Relevance Note"
+    },
+    "exemption_flags": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Exemption Flags"
+    },
+    "inclusion_status": {
+      "$ref": "#/components/schemas/InclusionStatus"
+    },
+    "attached_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Attached At"
+    },
+    "attached_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Attached By"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "document_id",
+    "relevance_note",
+    "exemption_flags",
+    "inclusion_status",
+    "attached_at",
+    "attached_by"
+  ],
+  "title": "RequestDocumentRead"
+}
+
+
RequestRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "requester_name": {
+      "type": "string",
+      "title": "Requester Name"
+    },
+    "requester_email": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Email"
+    },
+    "requester_phone": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Phone"
+    },
+    "requester_type": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Requester Type"
+    },
+    "date_received": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Date Received"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "status": {
+      "$ref": "#/components/schemas/RequestStatus"
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "created_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "response_draft": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Response Draft"
+    },
+    "review_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Review Notes"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    },
+    "estimated_fee": {
+      "anyOf": [
+        {
+          "type": "number"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Estimated Fee"
+    },
+    "fee_status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Fee Status"
+    },
+    "fee_waiver_requested": {
+      "type": "boolean",
+      "title": "Fee Waiver Requested",
+      "default": false
+    },
+    "priority": {
+      "type": "string",
+      "title": "Priority",
+      "default": "normal"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    },
+    "closed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closed At"
+    },
+    "closure_reason": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Closure Reason"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "requester_name",
+    "requester_email",
+    "date_received",
+    "statutory_deadline",
+    "description",
+    "status",
+    "assigned_to",
+    "created_by",
+    "created_at",
+    "response_draft",
+    "review_notes"
+  ],
+  "title": "RequestRead"
+}
+
+
RequestStats
+{
+  "properties": {
+    "total_requests": {
+      "type": "integer",
+      "title": "Total Requests"
+    },
+    "by_status": {
+      "additionalProperties": {
+        "type": "integer"
+      },
+      "type": "object",
+      "title": "By Status"
+    },
+    "approaching_deadline": {
+      "type": "integer",
+      "title": "Approaching Deadline"
+    },
+    "overdue": {
+      "type": "integer",
+      "title": "Overdue"
+    }
+  },
+  "type": "object",
+  "required": [
+    "total_requests",
+    "by_status",
+    "approaching_deadline",
+    "overdue"
+  ],
+  "title": "RequestStats"
+}
+
+
RequestStatus
+{
+  "type": "string",
+  "enum": [
+    "received",
+    "clarification_needed",
+    "assigned",
+    "searching",
+    "in_review",
+    "ready_for_release",
+    "drafted",
+    "approved",
+    "fulfilled",
+    "closed"
+  ],
+  "title": "RequestStatus"
+}
+
+
RequestUpdate
+{
+  "properties": {
+    "description": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Description"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/RequestStatus"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    },
+    "assigned_to": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Assigned To"
+    },
+    "response_draft": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Response Draft"
+    },
+    "statutory_deadline": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Statutory Deadline"
+    },
+    "scope_assessment": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Scope Assessment"
+    }
+  },
+  "type": "object",
+  "title": "RequestUpdate"
+}
+
+
RequirementBundle
+{
+  "properties": {
+    "requirement_id": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9_-]{1,100}$",
+      "title": "Requirement Id"
+    },
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Title"
+    },
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "project_type": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Project Type"
+    },
+    "source_reference": {
+      "type": "string",
+      "maxLength": 1000,
+      "minLength": 1,
+      "title": "Source Reference"
+    },
+    "source_date": {
+      "type": "string",
+      "format": "date",
+      "title": "Source Date"
+    },
+    "effective_on": {
+      "type": "string",
+      "format": "date",
+      "title": "Effective On"
+    },
+    "dataset_kind": {
+      "type": "string",
+      "enum": [
+        "municipal",
+        "fictional"
+      ],
+      "title": "Dataset Kind"
+    },
+    "filename": {
+      "type": "string",
+      "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$",
+      "title": "Filename"
+    },
+    "content_base64": {
+      "type": "string",
+      "maxLength": 14000000,
+      "minLength": 1,
+      "title": "Content Base64"
+    },
+    "sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Sha256"
+    },
+    "materials": {
+      "items": {
+        "$ref": "#/components/schemas/Material"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "minItems": 1,
+      "title": "Materials"
+    },
+    "pathway": {
+      "items": {
+        "$ref": "#/components/schemas/PathwayStep"
+      },
+      "type": "array",
+      "maxItems": 100,
+      "title": "Pathway"
+    },
+    "fee_link": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/townlight_permitting__workflow_models__SourceLink"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    },
+    "staff_note": {
+      "type": "string",
+      "maxLength": 4000,
+      "title": "Staff Note",
+      "default": ""
+    },
+    "change_note": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Change Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requirement_id",
+    "title",
+    "jurisdiction",
+    "project_type",
+    "source_reference",
+    "source_date",
+    "effective_on",
+    "dataset_kind",
+    "filename",
+    "content_base64",
+    "sha256",
+    "materials",
+    "change_note"
+  ],
+  "title": "RequirementBundle"
+}
+
+
ResponseLetterCreate
+{
+  "properties": {
+    "template_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Template Id"
+    }
+  },
+  "type": "object",
+  "title": "ResponseLetterCreate"
+}
+
+
ResponseLetterRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "template_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Template Id"
+    },
+    "generated_content": {
+      "type": "string",
+      "title": "Generated Content"
+    },
+    "edited_content": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Edited Content"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "generated_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Generated By"
+    },
+    "approved_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Approved By"
+    },
+    "sent_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Sent At"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "template_id",
+    "generated_content",
+    "edited_content",
+    "status",
+    "generated_by",
+    "approved_by",
+    "sent_at",
+    "created_at"
+  ],
+  "title": "ResponseLetterRead"
+}
+
+
ResponseLetterUpdate
+{
+  "properties": {
+    "edited_content": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Edited Content"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Status"
+    }
+  },
+  "type": "object",
+  "title": "ResponseLetterUpdate"
+}
+
+
ReviewInput
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 5000,
+      "title": "Body",
+      "default": ""
+    },
+    "hasAltText": {
+      "type": "boolean",
+      "title": "Hasalttext",
+      "default": false
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": "en"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "ReviewInput"
+}
+
+
Revision
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    },
+    "document": {
+      "$ref": "#/components/schemas/NoticeDraft"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence",
+    "document"
+  ],
+  "title": "Revision"
+}
+
+
RewriteInput
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "plain-language",
+        "language-variant"
+      ],
+      "title": "Action"
+    },
+    "text": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Text"
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "text"
+  ],
+  "title": "RewriteInput"
+}
+
+
RewriteResult
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "enum": [
+        "plain-language",
+        "language-variant"
+      ],
+      "title": "Action"
+    },
+    "text": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Text"
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": ""
+    },
+    "outcome": {
+      "type": "string",
+      "enum": [
+        "generated",
+        "unavailable"
+      ],
+      "title": "Outcome"
+    },
+    "generated": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 100000
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Generated"
+    },
+    "model": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 200
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Model"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "text",
+    "outcome"
+  ],
+  "title": "RewriteResult"
+}
+
+
Rule
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "zone_code": {
+      "type": "string",
+      "maxLength": 80,
+      "minLength": 1,
+      "title": "Zone Code"
+    },
+    "key": {
+      "type": "string",
+      "maxLength": 120,
+      "minLength": 1,
+      "title": "Key"
+    },
+    "section_number": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Section Number"
+    },
+    "kind": {
+      "type": "string",
+      "enum": [
+        "use",
+        "dimension"
+      ],
+      "title": "Kind"
+    },
+    "value": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Value"
+    },
+    "overlay_code": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 255
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Overlay Code"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "zone_code",
+    "key",
+    "section_number",
+    "kind",
+    "value"
+  ],
+  "title": "Rule"
+}
+
+
RuleTestMatch
+{
+  "properties": {
+    "matched_text": {
+      "type": "string",
+      "title": "Matched Text"
+    },
+    "start": {
+      "type": "integer",
+      "title": "Start"
+    },
+    "end": {
+      "type": "integer",
+      "title": "End"
+    }
+  },
+  "type": "object",
+  "required": [
+    "matched_text",
+    "start",
+    "end"
+  ],
+  "title": "RuleTestMatch"
+}
+
+
RuleTestRequest
+{
+  "properties": {
+    "sample_text": {
+      "type": "string",
+      "title": "Sample Text"
+    }
+  },
+  "type": "object",
+  "required": [
+    "sample_text"
+  ],
+  "title": "RuleTestRequest"
+}
+
+
RuleTestResponse
+{
+  "properties": {
+    "rule_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Rule Id"
+    },
+    "rule_type": {
+      "type": "string",
+      "title": "Rule Type"
+    },
+    "matched": {
+      "type": "boolean",
+      "title": "Matched"
+    },
+    "matches": {
+      "items": {
+        "$ref": "#/components/schemas/RuleTestMatch"
+      },
+      "type": "array",
+      "title": "Matches"
+    }
+  },
+  "type": "object",
+  "required": [
+    "rule_id",
+    "rule_type",
+    "matched",
+    "matches"
+  ],
+  "title": "RuleTestResponse"
+}
+
+
RuleType
+{
+  "type": "string",
+  "enum": [
+    "regex",
+    "keyword",
+    "llm_prompt"
+  ],
+  "title": "RuleType"
+}
+
+
SaveReview
+{
+  "properties": {
+    "title": {
+      "type": "string",
+      "maxLength": 500,
+      "title": "Title",
+      "default": ""
+    },
+    "body": {
+      "type": "string",
+      "maxLength": 5000,
+      "title": "Body",
+      "default": ""
+    },
+    "hasAltText": {
+      "type": "boolean",
+      "title": "Hasalttext",
+      "default": false
+    },
+    "language": {
+      "type": "string",
+      "maxLength": 80,
+      "title": "Language",
+      "default": "en"
+    },
+    "ai_analysis": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 100000
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ai Analysis"
+    },
+    "ai_analysis_model": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 200
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Ai Analysis Model"
+    },
+    "ai_outcome": {
+      "type": "string",
+      "enum": [
+        "generated",
+        "unavailable",
+        "failed"
+      ],
+      "title": "Ai Outcome"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "ai_outcome"
+  ],
+  "title": "SaveReview"
+}
+
+
SearchFilterOptions
+{
+  "properties": {
+    "file_types": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "File Types"
+    },
+    "source_names": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Source Names"
+    },
+    "departments": {
+      "items": {
+        "additionalProperties": true,
+        "type": "object"
+      },
+      "type": "array",
+      "title": "Departments",
+      "default": []
+    },
+    "date_range": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Date Range"
+    }
+  },
+  "type": "object",
+  "required": [
+    "file_types",
+    "source_names"
+  ],
+  "title": "SearchFilterOptions"
+}
+
+
SearchInput
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "SearchInput"
+}
+
+
SearchNoteCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "record-records-search",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/SearchNotePayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "SearchNoteCommand"
+}
+
+
SearchNotePayload
+{
+  "properties": {
+    "sourceNote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Sourcenote"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sourceNote"
+  ],
+  "title": "SearchNotePayload"
+}
+
+
SearchReceiptCommand
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "record-records-search-session",
+      "title": "Action"
+    },
+    "payload": {
+      "$ref": "#/components/schemas/SearchReceiptPayload"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action",
+    "payload"
+  ],
+  "title": "SearchReceiptCommand"
+}
+
+
SearchReceiptPayload
+{
+  "properties": {
+    "searchQuery": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchquery"
+    },
+    "searchLocations": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchlocations"
+    },
+    "searchResultTitle": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchresulttitle"
+    },
+    "searchResultCitation": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchresultcitation"
+    },
+    "searchResultSummary": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Searchresultsummary"
+    },
+    "searchResultStatus": {
+      "type": "string",
+      "title": "Searchresultstatus",
+      "default": ""
+    },
+    "searchReviewer": {
+      "type": "string",
+      "title": "Searchreviewer",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "searchQuery",
+    "searchLocations",
+    "searchResultTitle",
+    "searchResultCitation",
+    "searchResultSummary"
+  ],
+  "title": "SearchReceiptPayload"
+}
+
+
SearchReceiptView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "query": {
+      "type": "string",
+      "title": "Query"
+    },
+    "locations": {
+      "type": "string",
+      "title": "Locations"
+    },
+    "reviewer": {
+      "type": "string",
+      "title": "Reviewer"
+    },
+    "results": {
+      "items": {
+        "$ref": "#/components/schemas/SearchResultView"
+      },
+      "type": "array",
+      "title": "Results"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "query",
+    "locations",
+    "reviewer",
+    "results",
+    "created_at_unix_seconds"
+  ],
+  "title": "SearchReceiptView"
+}
+
+
SearchRequest
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "title": "Query"
+    },
+    "session_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Session Id"
+    },
+    "filters": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Filters"
+    },
+    "limit": {
+      "type": "integer",
+      "maximum": 50.0,
+      "title": "Limit",
+      "default": 10
+    },
+    "synthesize": {
+      "type": "boolean",
+      "title": "Synthesize",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "SearchRequest"
+}
+
+
SearchResponse
+{
+  "properties": {
+    "query_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Query Id"
+    },
+    "session_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Session Id"
+    },
+    "query_text": {
+      "type": "string",
+      "title": "Query Text"
+    },
+    "results": {
+      "items": {
+        "$ref": "#/components/schemas/SearchResultItem"
+      },
+      "type": "array",
+      "title": "Results"
+    },
+    "results_count": {
+      "type": "integer",
+      "title": "Results Count"
+    },
+    "synthesized_answer": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Synthesized Answer"
+    },
+    "ai_generated": {
+      "type": "boolean",
+      "title": "Ai Generated",
+      "default": false
+    }
+  },
+  "type": "object",
+  "required": [
+    "query_id",
+    "session_id",
+    "query_text",
+    "results",
+    "results_count"
+  ],
+  "title": "SearchResponse"
+}
+
+
SearchResultItem
+{
+  "properties": {
+    "chunk_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Chunk Id"
+    },
+    "document_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Document Id"
+    },
+    "filename": {
+      "type": "string",
+      "title": "Filename"
+    },
+    "file_type": {
+      "type": "string",
+      "title": "File Type"
+    },
+    "source_path": {
+      "type": "string",
+      "title": "Source Path"
+    },
+    "page_number": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Page Number"
+    },
+    "content_text": {
+      "type": "string",
+      "title": "Content Text"
+    },
+    "similarity_score": {
+      "type": "number",
+      "title": "Similarity Score"
+    },
+    "rank": {
+      "type": "integer",
+      "title": "Rank"
+    }
+  },
+  "type": "object",
+  "required": [
+    "chunk_id",
+    "document_id",
+    "filename",
+    "file_type",
+    "source_path",
+    "page_number",
+    "content_text",
+    "similarity_score",
+    "rank"
+  ],
+  "title": "SearchResultItem"
+}
+
+
SearchResultView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "title": {
+      "type": "string",
+      "title": "Title"
+    },
+    "citation": {
+      "type": "string",
+      "title": "Citation"
+    },
+    "summary": {
+      "type": "string",
+      "title": "Summary"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "title",
+    "citation",
+    "summary",
+    "status"
+  ],
+  "title": "SearchResultView"
+}
+
+
SearchSessionRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "user_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "User Id"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "queries": {
+      "items": {
+        "additionalProperties": true,
+        "type": "object"
+      },
+      "type": "array",
+      "title": "Queries",
+      "default": []
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "user_id",
+    "created_at"
+  ],
+  "title": "SearchSessionRead"
+}
+
+
SectionCreate
+{
+  "properties": {
+    "section_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Section Id"
+    },
+    "chapter_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Chapter Id"
+    },
+    "section_number": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Number"
+    },
+    "section_heading": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Heading"
+    },
+    "parent_section_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Parent Section Id"
+    },
+    "sort_order": {
+      "type": "integer",
+      "title": "Sort Order",
+      "default": 0
+    },
+    "administrative_regulation_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Administrative Regulation Refs"
+    },
+    "resolution_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Resolution Refs"
+    },
+    "policy_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Policy Refs"
+    },
+    "approved_summary_refs": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Approved Summary Refs"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "chapter_id",
+    "section_number",
+    "section_heading"
+  ],
+  "title": "SectionCreate",
+  "description": "Request body for creating a code section or subsection."
+}
+
+
SectionVersionCreate
+{
+  "properties": {
+    "version_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Version Id"
+    },
+    "section_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Section Id"
+    },
+    "source_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "version_label": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Version Label"
+    },
+    "body": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Body"
+    },
+    "effective_start": {
+      "type": "string",
+      "format": "date",
+      "title": "Effective Start"
+    },
+    "effective_end": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Effective End"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    },
+    "is_current": {
+      "type": "boolean",
+      "title": "Is Current",
+      "default": false
+    },
+    "adoption_event_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Adoption Event Id"
+    },
+    "amendment_event_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Amendment Event Id"
+    },
+    "amendment_summary": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Amendment Summary"
+    },
+    "prior_version_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Prior Version Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "section_id",
+    "source_id",
+    "version_label",
+    "body",
+    "effective_start"
+  ],
+  "title": "SectionVersionCreate",
+  "description": "Request body for adding an immutable section version."
+}
+
+
Selection
+{
+  "properties": {
+    "recording_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Recording Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[0-9a-f]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "recording_id",
+    "expected_sha256"
+  ],
+  "title": "Selection"
+}
+
+
SentenceInput
+{
+  "properties": {
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    },
+    "citations": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "title": "Citations"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "text"
+  ],
+  "title": "SentenceInput"
+}
+
+
ServiceAccountCreate
+{
+  "properties": {
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole",
+      "default": "read_only"
+    }
+  },
+  "type": "object",
+  "required": [
+    "name"
+  ],
+  "title": "ServiceAccountCreate"
+}
+
+
ServiceAccountCreated
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    },
+    "api_key": {
+      "type": "string",
+      "title": "Api Key"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "role",
+    "created_by",
+    "created_at",
+    "is_active",
+    "api_key"
+  ],
+  "title": "ServiceAccountCreated",
+  "description": "Returned only on creation — includes the plaintext API key (shown once)."
+}
+
+
ServiceAccountRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "name": {
+      "type": "string",
+      "title": "Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole"
+    },
+    "created_by": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Created By"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "name",
+    "role",
+    "created_by",
+    "created_at",
+    "is_active"
+  ],
+  "title": "ServiceAccountRead"
+}
+
+
ServiceAccountUpdate
+{
+  "properties": {
+    "role": {
+      "anyOf": [
+        {
+          "$ref": "#/components/schemas/UserRole"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "ServiceAccountUpdate"
+}
+
+
Snapshot
+{
+  "properties": {
+    "expected_revision": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Expected Revision"
+    },
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "staff_only",
+        "public"
+      ],
+      "title": "Visibility"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "expected_revision",
+    "visibility"
+  ],
+  "title": "Snapshot"
+}
+
+
SourceCreate
+{
+  "properties": {
+    "source_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Id"
+    },
+    "name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Name"
+    },
+    "publisher": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Publisher"
+    },
+    "source_type": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Type"
+    },
+    "source_category": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Category"
+    },
+    "source_url": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Url"
+    },
+    "file_reference": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "File Reference"
+    },
+    "retrieved_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Retrieved At"
+    },
+    "retrieval_method": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Retrieval Method"
+    },
+    "checksum": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Checksum"
+    },
+    "source_owner": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Source Owner"
+    },
+    "is_official": {
+      "type": "boolean",
+      "title": "Is Official",
+      "default": true
+    },
+    "official_status_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Official Status Note"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status",
+      "default": "draft"
+    },
+    "staff_notes": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Staff Notes"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "name",
+    "publisher",
+    "source_type",
+    "source_category"
+  ],
+  "title": "SourceCreate",
+  "description": "Request body for registering an official or explicitly labeled source."
+}
+
+
SourceInput
+{
+  "properties": {
+    "source_id": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "label": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Label"
+    },
+    "text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Text"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "label",
+    "text"
+  ],
+  "title": "SourceInput"
+}
+
+
SourceSnapshot
+{
+  "properties": {
+    "visibility": {
+      "type": "string",
+      "enum": [
+        "public",
+        "staff_only"
+      ],
+      "title": "Visibility"
+    },
+    "meeting_event_ids": {
+      "items": {
+        "type": "string",
+        "format": "uuid"
+      },
+      "type": "array",
+      "maxItems": 50,
+      "title": "Meeting Event Ids"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "visibility"
+  ],
+  "title": "SourceSnapshot"
+}
+
+
SourceType
+{
+  "type": "string",
+  "enum": [
+    "manual_drop",
+    "file_system",
+    "rest_api",
+    "odbc"
+  ],
+  "title": "SourceType"
+}
+
+
StaffRecordsIntake
+{
+  "properties": {
+    "requester": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Requester"
+    },
+    "summary": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Summary"
+    },
+    "deadline": {
+      "type": "string",
+      "title": "Deadline"
+    },
+    "deadlineBasis": {
+      "type": "string",
+      "title": "Deadlinebasis",
+      "default": ""
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "requester",
+    "summary",
+    "deadline"
+  ],
+  "title": "StaffRecordsIntake",
+  "description": "Existing native create-records-request input; no caller-supplied actor."
+}
+
+
StandardsExplanation
+{
+  "properties": {
+    "question": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Question"
+    },
+    "process_section": {
+      "type": "string",
+      "maxLength": 255,
+      "title": "Process Section",
+      "default": ""
+    },
+    "zone_code": {
+      "type": "string",
+      "maxLength": 40,
+      "title": "Zone Code",
+      "default": ""
+    },
+    "rule_types": {
+      "items": {
+        "type": "string"
+      },
+      "type": "array",
+      "maxItems": 10,
+      "title": "Rule Types"
+    },
+    "observed": {
+      "additionalProperties": {
+        "type": "string"
+      },
+      "type": "object",
+      "title": "Observed"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "question"
+  ],
+  "title": "StandardsExplanation"
+}
+
+
SyncFailureRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "source_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Source Id"
+    },
+    "source_path": {
+      "type": "string",
+      "title": "Source Path"
+    },
+    "error_message": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Message"
+    },
+    "error_class": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Class"
+    },
+    "http_status_code": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Http Status Code"
+    },
+    "retry_count": {
+      "type": "integer",
+      "title": "Retry Count"
+    },
+    "status": {
+      "type": "string",
+      "title": "Status"
+    },
+    "first_failed_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "First Failed At"
+    },
+    "last_retried_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Retried At"
+    },
+    "dismissed_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Dismissed At"
+    },
+    "dismissed_by": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Dismissed By"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "source_id",
+    "source_path",
+    "error_message",
+    "error_class",
+    "http_status_code",
+    "retry_count",
+    "status",
+    "first_failed_at",
+    "last_retried_at",
+    "dismissed_at",
+    "dismissed_by"
+  ],
+  "title": "SyncFailureRead"
+}
+
+
SyncRunLogRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "source_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Source Id"
+    },
+    "started_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Started At"
+    },
+    "finished_at": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Finished At"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Status"
+    },
+    "records_attempted": {
+      "type": "integer",
+      "title": "Records Attempted"
+    },
+    "records_succeeded": {
+      "type": "integer",
+      "title": "Records Succeeded"
+    },
+    "records_failed": {
+      "type": "integer",
+      "title": "Records Failed"
+    },
+    "error_summary": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Error Summary"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "source_id",
+    "started_at",
+    "finished_at",
+    "status",
+    "records_attempted",
+    "records_succeeded",
+    "records_failed",
+    "error_summary"
+  ],
+  "title": "SyncRunLogRead"
+}
+
+
SystemStatus
+{
+  "properties": {
+    "version": {
+      "type": "string",
+      "title": "Version"
+    },
+    "database": {
+      "type": "string",
+      "title": "Database"
+    },
+    "ollama": {
+      "type": "string",
+      "title": "Ollama"
+    },
+    "redis": {
+      "type": "string",
+      "title": "Redis"
+    },
+    "user_count": {
+      "type": "integer",
+      "title": "User Count"
+    },
+    "audit_log_count": {
+      "type": "integer",
+      "title": "Audit Log Count"
+    },
+    "suite_session": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Suite Session"
+    }
+  },
+  "type": "object",
+  "required": [
+    "version",
+    "database",
+    "ollama",
+    "redis",
+    "user_count",
+    "audit_log_count"
+  ],
+  "title": "SystemStatus"
+}
+
+
TaggedPlan
+{
+  "properties": {
+    "action": {
+      "type": "string",
+      "const": "tagged-pdf",
+      "title": "Action"
+    },
+    "headingLevels": {
+      "items": {
+        "type": "integer",
+        "maximum": 4294967295.0,
+        "minimum": 0.0
+      },
+      "type": "array",
+      "maxItems": 50,
+      "title": "Headinglevels"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "title": "TaggedPlan"
+}
+
+
TestConnectionRequest
+{
+  "properties": {
+    "source_type": {
+      "type": "string",
+      "title": "Source Type"
+    },
+    "host": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Host"
+    },
+    "port": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Port"
+    },
+    "path": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Path"
+    },
+    "username": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Username"
+    },
+    "password": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Password"
+    },
+    "rest_api_config": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Rest Api Config"
+    },
+    "odbc_config": {
+      "anyOf": [
+        {
+          "additionalProperties": true,
+          "type": "object"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Odbc Config"
+    }
+  },
+  "type": "object",
+  "required": [
+    "source_type"
+  ],
+  "title": "TestConnectionRequest",
+  "description": "Dedicated schema for test-connection. NOT the create schema.\n\nSecurity: credentials in this request body are never persisted, never\nwritten to audit logs, and never returned in the response."
+}
+
+
TestConnectionResponse
+{
+  "properties": {
+    "success": {
+      "type": "boolean",
+      "title": "Success"
+    },
+    "message": {
+      "type": "string",
+      "title": "Message"
+    },
+    "latency_ms": {
+      "anyOf": [
+        {
+          "type": "integer"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Latency Ms"
+    },
+    "status": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Status"
+    },
+    "warning": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Warning"
+    },
+    "differing_keys": {
+      "anyOf": [
+        {
+          "items": {
+            "type": "string"
+          },
+          "type": "array"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Differing Keys"
+    }
+  },
+  "type": "object",
+  "required": [
+    "success",
+    "message"
+  ],
+  "title": "TestConnectionResponse"
+}
+
+
TimelineEventCreate
+{
+  "properties": {
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "internal_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Internal Note"
+    }
+  },
+  "type": "object",
+  "required": [
+    "event_type",
+    "description"
+  ],
+  "title": "TimelineEventCreate"
+}
+
+
TimelineEventRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "request_id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Request Id"
+    },
+    "event_type": {
+      "type": "string",
+      "title": "Event Type"
+    },
+    "actor_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Actor Id"
+    },
+    "actor_role": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Actor Role"
+    },
+    "description": {
+      "type": "string",
+      "title": "Description"
+    },
+    "internal_note": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Internal Note"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "request_id",
+    "event_type",
+    "actor_id",
+    "actor_role",
+    "description",
+    "internal_note",
+    "created_at"
+  ],
+  "title": "TimelineEventRead"
+}
+
+
TimelineView
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "title": "Id"
+    },
+    "action": {
+      "type": "string",
+      "title": "Action"
+    },
+    "actor": {
+      "type": "string",
+      "title": "Actor"
+    },
+    "note": {
+      "type": "string",
+      "title": "Note"
+    },
+    "created_at_unix_seconds": {
+      "type": "integer",
+      "title": "Created At Unix Seconds"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "id",
+    "action",
+    "actor",
+    "note",
+    "created_at_unix_seconds"
+  ],
+  "title": "TimelineView"
+}
+
+
TitleCreate
+{
+  "properties": {
+    "title_id": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Title Id"
+    },
+    "title_number": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title Number"
+    },
+    "title_name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Title Name"
+    },
+    "sort_order": {
+      "type": "integer",
+      "title": "Sort Order",
+      "default": 0
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "title_number",
+    "title_name"
+  ],
+  "title": "TitleCreate",
+  "description": "Request body for creating a code title."
+}
+
+
TranscriptInput
+{
+  "properties": {
+    "source_label": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Source Label"
+    },
+    "transcript_text": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Transcript Text"
+    },
+    "correction_of_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Correction Of Id"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_label",
+    "transcript_text"
+  ],
+  "title": "TranscriptInput"
+}
+
+
UserRead
+{
+  "properties": {
+    "id": {
+      "type": "string",
+      "format": "uuid",
+      "title": "Id"
+    },
+    "email": {
+      "type": "string",
+      "format": "email",
+      "title": "Email"
+    },
+    "is_active": {
+      "type": "boolean",
+      "title": "Is Active",
+      "default": true
+    },
+    "is_superuser": {
+      "type": "boolean",
+      "title": "Is Superuser",
+      "default": false
+    },
+    "is_verified": {
+      "type": "boolean",
+      "title": "Is Verified",
+      "default": false
+    },
+    "full_name": {
+      "type": "string",
+      "title": "Full Name"
+    },
+    "role": {
+      "$ref": "#/components/schemas/UserRole"
+    },
+    "created_at": {
+      "type": "string",
+      "format": "date-time",
+      "title": "Created At"
+    },
+    "last_login": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "date-time"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Last Login"
+    },
+    "must_change_password": {
+      "type": "boolean",
+      "title": "Must Change Password",
+      "default": false
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    }
+  },
+  "type": "object",
+  "required": [
+    "id",
+    "email",
+    "full_name",
+    "role",
+    "created_at",
+    "last_login"
+  ],
+  "title": "UserRead"
+}
+
+
UserRole
+{
+  "type": "string",
+  "enum": [
+    "admin",
+    "staff",
+    "reviewer",
+    "read_only",
+    "liaison",
+    "public"
+  ],
+  "title": "UserRole"
+}
+
+
UserSelfUpdate
+{
+  "properties": {
+    "password": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Password"
+    },
+    "email": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "email"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Email"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    },
+    "is_superuser": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Superuser"
+    },
+    "is_verified": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Verified"
+    },
+    "full_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Full Name"
+    }
+  },
+  "type": "object",
+  "title": "UserSelfUpdate",
+  "description": "Schema for user self-update via PATCH /users/me.\n\nExcludes role and department_id. Any payload containing those fields is\nrejected at parse time (HTTP 422). Role and department changes require\nadmin privileges via /admin/users/{id}."
+}
+
+
UserUpdateRequest
+{
+  "properties": {
+    "full_name": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Full Name"
+    },
+    "role": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Role"
+    },
+    "department_id": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Department Id"
+    },
+    "is_active": {
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Is Active"
+    }
+  },
+  "type": "object",
+  "title": "UserUpdateRequest"
+}
+
+
ValidationError
+{
+  "properties": {
+    "loc": {
+      "items": {
+        "anyOf": [
+          {
+            "type": "string"
+          },
+          {
+            "type": "integer"
+          }
+        ]
+      },
+      "type": "array",
+      "title": "Location"
+    },
+    "msg": {
+      "type": "string",
+      "title": "Message"
+    },
+    "type": {
+      "type": "string",
+      "title": "Error Type"
+    },
+    "input": {
+      "title": "Input"
+    },
+    "ctx": {
+      "type": "object",
+      "title": "Context"
+    }
+  },
+  "type": "object",
+  "required": [
+    "loc",
+    "msg",
+    "type"
+  ],
+  "title": "ValidationError"
+}
+
+
Version
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence"
+  ],
+  "title": "Version"
+}
+
+
VoteCorrection
+{
+  "properties": {
+    "vote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Vote"
+    },
+    "reason": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Reason"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "vote",
+    "reason"
+  ],
+  "title": "VoteCorrection"
+}
+
+
VoteInput
+{
+  "properties": {
+    "voter_name": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Voter Name"
+    },
+    "vote": {
+      "type": "string",
+      "minLength": 1,
+      "title": "Vote"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "voter_name",
+    "vote"
+  ],
+  "title": "VoteInput"
+}
+
+
_ParcelLookupIn
+{
+  "properties": {
+    "jurisdiction": {
+      "type": "string",
+      "maxLength": 255,
+      "minLength": 1,
+      "title": "Jurisdiction"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "jurisdiction",
+    "query"
+  ],
+  "title": "_ParcelLookupIn"
+}
+
+
townlight_inspections__workflow_models__SourceLink
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "const": "code",
+      "title": "Provider",
+      "default": "code"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "SourceLink"
+}
+
+
townlight_permitting__workflow_models__SourceLink
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "enum": [
+        "code",
+        "zoning"
+      ],
+      "title": "Provider"
+    },
+    "source_id": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Source Id"
+    },
+    "expected_sha256": {
+      "type": "string",
+      "pattern": "^[a-f0-9]{64}$",
+      "title": "Expected Sha256"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "source_id",
+    "expected_sha256"
+  ],
+  "title": "SourceLink"
+}
+
+
townlight_runtime__inspections_bridge__Search
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "const": "code",
+      "title": "Provider"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "query"
+  ],
+  "title": "Search"
+}
+
+
townlight_runtime__notice_bridge__Review
+{
+  "properties": {
+    "sequence": {
+      "type": "integer",
+      "minimum": 1.0,
+      "title": "Sequence"
+    },
+    "note": {
+      "type": "string",
+      "maxLength": 5000,
+      "minLength": 1,
+      "title": "Note"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "sequence",
+    "note"
+  ],
+  "title": "Review"
+}
+
+
townlight_runtime__permitting_bridge__Import
+{
+  "properties": {
+    "bundle": {
+      "$ref": "#/components/schemas/RequirementBundle"
+    },
+    "expected_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "format": "uuid"
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Revision"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "bundle"
+  ],
+  "title": "Import"
+}
+
+
townlight_runtime__permitting_bridge__Search
+{
+  "properties": {
+    "provider": {
+      "type": "string",
+      "enum": [
+        "code",
+        "zoning"
+      ],
+      "title": "Provider"
+    },
+    "query": {
+      "type": "string",
+      "maxLength": 500,
+      "minLength": 1,
+      "title": "Query"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "provider",
+    "query"
+  ],
+  "title": "Search"
+}
+
+
townlight_runtime__planning_bridge__Import
+{
+  "properties": {
+    "bundle": {
+      "additionalProperties": true,
+      "type": "object",
+      "title": "Bundle"
+    },
+    "expected_previous_revision": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 36,
+          "minLength": 36
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Expected Previous Revision"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "bundle"
+  ],
+  "title": "Import"
+}
+
+
townlight_runtime__planning_bridge__Search
+{
+  "properties": {
+    "query": {
+      "type": "string",
+      "maxLength": 2000,
+      "minLength": 1,
+      "title": "Query"
+    },
+    "plan_type": {
+      "anyOf": [
+        {
+          "type": "string",
+          "maxLength": 40
+        },
+        {
+          "type": "null"
+        }
+      ],
+      "title": "Plan Type"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "required": [
+    "query"
+  ],
+  "title": "Search"
+}
+
+
townlight_runtime__zoning_bridge__Review
+{
+  "properties": {
+    "answer": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Answer",
+      "default": ""
+    },
+    "notes": {
+      "type": "string",
+      "maxLength": 10000,
+      "title": "Notes",
+      "default": ""
+    },
+    "queue_status": {
+      "type": "string",
+      "enum": [
+        "open",
+        "in_review",
+        "resolved",
+        "closed"
+      ],
+      "title": "Queue Status",
+      "default": "resolved"
+    }
+  },
+  "additionalProperties": false,
+  "type": "object",
+  "title": "Review"
+}
+
Townlight · AGPL-3.0-only · Source schema evidence only
\ No newline at end of file diff --git a/docs/beta-1/reference/index.html b/docs/beta-1/reference/index.html index 27ea726..49e778d 100644 --- a/docs/beta-1/reference/index.html +++ b/docs/beta-1/reference/index.html @@ -1,98 +1 @@ -Technical -Reference Directory | Townlight Beta 1
townlightTownlight Beta 1
-
Townlight Beta 1

Technical -Reference -Directory

Staff guide and technical reference

Documentation edition 30 October 2026
Existing component versions retained
Signed suite installer 1.6.0.1
Private beta documentation companion

Technical reference directory

-

Every entry describes Townlight Beta 1 while preserving the component -versions of the actual candidate. OpenAPI is generated from the -installed domain without running endpoints. Source supplements -distinguish standalone APIs from installed routes. Receipt -filenames/hashes identify acceptance evidence retained in the private -handoff.

- -

Per-product contract -directory

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ProductOperations and data dictionary
CoreCore
RecordsRecords (suite companion)
MeetingsMeetings (suite companion)
CodeCode (suite companion)
ZoningZoning (suite companion)
PlanningPlanning (suite companion)
PermittingPermitting (suite companion)
InspectionsInspections (suite companion)
StationStation (suite companion)
- \ No newline at end of file +Townlight candidate technical reference
Townlight

Current candidate technical reference

Prepared November 2, 2026. Build, signing, exact installed acceptance and publication remain pending.

The API pages describe the actual native composition; standalone applications and the separate Station service have their documented boundaries.

Complete native domain API · Current source inventory and SHA-256 values · Component versions

ProductContractInventory
Townlight CoreAPI reference114 source files
Townlight RecordsAPI reference126 source files
Townlight MeetingsAPI reference59 source files
Townlight CodeAPI reference49 source files
Townlight ZoningAPI reference30 source files
Townlight PlanningAPI reference31 source files
Townlight PermittingAPI reference18 source files
Townlight InspectionsAPI reference20 source files
Townlight AccessAPI reference10 source files
Townlight NoticeAPI reference16 source files
Townlight StationAPI reference21 source files
Townlight RuntimeAPI reference101 source files

AST route declarations alone do not prove mounting or runtime behavior. The inventory marks source companion assembly as pending until an actual built companion is supplied; it makes no signed-installer claim.

Townlight · AGPL-3.0-only
\ No newline at end of file diff --git a/docs/beta-1/reference/source-inventory.json b/docs/beta-1/reference/source-inventory.json index 7b307de..0e532d4 100644 --- a/docs/beta-1/reference/source-inventory.json +++ b/docs/beta-1/reference/source-inventory.json @@ -1,27 +1,34 @@ { - "candidate_source_sha256": "84a23e1297e42d17b16cfc9e51b2dd78bc46414c0de8ad7ebd2466c1a409d06b", - "basis": "Immutable corresponding source of signed candidate; AST extraction is not executed endpoint acceptance. Router mounts require runtime OpenAPI or source include_router context.", + "source_companion_sha256": null, + "source_companion_pending": true, + "basis": "Actual current candidate source bytes. Source AST declarations do not establish router mounting, authorization, installed behavior or delivery. Use the composed OpenAPI reference and exact candidate acceptance separately.", "products": { "core": { - "package": "townlight_core", + "repository": "townlight/core", + "repository_head": "cb374b2a582ebd8811c6191c856982e3399c48ff", + "working_tree_modified": true, + "principal_import": "townlight_core", "source": [ { - "source": "installed-owned-source/townlight_core/__init__.py", - "sha256": "22823aa2e5f34ff62c57276cc877fc52fb6c654877b5e3756d6dccdb40f7dc15", + "source": "townlight_core/__init__.py", + "sha256": "271ec6a8d23264747891f8909e8ed1986cb8b2d56098bcaf59e3550b1978e9c4", + "bytes": 10845, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/audit/__init__.py", - "sha256": "9066c9b752564f42427bb925f2ec72e92007f389fbec24b3bde90655cfb3c9d9", + "source": "townlight_core/audit/__init__.py", + "sha256": "4e1568afe62b114bdaa5bc329ce9eeb0f2a050304b2087d25dd4ea862e7a44b0", + "bytes": 807, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/audit/primitives.py", - "sha256": "293ba8cf2d89165bf50d1fb019c05a4a1e5a1ca22c3703be25f6c96014491d3a", + "source": "townlight_core/audit/primitives.py", + "sha256": "b2c07101e233c2fddf03c0395f84ee8975e6a83aa2e66a51980a926b7f5474fc", + "bytes": 9770, "routes": [], "models": [ { @@ -33,21 +40,20 @@ { "name": "actor_id", "type": "str", - "default": "" + "line": 60 }, { "name": "actor_type", "type": "str", - "default": "" + "line": 61 }, { "name": "display_name", "type": "str | None", - "default": "None" + "line": 62 } ], - "line": 55, - "doc": "Actor that initiated an auditable action." + "line": 55 }, { "name": "AuditSubject", @@ -58,21 +64,20 @@ { "name": "subject_id", "type": "str", - "default": "" + "line": 70 }, { "name": "subject_type", "type": "str", - "default": "" + "line": 71 }, { "name": "display_name", "type": "str | None", - "default": "None" + "line": 72 } ], - "line": 65, - "doc": "Record, document, workflow, or other entity affected by an action." + "line": 65 }, { "name": "AuditEvent", @@ -83,51 +88,50 @@ { "name": "event_id", "type": "str", - "default": "Field(default_factory=lambda: str(uuid4()))" + "line": 80 }, { "name": "actor", "type": "AuditActor", - "default": "" + "line": 81 }, { "name": "action", "type": "str", - "default": "" + "line": 82 }, { "name": "subject", "type": "AuditSubject", - "default": "" + "line": 83 }, { "name": "source_module", "type": "str", - "default": "" + "line": 84 }, { "name": "timestamp", "type": "datetime", - "default": "Field(default_factory=_utc_now)" + "line": 85 }, { "name": "metadata", "type": "dict[str, Any]", - "default": "Field(default_factory=dict)" + "line": 86 }, { "name": "previous_hash", "type": "str | None", - "default": "None" + "line": 87 }, { "name": "current_hash", "type": "str | None", - "default": "None" + "line": 88 } ], - "line": 75, - "doc": "One audit event with deterministic hash-chain fields." + "line": 75 }, { "name": "AuditHashChain", @@ -138,11 +142,10 @@ { "name": "events", "type": "list[AuditEvent]", - "default": "Field(default_factory=list)" + "line": 164 } ], - "line": 159, - "doc": "In-memory helper for building and verifying hash-chained events." + "line": 159 }, { "name": "PersistedAuditLogEntry", @@ -153,55 +156,56 @@ { "name": "previous_hash", "type": "str", - "default": "Field(default=ZERO_HASH, min_length=64, max_length=64)" + "line": 203 }, { "name": "entry_hash", "type": "str", - "default": "Field(min_length=64, max_length=64)" + "line": 204 }, { "name": "timestamp", "type": "datetime | str", - "default": "" + "line": 205 }, { "name": "actor_id", "type": "str | None", - "default": "None" + "line": 206 }, { "name": "action", "type": "str", - "default": "" + "line": 207 }, { "name": "details", "type": "dict[str, Any] | None", - "default": "None" + "line": 208 }, { "name": "entry_id", "type": "int | str | None", - "default": "None" + "line": 209 } ], - "line": 192, - "doc": "Storage-neutral view of a legacy persisted audit-log row.\n\nThis model preserves the historical Townlight Records hash formula for\ndatabase-backed ``audit_log`` rows. It intentionally lives beside, rather\nthan replacing, ``AuditEvent`` because existing deployed rows must continue\nto verify after modules move their reusable audit math into Townlight Core." + "line": 192 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/auth/__init__.py", - "sha256": "7a3f307c6fc4ac465688b2ad83b49b85d551721d248e569d0acbb8bf0db49f5a", + "source": "townlight_core/auth/__init__.py", + "sha256": "04eb39badadea67810426e791606cafdbd7dfe05491baabc56feaab7d4e660bd", + "bytes": 2711, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/auth/bearer.py", - "sha256": "6515b07ecf4be9fc344ab05eeef891b165f3e0310387dfa3a59fc2531c5dacb9", + "source": "townlight_core/auth/bearer.py", + "sha256": "28a8ef40450dd3a0b5424916f8d50f08945c7b961170702971ad8686c928ec59", + "bytes": 6057, "routes": [], "models": [ { @@ -211,38 +215,38 @@ { "name": "token_fingerprint", "type": "str | None", - "default": "" + "line": 19 }, { "name": "roles", "type": "frozenset[str]", - "default": "" + "line": 20 }, { "name": "auth_method", "type": "str", - "default": "'bearer'" + "line": 21 }, { "name": "subject", "type": "str | None", - "default": "None" + "line": 22 }, { "name": "provider", "type": "str | None", - "default": "None" + "line": 23 } ], - "line": 16, - "doc": "Represents the caller that satisfied a bearer-token role check." + "line": 16 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/auth/department_scope.py", - "sha256": "57905c13074c10acdf07f7a353634bf3e51b1f42f67cd6f7b3d8920dca91f7d1", + "source": "townlight_core/auth/department_scope.py", + "sha256": "78e0840399fbd1b447436e231cc0fee52e77a2271b32f383cbbe9035d9fe23ce", + "bytes": 27460, "routes": [], "models": [ { @@ -254,51 +258,50 @@ { "name": "scope_id", "type": "str", - "default": "Field(min_length=2, max_length=64)" + "line": 158 }, { "name": "subject", "type": "str", - "default": "Field(min_length=1, max_length=320)" + "line": 159 }, { "name": "department_id", "type": "UUID", - "default": "" + "line": 160 }, { "name": "sequence", "type": "int", - "default": "Field(ge=1)" + "line": 161 }, { "name": "action", "type": "GrantAction", - "default": "" + "line": 162 }, { "name": "roles", "type": "tuple[str, ...]", - "default": "()" + "line": 163 }, { "name": "recorded_by", "type": "str", - "default": "Field(min_length=1, max_length=128)" + "line": 164 }, { "name": "recorded_at", "type": "AwareDatetime", - "default": "" + "line": 165 }, { "name": "content_sha256", "type": "str", - "default": "Field(min_length=64, max_length=64)" + "line": 166 } ], - "line": 148, - "doc": "One persisted grant/revoke event for a subject in one scope and department.\n\nRows are append-only: a ``revoke`` event does not delete the earlier ``grant`` event, it\nsupersedes it. ``sequence`` is monotonic per ``(scope_id, subject, department_id)`` so the\nactive state is always the highest-sequence event." + "line": 148 }, { "name": "DepartmentEntitlement", @@ -307,26 +310,25 @@ { "name": "department_id", "type": "UUID", - "default": "" + "line": 213 }, { "name": "roles", "type": "frozenset[str]", - "default": "" + "line": 214 }, { "name": "granted_by", "type": "str", - "default": "" + "line": 215 }, { "name": "granted_at", "type": "datetime", - "default": "" + "line": 216 } ], - "line": 210, - "doc": "A department this subject may reach, with the roles granted there." + "line": 210 }, { "name": "DepartmentAuthority", @@ -335,56 +337,55 @@ { "name": "scope_id", "type": "str", - "default": "" + "line": 228 }, { "name": "subject", "type": "str", - "default": "" + "line": 229 }, { "name": "auth_method", "type": "str", - "default": "" + "line": 230 }, { "name": "provider", "type": "str | None", - "default": "" + "line": 231 }, { "name": "roles", "type": "frozenset[str]", - "default": "" + "line": 232 }, { "name": "entitlements", "type": "tuple[DepartmentEntitlement, ...]", - "default": "" + "line": 233 }, { "name": "resolved_at", "type": "datetime", - "default": "" + "line": 234 }, { "name": "grants_digest", "type": "str", - "default": "" + "line": 235 }, { "name": "provenance", "type": "Literal['persisted-grant']", - "default": "'persisted-grant'" + "line": 236 }, { "name": "_token", "type": "Any", - "default": "field(default=None, repr=False, compare=False)" + "line": 237 } ], - "line": 220, - "doc": "The only object Core consumers may use to scope search, exports and model context.\n\nInstances are produced by :func:`resolve_department_authority`. Direct construction raises\n:class:`AuthorityProvenanceError`, because a hand-built authority would be exactly the\n\"trust the caller's department claim\" hole this contract exists to close." + "line": 220 }, { "name": "GrantOutcome", @@ -393,30 +394,31 @@ { "name": "grant", "type": "DepartmentGrant", - "default": "" + "line": 440 }, { "name": "inserted", "type": "bool", - "default": "" + "line": 441 } ], - "line": 437, - "doc": "Result of an append attempt. ``inserted`` is False for an exact repeat." + "line": 437 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/auth/staff_key.py", - "sha256": "ef7dc371bcd7f419d6266cc61aad01884f263edbcca5db7d5ba4dc1e91d251db", + "source": "townlight_core/auth/staff_key.py", + "sha256": "70975c90b8629762c541c50ed63d5ebb230101569caaa7f27741040a92102624", + "bytes": 2495, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/auth/suite_session.py", - "sha256": "e33e13634568261accb2ba6706402de013975f3c58117b987cced3cd92c0db2e", + "source": "townlight_core/auth/suite_session.py", + "sha256": "7276e30b9d2d6ff7c5cf247c7b3f0ad25c532341ea400387a355c6c7d89f028a", + "bytes": 10405, "routes": [], "models": [ { @@ -426,28 +428,28 @@ { "name": "subject", "type": "str", - "default": "" + "line": 38 }, { "name": "roles", "type": "frozenset[str]", - "default": "" + "line": 39 }, { "name": "session_id", "type": "str", - "default": "" + "line": 40 } ], - "line": 35, - "doc": "Immutable principal decoded from a shared Townlight staff session." + "line": 35 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/auth/trusted_headers.py", - "sha256": "771e7cbf1f5d73dafad082d97ebb6e350a49b15362ce50eb36b261172e3b9c5c", + "source": "townlight_core/auth/trusted_headers.py", + "sha256": "e5fb52bfe52188a62f71cc5aca5facccac58c3981802a56a29939edc1804514b", + "bytes": 8041, "routes": [], "models": [ { @@ -457,33 +459,33 @@ { "name": "provider_name", "type": "str", - "default": "" + "line": 20 }, { "name": "principal_header_name", "type": "str", - "default": "" + "line": 21 }, { "name": "roles_header_name", "type": "str", - "default": "" + "line": 22 }, { "name": "trusted_proxy_cidrs", "type": "tuple[str, ...]", - "default": "" + "line": 23 } ], - "line": 17, - "doc": "Service-specific trusted-header auth settings loaded from env/defaults." + "line": 17 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/catalog/__init__.py", - "sha256": "e323a7808ae719b4b90530c238dc945a107ee1cf9a9050cb00d7efbf5aa1a823", + "source": "townlight_core/catalog/__init__.py", + "sha256": "d6348d181abc14c16a11b1e2b63074d2a34efb49416ec3d6fc223af2de21525b", + "bytes": 7654, "routes": [], "models": [ { @@ -495,36 +497,35 @@ { "name": "vendor_name", "type": "str", - "default": "Field(min_length=1, max_length=200)" + "line": 18 }, { "name": "access_protocol", "type": "str", - "default": "Field(min_length=1, max_length=50)" + "line": 19 }, { "name": "data_shape", "type": "str", - "default": "Field(min_length=1, max_length=50)" + "line": 20 }, { "name": "common_record_types", "type": "list[str]", - "default": "Field(max_length=100)" + "line": 21 }, { "name": "redaction_tier", "type": "int", - "default": "Field(ge=1, le=3)" + "line": 22 }, { "name": "discovery_hints", "type": "dict", - "default": "Field(default_factory=dict)" + "line": 23 } ], - "line": 16, - "doc": "" + "line": 16 }, { "name": "DomainInput", @@ -535,16 +536,15 @@ { "name": "domain", "type": "str", - "default": "Field(min_length=1, max_length=100)" + "line": 40 }, { "name": "systems", "type": "list[SystemInput]", - "default": "Field(max_length=500)" + "line": 41 } ], - "line": 38, - "doc": "" + "line": 38 }, { "name": "CatalogInput", @@ -555,30 +555,31 @@ { "name": "catalog_version", "type": "str", - "default": "Field(min_length=1, max_length=20)" + "line": 46 }, { "name": "domains", "type": "list[DomainInput]", - "default": "Field(max_length=100)" + "line": 47 } ], - "line": 44, - "doc": "" + "line": 44 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/city_profile/__init__.py", - "sha256": "c22e26dac2fcb454cbf91bcbf23311fdef9bf854fbb2bba2d76149945986bd72", + "source": "townlight_core/city_profile/__init__.py", + "sha256": "65b6e3fafad6ab9355db419530d2d5398d9529db37eb761468f4a7a14e569b6b", + "bytes": 385, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/city_profile/models.py", - "sha256": "e34b6bbc69f44656ad22217de2b911b5c437fb226b594439f935705c95a47ed6", + "source": "townlight_core/city_profile/models.py", + "sha256": "efddf634764a89de9eef92c50018e78358ab2536be43cd8b50758603d903c4ab", + "bytes": 4868, "routes": [], "models": [ { @@ -590,26 +591,25 @@ { "name": "name", "type": "str", - "default": "Field(min_length=1)" + "line": 21 }, { "name": "slug", "type": "str", - "default": "Field(min_length=1, pattern='^[a-z0-9][a-z0-9-]*$')" + "line": 22 }, { "name": "public_email", "type": "str | None", - "default": "Field(default=None, min_length=3)" + "line": 23 }, { "name": "public_phone", "type": "str | None", - "default": "Field(default=None, min_length=3)" + "line": 24 } ], - "line": 16, - "doc": "A city department surfaced during local onboarding." + "line": 16 }, { "name": "DeploymentProfile", @@ -620,16 +620,15 @@ { "name": "mode", "type": "Literal['local_demo', 'local', 'self_hosted']", - "default": "'local_demo'" + "line": 32 }, { "name": "allow_outbound_services", "type": "bool", - "default": "False" + "line": 33 } ], - "line": 27, - "doc": "Deployment posture for a profile without acting as an installer." + "line": 27 }, { "name": "ModuleEnablement", @@ -640,21 +639,20 @@ { "name": "name", "type": "str", - "default": "Field(min_length=1, pattern='^[a-z0-9][a-z0-9_-]*$')" + "line": 41 }, { "name": "enabled", "type": "bool", - "default": "True" + "line": 42 }, { "name": "settings", "type": "dict[str, Any]", - "default": "Field(default_factory=dict)" + "line": 43 } ], - "line": 36, - "doc": "Per-module enablement flags and local configuration metadata." + "line": 36 }, { "name": "CityProfile", @@ -665,60 +663,61 @@ { "name": "city_name", "type": "str", - "default": "Field(min_length=1)" + "line": 51 }, { "name": "timezone", "type": "str", - "default": "Field(min_length=1)" + "line": 52 }, { "name": "departments", "type": "list[DepartmentProfile]", - "default": "Field(default_factory=list)" + "line": 53 }, { "name": "enabled_modules", "type": "list[ModuleEnablement]", - "default": "Field(default_factory=list)" + "line": 54 }, { "name": "default_llm_provider", "type": "str", - "default": "'ollama'" + "line": 55 }, { "name": "file_drop_roots", "type": "list[Path]", - "default": "Field(default_factory=list)" + "line": 56 }, { "name": "public_contact", "type": "dict[str, str]", - "default": "Field(default_factory=dict)" + "line": 57 }, { "name": "deployment", "type": "DeploymentProfile", - "default": "Field(default_factory=DeploymentProfile)" + "line": 58 } ], - "line": 46, - "doc": "Local city profile loaded from trusted JSON/YAML configuration." + "line": 46 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/connectors/__init__.py", - "sha256": "92d5a39aa8241f8fed6405fd0a8b3068994fdeb66ea3f80975ff708dde673870", + "source": "townlight_core/connectors/__init__.py", + "sha256": "4c6cf98564b9c46440fdf01d6895165ad39566e3270da02adbf088fd8f242a7f", + "bytes": 1732, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/connectors/delta.py", - "sha256": "d99e5624e0eebcc434146909d65040eba0023cc84b2d5d03ce1de2b36c70e52f", + "source": "townlight_core/connectors/delta.py", + "sha256": "58de5706cd1e50043ffccc6bae552c094dab2b156235bf5959f3af2a28fa7741", + "bytes": 3211, "routes": [], "models": [ { @@ -728,48 +727,48 @@ { "name": "connector", "type": "str", - "default": "" + "line": 22 }, { "name": "request_url", "type": "str", - "default": "" + "line": 23 }, { "name": "delta_enabled", "type": "bool", - "default": "" + "line": 24 }, { "name": "cursor_param", "type": "str | None", - "default": "" + "line": 25 }, { "name": "cursor_value", "type": "str | None", - "default": "" + "line": 26 }, { "name": "message", "type": "str", - "default": "" + "line": 27 }, { "name": "fix", "type": "str", - "default": "" + "line": 28 } ], - "line": 19, - "doc": "Storage-neutral plan for a full or cursor-based vendor pull." + "line": 19 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/connectors/imports.py", - "sha256": "1ed6dafe0072eb57327e7d61b12df801f79bfb9ea7ea1738548afb5a002e0606", + "source": "townlight_core/connectors/imports.py", + "sha256": "d8471df1e6c8ca2ae5f63a8e70419e83129e24fc8ee885a2803c0d023c57fe0e", + "bytes": 7068, "routes": [], "models": [ { @@ -781,16 +780,15 @@ { "name": "message", "type": "str", - "default": "" + "line": 16 }, { "name": "fix", "type": "str", - "default": "" + "line": 17 } ], - "line": 13, - "doc": "Actionable validation error for local connector import payloads." + "line": 13 }, { "name": "ImportedAgendaItem", @@ -799,26 +797,25 @@ { "name": "external_item_id", "type": "str", - "default": "" + "line": 30 }, { "name": "title", "type": "str", - "default": "" + "line": 31 }, { "name": "department", "type": "str | None", - "default": "" + "line": 32 }, { "name": "connector", "type": "str", - "default": "" + "line": 33 } ], - "line": 27, - "doc": "Normalized agenda item imported from a local connector payload." + "line": 27 }, { "name": "ImportedMeeting", @@ -827,38 +824,38 @@ { "name": "connector", "type": "str", - "default": "" + "line": 52 }, { "name": "external_meeting_id", "type": "str", - "default": "" + "line": 53 }, { "name": "title", "type": "str", - "default": "" + "line": 54 }, { "name": "scheduled_start", "type": "str", - "default": "" + "line": 55 }, { "name": "agenda_items", "type": "tuple[ImportedAgendaItem, ...]", - "default": "" + "line": 56 } ], - "line": 49, - "doc": "Normalized meeting imported from a local connector payload." + "line": 49 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/connectors/manifest.py", - "sha256": "15caa167acce428facdf7683085d47dd4a01b02cc2d05df25d6aa1d157bb79bd", + "source": "townlight_core/connectors/manifest.py", + "sha256": "2d7ee3abedf89af90ee2f3c474925d11b93aa3117370aeee4ee5f783dad347a4", + "bytes": 8356, "routes": [], "models": [ { @@ -870,31 +867,30 @@ { "name": "path", "type": "str", - "default": "" + "line": 46 }, { "name": "byte_size", "type": "int", - "default": "Field(ge=0)" + "line": 47 }, { "name": "sha256", "type": "str", - "default": "" + "line": 48 }, { "name": "media_type", "type": "str | None", - "default": "None" + "line": 49 }, { "name": "description", "type": "str | None", - "default": "None" + "line": 50 } ], - "line": 43, - "doc": "A file entry recorded in an import or export manifest." + "line": 43 }, { "name": "_ManifestBase", @@ -905,46 +901,45 @@ { "name": "manifest_version", "type": "str", - "default": "'1.0'" + "line": 80 }, { "name": "module_name", "type": "str", - "default": "" + "line": 81 }, { "name": "module_version", "type": "str", - "default": "" + "line": 82 }, { "name": "townlight_core_version", "type": "str", - "default": "" + "line": 83 }, { "name": "purpose", "type": "ManifestPurpose", - "default": "" + "line": 84 }, { "name": "source_files", "type": "list[ManifestFile]", - "default": "Field(default_factory=list)" + "line": 85 }, { "name": "generated_files", "type": "list[ManifestFile]", - "default": "Field(default_factory=list)" + "line": 86 }, { "name": "limitations", "type": "list[str]", - "default": "Field(default_factory=list)" + "line": 87 } ], - "line": 79, - "doc": "" + "line": 79 }, { "name": "ImportManifest", @@ -955,11 +950,10 @@ { "name": "purpose", "type": "ImportPurpose", - "default": "" + "line": 126 } ], - "line": 123, - "doc": "Manifest for offline file-drop, CSV, or GeoJSON imports." + "line": 123 }, { "name": "ExportManifest", @@ -970,18 +964,18 @@ { "name": "purpose", "type": "ExportPurpose", - "default": "'static_export_bundle'" + "line": 138 } ], - "line": 135, - "doc": "Manifest for an offline static export bundle." + "line": 135 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/connectors/sync.py", - "sha256": "ef8bb329bf9d385fd96c617e58a8495989dd76a5d641e0afae3fcf3cba2ca503", + "source": "townlight_core/connectors/sync.py", + "sha256": "b3323199a3be7739aa2a1b6aaee9efca861a86ac7e3764b04637c13e5128172e", + "bytes": 13744, "routes": [], "models": [ { @@ -991,31 +985,30 @@ { "name": "max_attempts", "type": "int", - "default": "3" + "line": 31 }, { "name": "base_delay_seconds", "type": "float", - "default": "1.0" + "line": 32 }, { "name": "jitter_factor", "type": "float", - "default": "0.2" + "line": 33 }, { "name": "max_backoff_seconds", "type": "float", - "default": "30.0" + "line": 34 }, { "name": "retry_after_cap_seconds", "type": "float", - "default": "600.0" + "line": 35 } ], - "line": 28, - "doc": "HTTP retry policy for live vendor connector calls." + "line": 28 }, { "name": "SyncCircuitPolicy", @@ -1024,21 +1017,20 @@ { "name": "full_failure_threshold", "type": "int", - "default": "5" + "line": 46 }, { "name": "grace_period_failure_threshold", "type": "int", - "default": "2" + "line": 47 }, { "name": "grace_period_reason", "type": "str", - "default": "'grace_period'" + "line": 48 } ], - "line": 43, - "doc": "Circuit-breaker thresholds shared by live connector consumers." + "line": 43 }, { "name": "SyncCircuitState", @@ -1047,51 +1039,50 @@ { "name": "connector", "type": "str", - "default": "" + "line": 55 }, { "name": "source_name", "type": "str", - "default": "'connector source'" + "line": 56 }, { "name": "consecutive_failure_count", "type": "int", - "default": "0" + "line": 57 }, { "name": "active_failure_count", "type": "int", - "default": "0" + "line": 58 }, { "name": "sync_paused", "type": "bool", - "default": "False" + "line": 59 }, { "name": "sync_paused_at", "type": "datetime | None", - "default": "None" + "line": 60 }, { "name": "sync_paused_reason", "type": "str | None", - "default": "None" + "line": 61 }, { "name": "last_sync_status", "type": "str | None", - "default": "None" + "line": 62 }, { "name": "last_error_at", "type": "datetime | None", - "default": "None" + "line": 63 } ], - "line": 52, - "doc": "Storage-neutral state needed to compute live-sync health." + "line": 52 }, { "name": "SyncRunResult", @@ -1100,31 +1091,30 @@ { "name": "records_discovered", "type": "int", - "default": "" + "line": 74 }, { "name": "records_succeeded", "type": "int", - "default": "" + "line": 75 }, { "name": "records_failed", "type": "int", - "default": "" + "line": 76 }, { "name": "retries_attempted", "type": "int", - "default": "0" + "line": 77 }, { "name": "error_summary", "type": "str | None", - "default": "None" + "line": 78 } ], - "line": 71, - "doc": "Normalized result summary for one connector sync run." + "line": 71 }, { "name": "SyncOperatorStatus", @@ -1133,51 +1123,50 @@ { "name": "connector", "type": "str", - "default": "" + "line": 97 }, { "name": "source_name", "type": "str", - "default": "" + "line": 98 }, { "name": "health_status", "type": "SyncHealthStatus", - "default": "" + "line": 99 }, { "name": "consecutive_failure_count", "type": "int", - "default": "" + "line": 100 }, { "name": "active_failure_count", "type": "int", - "default": "" + "line": 101 }, { "name": "sync_paused", "type": "bool", - "default": "" + "line": 102 }, { "name": "sync_paused_reason", "type": "str | None", - "default": "" + "line": 103 }, { "name": "message", "type": "str", - "default": "" + "line": 104 }, { "name": "fix", "type": "str", - "default": "" + "line": 105 } ], - "line": 94, - "doc": "Actionable health copy that can be rendered directly in module UIs." + "line": 94 }, { "name": "SyncSourceStatus", @@ -1186,75 +1175,76 @@ { "name": "connector", "type": "str", - "default": "" + "line": 125 }, { "name": "source_name", "type": "str", - "default": "" + "line": 126 }, { "name": "health_status", "type": "SyncHealthStatus", - "default": "" + "line": 127 }, { "name": "consecutive_failure_count", "type": "int", - "default": "" + "line": 128 }, { "name": "active_failure_count", "type": "int", - "default": "" + "line": 129 }, { "name": "sync_paused", "type": "bool", - "default": "" + "line": 130 }, { "name": "sync_paused_reason", "type": "str | None", - "default": "" + "line": 131 }, { "name": "last_sync_status", "type": "str | None", - "default": "" + "line": 132 }, { "name": "next_sync_at", "type": "datetime | None", - "default": "" + "line": 133 }, { "name": "message", "type": "str", - "default": "" + "line": 134 }, { "name": "fix", "type": "str", - "default": "" + "line": 135 } ], - "line": 122, - "doc": "Storage-neutral status projection for module connector source lists." + "line": 122 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/db/__init__.py", - "sha256": "19fc1241d2d81b136813d1ca7ebb47d3831a5ffccec8b548237577ddcd65aebb", + "source": "townlight_core/db/__init__.py", + "sha256": "e42367febc6c5201dd39755c988c9e2c4cc3c3f3d8fe2d9a61bff7af63c651b2", + "bytes": 596, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/exemptions/__init__.py", - "sha256": "83575c21379e697bbbc42b124c8674d8dc99020006f4806237eed0fb71083173", + "source": "townlight_core/exemptions/__init__.py", + "sha256": "edac488a794152402c2b523d5f846096a15d964906a0bbd61346e9e0d5d5ec94", + "bytes": 5566, "routes": [], "models": [ { @@ -1264,36 +1254,35 @@ { "name": "id", "type": "UUID", - "default": "" + "line": 27 }, { "name": "state_code", "type": "str", - "default": "" + "line": 28 }, { "name": "category", "type": "str", - "default": "" + "line": 29 }, { "name": "rule_type", "type": "str", - "default": "" + "line": 30 }, { "name": "definition", "type": "str", - "default": "" + "line": 31 }, { "name": "version", "type": "int", - "default": "" + "line": 32 } ], - "line": 26, - "doc": "" + "line": 26 }, { "name": "FlagResult", @@ -1302,43 +1291,43 @@ { "name": "category", "type": "str", - "default": "" + "line": 37 }, { "name": "matched_text", "type": "str", - "default": "" + "line": 38 }, { "name": "confidence", "type": "float", - "default": "" + "line": 39 }, { "name": "rule_id", "type": "UUID | None", - "default": "None" + "line": 40 }, { "name": "rule_type", "type": "str", - "default": "'regex'" + "line": 41 }, { "name": "rule_version", "type": "int | None", - "default": "None" + "line": 42 } ], - "line": 36, - "doc": "" + "line": 36 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/exemptions/history.py", - "sha256": "b6b1e5be26a6c7a16391d34b6e50e4c08eb19d5cc25788db8917b0b46044b0ea", + "source": "townlight_core/exemptions/history.py", + "sha256": "f58d7c1072189fa1260d54a2dba026b09de1b046b24bdfaebe9ccab55d1bdc74", + "bytes": 16427, "routes": [], "models": [ { @@ -1350,61 +1339,60 @@ { "name": "rule_id", "type": "UUID", - "default": "" + "line": 98 }, { "name": "state_code", "type": "str", - "default": "Field(min_length=2, max_length=2)" + "line": 99 }, { "name": "version", "type": "int", - "default": "Field(ge=1)" + "line": 100 }, { "name": "category", "type": "str", - "default": "Field(min_length=1, max_length=100)" + "line": 101 }, { "name": "rule_type", "type": "Literal['regex', 'keyword']", - "default": "" + "line": 103 }, { "name": "rule_definition", "type": "str", - "default": "Field(min_length=1, max_length=8000)" + "line": 104 }, { "name": "citation_text", "type": "str", - "default": "Field(min_length=1, max_length=1000)" + "line": 105 }, { "name": "citation_url", "type": "str | None", - "default": "Field(default=None, max_length=2000)" + "line": 106 }, { "name": "effective_from", "type": "date | None", - "default": "None" + "line": 107 }, { "name": "retrieved_at", "type": "AwareDatetime", - "default": "" + "line": 108 }, { "name": "coverage_declaration", "type": "Literal['synthetic-fixture', 'tenant-supplied']", - "default": "" + "line": 109 } ], - "line": 93, - "doc": "One cited rule version as supplied by an authorized caller." + "line": 93 }, { "name": "RuleVersion", @@ -1413,71 +1401,70 @@ { "name": "rule_id", "type": "UUID", - "default": "" + "line": 155 }, { "name": "state_code", "type": "str", - "default": "" + "line": 156 }, { "name": "version", "type": "int", - "default": "" + "line": 157 }, { "name": "category", "type": "str", - "default": "" + "line": 158 }, { "name": "rule_type", "type": "str", - "default": "" + "line": 159 }, { "name": "rule_definition", "type": "str", - "default": "" + "line": 160 }, { "name": "citation_text", "type": "str", - "default": "" + "line": 161 }, { "name": "citation_url", "type": "str | None", - "default": "" + "line": 162 }, { "name": "effective_from", "type": "date | None", - "default": "" + "line": 163 }, { "name": "retrieved_at", "type": "object", - "default": "" + "line": 164 }, { "name": "coverage_declaration", "type": "str", - "default": "" + "line": 165 }, { "name": "content_sha256", "type": "str", - "default": "" + "line": 166 }, { "name": "recorded_by", "type": "str", - "default": "" + "line": 167 } ], - "line": 152, - "doc": "A persisted, immutable cited rule version." + "line": 152 }, { "name": "RecordOutcome", @@ -1486,28 +1473,28 @@ { "name": "rule_version", "type": "RuleVersion", - "default": "" + "line": 183 }, { "name": "inserted", "type": "bool", - "default": "" + "line": 184 }, { "name": "fingerprint", "type": "str", - "default": "" + "line": 185 } ], - "line": 182, - "doc": "" + "line": 182 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/exemptions/patterns.py", + "source": "townlight_core/exemptions/patterns.py", "sha256": "b8c4ea484f1fe521295d29eebcc36703c4560d274b36c88f5af28f5abded98af", + "bytes": 5982, "routes": [], "models": [ { @@ -1517,31 +1504,30 @@ { "name": "name", "type": "str", - "default": "" + "line": 16 }, { "name": "category", "type": "str", - "default": "" + "line": 17 }, { "name": "pattern", "type": "re.Pattern", - "default": "" + "line": 18 }, { "name": "description", "type": "str", - "default": "" + "line": 19 }, { "name": "confidence", "type": "float", - "default": "" + "line": 20 } ], - "line": 15, - "doc": "" + "line": 15 }, { "name": "PIIMatch", @@ -1550,50 +1536,51 @@ { "name": "pattern_name", "type": "str", - "default": "" + "line": 150 }, { "name": "category", "type": "str", - "default": "" + "line": 151 }, { "name": "matched_text", "type": "str", - "default": "" + "line": 152 }, { "name": "start", "type": "int", - "default": "" + "line": 153 }, { "name": "end", "type": "int", - "default": "" + "line": 154 }, { "name": "confidence", "type": "float", - "default": "" + "line": 155 } ], - "line": 149, - "doc": "" + "line": 149 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/exports/__init__.py", - "sha256": "7b46221c065defc5c31f148cdc5d2464ff6f665d786499b90a0059474fe9713c", + "source": "townlight_core/exports/__init__.py", + "sha256": "0b855da9162dda8954a082a7fd90efcf118b89b4a2019c2f9f497e1db0696f89", + "bytes": 346, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/exports/bundle.py", - "sha256": "22075c7ad189a9eb958b16a5cb4ef759213789f63e799e78b585a671a84ea5bd", + "source": "townlight_core/exports/bundle.py", + "sha256": "86ce615b7a1a6a73134f88fb82712738610bde6da23d4a3fa7ba3d66e0408af0", + "bytes": 7190, "routes": [], "models": [ { @@ -1605,50 +1592,51 @@ { "name": "module_name", "type": "str", - "default": "" + "line": 57 }, { "name": "module_version", "type": "str", - "default": "" + "line": 58 }, { "name": "townlight_core_version", "type": "str", - "default": "TOWNLIGHT_CORE_VERSION" + "line": 59 }, { "name": "purpose", "type": "str", - "default": "'static_export_bundle'" + "line": 60 }, { "name": "files", "type": "list[BundleFile]", - "default": "Field(default_factory=list)" + "line": 61 }, { "name": "limitations", "type": "list[str]", - "default": "Field(default_factory=list)" + "line": 62 } ], - "line": 54, - "doc": "Description of a static export bundle that can be validated offline." + "line": 54 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/ingest/__init__.py", - "sha256": "6bef6d820315269d126b92aafa02a6d023c6c8706e378003a0cbad434318b791", + "source": "townlight_core/ingest/__init__.py", + "sha256": "a73d8e5e2d5e8c85774c139d72886a8b3cf37d84a2f3108522e6cbaaa95e0b83", + "bytes": 1342, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/ingest/chunker.py", - "sha256": "cf9515ec9aecfa7a5b4bbe077c99711ecce651c6c155a4bef07475e404a96c83", + "source": "townlight_core/ingest/chunker.py", + "sha256": "8d3fa815c5ad9f920447467dfe0d08729a0a48d053f0fcc6d78877b97936c55d", + "bytes": 2303, "routes": [], "models": [ { @@ -1658,33 +1646,33 @@ { "name": "text", "type": "str", - "default": "" + "line": 6 }, { "name": "index", "type": "int", - "default": "" + "line": 7 }, { "name": "page_number", "type": "int | None", - "default": "None" + "line": 8 }, { "name": "token_count", "type": "int", - "default": "0" + "line": 9 } ], - "line": 5, - "doc": "" + "line": 5 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/ingest/contracts.py", - "sha256": "7536789de18c66e150ad16986c44a794c6ad3353c5dd9e1b29b10f24fa5afaca", + "source": "townlight_core/ingest/contracts.py", + "sha256": "68e2ea96be6e81be5ed543c7bf3eafe80a7cdf02d78be6d9e50f7e519d73266a", + "bytes": 2977, "routes": [], "models": [ { @@ -1694,36 +1682,35 @@ { "name": "status", "type": "HealthStatus", - "default": "" + "line": 19 }, { "name": "latency_ms", "type": "int | None", - "default": "None" + "line": 20 }, { "name": "error_message", "type": "str | None", - "default": "None" + "line": 21 }, { "name": "records_available", "type": "int | None", - "default": "None" + "line": 22 }, { "name": "schema_hash", "type": "str | None", - "default": "None" + "line": 23 }, { "name": "checked_at", "type": "datetime", - "default": "field(default_factory=lambda: datetime.now(timezone.utc))" + "line": 24 } ], - "line": 18, - "doc": "" + "line": 18 }, { "name": "DiscoveredRecord", @@ -1732,36 +1719,35 @@ { "name": "source_path", "type": "str", - "default": "" + "line": 31 }, { "name": "filename", "type": "str", - "default": "" + "line": 32 }, { "name": "file_type", "type": "str", - "default": "" + "line": 33 }, { "name": "file_size", "type": "int", - "default": "" + "line": 34 }, { "name": "last_modified", "type": "datetime | None", - "default": "None" + "line": 35 }, { "name": "metadata", "type": "dict", - "default": "field(default_factory=dict)" + "line": 36 } ], - "line": 28, - "doc": "A record discovered in a source system." + "line": 28 }, { "name": "FetchedDocument", @@ -1770,36 +1756,35 @@ { "name": "source_path", "type": "str", - "default": "" + "line": 43 }, { "name": "filename", "type": "str", - "default": "" + "line": 44 }, { "name": "file_type", "type": "str", - "default": "" + "line": 45 }, { "name": "content", "type": "bytes", - "default": "" + "line": 46 }, { "name": "file_size", "type": "int", - "default": "" + "line": 47 }, { "name": "metadata", "type": "dict", - "default": "field(default_factory=dict)" + "line": 48 } ], - "line": 40, - "doc": "A document fetched from a source system, ready for ingest." + "line": 40 }, { "name": "SourceMaterial", @@ -1808,21 +1793,20 @@ { "name": "source_id", "type": "str", - "default": "" + "line": 55 }, { "name": "label", "type": "str", - "default": "" + "line": 56 }, { "name": "text", "type": "str", - "default": "" + "line": 57 } ], - "line": 52, - "doc": "Human-readable source text that downstream workflows may cite." + "line": 52 }, { "name": "CitedSentence", @@ -1831,16 +1815,15 @@ { "name": "text", "type": "str", - "default": "" + "line": 71 }, { "name": "citations", "type": "tuple[str, ...]", - "default": "" + "line": 72 } ], - "line": 68, - "doc": "One output sentence plus the source ids it cites." + "line": 68 }, { "name": "CitationValidationError", @@ -1849,49 +1832,39 @@ { "name": "message", "type": "str", - "default": "" + "line": 83 }, { "name": "fix", "type": "str", - "default": "" + "line": 84 } ], - "line": 82, - "doc": "" + "line": 82 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/ingest/embedder.py", - "sha256": "655ae601f7901c847507e7ef4ab7cc3b77463e7ca1011831d9006b44cb3045ea", + "source": "townlight_core/ingest/embedder.py", + "sha256": "ae0eceb9f2c7345d849556d9dbb52349fa50676b970012a91eeda4e090f56cd4", + "bytes": 1653, "routes": [], "models": [], - "configuration": [ - { - "variable": "OLLAMA_BASE_URL", - "default": "'http://localhost:11434'", - "line": 13 - } - ] + "configuration": [] }, { - "source": "installed-owned-source/townlight_core/ingest/llm_extractor.py", - "sha256": "bfa082031b17b4a1af58472eb3faac4cd6cbc91f2d9a2f7e59763f5c92fa5680", + "source": "townlight_core/ingest/llm_extractor.py", + "sha256": "4a4d4d1464e32f8b9abe77c67472c75e59352b78265ac33112611dd940b3b445", + "bytes": 3128, "routes": [], "models": [], - "configuration": [ - { - "variable": "OLLAMA_BASE_URL", - "default": "'http://localhost:11434'", - "line": 15 - } - ] + "configuration": [] }, { - "source": "installed-owned-source/townlight_core/ingest/models.py", - "sha256": "a10de63e573ec5d4df5d258265f07695e6ed1805b3cf02897828dfe6008f73bd", + "source": "townlight_core/ingest/models.py", + "sha256": "08076031a8f61e62813665fa544e71a8957a9f79ef34a8316e983ba15855c288", + "bytes": 6450, "routes": [], "models": [ { @@ -1903,131 +1876,130 @@ { "name": "id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)" + "line": 41 }, { "name": "name", "type": "Mapped[str]", - "default": "mapped_column(String(255), unique=True)" + "line": 42 }, { "name": "source_type", "type": "Mapped[SourceType]", - "default": "mapped_column(Enum(SourceType, name='source_type', create_type=False, values_callable=lambda e: [m.value for m in e]))" + "line": 43 }, { "name": "connection_config", "type": "Mapped[dict[str, Any]]", - "default": "mapped_column(JSONB, default=dict)" + "line": 46 }, { "name": "is_active", "type": "Mapped[bool]", - "default": "mapped_column(Boolean, default=True)" + "line": 47 }, { "name": "created_by", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True))" + "line": 51 }, { "name": "created_at", "type": "Mapped[datetime]", - "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + "line": 52 }, { "name": "last_ingestion_at", "type": "Mapped[datetime | None]", - "default": "mapped_column(DateTime(timezone=True), nullable=True)" + "line": 53 }, { "name": "discovered_source_id", "type": "Mapped[uuid.UUID | None]", - "default": "mapped_column(nullable=True)" + "line": 55 }, { "name": "connector_template_id", "type": "Mapped[int | None]", - "default": "mapped_column(Integer, nullable=True)" + "line": 56 }, { "name": "sync_schedule", "type": "Mapped[str | None]", - "default": "mapped_column(String(50), nullable=True)" + "line": 57 }, { "name": "schedule_enabled", "type": "Mapped[bool]", - "default": "mapped_column(Boolean, default=True, server_default='true')" + "line": 58 }, { "name": "last_sync_at", "type": "Mapped[datetime | None]", - "default": "mapped_column(DateTime(timezone=True), nullable=True)" + "line": 59 }, { "name": "last_sync_cursor", "type": "Mapped[str | None]", - "default": "mapped_column(String, nullable=True)" + "line": 60 }, { "name": "last_sync_status", "type": "Mapped[str | None]", - "default": "mapped_column(String(20), nullable=True)" + "line": 61 }, { "name": "consecutive_failure_count", "type": "Mapped[int]", - "default": "mapped_column(Integer, default=0, server_default='0')" + "line": 63 }, { "name": "last_error_message", "type": "Mapped[str | None]", - "default": "mapped_column(String(500), nullable=True)" + "line": 64 }, { "name": "last_error_at", "type": "Mapped[datetime | None]", - "default": "mapped_column(DateTime(timezone=True), nullable=True)" + "line": 65 }, { "name": "sync_paused", "type": "Mapped[bool]", - "default": "mapped_column(Boolean, default=False, server_default='false')" + "line": 66 }, { "name": "sync_paused_at", "type": "Mapped[datetime | None]", - "default": "mapped_column(DateTime(timezone=True), nullable=True)" + "line": 67 }, { "name": "sync_paused_reason", "type": "Mapped[str | None]", - "default": "mapped_column(String(200), nullable=True)" + "line": 68 }, { "name": "retry_batch_size", "type": "Mapped[int | None]", - "default": "mapped_column(Integer, nullable=True)" + "line": 69 }, { "name": "retry_time_limit_seconds", "type": "Mapped[int | None]", - "default": "mapped_column(Integer, nullable=True)" + "line": 70 }, { "name": "health_status", "type": "Mapped[str | None]", - "default": "mapped_column(String(20), nullable=True)" + "line": 71 }, { "name": "schema_hash", "type": "Mapped[str | None]", - "default": "mapped_column(String(64), nullable=True)" + "line": 72 } ], - "line": 36, - "doc": "Source system or corpus that owns ingested documents." + "line": 36 }, { "name": "Document", @@ -2038,101 +2010,100 @@ { "name": "id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)" + "line": 80 }, { "name": "source_id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True), ForeignKey('data_sources.id'), index=True)" + "line": 81 }, { "name": "source_path", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 82 }, { "name": "filename", "type": "Mapped[str]", - "default": "mapped_column(String(500))" + "line": 83 }, { "name": "file_type", "type": "Mapped[str]", - "default": "mapped_column(String(50))" + "line": 84 }, { "name": "file_hash", "type": "Mapped[str]", - "default": "mapped_column(String(64), index=True)" + "line": 85 }, { "name": "file_size", "type": "Mapped[int]", - "default": "mapped_column(Integer, default=0)" + "line": 86 }, { "name": "ingestion_status", "type": "Mapped[IngestionStatus]", - "default": "mapped_column(Enum(IngestionStatus, name='ingestion_status', create_type=False, values_callable=lambda e: [m.value for m in e]), default=IngestionStatus.PENDING)" + "line": 87 }, { "name": "ingestion_error", "type": "Mapped[str | None]", - "default": "mapped_column(Text, nullable=True)" + "line": 96 }, { "name": "chunk_count", "type": "Mapped[int]", - "default": "mapped_column(Integer, default=0)" + "line": 97 }, { "name": "ingested_at", "type": "Mapped[datetime | None]", - "default": "mapped_column(DateTime(timezone=True), nullable=True)" + "line": 98 }, { "name": "metadata_", "type": "Mapped[dict[str, Any] | None]", - "default": "mapped_column('metadata', JSONB, nullable=True)" + "line": 99 }, { "name": "connector_type", "type": "Mapped[str | None]", - "default": "mapped_column(String(20), nullable=True)" + "line": 101 }, { "name": "updated_at", "type": "Mapped[datetime | None]", - "default": "mapped_column(DateTime(timezone=True), nullable=True)" + "line": 102 }, { "name": "display_name", "type": "Mapped[str | None]", - "default": "mapped_column(String(500), nullable=True)" + "line": 104 }, { "name": "department_id", "type": "Mapped[uuid.UUID | None]", - "default": "mapped_column(nullable=True)" + "line": 105 }, { "name": "redaction_status", "type": "Mapped[str]", - "default": "mapped_column(String(20), server_default='none')" + "line": 106 }, { "name": "derivative_path", "type": "Mapped[str | None]", - "default": "mapped_column(String(1000), nullable=True)" + "line": 107 }, { "name": "original_locked", "type": "Mapped[bool]", - "default": "mapped_column(Boolean, server_default='false')" + "line": 108 } ], - "line": 75, - "doc": "One ingested file or structured record." + "line": 75 }, { "name": "DocumentChunk", @@ -2143,55 +2114,56 @@ { "name": "id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)" + "line": 118 }, { "name": "document_id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True), ForeignKey('documents.id', ondelete='CASCADE'), index=True)" + "line": 119 }, { "name": "chunk_index", "type": "Mapped[int]", - "default": "mapped_column(Integer)" + "line": 122 }, { "name": "content_text", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 123 }, { "name": "embedding", "type": "Mapped[list[float] | None]", - "default": "mapped_column(Vector(768), nullable=True)" + "line": 124 }, { "name": "token_count", "type": "Mapped[int]", - "default": "mapped_column(Integer, default=0)" + "line": 125 }, { "name": "page_number", "type": "Mapped[int | None]", - "default": "mapped_column(Integer, nullable=True)" + "line": 126 } ], - "line": 113, - "doc": "Sentence-aware chunk text and vector embedding for one document." + "line": 113 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/ingest/parsers/__init__.py", - "sha256": "f6d7f512bae3794abd587b16845f42af7689ada1f994aca134389f922a445537", + "source": "townlight_core/ingest/parsers/__init__.py", + "sha256": "143dc760e3328838da545d9bcbd2e02a30e9761e1c906eed79713ca521e06692", + "bytes": 1072, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/ingest/parsers/base.py", - "sha256": "d2618295496026752492dcbab6230d8973ed51f4a91984f7150e1bb064c36423", + "source": "townlight_core/ingest/parsers/base.py", + "sha256": "95e1302e3e2dfabc8cf91d4086706d06e35474e68e4ed3e35a9f08185764fe1f", + "bytes": 878, "routes": [], "models": [ { @@ -2201,21 +2173,20 @@ { "name": "text", "type": "str", - "default": "" + "line": 7 }, { "name": "page_number", "type": "int | None", - "default": "None" + "line": 8 }, { "name": "metadata", "type": "dict", - "default": "field(default_factory=dict)" + "line": 9 } ], - "line": 6, - "doc": "" + "line": 6 }, { "name": "ParseResult", @@ -2224,21 +2195,20 @@ { "name": "pages", "type": "list[ParsedPage]", - "default": "" + "line": 13 }, { "name": "metadata", "type": "dict", - "default": "field(default_factory=dict)" + "line": 14 }, { "name": "file_type", "type": "str", - "default": "''" + "line": 15 } ], - "line": 12, - "doc": "" + "line": 12 }, { "name": "BaseParser", @@ -2249,67 +2219,74 @@ { "name": "supported_extensions", "type": "list[str]", - "default": "[]" + "line": 26 } ], - "line": 25, - "doc": "" + "line": 25 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/ingest/parsers/csv_parser.py", - "sha256": "7c8208fed09911e4f8153ab3c7d1fcfc281b5aec016589b697a728769bdcb41c", + "source": "townlight_core/ingest/parsers/csv_parser.py", + "sha256": "73e60408c70bb358deb0d6a00a2af942539743128b1c3e5e545f95ad6b27b463", + "bytes": 799, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/ingest/parsers/docx.py", - "sha256": "224542a9d2ebfdf9d3ef8947c7040ec683d13b507462a9c929e167c6b05529f3", + "source": "townlight_core/ingest/parsers/docx.py", + "sha256": "a101377c0cc7585f8bc91ad2f2f0e8790468e93ca663a29875d0cf605f5add56", + "bytes": 3349, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/ingest/parsers/email.py", - "sha256": "a83333d1ed5498fd56c61b47ce897b3d2c3b221070d7d13b000ea95336ea08e1", + "source": "townlight_core/ingest/parsers/email.py", + "sha256": "067103e5dea87b75d4f9eb23ecb9313d59f343fc777d41d3d201ab6c3a32897c", + "bytes": 1267, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/ingest/parsers/html.py", - "sha256": "a0383c330920702a913140377891e3eed43f029a3c756e9dceade4eb6d81b92e", + "source": "townlight_core/ingest/parsers/html.py", + "sha256": "800f7e82730c897eedb9b815140b2c90ff606bc31a1c57d82b55c69295ed7c76", + "bytes": 804, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/ingest/parsers/pdf.py", - "sha256": "fe312d998d3224a5cc10ee28c6f76f50a856075b5338370baed56d83ebbc0032", + "source": "townlight_core/ingest/parsers/pdf.py", + "sha256": "77a84cd4080a5d75505f074ed5ccafc619c3a5b7e788f77b254f30da29be095e", + "bytes": 888, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/ingest/parsers/text.py", - "sha256": "b77c107e8446d92e1fa0ce4f11ed54906e02c2bc5980c19e344c175d635c3441", + "source": "townlight_core/ingest/parsers/text.py", + "sha256": "40ac3d40fb1cbddc34ab5d03347f1c0836992516895df34ca5bfa4a51022d903", + "bytes": 578, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/ingest/parsers/xlsx.py", - "sha256": "3bd37c6f389644b630d44fe4964f5f82623469ae2855c04e81437b0fbe9f8fe0", + "source": "townlight_core/ingest/parsers/xlsx.py", + "sha256": "4bca7a22946eea259a61a5d97040b290e82271d1ad2964fcf65988cef0643e94", + "bytes": 3230, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/ingest/pipeline.py", - "sha256": "6d1cbe9794d4bf98e22ddbf18ba4bed5bb96e8a0231f87075b92eeebac4bf570", + "source": "townlight_core/ingest/pipeline.py", + "sha256": "6cda90ee5128384ca716760865ed28d76f2b46ce141c7df9395b311e5d8d4459", + "bytes": 13615, "routes": [], "models": [ { @@ -2321,25 +2298,26 @@ { "name": "supported_extensions", "type": "list[str]", - "default": "" + "line": 22 } ], - "line": 19, - "doc": "Parser-like handler contract for file suffixes." + "line": 19 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/llm/__init__.py", - "sha256": "7f8341c07da53f39684a477f9b4fe88ce425a3dc5444f9ac6560eca9787bdac5", + "source": "townlight_core/llm/__init__.py", + "sha256": "ed910741b77a88421ad13583f6d0858361b016e28dfc8d2350bfee5f058836ab", + "bytes": 3865, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/llm/context.py", - "sha256": "e7df765626e5ff642e0b86c36771379662ce35594b147391fef0566835762daa", + "source": "townlight_core/llm/context.py", + "sha256": "d032bc3bf9b0150528ebee667b4cb684bfd739223d30c569e4eb2894829857d8", + "bytes": 8808, "routes": [], "models": [ { @@ -2349,36 +2327,35 @@ { "name": "system_instruction", "type": "int", - "default": "500" + "line": 37 }, { "name": "request_context", "type": "int", - "default": "500" + "line": 38 }, { "name": "retrieved_chunks", "type": "int", - "default": "5000" + "line": 39 }, { "name": "exemption_rules", "type": "int", - "default": "500" + "line": 40 }, { "name": "output_reservation", "type": "int", - "default": "1500" + "line": 41 }, { "name": "safety_margin", "type": "int", - "default": "192" + "line": 42 } ], - "line": 34, - "doc": "Token budget allocation for an LLM call." + "line": 34 }, { "name": "ContextBlock", @@ -2387,56 +2364,60 @@ { "name": "role", "type": "str", - "default": "" + "line": 60 }, { "name": "content", "type": "str", - "default": "" + "line": 61 }, { "name": "estimated_tokens", "type": "int", - "default": "0" + "line": 62 } ], - "line": 57, - "doc": "A block of content with its role and estimated token count." + "line": 57 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/llm/factory.py", - "sha256": "0497147ca6d8af7c4b233a4157089fe4911bb49d0ea214f4fce9ac4c65e48aee", + "source": "townlight_core/llm/factory.py", + "sha256": "e2358941f74a34a659e8f79f42f897309be4ce99c6882d8318cec87ce1a23bb5", + "bytes": 2948, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/llm/providers/__init__.py", - "sha256": "4decd4720c452fa27d1b245a603d409b7dc99db1c5015dbdb3ae29d745ac61fc", + "source": "townlight_core/llm/providers/__init__.py", + "sha256": "6590c160c8baefb7049826b23d187d46b66eb657afb645ca0a4c8d43d840805f", + "bytes": 1316, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/llm/providers/anthropic.py", - "sha256": "dba9eb64c724fe8a209dbac48743f99463f99e0c1c67b1306d9126985348b267", + "source": "townlight_core/llm/providers/anthropic.py", + "sha256": "b60ffd6acc8eb71a9ea53a101124bbc97adcfed14b59bc74361a5a10b22aa5a4", + "bytes": 5338, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/llm/providers/base.py", - "sha256": "fe430884bcaf7678f625db6203312e1f1dcdce617db36870623e87b5ac066b32", + "source": "townlight_core/llm/providers/base.py", + "sha256": "57f4cc31b824641b6533353a08069ad8efe164e2f2795dced911f1a489a6e12a", + "bytes": 3845, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/llm/providers/config.py", - "sha256": "db4ee77e2e0a3ac16fd71df4f0979fab89d36b2ff1985c1e2d4498299810fd3a", + "source": "townlight_core/llm/providers/config.py", + "sha256": "b82987ff817044c3f3493fb9e97d5e0ce49c5dee138545264119596ced9358f5", + "bytes": 1836, "routes": [], "models": [ { @@ -2448,26 +2429,25 @@ { "name": "base_url", "type": "str", - "default": "Field(default='http://localhost:11434')" + "line": 18 }, { "name": "default_model", "type": "str", - "default": "Field(default='gemma4:e4b')" + "line": 19 }, { "name": "default_embed_model", "type": "str", - "default": "Field(default='nomic-embed-text')" + "line": 20 }, { "name": "think", "type": "bool | str | None", - "default": "Field(default=None)" + "line": 23 } ], - "line": 12, - "doc": "Config schema for OllamaProvider.\n\nAll fields have sensible defaults \u2014 Ollama runs locally and does not\nrequire credentials." + "line": 12 }, { "name": "OpenAIConfig", @@ -2478,21 +2458,20 @@ { "name": "api_key", "type": "str", - "default": "Field(min_length=1, description='OpenAI API key')" + "line": 32 }, { "name": "default_model", "type": "str", - "default": "Field(default='gpt-4o-mini')" + "line": 33 }, { "name": "default_embed_model", "type": "str", - "default": "Field(default='text-embedding-3-small')" + "line": 34 } ], - "line": 26, - "doc": "Config schema for OpenAIProvider.\n\napi_key is required; passing it via env var is the caller's responsibility\n(e.g., `OpenAIConfig(api_key=os.environ[\"OPENAI_API_KEY\"])`)." + "line": 26 }, { "name": "AnthropicConfig", @@ -2503,56 +2482,60 @@ { "name": "api_key", "type": "str", - "default": "Field(min_length=1, description='Anthropic API key')" + "line": 43 }, { "name": "default_model", "type": "str", - "default": "Field(default='claude-haiku-4-5')" + "line": 44 }, { "name": "max_tokens", "type": "int", - "default": "Field(default=4096, gt=0)" + "line": 45 } ], - "line": 37, - "doc": "Config schema for AnthropicProvider.\n\napi_key is required. max_tokens is a sensible default (4096) and can be\nincreased for longer outputs." + "line": 37 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/llm/providers/ollama.py", - "sha256": "bd1c78980c464dd41c7fdc24d9c362d17d20d343c9eac3c01000609bacd47e2b", + "source": "townlight_core/llm/providers/ollama.py", + "sha256": "c7514fc0f714f520b90e0b93300fa4ba292f84bd770a8bdede416921f2bb9054", + "bytes": 4789, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/llm/providers/openai.py", - "sha256": "d54920131ea2f0f14b8eee8c970dce47bf5ee5886815626f09f765fd8d4f4a30", + "source": "townlight_core/llm/providers/openai.py", + "sha256": "b7d86e8967dbb9733ddbadb62622d22b969dcae3891eb4f08ef41a25a0630295", + "bytes": 4684, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/llm/providers/registry.py", - "sha256": "2733af50366c7e8975c1b552fbe5302ed12d284abd59e65768ac8453d3639870", + "source": "townlight_core/llm/providers/registry.py", + "sha256": "9fce82b519c2e327fff38f3a4cd4c0638b941f5b08ea7c9ff8c44f65c8143fb3", + "bytes": 3234, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/llm/registry/__init__.py", - "sha256": "9223edf2e5652dcee6612a2593299b12e06c6e46f24b4784d9d97bdda333a3d0", + "source": "townlight_core/llm/registry/__init__.py", + "sha256": "37336ea704f8a53133a5b0a08eb78e63ebbbba00f63193cec7f492b5f7e69100", + "bytes": 1711, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/llm/registry/models.py", - "sha256": "f58ccb6ce42a7d344c4de7432ca3623e7865a59c91646736e1d397b565e07b0e", + "source": "townlight_core/llm/registry/models.py", + "sha256": "0aceeca8a9a101bd0cf8a0362043eae7c5500f8f9d9f71fc8bf4d3f409165545", + "bytes": 2328, "routes": [], "models": [ { @@ -2564,147 +2547,107 @@ { "name": "id", "type": "Mapped[int]", - "default": "mapped_column(Integer, primary_key=True)" + "line": 34 }, { "name": "model_name", "type": "Mapped[str]", - "default": "mapped_column(String(255), nullable=False)" + "line": 35 }, { "name": "model_version", "type": "Mapped[str | None]", - "default": "mapped_column(String(100), nullable=True)" + "line": 36 }, { "name": "parameter_count", "type": "Mapped[str | None]", - "default": "mapped_column(String(50), nullable=True)" + "line": 37 }, { "name": "license", "type": "Mapped[str | None]", - "default": "mapped_column(String(100), nullable=True)" + "line": 38 }, { "name": "model_card_url", "type": "Mapped[str | None]", - "default": "mapped_column(Text, nullable=True)" + "line": 39 }, { "name": "is_active", "type": "Mapped[bool]", - "default": "mapped_column(Boolean, nullable=False, server_default='false')" + "line": 40 }, { "name": "added_at", "type": "Mapped[datetime | None]", - "default": "mapped_column(TIMESTAMP(timezone=True), nullable=True)" + "line": 43 }, { "name": "context_window_size", "type": "Mapped[int | None]", - "default": "mapped_column(Integer, nullable=True)" + "line": 46 }, { "name": "supports_ner", "type": "Mapped[bool]", - "default": "mapped_column(Boolean, nullable=False, server_default='false')" + "line": 47 }, { "name": "supports_vision", "type": "Mapped[bool]", - "default": "mapped_column(Boolean, nullable=False, server_default='false')" + "line": 50 } ], - "line": 29, - "doc": "ORM model for the model_registry table." + "line": 29 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/llm/registry/router.py", - "sha256": "03815bc31f8b2651acee939dd370f44c91a2c92e663ebe25273986540a379b2f", + "source": "townlight_core/llm/registry/router.py", + "sha256": "29c58ae8b9c85648deb54b557a5f2f78a2d92157e5d624dffbb3c9a1c0d7bd2c", + "bytes": 3424, "routes": [ { "method": "GET", - "path": "/admin/models", - "router": "router", - "prefix_resolved": true, - "name": "list_models", - "signature": "session: AsyncSession=Depends(get_session)", - "returns": "", - "line": 46, - "doc": "", - "decorator": "router.get('', response_model=list[ModelRegistryRead])", - "errors": [] + "declared_path": "", + "function": "list_models", + "line": 46 }, { "method": "GET", - "path": "/admin/models/{model_id}", - "router": "router", - "prefix_resolved": true, - "name": "get_model", - "signature": "model_id: int, session: AsyncSession=Depends(get_session)", - "returns": "", - "line": 53, - "doc": "", - "decorator": "router.get('/{model_id}', response_model=ModelRegistryRead)", - "errors": [ - "HTTPException(status_code=404, detail=f'Model {model_id} not found')" - ] + "declared_path": "/{model_id}", + "function": "get_model", + "line": 53 }, { "method": "POST", - "path": "/admin/models", - "router": "router", - "prefix_resolved": true, - "name": "create_model", - "signature": "payload: ModelRegistryCreate, session: AsyncSession=Depends(get_session)", - "returns": "", - "line": 61, - "doc": "", - "decorator": "router.post('', response_model=ModelRegistryRead, status_code=201)", - "errors": [] + "declared_path": "", + "function": "create_model", + "line": 61 }, { "method": "PATCH", - "path": "/admin/models/{model_id}", - "router": "router", - "prefix_resolved": true, - "name": "update_model", - "signature": "model_id: int, payload: ModelRegistryUpdate, session: AsyncSession=Depends(get_session)", - "returns": "", - "line": 73, - "doc": "", - "decorator": "router.patch('/{model_id}', response_model=ModelRegistryRead)", - "errors": [ - "HTTPException(status_code=404, detail=f'Model {model_id} not found')" - ] + "declared_path": "/{model_id}", + "function": "update_model", + "line": 73 }, { "method": "DELETE", - "path": "/admin/models/{model_id}", - "router": "router", - "prefix_resolved": true, - "name": "delete_model", - "signature": "model_id: int, session: AsyncSession=Depends(get_session)", - "returns": "", - "line": 89, - "doc": "", - "decorator": "router.delete('/{model_id}', status_code=204)", - "errors": [ - "HTTPException(status_code=404, detail=f'Model {model_id} not found')" - ] + "declared_path": "/{model_id}", + "function": "delete_model", + "line": 89 } ], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/llm/registry/schemas.py", - "sha256": "324d0b48abc8d3d0b7a66f9763145a29fed4e81a6b8a59f865b63fb1ab980bfe", + "source": "townlight_core/llm/registry/schemas.py", + "sha256": "fe336b9719d82b236e6afc353671eb8eb3e6ed13343a3c941a80b4473582683d", + "bytes": 2133, "routes": [], "models": [ { @@ -2716,51 +2659,50 @@ { "name": "model_name", "type": "str", - "default": "" + "line": 21 }, { "name": "model_version", "type": "str | None", - "default": "None" + "line": 22 }, { "name": "parameter_count", "type": "str | None", - "default": "None" + "line": 23 }, { "name": "license", "type": "str | None", - "default": "None" + "line": 24 }, { "name": "model_card_url", "type": "str | None", - "default": "None" + "line": 25 }, { "name": "is_active", "type": "bool", - "default": "False" + "line": 26 }, { "name": "context_window_size", "type": "int | None", - "default": "None" + "line": 27 }, { "name": "supports_ner", "type": "bool", - "default": "False" + "line": 28 }, { "name": "supports_vision", "type": "bool", - "default": "False" + "line": 29 } ], - "line": 18, - "doc": "Schema for creating a new model_registry record (POST body)." + "line": 18 }, { "name": "ModelRegistryRead", @@ -2771,61 +2713,60 @@ { "name": "id", "type": "int", - "default": "" + "line": 40 }, { "name": "model_name", "type": "str", - "default": "" + "line": 41 }, { "name": "model_version", "type": "str | None", - "default": "None" + "line": 42 }, { "name": "parameter_count", "type": "str | None", - "default": "None" + "line": 43 }, { "name": "license", "type": "str | None", - "default": "None" + "line": 44 }, { "name": "model_card_url", "type": "str | None", - "default": "None" + "line": 45 }, { "name": "is_active", "type": "bool", - "default": "" + "line": 46 }, { "name": "added_at", "type": "datetime | None", - "default": "None" + "line": 47 }, { "name": "context_window_size", "type": "int | None", - "default": "None" + "line": 48 }, { "name": "supports_ner", "type": "bool", - "default": "" + "line": 49 }, { "name": "supports_vision", "type": "bool", - "default": "" + "line": 50 } ], - "line": 32, - "doc": "Schema for returning a model_registry record (GET response).\n\n``from_attributes=True`` allows construction directly from an ORM instance." + "line": 32 }, { "name": "ModelRegistryUpdate", @@ -2836,79 +2777,82 @@ { "name": "model_name", "type": "str | None", - "default": "None" + "line": 60 }, { "name": "model_version", "type": "str | None", - "default": "None" + "line": 61 }, { "name": "parameter_count", "type": "str | None", - "default": "None" + "line": 62 }, { "name": "license", "type": "str | None", - "default": "None" + "line": 63 }, { "name": "model_card_url", "type": "str | None", - "default": "None" + "line": 64 }, { "name": "is_active", "type": "bool | None", - "default": "None" + "line": 65 }, { "name": "context_window_size", "type": "int | None", - "default": "None" + "line": 66 }, { "name": "supports_ner", "type": "bool | None", - "default": "None" + "line": 67 }, { "name": "supports_vision", "type": "bool | None", - "default": "None" + "line": 68 } ], - "line": 53, - "doc": "Schema for partially updating a model_registry record (PATCH body).\n\nEvery field is optional so callers can send only the fields they want to\nchange." + "line": 53 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/llm/registry/service.py", - "sha256": "9280f0161a4db25de8182f214fa9d143ef2b1bfc3dac65b1b83b570ed12ee407", + "source": "townlight_core/llm/registry/service.py", + "sha256": "06d9babf0786d2d06069d98f9f2bbf51b881b1349c418ba2b1282644c098f3b7", + "bytes": 2811, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/llm/structured.py", - "sha256": "9f7ad6645f2a02aa6a41207906be09a6e1adfc70a89c6eb78387e78cb807477a", + "source": "townlight_core/llm/structured.py", + "sha256": "a8e3558896c8fdf339548a2d6d7e68bfafb88c1fb0913f3870fe7abd8a7cd17d", + "bytes": 5876, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/llm/templates/__init__.py", - "sha256": "a00806b2b0d3c3b7dd966dee85db8f2ee6178697c6f222c28abe4454518ba341", + "source": "townlight_core/llm/templates/__init__.py", + "sha256": "47c5b3b7fefe918ccd77b9d0c1b524db6ba8750240ccd5b74d6e45f0cdce841f", + "bytes": 1742, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/llm/templates/engine.py", - "sha256": "cb4f72ba249be0264c827c4503b64dea8b61fe525ebb1a93870a9ba58b46d5df", + "source": "townlight_core/llm/templates/engine.py", + "sha256": "d3b2d8618b20092302dd5fd4d10c3cb6ceb6f3b3c11aeaf1aa8c17568b1d71a0", + "bytes": 3187, "routes": [], "models": [ { @@ -2918,45 +2862,46 @@ { "name": "system", "type": "str", - "default": "" + "line": 31 }, { "name": "user", "type": "str", - "default": "" + "line": 32 }, { "name": "template_name", "type": "str", - "default": "" + "line": 33 }, { "name": "consumer_app", "type": "str", - "default": "" + "line": 34 }, { "name": "version", "type": "int", - "default": "" + "line": 35 } ], - "line": 20, - "doc": "Result of rendering a PromptTemplate.\n\nAttributes:\n system: Rendered system_prompt string.\n user: Rendered user_prompt_template string.\n template_name: The source template's logical name.\n consumer_app: The source template's consumer_app namespace.\n version: The source template's version number." + "line": 20 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/llm/templates/exceptions.py", - "sha256": "53bbdcfd915d751cc878edc148a39b52424b5c34a4d03ed8120d763464967a96", + "source": "townlight_core/llm/templates/exceptions.py", + "sha256": "5b40a69202c7dfb3292563716ecfda9b0255694795ff88308c57303fd8cccd73", + "bytes": 2331, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/llm/templates/models.py", - "sha256": "c1a61785d12d40657aad28ead8f8d27c947634ab159bc48b4309788ae4ed674d", + "source": "townlight_core/llm/templates/models.py", + "sha256": "6c460d2cd19320d4b905020c644001bcf5ab117dce2e1bfae18642018d5307be", + "bytes": 3958, "routes": [], "models": [ { @@ -2968,92 +2913,94 @@ { "name": "id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(PG_UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)" + "line": 51 }, { "name": "template_name", "type": "Mapped[str]", - "default": "mapped_column(String(200), nullable=False)" + "line": 56 }, { "name": "consumer_app", "type": "Mapped[str]", - "default": "mapped_column(String(100), nullable=False, server_default='townlight_core')" + "line": 57 }, { "name": "is_override", "type": "Mapped[bool]", - "default": "mapped_column(Boolean, nullable=False, server_default='false')" + "line": 60 }, { "name": "purpose", "type": "Mapped[str]", - "default": "mapped_column(String(50), nullable=False)" + "line": 63 }, { "name": "system_prompt", "type": "Mapped[str]", - "default": "mapped_column(Text, nullable=False)" + "line": 64 }, { "name": "user_prompt_template", "type": "Mapped[str]", - "default": "mapped_column(Text, nullable=False)" + "line": 65 }, { "name": "token_budget", "type": "Mapped[dict | None]", - "default": "mapped_column(JSONB, nullable=True)" + "line": 66 }, { "name": "model_id", "type": "Mapped[int | None]", - "default": "mapped_column(Integer, ForeignKey('model_registry.id', ondelete='SET NULL'), nullable=True)" + "line": 67 }, { "name": "version", "type": "Mapped[int]", - "default": "mapped_column(Integer, nullable=False, server_default='1')" + "line": 72 }, { "name": "is_active", "type": "Mapped[bool]", - "default": "mapped_column(Boolean, nullable=False, server_default='true')" + "line": 75 }, { "name": "created_by", "type": "Mapped[uuid.UUID | None]", - "default": "mapped_column(PG_UUID(as_uuid=True), nullable=True)" + "line": 84 }, { "name": "created_at", "type": "Mapped[datetime]", - "default": "mapped_column(TIMESTAMP(timezone=True), nullable=False, server_default=func.now())" + "line": 88 } ], - "line": 37, - "doc": "ORM model for the prompt_templates table." + "line": 37 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/llm/templates/overrides.py", - "sha256": "6a32018a76d803c74408937b75e6d3ad597f247d533e2d8092ce7bbccc0d0cd1", + "source": "townlight_core/llm/templates/overrides.py", + "sha256": "d5a896fb685ccae553bc2471512f597a054023b9f360bfe416dcc5227837d644", + "bytes": 2545, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/llm/templates/resolver.py", - "sha256": "389bf9b01902b046f8986fc3415125c859bf8a4923e07d146d0cdd75587b9636", + "source": "townlight_core/llm/templates/resolver.py", + "sha256": "44c1555f884f9bf8605671ea4cc18c431aa317bf1ddc91100e845a76572f9603", + "bytes": 4157, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/llm/templates/schemas.py", - "sha256": "f012308c13d12ec8e338335c5ba451d73c171605697a79a8f3dba334f4af1854", + "source": "townlight_core/llm/templates/schemas.py", + "sha256": "931cbb7e2c3a714e7c76239c18e7be8db1a97e520cb143e24ce15d799921f15b", + "bytes": 1769, "routes": [], "models": [ { @@ -3065,61 +3012,60 @@ { "name": "template_name", "type": "str", - "default": "" + "line": 17 }, { "name": "purpose", "type": "str", - "default": "" + "line": 18 }, { "name": "system_prompt", "type": "str", - "default": "" + "line": 19 }, { "name": "user_prompt_template", "type": "str", - "default": "" + "line": 20 }, { "name": "consumer_app", "type": "str", - "default": "'townlight_core'" + "line": 23 }, { "name": "is_override", "type": "bool", - "default": "False" + "line": 24 }, { "name": "token_budget", "type": "dict | None", - "default": "None" + "line": 25 }, { "name": "model_id", "type": "int | None", - "default": "None" + "line": 26 }, { "name": "version", "type": "int", - "default": "1" + "line": 27 }, { "name": "is_active", "type": "bool", - "default": "True" + "line": 28 }, { "name": "created_by", "type": "uuid.UUID | None", - "default": "None" + "line": 29 } ], - "line": 13, - "doc": "Fields required (or defaulted) when creating a new prompt template." + "line": 13 }, { "name": "PromptTemplateRead", @@ -3130,71 +3076,70 @@ { "name": "id", "type": "uuid.UUID", - "default": "" + "line": 37 }, { "name": "template_name", "type": "str", - "default": "" + "line": 38 }, { "name": "consumer_app", "type": "str", - "default": "" + "line": 39 }, { "name": "is_override", "type": "bool", - "default": "" + "line": 40 }, { "name": "purpose", "type": "str", - "default": "" + "line": 41 }, { "name": "system_prompt", "type": "str", - "default": "" + "line": 42 }, { "name": "user_prompt_template", "type": "str", - "default": "" + "line": 43 }, { "name": "token_budget", "type": "dict | None", - "default": "" + "line": 44 }, { "name": "model_id", "type": "int | None", - "default": "" + "line": 45 }, { "name": "version", "type": "int", - "default": "" + "line": 46 }, { "name": "is_active", "type": "bool", - "default": "" + "line": 47 }, { "name": "created_by", "type": "uuid.UUID | None", - "default": "" + "line": 48 }, { "name": "created_at", "type": "datetime", - "default": "" + "line": 49 } ], - "line": 32, - "doc": "All columns for reading a prompt template row." + "line": 32 }, { "name": "PromptTemplateUpdate", @@ -3205,192 +3150,213 @@ { "name": "template_name", "type": "str | None", - "default": "None" + "line": 55 }, { "name": "purpose", "type": "str | None", - "default": "None" + "line": 56 }, { "name": "system_prompt", "type": "str | None", - "default": "None" + "line": 57 }, { "name": "user_prompt_template", "type": "str | None", - "default": "None" + "line": 58 }, { "name": "consumer_app", "type": "str | None", - "default": "None" + "line": 59 }, { "name": "is_override", "type": "bool | None", - "default": "None" + "line": 60 }, { "name": "token_budget", "type": "dict | None", - "default": "None" + "line": 61 }, { "name": "model_id", "type": "int | None", - "default": "None" + "line": 62 }, { "name": "version", "type": "int | None", - "default": "None" + "line": 63 }, { "name": "is_active", "type": "bool | None", - "default": "None" + "line": 64 } ], - "line": 52, - "doc": "Partial update schema for PATCH operations. All fields optional." + "line": 52 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/migrations/__init__.py", - "sha256": "6cb4358063e7a281454ae36e2aa4565e9048e00d193d1da0bab81df47a453703", + "source": "townlight_core/migrations/__init__.py", + "sha256": "9a745f1756a2685c4d7fa974007c53f419502c238ed3956f97e844e343965c0f", + "bytes": 240, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_core/migrations/alembic.ini", + "sha256": "9f91262372d5cf06551f80272b10a44c197be3ef3e7dcda228271d6346c4eee6", + "bytes": 87, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/migrations/env.py", - "sha256": "208de714d58a5b3fa8f3797c05eadba49d0b46105afeb20c50e7685e298fb4cb", + "source": "townlight_core/migrations/env.py", + "sha256": "7ee4f5d2b7bb757689ed8466e665dff961ccb23d0541dd31dca730c806c3ed73", + "bytes": 3012, "routes": [], "models": [], "configuration": [ { - "variable": "DATABASE_URL", - "default": "", + "environment": "DATABASE_URL", "line": 64 }, { - "variable": "DATABASE_URL", - "default": "", + "environment": "DATABASE_URL", "line": 27 } ] }, { - "source": "installed-owned-source/townlight_core/migrations/guards.py", - "sha256": "c55de91c7189b39537aed6130a1e9f50817f819bd13aa4728ae4e8dd4c863aad", + "source": "townlight_core/migrations/guards.py", + "sha256": "ad6b3855ae5805aa44d4fd06239047228f0642fb1fc6b504ea47d447aea01608", + "bytes": 7852, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/migrations/runner.py", - "sha256": "4f3b554197baf06924cc3676d42df083f14f3a9db1456a775601d975499e354e", + "source": "townlight_core/migrations/runner.py", + "sha256": "20c85f60b4a55c9b01d334718794dd3de67cb81c13a341f3f6ed1a76f9a4f31f", + "bytes": 3669, "routes": [], "models": [], "configuration": [ { - "variable": "DATABASE_URL", - "default": "", + "environment": "DATABASE_URL", "line": 47 } ] }, { - "source": "installed-owned-source/townlight_core/migrations/versions/__init__.py", - "sha256": "61c059e42b35e302a4372a1c7697ca495118b123f7303306d7c54ff15173c8c6", + "source": "townlight_core/migrations/versions/__init__.py", + "sha256": "68926a3b7368abcbb421c607eb819cf0d9fefaa908c52e8d52c58700aebf7c47", + "bytes": 307, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/migrations/versions/townlight_core_0001_baseline_v1.py", - "sha256": "69186f3f798a01d61638ae42993761c3038ced04e143ea8dd292ebc1fc63afb7", + "source": "townlight_core/migrations/versions/townlight_core_0001_baseline_v1.py", + "sha256": "c2c15340fb08bab1113b277fde04a872bbf8acef3876aa8ca4f640ad320e6980", + "bytes": 24152, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/migrations/versions/townlight_core_0002_llm.py", - "sha256": "fa273e35f651a6298842df0de87bd5548d1a83698adc27e1385ceb28449b00cd", + "source": "townlight_core/migrations/versions/townlight_core_0002_llm.py", + "sha256": "d75548bca06143171c3704405c2671ae5191dc2b5fb85b7239b8a605dc321227", + "bytes": 6312, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/migrations/versions/townlight_core_0003_local_task_queue.py", - "sha256": "51276a0dc2737fd1fc2615f26d66d942c1df3be2ef40f1513436cd4579b1ecf0", + "source": "townlight_core/migrations/versions/townlight_core_0003_local_task_queue.py", + "sha256": "bc3d01f5e198904380fcc835b108a098ef9ba26f507c7d575219772adf5ab76f", + "bytes": 1909, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/migrations/versions/townlight_core_0004_catalog.py", - "sha256": "a9f46f8ca1bcde43a2796dd62891ad36840d1067220b16fdde8583a1f700a06d", + "source": "townlight_core/migrations/versions/townlight_core_0004_catalog.py", + "sha256": "8066969475b40be59d11ad9ad724402f3206456a82e440fc12b5f9bd4d3c8026", + "bytes": 748, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/migrations/versions/townlight_core_0005_job_leases.py", - "sha256": "a6651789d82cb0c39481f16855449bf09d65644c93a97bab1e33f8d7546157f7", + "source": "townlight_core/migrations/versions/townlight_core_0005_job_leases.py", + "sha256": "608b6d0e9bb2c17223b1708f655fe14596a32f0b68e2be86db044fade590cd8d", + "bytes": 899, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/migrations/versions/townlight_core_0006_rule_history.py", - "sha256": "ac29f724f60125de435235655a052ae3738a286467b1d6d8213a22558994a868", + "source": "townlight_core/migrations/versions/townlight_core_0006_rule_history.py", + "sha256": "c81a1f1c696696702aa1ae895ee6fc7cd2c9010766abf054491e8acc4f2e6302", + "bytes": 4206, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/migrations/versions/townlight_core_0007_module_inventory.py", - "sha256": "41aefee7ff2de883f92eebb7a39de2f0ed8b6bd4fecf88c6ebfd62a0b3cb7456", + "source": "townlight_core/migrations/versions/townlight_core_0007_module_inventory.py", + "sha256": "d8e4a304527de33536f5362a8eaaabd48992940265a6d72db6d666507433925b", + "bytes": 3596, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/migrations/versions/townlight_core_0008_department_authority.py", - "sha256": "fa7328f869594d1af2f4daceb4b362cd8ebe304b7e1ecbefaa22497d08430b4a", + "source": "townlight_core/migrations/versions/townlight_core_0008_department_authority.py", + "sha256": "96db7cdaa3c3465ba9f2e3ebe4996f3b9c9238e33f7ce85826dca3280b32901e", + "bytes": 3783, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/migrations/versions/townlight_core_0009_job_artifacts.py", - "sha256": "ee8952caff749c4b9df5cbc15c379f69f7066351ea5f7690525136be1481d9d8", + "source": "townlight_core/migrations/versions/townlight_core_0009_job_artifacts.py", + "sha256": "5c02e20fe7b91bd1f27d83191d337326db16a1b528c8b167094f5407f531e55a", + "bytes": 3392, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/models/__init__.py", - "sha256": "213b3086e533a98047d460720e7a1becd7f6196f4a6db989a39253351b8894c9", + "source": "townlight_core/models/__init__.py", + "sha256": "06147bb3a8ca75998557a755cd5966b4b617a9aab53426743f8ed915688f1d81", + "bytes": 363, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/notifications/__init__.py", - "sha256": "988bcb1091aef4451a1566202a6ec50e3b8908770707b5ad45398923bdb2d6be", + "source": "townlight_core/notifications/__init__.py", + "sha256": "a6b1d14746e7609f8b2512b2ef6ccf9c2cc94df1044a7b66d66a39c30636b824", + "bytes": 483, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/notifications/notice.py", - "sha256": "78c2542686403c647859b27f5a7bf7ff832cd29ca3ff4086b32c6e5fc098247b", + "source": "townlight_core/notifications/notice.py", + "sha256": "e6ad671cb058c276424a25ad0ded51b5525e1e2bd06fb7010e2c0049a8217de7", + "bytes": 5268, "routes": [], "models": [ { @@ -3400,31 +3366,30 @@ { "name": "notice_type", "type": "str", - "default": "" + "line": 16 }, { "name": "event_date", "type": "date", - "default": "" + "line": 17 }, { "name": "publish_by", "type": "date", - "default": "" + "line": 18 }, { "name": "reminders", "type": "tuple[str, ...]", - "default": "" + "line": 19 }, { "name": "staff_review_required", "type": "bool", - "default": "" + "line": 20 } ], - "line": 13, - "doc": "Deterministic notice deadline reminders without legal determinations." + "line": 13 }, { "name": "NoticeComplianceWarning", @@ -3433,21 +3398,20 @@ { "name": "code", "type": "str", - "default": "" + "line": 27 }, { "name": "message", "type": "str", - "default": "" + "line": 28 }, { "name": "fix", "type": "str", - "default": "" + "line": 29 } ], - "line": 24, - "doc": "Actionable warning describing a notice-compliance gap." + "line": 24 }, { "name": "NoticeComplianceResult", @@ -3456,75 +3420,76 @@ { "name": "meeting_id", "type": "str", - "default": "" + "line": 39 }, { "name": "notice_type", "type": "str", - "default": "" + "line": 40 }, { "name": "scheduled_start", "type": "datetime", - "default": "" + "line": 41 }, { "name": "posted_at", "type": "datetime", - "default": "" + "line": 42 }, { "name": "minimum_notice_hours", "type": "int", - "default": "" + "line": 43 }, { "name": "deadline_at", "type": "datetime", - "default": "" + "line": 44 }, { "name": "statutory_basis", "type": "str | None", - "default": "" + "line": 45 }, { "name": "approved_by", "type": "str | None", - "default": "" + "line": 46 }, { "name": "compliant", "type": "bool", - "default": "" + "line": 47 }, { "name": "http_status", "type": "int", - "default": "" + "line": 48 }, { "name": "warnings", "type": "tuple[NoticeComplianceWarning, ...]", - "default": "" + "line": 49 } ], - "line": 36, - "doc": "Result of checking whether a meeting notice is ready to publish." + "line": 36 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/onboarding/__init__.py", - "sha256": "d4d47bddbea571ade848657d39a128849e7b02c45a2c5476bd4ee933033a5713", + "source": "townlight_core/onboarding/__init__.py", + "sha256": "571ae2118d589efff98a29f0617b81fbf57ffa564944081ba090cd26aebd5f64", + "bytes": 544, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/onboarding/profile.py", - "sha256": "76f82f3b710700d4d3913a1ec5575c15499e46c11b4bb9ddffa2455710b93a93", + "source": "townlight_core/onboarding/profile.py", + "sha256": "b67bc5f483f07cc7966e6db37bfbd5aa4950f7f9ee530bc7fef27ed792885bd1", + "bytes": 5271, "routes": [], "models": [ { @@ -3534,21 +3499,20 @@ { "name": "name", "type": "str", - "default": "" + "line": 13 }, { "name": "question", "type": "str", - "default": "" + "line": 14 }, { "name": "kind", "type": "str", - "default": "'text'" + "line": 15 } ], - "line": 10, - "doc": "A tracked onboarding field and the default prompt used to ask for it." + "line": 10 }, { "name": "OnboardingProgress", @@ -3557,45 +3521,46 @@ { "name": "next_field", "type": "str | None", - "default": "" + "line": 22 }, { "name": "next_question", "type": "str | None", - "default": "" + "line": 23 }, { "name": "completed_fields", "type": "tuple[str, ...]", - "default": "" + "line": 24 }, { "name": "skipped_fields", "type": "tuple[str, ...]", - "default": "" + "line": 25 }, { "name": "all_complete", "type": "bool", - "default": "" + "line": 26 } ], - "line": 19, - "doc": "Skip-aware progress state for an interview-style onboarding walk." + "line": 19 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/platform/__init__.py", - "sha256": "a8618133480c425c95c6ab8b773261aa430f600603941248148b402341ac9f94", + "source": "townlight_core/platform/__init__.py", + "sha256": "8566d9cb030f415cc760ff53c2d2a86065ba24fb0098a1cf232fafba3a452ec2", + "bytes": 3698, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/platform/backup.py", - "sha256": "15396fd6bdeaebbddead4a619e11090b427dfcb8744dccd582bbbaf5ca49b407", + "source": "townlight_core/platform/backup.py", + "sha256": "3c2580aaf0bad4989fd048927ba4eb669b85fa6fccc5119d656c054a8bfd1bfe", + "bytes": 6873, "routes": [], "models": [ { @@ -3607,31 +3572,30 @@ { "name": "module_id", "type": "str", - "default": "Field(pattern='^[a-z][a-z0-9-]{1,63}$')" + "line": 20 }, { "name": "relative_path", "type": "str", - "default": "Field(min_length=1)" + "line": 21 }, { "name": "size_bytes", "type": "int", - "default": "Field(ge=0)" + "line": 22 }, { "name": "sha256", "type": "str", - "default": "Field(pattern='^[a-f0-9]{64}$')" + "line": 23 }, { "name": "required", "type": "bool", - "default": "True" + "line": 24 } ], - "line": 15, - "doc": "One file captured in a local backup." + "line": 15 }, { "name": "BackupManifest", @@ -3642,41 +3606,40 @@ { "name": "schema_version", "type": "str", - "default": "'1.0'" + "line": 32 }, { "name": "backup_id", "type": "str", - "default": "Field(min_length=1)" + "line": 33 }, { "name": "city_profile_id", "type": "str", - "default": "Field(min_length=1)" + "line": 34 }, { "name": "townlight_core_version", "type": "str", - "default": "Field(min_length=1)" + "line": 35 }, { "name": "created_at", "type": "datetime", - "default": "Field(default_factory=lambda: datetime.now(UTC))" + "line": 36 }, { "name": "modules", "type": "list[str]", - "default": "Field(default_factory=list)" + "line": 37 }, { "name": "items", "type": "list[BackupItem]", - "default": "" + "line": 38 } ], - "line": 27, - "doc": "Versioned backup manifest for a Townlight local profile." + "line": 27 }, { "name": "BackupValidationResult", @@ -3687,21 +3650,20 @@ { "name": "valid", "type": "bool", - "default": "" + "line": 46 }, { "name": "missing", "type": "list[str]", - "default": "Field(default_factory=list)" + "line": 47 }, { "name": "hash_mismatches", "type": "list[str]", - "default": "Field(default_factory=list)" + "line": 48 } ], - "line": 41, - "doc": "Result of checking a backup manifest against files on disk." + "line": 41 }, { "name": "BackupRestoreAction", @@ -3712,26 +3674,25 @@ { "name": "source_relative_path", "type": "str", - "default": "" + "line": 56 }, { "name": "target_relative_path", "type": "str", - "default": "" + "line": 57 }, { "name": "status", "type": "RestoreActionStatus", - "default": "" + "line": 58 }, { "name": "message", "type": "str", - "default": "" + "line": 59 } ], - "line": 51, - "doc": "One file restore action and its safety status." + "line": 51 }, { "name": "BackupRestorePlan", @@ -3742,28 +3703,28 @@ { "name": "ready", "type": "bool", - "default": "" + "line": 67 }, { "name": "actions", "type": "list[BackupRestoreAction]", - "default": "" + "line": 68 }, { "name": "blocked_reason", "type": "str | None", - "default": "None" + "line": 69 } ], - "line": 62, - "doc": "A non-destructive restore plan." + "line": 62 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/platform/health.py", - "sha256": "41f35066ee9a5c1ea3948605f3acf39c568a8916340598468def3502a0ec1634", + "source": "townlight_core/platform/health.py", + "sha256": "e63da46e405d5505dfde8b29723687698e0f84b7f692f42bdf5ba5468ceb0858", + "bytes": 3592, "routes": [], "models": [ { @@ -3775,46 +3736,45 @@ { "name": "component", "type": "str", - "default": "Field(min_length=1)" + "line": 24 }, { "name": "label", "type": "str", - "default": "Field(min_length=1)" + "line": 25 }, { "name": "status", "type": "PlatformHealthStatus", - "default": "" + "line": 26 }, { "name": "message", "type": "str", - "default": "Field(min_length=1)" + "line": 27 }, { "name": "next_action", "type": "str", - "default": "Field(min_length=1)" + "line": 28 }, { "name": "blocking", "type": "bool", - "default": "False" + "line": 29 }, { "name": "checked_at", "type": "datetime", - "default": "Field(default_factory=lambda: datetime.now(UTC))" + "line": 30 }, { "name": "admin_detail", "type": "str | None", - "default": "Field(default=None, min_length=1)" + "line": 31 } ], - "line": 19, - "doc": "One health check result suitable for staff/admin health screens." + "line": 19 }, { "name": "PlatformHealthSummary", @@ -3825,48 +3785,48 @@ { "name": "status", "type": "PlatformHealthStatus", - "default": "" + "line": 39 }, { "name": "checks", "type": "list[PlatformHealthCheck]", - "default": "" + "line": 40 }, { "name": "next_action", "type": "str", - "default": "" + "line": 41 }, { "name": "staff_message", "type": "str", - "default": "" + "line": 42 }, { "name": "admin_message", "type": "str", - "default": "" + "line": 43 }, { "name": "blocked_components", "type": "list[str]", - "default": "" + "line": 44 }, { "name": "degraded_components", "type": "list[str]", - "default": "" + "line": 45 } ], - "line": 34, - "doc": "Aggregated health status for the umbrella shell." + "line": 34 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/platform/inventory.py", - "sha256": "b6b1936c8bc2d5ba459370e9406395b3bf899a24ba439ff92ac38ae393fe7dda", + "source": "townlight_core/platform/inventory.py", + "sha256": "843f4399d19f328d98c6988bcc82f42a945ebd53df6833941aac501123dc7f70", + "bytes": 21323, "routes": [], "models": [ { @@ -3878,26 +3838,25 @@ { "name": "module_id", "type": "str", - "default": "Field(min_length=2, max_length=64)" + "line": 125 }, { "name": "version", "type": "str", - "default": "Field(min_length=1)" + "line": 126 }, { "name": "enabled", "type": "bool", - "default": "" + "line": 127 }, { "name": "manifest", "type": "ModuleManifest", - "default": "" + "line": 128 } ], - "line": 120, - "doc": "One module the scope declares it has, plus the manifest it was installed from." + "line": 120 }, { "name": "ModuleInventory", @@ -3908,31 +3867,30 @@ { "name": "scope_id", "type": "str", - "default": "Field(min_length=2, max_length=64)" + "line": 144 }, { "name": "revision", "type": "int", - "default": "Field(ge=1)" + "line": 145 }, { "name": "profile", "type": "InstallProfile", - "default": "'windows_local'" + "line": 146 }, { "name": "townlight_core_version", "type": "str", - "default": "Field(min_length=1)" + "line": 147 }, { "name": "entries", "type": "list[ModuleInventoryEntry]", - "default": "Field(default_factory=list)" + "line": 148 } ], - "line": 139, - "doc": "A scope's declared installed/enabled module set at one revision." + "line": 139 }, { "name": "InventoryOutcome", @@ -3943,21 +3901,20 @@ { "name": "inventory", "type": "ModuleInventory", - "default": "" + "line": 209 }, { "name": "inserted", "type": "bool", - "default": "" + "line": 210 }, { "name": "fingerprint", "type": "str", - "default": "" + "line": 211 } ], - "line": 204, - "doc": "Result of one append attempt." + "line": 204 }, { "name": "ModuleRecommendation", @@ -3968,38 +3925,38 @@ { "name": "module_id", "type": "str", - "default": "Field(min_length=2, max_length=64)" + "line": 415 }, { "name": "action", "type": "RecommendationAction", - "default": "" + "line": 416 }, { "name": "basis", "type": "RecommendationBasis", - "default": "" + "line": 417 }, { "name": "reasons", "type": "list[str]", - "default": "Field(min_length=1)" + "line": 418 }, { "name": "operator_action", "type": "str", - "default": "Field(min_length=1)" + "line": 419 } ], - "line": 410, - "doc": "Advisory next step for one module. Never installation or health evidence." + "line": 410 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/platform/modules.py", - "sha256": "7d3af6bcdc8cc3af90c6c663f5e0ea4571cfe607b0c3ee76a3ce0f966cb8a0c3", + "source": "townlight_core/platform/modules.py", + "sha256": "7857122ac3cc026595b8f326a8b232fd8c23b9735b49df7c776f1a34f2b0ac15", + "bytes": 15072, "routes": [], "models": [ { @@ -4011,21 +3968,20 @@ { "name": "module_id", "type": "str", - "default": "Field(pattern=MODULE_ID_PATTERN)" + "line": 51 }, { "name": "min_version", "type": "str | None", - "default": "Field(default=None, min_length=1)" + "line": 52 }, { "name": "required", "type": "bool", - "default": "True" + "line": 53 } ], - "line": 46, - "doc": "Another Townlight module required by a manifest." + "line": 46 }, { "name": "ModulePermission", @@ -4036,31 +3992,30 @@ { "name": "key", "type": "str", - "default": "Field(pattern=SLUG_PATTERN)" + "line": 61 }, { "name": "label", "type": "str", - "default": "Field(min_length=1)" + "line": 62 }, { "name": "description", "type": "str", - "default": "Field(min_length=1)" + "line": 63 }, { "name": "surface", "type": "ModuleSurface", - "default": "'staff'" + "line": 64 }, { "name": "roles", "type": "list[str]", - "default": "Field(default_factory=list)" + "line": 65 } ], - "line": 56, - "doc": "Permission surfaced to the shell and module manager." + "line": 56 }, { "name": "ModuleRoute", @@ -4071,31 +4026,30 @@ { "name": "id", "type": "str", - "default": "Field(pattern=SLUG_PATTERN)" + "line": 80 }, { "name": "path", "type": "str", - "default": "Field(pattern='^/[a-z0-9/_:-]*$')" + "line": 81 }, { "name": "label", "type": "str", - "default": "Field(min_length=1)" + "line": 82 }, { "name": "surface", "type": "ModuleSurface", - "default": "'staff'" + "line": 83 }, { "name": "permission", "type": "str | None", - "default": "Field(default=None, pattern=SLUG_PATTERN)" + "line": 84 } ], - "line": 75, - "doc": "A route the desktop shell may expose for a module." + "line": 75 }, { "name": "ModuleService", @@ -4106,36 +4060,35 @@ { "name": "id", "type": "str", - "default": "Field(pattern=SLUG_PATTERN)" + "line": 92 }, { "name": "service_type", "type": "ServiceType", - "default": "" + "line": 93 }, { "name": "description", "type": "str", - "default": "Field(min_length=1)" + "line": 94 }, { "name": "required", "type": "bool", - "default": "True" + "line": 95 }, { "name": "start_order", "type": "int", - "default": "Field(default=100, ge=0)" + "line": 96 }, { "name": "health_check_id", "type": "str | None", - "default": "Field(default=None, pattern=SLUG_PATTERN)" + "line": 97 } ], - "line": 87, - "doc": "A local service, schema, or command needed by a module." + "line": 87 }, { "name": "ModuleMigration", @@ -4146,26 +4099,25 @@ { "name": "id", "type": "str", - "default": "Field(pattern=SLUG_PATTERN)" + "line": 105 }, { "name": "description", "type": "str", - "default": "Field(min_length=1)" + "line": 106 }, { "name": "owner_schema", "type": "str | None", - "default": "Field(default=None, min_length=1)" + "line": 107 }, { "name": "required", "type": "bool", - "default": "True" + "line": 108 } ], - "line": 100, - "doc": "A migration contract that the installer/runtime must apply or verify." + "line": 100 }, { "name": "ModuleHealthCheck", @@ -4176,36 +4128,35 @@ { "name": "id", "type": "str", - "default": "Field(pattern=SLUG_PATTERN)" + "line": 116 }, { "name": "label", "type": "str", - "default": "Field(min_length=1)" + "line": 117 }, { "name": "description", "type": "str", - "default": "Field(min_length=1)" + "line": 118 }, { "name": "blocking", "type": "bool", - "default": "True" + "line": 119 }, { "name": "surface", "type": "Literal['staff', 'admin', 'system']", - "default": "'admin'" + "line": 120 }, { "name": "repair_action", "type": "str | None", - "default": "Field(default=None, min_length=1)" + "line": 121 } ], - "line": 111, - "doc": "A module health check known to the umbrella health center." + "line": 111 }, { "name": "ModuleBackupHook", @@ -4216,26 +4167,25 @@ { "name": "id", "type": "str", - "default": "Field(pattern=SLUG_PATTERN)" + "line": 129 }, { "name": "label", "type": "str", - "default": "Field(min_length=1)" + "line": 130 }, { "name": "includes", "type": "list[str]", - "default": "Field(min_length=1)" + "line": 131 }, { "name": "restore_supported", "type": "bool", - "default": "True" + "line": 132 } ], - "line": 124, - "doc": "A backup/restore hook the module contributes to the shared backup plan." + "line": 124 }, { "name": "ModuleModelRequirement", @@ -4246,51 +4196,50 @@ { "name": "id", "type": "str", - "default": "Field(pattern=SLUG_PATTERN)" + "line": 140 }, { "name": "provider", "type": "Literal['ollama', 'local', 'none', 'openai', 'anthropic']", - "default": "'ollama'" + "line": 141 }, { "name": "model_name", "type": "str", - "default": "Field(min_length=1)" + "line": 142 }, { "name": "required", "type": "bool", - "default": "True" + "line": 143 }, { "name": "local_only", "type": "bool", - "default": "True" + "line": 144 }, { "name": "minimum_context_tokens", "type": "int | None", - "default": "Field(default=None, ge=1)" + "line": 145 }, { "name": "checksum_sha256", "type": "str | None", - "default": "Field(default=None, pattern='^[a-fA-F0-9]{64}$')" + "line": 146 }, { "name": "download_url", "type": "str | None", - "default": "Field(default=None, min_length=1)" + "line": 147 }, { "name": "license_name", "type": "str | None", - "default": "Field(default=None, min_length=1)" + "line": 148 } ], - "line": 135, - "doc": "A model requirement declared by a module." + "line": 135 }, { "name": "ModuleRuntimeRequirement", @@ -4301,31 +4250,30 @@ { "name": "kind", "type": "RuntimeRequirementKind", - "default": "" + "line": 156 }, { "name": "name", "type": "str", - "default": "Field(min_length=1)" + "line": 157 }, { "name": "description", "type": "str", - "default": "Field(min_length=1)" + "line": 158 }, { "name": "required", "type": "bool", - "default": "True" + "line": 159 }, { "name": "operator_visible", "type": "bool", - "default": "False" + "line": 160 } ], - "line": 151, - "doc": "Runtime capability needed by a module." + "line": 151 }, { "name": "ModuleManifest", @@ -4336,101 +4284,100 @@ { "name": "module_id", "type": "str", - "default": "Field(pattern=MODULE_ID_PATTERN)" + "line": 168 }, { "name": "name", "type": "str", - "default": "Field(min_length=1)" + "line": 169 }, { "name": "version", "type": "str", - "default": "Field(min_length=1)" + "line": 170 }, { "name": "package_name", "type": "str", - "default": "Field(min_length=1)" + "line": 171 }, { "name": "townlight_core_min_version", "type": "str", - "default": "Field(min_length=1)" + "line": 172 }, { "name": "enabled_by_default", "type": "bool", - "default": "True" + "line": 173 }, { "name": "surfaces", "type": "list[ModuleSurface]", - "default": "Field(default_factory=lambda: ['staff'])" + "line": 174 }, { "name": "install_profiles", "type": "list[InstallProfile]", - "default": "Field(default_factory=lambda: ['windows_local'])" + "line": 175 }, { "name": "dependencies", "type": "list[ModuleDependency]", - "default": "Field(default_factory=list)" + "line": 176 }, { "name": "routes", "type": "list[ModuleRoute]", - "default": "Field(default_factory=list)" + "line": 177 }, { "name": "permissions", "type": "list[ModulePermission]", - "default": "Field(default_factory=list)" + "line": 178 }, { "name": "services", "type": "list[ModuleService]", - "default": "Field(default_factory=list)" + "line": 179 }, { "name": "migrations", "type": "list[ModuleMigration]", - "default": "Field(default_factory=list)" + "line": 180 }, { "name": "health_checks", "type": "list[ModuleHealthCheck]", - "default": "Field(default_factory=list)" + "line": 181 }, { "name": "backup_hooks", "type": "list[ModuleBackupHook]", - "default": "Field(default_factory=list)" + "line": 182 }, { "name": "model_requirements", "type": "list[ModuleModelRequirement]", - "default": "Field(default_factory=list)" + "line": 183 }, { "name": "runtime_requirements", "type": "list[ModuleRuntimeRequirement]", - "default": "Field(default_factory=list)" + "line": 184 }, { "name": "settings_schema_version", "type": "str | None", - "default": "Field(default=None, min_length=1)" + "line": 185 }, { "name": "metadata", "type": "dict[str, Any]", - "default": "Field(default_factory=dict)" + "line": 186 } ], - "line": 163, - "doc": "Complete manifest for a Townlight module package." + "line": 163 }, { "name": "ModuleRegistryEntry", @@ -4441,46 +4388,45 @@ { "name": "module_id", "type": "str", - "default": "Field(pattern=MODULE_ID_PATTERN)" + "line": 235 }, { "name": "name", "type": "str", - "default": "Field(min_length=1)" + "line": 236 }, { "name": "version", "type": "str", - "default": "Field(min_length=1)" + "line": 237 }, { "name": "enabled", "type": "bool", - "default": "" + "line": 238 }, { "name": "locked", "type": "bool", - "default": "False" + "line": 239 }, { "name": "status", "type": "ModuleRegistryStatus", - "default": "" + "line": 240 }, { "name": "reason", "type": "str | None", - "default": "None" + "line": 241 }, { "name": "manifest", "type": "ModuleManifest", - "default": "" + "line": 242 } ], - "line": 230, - "doc": "One module's resolved state in a runtime profile." + "line": 230 }, { "name": "ModuleRegistryState", @@ -4491,33 +4437,33 @@ { "name": "profile", "type": "InstallProfile", - "default": "'windows_local'" + "line": 250 }, { "name": "townlight_core_version", "type": "str", - "default": "Field(min_length=1)" + "line": 251 }, { "name": "townlight_core_locked", "type": "bool", - "default": "True" + "line": 252 }, { "name": "entries", "type": "list[ModuleRegistryEntry]", - "default": "" + "line": 253 } ], - "line": 245, - "doc": "Resolved module registry for the desktop shell and installer." + "line": 245 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/platform/runtime.py", - "sha256": "8c9ba7958b8fa08e7b0378a78d3693d8a586714555e5de9420a10626283f579a", + "source": "townlight_core/platform/runtime.py", + "sha256": "5328e622bd17db907c66fb424fc8a5d924be0704fc99eff3a8f0dc42f855061e", + "bytes": 1989, "routes": [], "models": [ { @@ -4529,46 +4475,45 @@ { "name": "action", "type": "RuntimeAction", - "default": "" + "line": 33 }, { "name": "status", "type": "RuntimeActionStatus", - "default": "" + "line": 34 }, { "name": "title", "type": "str", - "default": "Field(min_length=1)" + "line": 35 }, { "name": "message", "type": "str", - "default": "Field(min_length=1)" + "line": 36 }, { "name": "next_action", "type": "str | None", - "default": "Field(default=None, min_length=1)" + "line": 37 }, { "name": "evidence", "type": "dict[str, str | int | bool | None]", - "default": "Field(default_factory=dict)" + "line": 38 }, { "name": "started_at", "type": "datetime", - "default": "Field(default_factory=lambda: datetime.now(UTC))" + "line": 39 }, { "name": "completed_at", "type": "datetime | None", - "default": "None" + "line": 40 } ], - "line": 28, - "doc": "Plain-English result returned by installer/runtime APIs." + "line": 28 }, { "name": "LocalRuntimeProfile", @@ -4579,53 +4524,53 @@ { "name": "profile_id", "type": "str", - "default": "Field(min_length=1)" + "line": 48 }, { "name": "city_name", "type": "str", - "default": "Field(min_length=1)" + "line": 49 }, { "name": "data_root", "type": "Path", - "default": "" + "line": 50 }, { "name": "backup_root", "type": "Path", - "default": "" + "line": 51 }, { "name": "module_registry", "type": "ModuleRegistryState", - "default": "" + "line": 52 }, { "name": "model_provider", "type": "str", - "default": "'ollama'" + "line": 53 }, { "name": "local_only", "type": "bool", - "default": "True" + "line": 54 }, { "name": "network_allowed_for", "type": "list[str]", - "default": "Field(default_factory=list)" + "line": 55 } ], - "line": 43, - "doc": "Resolved local runtime profile for one installed city." + "line": 43 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/platform/task_queue.py", - "sha256": "438c2e7364ef0232b62a4ea379b22a679c248c8c1ab9c0b3149fd87ec8e5fb46", + "source": "townlight_core/platform/task_queue.py", + "sha256": "7d5108826b83b154d96412c12e3e52ac70c32412208923e8fef00ef3de8864d6", + "bytes": 12258, "routes": [], "models": [ { @@ -4637,83 +4582,83 @@ { "name": "task_id", "type": "Mapped[str]", - "default": "mapped_column(String(128), primary_key=True)" + "line": 32 }, { "name": "module_id", "type": "Mapped[str]", - "default": "mapped_column(String(64), index=True)" + "line": 33 }, { "name": "task_type", "type": "Mapped[str]", - "default": "mapped_column(String(100), index=True)" + "line": 34 }, { "name": "status", "type": "Mapped[str]", - "default": "mapped_column(String(20), index=True, default='queued')" + "line": 35 }, { "name": "payload", "type": "Mapped[dict[str, Any]]", - "default": "mapped_column(JSONB, default=dict)" + "line": 36 }, { "name": "attempt_count", "type": "Mapped[int]", - "default": "mapped_column(Integer, default=0)" + "line": 37 }, { "name": "queued_at", "type": "Mapped[datetime]", - "default": "mapped_column(DateTime(timezone=True))" + "line": 38 }, { "name": "available_at", "type": "Mapped[datetime | None]", - "default": "mapped_column(DateTime(timezone=True), nullable=True)" + "line": 39 }, { "name": "last_error", "type": "Mapped[str | None]", - "default": "mapped_column(Text, nullable=True)" + "line": 40 }, { "name": "idempotency_key", "type": "Mapped[str | None]", - "default": "mapped_column(String(255), nullable=True, unique=True)" + "line": 41 }, { "name": "audit_subject_id", "type": "Mapped[str | None]", - "default": "mapped_column(String(255), nullable=True)" + "line": 42 }, { "name": "claim_token", "type": "Mapped[str | None]", - "default": "mapped_column(String(64), nullable=True)" + "line": 43 }, { "name": "lease_expires_at", "type": "Mapped[datetime | None]", - "default": "mapped_column(DateTime(timezone=True), nullable=True)" + "line": 44 }, { "name": "cancelled_by", "type": "Mapped[str | None]", - "default": "mapped_column(String(128), nullable=True)" + "line": 47 } ], - "line": 27, - "doc": "Durable local task row used by the Windows local runtime." + "line": 27 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/platform/tasks.py", - "sha256": "cbf2bf5323fb37c5ff58038d77597464b16c6637b205dcf00a03ad274d120847", + "source": "townlight_core/platform/tasks.py", + "sha256": "29f5509deecd7e196d9c43a964e34641c53bd4fa502491e680620a83f9b9622c", + "bytes": 5754, "routes": [], "models": [ { @@ -4725,21 +4670,20 @@ { "name": "max_attempts", "type": "int", - "default": "Field(default=3, ge=1)" + "line": 19 }, { "name": "base_delay_seconds", "type": "int", - "default": "Field(default=30, ge=0)" + "line": 20 }, { "name": "max_delay_seconds", "type": "int", - "default": "Field(default=3600, ge=0)" + "line": 21 } ], - "line": 14, - "doc": "Retry settings for local durable task queues." + "line": 14 }, { "name": "LocalTaskEnvelope", @@ -4750,71 +4694,70 @@ { "name": "task_id", "type": "str", - "default": "Field(min_length=1)" + "line": 29 }, { "name": "module_id", "type": "str", - "default": "Field(pattern='^[a-z][a-z0-9-]{1,63}$')" + "line": 30 }, { "name": "task_type", "type": "str", - "default": "Field(min_length=1)" + "line": 31 }, { "name": "status", "type": "TaskStatus", - "default": "'queued'" + "line": 32 }, { "name": "payload", "type": "dict[str, Any]", - "default": "Field(default_factory=dict)" + "line": 33 }, { "name": "attempt_count", "type": "int", - "default": "Field(default=0, ge=0)" + "line": 34 }, { "name": "queued_at", "type": "datetime", - "default": "Field(default_factory=lambda: datetime.now(UTC))" + "line": 35 }, { "name": "available_at", "type": "datetime | None", - "default": "None" + "line": 36 }, { "name": "last_error", "type": "str | None", - "default": "Field(default=None, min_length=1)" + "line": 37 }, { "name": "idempotency_key", "type": "str | None", - "default": "Field(default=None, min_length=1)" + "line": 38 }, { "name": "audit_subject_id", "type": "str | None", - "default": "Field(default=None, min_length=1)" + "line": 39 }, { "name": "claim_token", "type": "str | None", - "default": "None" + "line": 40 }, { "name": "lease_expires_at", "type": "datetime | None", - "default": "None" + "line": 41 } ], - "line": 24, - "doc": "Storage-neutral task record for module-owned persistence." + "line": 24 }, { "name": "LocalTaskResult", @@ -4825,21 +4768,20 @@ { "name": "task", "type": "LocalTaskEnvelope", - "default": "" + "line": 57 }, { "name": "message", "type": "str", - "default": "" + "line": 58 }, { "name": "retry_at", "type": "datetime | None", - "default": "None" + "line": 59 } ], - "line": 52, - "doc": "Result returned after recording a local task attempt." + "line": 52 }, { "name": "TaskQueueSummary", @@ -4850,40 +4792,41 @@ { "name": "total", "type": "int", - "default": "" + "line": 67 }, { "name": "counts", "type": "dict[str, int]", - "default": "" + "line": 68 }, { "name": "blocked", "type": "bool", - "default": "" + "line": 69 }, { "name": "message", "type": "str", - "default": "" + "line": 70 } ], - "line": 62, - "doc": "Counts and operator copy for a module task queue." + "line": 62 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/provenance/__init__.py", - "sha256": "0f703072d5ba898b13a2683285eb8d57e66815356391103f27d63237467d0ab8", + "source": "townlight_core/provenance/__init__.py", + "sha256": "a54d29222c9fc54bd9dc6dfd237a73003a31bd6508fbb315eff200d316685607", + "bytes": 385, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/provenance/contracts.py", - "sha256": "56dfe26f57056ae1ea85fb8eb808a5259700609483d8e14e67625e123040d57c", + "source": "townlight_core/provenance/contracts.py", + "sha256": "cb75de8d4de91b9b2ab0e1c94f6cd6fd04ca8266b56c24c4603507fb9e7c73fc", + "bytes": 3912, "routes": [], "models": [ { @@ -4895,41 +4838,40 @@ { "name": "label", "type": "str | None", - "default": "None" + "line": 46 }, { "name": "page", "type": "int | None", - "default": "Field(default=None, ge=1)" + "line": 47 }, { "name": "section", "type": "str | None", - "default": "None" + "line": 48 }, { "name": "line_start", "type": "int | None", - "default": "Field(default=None, ge=1)" + "line": 49 }, { "name": "line_end", "type": "int | None", - "default": "Field(default=None, ge=1)" + "line": 50 }, { "name": "parcel_id", "type": "str | None", - "default": "None" + "line": 51 }, { "name": "anchor", "type": "str | None", - "default": "None" + "line": 52 } ], - "line": 41, - "doc": "Locator that lets an export cite a precise place in a source." + "line": 41 }, { "name": "SourceReference", @@ -4940,61 +4882,60 @@ { "name": "source_id", "type": "str", - "default": "" + "line": 60 }, { "name": "kind", "type": "SourceKind", - "default": "" + "line": 61 }, { "name": "title", "type": "str", - "default": "" + "line": 62 }, { "name": "source_system", "type": "str | None", - "default": "None" + "line": 63 }, { "name": "source_path", "type": "str | None", - "default": "None" + "line": 64 }, { "name": "source_url", "type": "str | None", - "default": "None" + "line": 65 }, { "name": "captured_at", "type": "datetime", - "default": "Field(default_factory=_utc_now)" + "line": 66 }, { "name": "checksum", "type": "str | None", - "default": "None" + "line": 67 }, { "name": "retention_hint", "type": "str | None", - "default": "None" + "line": 68 }, { "name": "sensitivity_label", "type": "str | None", - "default": "None" + "line": 69 }, { "name": "citation_locator", "type": "CitationTarget | None", - "default": "Field(default=None, validation_alias=AliasChoices('citation_locator', 'citation'))" + "line": 70 } ], - "line": 55, - "doc": "Metadata for an original source used by Townlight Core." + "line": 55 }, { "name": "DocumentMetadata", @@ -5005,51 +4946,50 @@ { "name": "document_id", "type": "str", - "default": "" + "line": 86 }, { "name": "title", "type": "str", - "default": "" + "line": 87 }, { "name": "source", "type": "SourceReference", - "default": "" + "line": 88 }, { "name": "document_type", "type": "str | None", - "default": "None" + "line": 89 }, { "name": "created_at", "type": "datetime | None", - "default": "None" + "line": 90 }, { "name": "captured_at", "type": "datetime", - "default": "Field(default_factory=_utc_now)" + "line": 91 }, { "name": "checksum", "type": "str | None", - "default": "None" + "line": 92 }, { "name": "retention_hint", "type": "str | None", - "default": "None" + "line": 93 }, { "name": "sensitivity_label", "type": "str | None", - "default": "None" + "line": 94 } ], - "line": 81, - "doc": "Document-level descriptive metadata for export manifests." + "line": 81 }, { "name": "ProvenanceBundle", @@ -5060,72 +5000,74 @@ { "name": "bundle_id", "type": "str", - "default": "" + "line": 109 }, { "name": "generated_at", "type": "datetime", - "default": "Field(default_factory=_utc_now)" + "line": 110 }, { "name": "sources", "type": "list[SourceReference]", - "default": "Field(default_factory=list)" + "line": 111 }, { "name": "documents", "type": "list[DocumentMetadata]", - "default": "Field(default_factory=list)" + "line": 112 } ], - "line": 104, - "doc": "Serializable manifest of sources and documents behind an export." + "line": 104 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/release_provenance.py", - "sha256": "52df52fe6354b741a0cfb759156601fc6682aa34caed7cead9e624ac70e1faf7", + "source": "townlight_core/release_provenance.py", + "sha256": "5b73394b358fed482549e0f544988d85f8acd5b6510609332d3b61fca34cfa28", + "bytes": 22694, "routes": [], "models": [], "configuration": [ { - "variable": "GH_TOKEN", - "default": "", + "environment": "GH_TOKEN", "line": 62 }, { - "variable": "GITHUB_TOKEN", - "default": "", + "environment": "GITHUB_TOKEN", "line": 62 } ] }, { - "source": "installed-owned-source/townlight_core/scaffold/__init__.py", - "sha256": "313ad60b0afe49ab6d7632c99d96a13deec90466a74e1d4d375a6c663e4a2266", + "source": "townlight_core/scaffold/__init__.py", + "sha256": "a7cfa7320296bee9a99761fb5c5735ce578914e451b6b54b249ebfb8734f52f1", + "bytes": 1592, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/scaffold/__main__.py", - "sha256": "926a8bb2eede99ffb44ac34a5ff57950df4de748280d37edb38a8cf1c8441819", + "source": "townlight_core/scaffold/__main__.py", + "sha256": "5735e7445cf005e809f9cdfca7485796481f20b40d6ac62978df53cac985a09b", + "bytes": 332, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/scaffold/cli.py", - "sha256": "a2228cce93986f97ae26cbdc5ce402ea31c5e83685b6b2cf31c1e52a4ee669d5", + "source": "townlight_core/scaffold/cli.py", + "sha256": "0e45c64c04a1a86871d41f7acc2c5c62357e1db8248120afc877c46a5fd9d7eb", + "bytes": 5592, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/scaffold/project.py", - "sha256": "343d74719e25beec71fdc0b855f4e1a38db1e338e3a4b62ef1c7b3951e070587", + "source": "townlight_core/scaffold/project.py", + "sha256": "ec9ec04b46d6d26f1764e487d52fcb01fc66ea8b05553c771a289b8c183c8b41", + "bytes": 23120, "routes": [], "models": [ { @@ -5135,21 +5077,20 @@ { "name": "relative_path", "type": "str", - "default": "" + "line": 36 }, { "name": "content", "type": "str", - "default": "" + "line": 37 }, { "name": "executable", "type": "bool", - "default": "False" + "line": 38 } ], - "line": 33, - "doc": "One file the generator will create, relative to the project root." + "line": 33 }, { "name": "ProjectPlan", @@ -5158,21 +5099,20 @@ { "name": "spec", "type": "ModuleSpec", - "default": "" + "line": 47 }, { "name": "project_root_name", "type": "str", - "default": "" + "line": 48 }, { "name": "files", "type": "tuple[PlannedFile, ...]", - "default": "field(default_factory=tuple)" + "line": 49 } ], - "line": 46, - "doc": "" + "line": 46 }, { "name": "GenerationResult", @@ -5181,33 +5121,33 @@ { "name": "spec", "type": "ModuleSpec", - "default": "" + "line": 58 }, { "name": "project_root", "type": "Path", - "default": "" + "line": 59 }, { "name": "created", "type": "tuple[str, ...]", - "default": "" + "line": 60 }, { "name": "dry_run", "type": "bool", - "default": "" + "line": 61 } ], - "line": 57, - "doc": "" + "line": 57 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/scaffold/spec.py", - "sha256": "603e6d89700bf64b4ffc285c06446b9cf9f66b318613de01ca8b5ef94cc134d2", + "source": "townlight_core/scaffold/spec.py", + "sha256": "7f7f2e4b1bed9e331b002ef9c560a25cc4f4d2e81922204455fecb9f490831e8", + "bytes": 5927, "routes": [], "models": [ { @@ -5219,46 +5159,45 @@ { "name": "module_id", "type": "str", - "default": "Field(pattern=MODULE_ID_PATTERN)" + "line": 75 }, { "name": "name", "type": "str", - "default": "Field(min_length=1, max_length=120)" + "line": 76 }, { "name": "description", "type": "str", - "default": "Field(min_length=12, max_length=500)" + "line": 77 }, { "name": "version", "type": "str", - "default": "'0.1.0'" + "line": 78 }, { "name": "townlight_core_min_version", "type": "str", - "default": "'1.3.0.dev1'" + "line": 79 }, { "name": "permission_key", "type": "str | None", - "default": "Field(default=None, pattern=SLUG_PATTERN)" + "line": 80 }, { "name": "staff_roles", "type": "tuple[str, ...]", - "default": "('staff',)" + "line": 81 }, { "name": "route_path", "type": "str | None", - "default": "Field(default=None, pattern=ROUTE_PATH_PATTERN)" + "line": 82 } ], - "line": 65, - "doc": "Everything the generator needs, already validated.\n\n``module_id`` is the only identity; ``package_name``, import path, env-var\nprefix and migration revision ids are derived from it so a caller cannot\ncreate an inconsistent project." + "line": 65 }, { "name": "ScaffoldOptions", @@ -5267,74 +5206,82 @@ { "name": "dry_run", "type": "bool", - "default": "False" + "line": 168 } ], - "line": 165, - "doc": "Non-identity options, kept out of the persisted manifest." + "line": 165 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/scheduling/__init__.py", - "sha256": "f887d66fc8bf298e094c46bae19fa42b67e5d26911522913d8c5a546d606b4cc", + "source": "townlight_core/scheduling/__init__.py", + "sha256": "2bde5b7b97b7e42e6828d6f898908c43fa81f0e138c12fe98e389839a1b81f84", + "bytes": 340, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/scheduling/cron.py", - "sha256": "a7c5688dc5a3e5c410466cc92a7d884a88a50fe92974d0a7642b0fbe954f0b08", + "source": "townlight_core/scheduling/cron.py", + "sha256": "6e385d99111b7809af36ce9846902068545757f66425e72e924e1088b53277cc", + "bytes": 2668, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/search/__init__.py", - "sha256": "2450f3768c47b0e2869ca1056b188d41b9ba58f88a0865cad5ad854f03801908", + "source": "townlight_core/search/__init__.py", + "sha256": "13d8bec659e5056118385219d8741e0e25d77ef57409de94eedbadf4b1fc7dc2", + "bytes": 4610, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/security/__init__.py", - "sha256": "376e78b0875c2fd3074935b586cef2b806c371f140085ffc40eeb6aed09b9211", + "source": "townlight_core/security/__init__.py", + "sha256": "c89bf972b45da10e18076bb17fa8b9cf8ae0b9bf76475f90e136baa8d832bb42", + "bytes": 1715, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/security/at_rest.py", - "sha256": "eb339fa93cff4af29df7f01b3f5552fff56c6bdc676fef6cb9aad8356a610d3e", + "source": "townlight_core/security/at_rest.py", + "sha256": "87bb3aef0e3fbba957364037e1c4fd96f972fc758b30e0684c6c9915ed2089e0", + "bytes": 2966, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/security/config_validation.py", - "sha256": "e4064bf0394ffc7cdc0aafccfc689a2a17667cfd31d8455dc6f8a623d963af45", + "source": "townlight_core/security/config_validation.py", + "sha256": "7043de1ab5799079e7521603510206945c91a0ddb3fdd16464b3e4190010d110", + "bytes": 5008, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/security/host_validation.py", - "sha256": "3e62ec5540713eea903409c88c4e2255b0dd8d54a9d5d23fc69ad15e03c15045", + "source": "townlight_core/security/host_validation.py", + "sha256": "dc3ee223e1875baabed6202ecf673f91b837c7b5ec51f751efe594d76ad0addb", + "bytes": 5292, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/tasks/__init__.py", - "sha256": "2b30985e76210900397d5e65b5060786e8fec6478d8762690e8971a37c49d5f1", + "source": "townlight_core/tasks/__init__.py", + "sha256": "fa149df79666a714bc9fa46bbd275f89b5eeca1b6244d4e0415989ce3c38d85a", + "bytes": 873, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/tasks/artifacts.py", - "sha256": "fbb9db7c76ce4b3bd91b3412ba2cfdcc52d3c67959ef117a0a765ee9dc3d972f", + "source": "townlight_core/tasks/artifacts.py", + "sha256": "4827aa4c8778f0612e5deba771be06bdb404ea19149166ff8ab2f7c7c56c229d", + "bytes": 16399, "routes": [], "models": [ { @@ -5346,81 +5293,80 @@ { "name": "artifact_id", "type": "Mapped[str]", - "default": "mapped_column(String(64), primary_key=True)" + "line": 101 }, { "name": "task_id", "type": "Mapped[str]", - "default": "mapped_column(String(128), index=True)" + "line": 102 }, { "name": "module_id", "type": "Mapped[str]", - "default": "mapped_column(String(64))" + "line": 103 }, { "name": "task_type", "type": "Mapped[str]", - "default": "mapped_column(String(100))" + "line": 104 }, { "name": "claim_token", "type": "Mapped[str]", - "default": "mapped_column(String(64))" + "line": 105 }, { "name": "attempt_count", "type": "Mapped[int]", - "default": "mapped_column(Integer, default=0)" + "line": 106 }, { "name": "artifact_name", "type": "Mapped[str]", - "default": "mapped_column(String(200))" + "line": 107 }, { "name": "relative_path", "type": "Mapped[str]", - "default": "mapped_column(String(400))" + "line": 108 }, { "name": "artifact_sha256", "type": "Mapped[str]", - "default": "mapped_column(String(64))" + "line": 109 }, { "name": "artifact_bytes", "type": "Mapped[int]", - "default": "mapped_column(BigInteger, default=0)" + "line": 110 }, { "name": "artifact_kind", "type": "Mapped[str]", - "default": "mapped_column(String(40))" + "line": 111 }, { "name": "source_sha256", "type": "Mapped[str]", - "default": "mapped_column(String(64))" + "line": 112 }, { "name": "source_label", "type": "Mapped[str]", - "default": "mapped_column(String(200))" + "line": 113 }, { "name": "recorded_by", "type": "Mapped[str]", - "default": "mapped_column(String(128))" + "line": 114 }, { "name": "recorded_at", "type": "Mapped[datetime]", - "default": "mapped_column(DateTime(timezone=True))" + "line": 115 } ], - "line": 96, - "doc": "Append-only acceptance record for one artifact produced by one claimed job." + "line": 96 }, { "name": "ArtifactStore", @@ -5429,11 +5375,10 @@ { "name": "root", "type": "Path", - "default": "" + "line": 122 } ], - "line": 119, - "doc": "A configured artifact root. Every published path must resolve inside it." + "line": 119 }, { "name": "SourceBinding", @@ -5442,16 +5387,15 @@ { "name": "sha256", "type": "str", - "default": "" + "line": 144 }, { "name": "label", "type": "str", - "default": "" + "line": 145 } ], - "line": 141, - "doc": "The synthetic or real source a derivative was computed from." + "line": 141 }, { "name": "ArtifactProposal", @@ -5460,26 +5404,25 @@ { "name": "name", "type": "str", - "default": "" + "line": 152 }, { "name": "kind", "type": "str", - "default": "" + "line": 153 }, { "name": "content", "type": "bytes", - "default": "" + "line": 154 }, { "name": "source", "type": "SourceBinding", - "default": "" + "line": 155 } ], - "line": 149, - "doc": "Caller-supplied intent. The hash is recomputed and never taken from here." + "line": 149 }, { "name": "PreparedArtifact", @@ -5488,87 +5431,89 @@ { "name": "store", "type": "ArtifactStore", - "default": "" + "line": 162 }, { "name": "staging_path", "type": "Path", - "default": "" + "line": 163 }, { "name": "name", "type": "str", - "default": "" + "line": 164 }, { "name": "kind", "type": "str", - "default": "" + "line": 165 }, { "name": "sha256", "type": "str", - "default": "" + "line": 166 }, { "name": "size", "type": "int", - "default": "" + "line": 167 }, { "name": "source", "type": "SourceBinding", - "default": "" + "line": 168 } ], - "line": 159, - "doc": "A staged, hash-verified file that is not yet published or recorded." + "line": 159 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/tasks/leased.py", - "sha256": "eef2a9e339274c1caccde7cb3295a9d5bd88da6561090cbfc0a6bf10c8d29e1d", + "source": "townlight_core/tasks/leased.py", + "sha256": "1a2d44107db916e54fe2bf05d6909d356603393d9686b4e28ba763702c3671a0", + "bytes": 3267, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/tasks/registry.py", - "sha256": "96bf04036bdc4be3b9097d7bc85f447105fd5d82e8ef548cd3d88354f7b3fce8", + "source": "townlight_core/tasks/registry.py", + "sha256": "71ce9c95a7f30cd97f045ddbeb6a7d36472b82a50c0ba07782b6ec9b465264c8", + "bytes": 776, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/tasks/worker.py", - "sha256": "106d83f412c66d939e5d9a55276b51020c078ee89763135dc53f7c02ae20f76f", + "source": "townlight_core/tasks/worker.py", + "sha256": "2f4bf95de44b0f1f90f21a0b773748bc8f80838498d5f25c05d63ce9d34df841", + "bytes": 3095, "routes": [], "models": [], "configuration": [ { - "variable": "DATABASE_URL", - "default": "", + "environment": "DATABASE_URL", "line": 34 }, { - "variable": "TOWNLIGHT_CORE_TASK_HANDLER_MODULES", - "default": "", + "environment": "TOWNLIGHT_CORE_TASK_HANDLER_MODULES", "line": 37 } ] }, { - "source": "installed-owned-source/townlight_core/testing/__init__.py", - "sha256": "359cfd4ae5b7324db08f496a0ee5043456f1ce60a4ae34fa75761a8790b88d50", + "source": "townlight_core/testing/__init__.py", + "sha256": "6033e371f9adb5bb4107ec14c541768a7b6acfab5d9d1b184fd490461c9b87df", + "bytes": 2115, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/testing/mock_city.py", - "sha256": "c1bac5478d09e0958115da8d4f55f4d5211ec1531062e76829381f5a6c47e389", + "source": "townlight_core/testing/mock_city.py", + "sha256": "0268eb2457e22ab2c99f4a0b5c2f3dc34aef0102cf7d0f10019b1db9c2918961", + "bytes": 51471, "routes": [], "models": [ { @@ -5578,51 +5523,50 @@ { "name": "connector", "type": "str", - "default": "" + "line": 91 }, { "name": "vendor_name", "type": "str", - "default": "" + "line": 92 }, { "name": "interface_status", "type": "str", - "default": "" + "line": 93 }, { "name": "method", "type": "str", - "default": "" + "line": 94 }, { "name": "path", "type": "str", - "default": "" + "line": 95 }, { "name": "auth_method", "type": "str", - "default": "" + "line": 96 }, { "name": "delta_query_param", "type": "str", - "default": "" + "line": 97 }, { "name": "sample_payload", "type": "dict[str, Any]", - "default": "" + "line": 98 }, { "name": "notes", "type": "str", - "default": "" + "line": 99 } ], - "line": 90, - "doc": "" + "line": 90 }, { "name": "MockCityIdpContract", @@ -5631,81 +5575,80 @@ { "name": "provider", "type": "str", - "default": "" + "line": 117 }, { "name": "interface_status", "type": "str", - "default": "" + "line": 118 }, { "name": "issuer", "type": "str", - "default": "" + "line": 119 }, { "name": "audience", "type": "str", - "default": "" + "line": 120 }, { "name": "authorization_url", "type": "str", - "default": "" + "line": 121 }, { "name": "token_url", "type": "str", - "default": "" + "line": 122 }, { "name": "jwks_path", "type": "str", - "default": "" + "line": 123 }, { "name": "role_claims", "type": "tuple[str, ...]", - "default": "" + "line": 124 }, { "name": "algorithms", "type": "tuple[str, ...]", - "default": "" + "line": 125 }, { "name": "client_id", "type": "str", - "default": "" + "line": 126 }, { "name": "redirect_uri", "type": "str", - "default": "" + "line": 127 }, { "name": "staff_subject", "type": "str", - "default": "" + "line": 128 }, { "name": "staff_email", "type": "str", - "default": "" + "line": 129 }, { "name": "staff_roles", "type": "tuple[str, ...]", - "default": "" + "line": 130 }, { "name": "notes", "type": "str", - "default": "" + "line": 131 } ], - "line": 116, - "doc": "" + "line": 116 }, { "name": "MockCityBackupRetentionContract", @@ -5714,71 +5657,70 @@ { "name": "city", "type": "str", - "default": "" + "line": 155 }, { "name": "interface_status", "type": "str", - "default": "" + "line": 156 }, { "name": "backup_scope", "type": "tuple[str, ...]", - "default": "" + "line": 157 }, { "name": "restore_proof_required", "type": "bool", - "default": "" + "line": 158 }, { "name": "manifest_required_fields", "type": "tuple[str, ...]", - "default": "" + "line": 159 }, { "name": "retention_years", "type": "int", - "default": "" + "line": 160 }, { "name": "restore_test_interval_days", "type": "int", - "default": "" + "line": 161 }, { "name": "off_host_storage", "type": "str", - "default": "" + "line": 162 }, { "name": "encryption_at_rest_required", "type": "bool", - "default": "" + "line": 163 }, { "name": "immutable_retention_required", "type": "bool", - "default": "" + "line": 164 }, { "name": "legal_hold_supported", "type": "bool", - "default": "" + "line": 165 }, { "name": "approval_artifact", "type": "str", - "default": "" + "line": 166 }, { "name": "notes", "type": "str", - "default": "" + "line": 167 } ], - "line": 154, - "doc": "" + "line": 154 }, { "name": "MockCityContractCheck", @@ -5787,36 +5729,35 @@ { "name": "connector", "type": "str", - "default": "" + "line": 189 }, { "name": "ok", "type": "bool", - "default": "" + "line": 190 }, { "name": "message", "type": "str", - "default": "" + "line": 191 }, { "name": "fix", "type": "str", - "default": "" + "line": 192 }, { "name": "normalized_external_meeting_id", "type": "str | None", - "default": "None" + "line": 193 }, { "name": "delta_request_url", "type": "str | None", - "default": "None" + "line": 194 } ], - "line": 188, - "doc": "" + "line": 188 }, { "name": "MockCityIdpCheck", @@ -5825,41 +5766,40 @@ { "name": "provider", "type": "str", - "default": "" + "line": 209 }, { "name": "ok", "type": "bool", - "default": "" + "line": 210 }, { "name": "message", "type": "str", - "default": "" + "line": 211 }, { "name": "fix", "type": "str", - "default": "" + "line": 212 }, { "name": "auth_method", "type": "str | None", - "default": "None" + "line": 213 }, { "name": "subject", "type": "str | None", - "default": "None" + "line": 214 }, { "name": "roles", "type": "tuple[str, ...]", - "default": "()" + "line": 215 } ], - "line": 208, - "doc": "" + "line": 208 }, { "name": "MockCityBackupRetentionCheck", @@ -5868,31 +5808,30 @@ { "name": "city", "type": "str", - "default": "" + "line": 231 }, { "name": "ok", "type": "bool", - "default": "" + "line": 232 }, { "name": "message", "type": "str", - "default": "" + "line": 233 }, { "name": "fix", "type": "str", - "default": "" + "line": 234 }, { "name": "checked_fields", "type": "tuple[str, ...]", - "default": "()" + "line": 235 } ], - "line": 230, - "doc": "" + "line": 230 }, { "name": "DemoTownFixtureContract", @@ -5901,70 +5840,71 @@ { "name": "schema_version", "type": "str", - "default": "" + "line": 251 }, { "name": "fixture_id", "type": "str", - "default": "" + "line": 252 }, { "name": "fixture_version", "type": "str", - "default": "" + "line": 253 }, { "name": "deterministic_seed", "type": "str", - "default": "" + "line": 254 }, { "name": "generated_at", "type": "str", - "default": "" + "line": 255 }, { "name": "municipality", "type": "dict[str, Any]", - "default": "" + "line": 256 }, { "name": "sources", "type": "tuple[dict[str, Any], ...]", - "default": "" + "line": 257 }, { "name": "records", "type": "tuple[dict[str, Any], ...]", - "default": "" + "line": 258 }, { "name": "requests", "type": "tuple[dict[str, Any], ...]", - "default": "" + "line": 259 }, { "name": "expected", "type": "dict[str, Any]", - "default": "" + "line": 260 } ], - "line": 248, - "doc": "Versioned, deterministic and independently authored municipal demo data." + "line": 248 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/verification/__init__.py", - "sha256": "79e2b135ad90bfad95db77a54f7d2c65d96eb13bb8ad1ed0a35e3655dc03a0e7", + "source": "townlight_core/verification/__init__.py", + "sha256": "c70e114fe70b60ccc09ee541df728316be966ca7660be3275ce66086e737f233", + "bytes": 441, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_core/verification/browser_evidence.py", - "sha256": "493219d45f5c50d5c514a4ea9534ccfab35979d0c58a577a2e9afd01328c7fe1", + "source": "townlight_core/verification/browser_evidence.py", + "sha256": "1edca65a6a73ca5b42a3eddc9db530e5d78b2bd7eec54e867c4e2dfe061a3c0b", + "bytes": 3230, "routes": [], "models": [ { @@ -5974,345 +5914,141 @@ { "name": "version", "type": "str", - "default": "" + "line": 24 }, { "name": "reviewed_at", "type": "str", - "default": "" + "line": 25 }, { "name": "page", "type": "Path", - "default": "" + "line": 26 }, { "name": "screenshots", "type": "dict[str, Path]", - "default": "" + "line": 27 } ], - "line": 23, - "doc": "" + "line": 23 } ], "configuration": [] } - ], - "bridge": [ - { - "source": "installed-owned-source/townlight_runtime/services.py", - "sha256": "5dfb0f58ea1f94185081426a3734905c78624d7bcd5407fd2c4e0fa1fb054a6b", - "routes": [ - { - "method": "GET", - "path": "/health", - "router": "app", - "prefix_resolved": true, - "name": "runtime_health", - "signature": "", - "returns": "", - "line": 439, - "doc": "", - "decorator": "app.get('/health')", - "errors": [] - }, - { - "method": "GET", - "path": "/modules", - "router": "app", - "prefix_resolved": true, - "name": "runtime_health", - "signature": "", - "returns": "", - "line": 439, - "doc": "", - "decorator": "app.get('/modules')", - "errors": [] - }, - { - "method": "GET", - "path": "/ready", - "router": "app", - "prefix_resolved": true, - "name": "domain_ready", - "signature": "", - "returns": "", - "line": 444, - "doc": "", - "decorator": "app.get('/ready')", - "errors": [] - } - ], - "models": [], - "configuration": [ - { - "variable": "TOWNLIGHT_PROFILE_ROOT", - "default": "", - "line": 56 - }, - { - "variable": "TOWNLIGHT_DATA_DIR", - "default": "", - "line": 61 - }, - { - "variable": "LOCALAPPDATA", - "default": "", - "line": 64 - }, - { - "variable": "DATABASE_URL", - "default": "", - "line": 148 - }, - { - "variable": "TOWNLIGHT_RUNTIME_HOST", - "default": "DEFAULT_HOST", - "line": 479 - }, - { - "variable": "TESTING", - "default": "", - "line": 113 - }, - { - "variable": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", - "default": "''", - "line": 240 - }, - { - "variable": "DATABASE_URL", - "default": "", - "line": 300 - }, - { - "variable": "TOWNLIGHT_RUNTIME_PORT", - "default": "str(DEFAULT_PORT)", - "line": 482 - } - ] - } ] }, "records": { - "package": "app", + "repository": "townlight/sunshine", + "repository_head": "156ef1ba2d06c77eb1820fa7efdbcb94a2c92fa8", + "working_tree_modified": true, + "principal_import": "townlight_records", "source": [ { - "source": "installed-owned-source/app/__init__.py", - "sha256": "faef907da0d1b1e4b467dc711514a24f6112ff32809ee7e7e6065c684ab7f2b9", + "source": "backend/townlight_records/__init__.py", + "sha256": "ff95c656e3245c0b6c3400fb8c22ab8d06559682f96d4f456deabc81cf970cb3", + "bytes": 31, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/admin/__init__.py", - "sha256": "5724a9ba19246885896a1603eecc360d7cb5b5cc6c745f635553158f7c46431d", + "source": "backend/townlight_records/admin/__init__.py", + "sha256": "41dd8646dfff4f77df72dd38cfbb57cd88c037c7d45192dbc1fdfe537d35e6ca", + "bytes": 97, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/admin/router.py", - "sha256": "daea85a6114138f50a2a3da4bff8736c1140174599440b07cac35aee27694b7d", + "source": "backend/townlight_records/admin/router.py", + "sha256": "7c20b2df8ab59a3b35d77ff6734689873c5ba6d2f9a3c3a733a0ae9088147ace", + "bytes": 18069, "routes": [ { "method": "GET", - "path": "/admin/status", - "router": "router", - "prefix_resolved": true, - "name": "system_status", - "signature": "request: Request, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 53, - "doc": "", - "decorator": "router.get('/status', response_model=SystemStatus)", - "errors": [] + "declared_path": "/status", + "function": "system_status", + "line": 53 }, { "method": "GET", - "path": "/admin/users", - "router": "router", - "prefix_resolved": true, - "name": "list_users", - "signature": "session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 100, - "doc": "List all users. Admin only.", - "decorator": "router.get('/users', response_model=list[UserRead])", - "errors": [] + "declared_path": "/users", + "function": "list_users", + "line": 100 }, { "method": "POST", - "path": "/admin/users", - "router": "router", - "prefix_resolved": true, - "name": "create_user", - "signature": "body: AdminUserCreateRequest, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 127, - "doc": "Create a new user. Admin only.", - "decorator": "router.post('/users', response_model=AdminUserCreateResponse, status_code=201)", - "errors": [ - "_HTTPException(status_code=422, detail=f'Invalid role: {body.role}')", - "_HTTPException(status_code=400, detail=str(e))" - ] + "declared_path": "/users", + "function": "create_user", + "line": 127 }, { "method": "PATCH", - "path": "/admin/users/{user_id}", - "router": "router", - "prefix_resolved": true, - "name": "update_user", - "signature": "user_id: uuid.UUID, body: UserUpdateRequest, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 178, - "doc": "Update user fields. Admin only.\n\nGuards against self-demotion: admins cannot change their own role.", - "decorator": "router.patch('/users/{user_id}', response_model=AdminUserCreateResponse)", - "errors": [ - "HTTPException(status_code=404, detail='User not found')", - "HTTPException(status_code=400, detail='Cannot change your own role. Another admin must do this.')", - "HTTPException(status_code=400, detail='Cannot deactivate your own account.')", - "HTTPException(status_code=422, detail=f'Invalid role: {body.role}')" - ] - }, - { - "method": "GET", - "path": "/admin/models", - "router": "router", - "prefix_resolved": true, - "name": "list_models", - "signature": "user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 239, - "doc": "", - "decorator": "router.get('/models', response_model=OllamaStatus)", - "errors": [] - }, - { - "method": "GET", - "path": "/admin/models/registry", - "router": "router", - "prefix_resolved": true, - "name": "list_model_registry", - "signature": "session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 265, - "doc": "", - "decorator": "router.get('/models/registry', response_model=list[ModelRegistryRead])", - "errors": [] - }, - { - "method": "POST", - "path": "/admin/models/registry", - "router": "router", - "prefix_resolved": true, - "name": "register_model", - "signature": "data: ModelRegistryCreate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 276, - "doc": "", - "decorator": "router.post('/models/registry', response_model=ModelRegistryRead, status_code=201)", - "errors": [] + "declared_path": "/users/{user_id}", + "function": "update_user", + "line": 178 + }, + { + "method": "GET", + "declared_path": "/models", + "function": "list_models", + "line": 239 + }, + { + "method": "GET", + "declared_path": "/models/registry", + "function": "list_model_registry", + "line": 265 + }, + { + "method": "POST", + "declared_path": "/models/registry", + "function": "register_model", + "line": 276 }, { "method": "PATCH", - "path": "/admin/models/registry/{model_id}", - "router": "router", - "prefix_resolved": true, - "name": "update_model_registry", - "signature": "model_id: int, data: ModelRegistryUpdate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 305, - "doc": "", - "decorator": "router.patch('/models/registry/{model_id}', response_model=ModelRegistryRead)", - "errors": [ - "HTTPException(status_code=404, detail='Model not found')" - ] + "declared_path": "/models/registry/{model_id}", + "function": "update_model_registry", + "line": 305 }, { "method": "DELETE", - "path": "/admin/models/registry/{model_id}", - "router": "router", - "prefix_resolved": true, - "name": "delete_model_registry", - "signature": "model_id: int, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 330, - "doc": "", - "decorator": "router.delete('/models/registry/{model_id}', status_code=204)", - "errors": [ - "HTTPException(status_code=404, detail='Model not found')" - ] - }, - { - "method": "GET", - "path": "/admin/fee-schedules", - "router": "router", - "prefix_resolved": true, - "name": "list_fee_schedules", - "signature": "jurisdiction: str | None=None, limit: int=50, offset: int=0, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 354, - "doc": "List all fee schedules. Admin only.", - "decorator": "router.get('/fee-schedules', response_model=list[FeeScheduleRead])", - "errors": [] - }, - { - "method": "POST", - "path": "/admin/fee-schedules", - "router": "router", - "prefix_resolved": true, - "name": "create_fee_schedule", - "signature": "data: FeeScheduleCreate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 371, - "doc": "Create a new fee schedule. Admin only.", - "decorator": "router.post('/fee-schedules', response_model=FeeScheduleRead, status_code=201)", - "errors": [] + "declared_path": "/models/registry/{model_id}", + "function": "delete_model_registry", + "line": 330 + }, + { + "method": "GET", + "declared_path": "/fee-schedules", + "function": "list_fee_schedules", + "line": 354 + }, + { + "method": "POST", + "declared_path": "/fee-schedules", + "function": "create_fee_schedule", + "line": 371 }, { "method": "PATCH", - "path": "/admin/fee-schedules/{schedule_id}", - "router": "router", - "prefix_resolved": true, - "name": "update_fee_schedule", - "signature": "schedule_id: uuid.UUID, data: FeeScheduleUpdate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 398, - "doc": "Update a fee schedule. Admin only.", - "decorator": "router.patch('/fee-schedules/{schedule_id}', response_model=FeeScheduleRead)", - "errors": [ - "HTTPException(status_code=404, detail='Fee schedule not found')" - ] + "declared_path": "/fee-schedules/{schedule_id}", + "function": "update_fee_schedule", + "line": 398 }, { "method": "DELETE", - "path": "/admin/fee-schedules/{schedule_id}", - "router": "router", - "prefix_resolved": true, - "name": "delete_fee_schedule", - "signature": "schedule_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 424, - "doc": "Delete a fee schedule. Admin only.", - "decorator": "router.delete('/fee-schedules/{schedule_id}', status_code=204)", - "errors": [ - "HTTPException(status_code=404, detail='Fee schedule not found')" - ] - }, - { - "method": "GET", - "path": "/admin/coverage-gaps", - "router": "router", - "prefix_resolved": true, - "name": "get_coverage_gaps", - "signature": "session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 454, - "doc": "Identify coverage gaps across jurisdictions, departments, and exemption categories.\n\nReturns:\n- Jurisdictions (state codes) that have no exemption rules\n- Departments with no assigned staff users\n- Exemption categories without any active rules", - "decorator": "router.get('/coverage-gaps', response_model=CoverageGapResponse)", - "errors": [] + "declared_path": "/fee-schedules/{schedule_id}", + "function": "delete_fee_schedule", + "line": 424 + }, + { + "method": "GET", + "declared_path": "/coverage-gaps", + "function": "get_coverage_gaps", + "line": 454 } ], "models": [ @@ -6325,41 +6061,40 @@ { "name": "version", "type": "str", - "default": "" + "line": 32 }, { "name": "database", "type": "str", - "default": "" + "line": 33 }, { "name": "ollama", "type": "str", - "default": "" + "line": 34 }, { "name": "redis", "type": "str", - "default": "" + "line": 35 }, { "name": "user_count", "type": "int", - "default": "" + "line": 36 }, { "name": "audit_log_count", "type": "int", - "default": "" + "line": 37 }, { "name": "suite_session", "type": "dict | None", - "default": "None" + "line": 38 } ], - "line": 31, - "doc": "" + "line": 31 }, { "name": "OllamaModelInfo", @@ -6370,21 +6105,20 @@ { "name": "name", "type": "str", - "default": "" + "line": 42 }, { "name": "size", "type": "int | None", - "default": "None" + "line": 43 }, { "name": "details", "type": "dict | None", - "default": "None" + "line": 44 } ], - "line": 41, - "doc": "" + "line": 41 }, { "name": "OllamaStatus", @@ -6395,16 +6129,15 @@ { "name": "status", "type": "str", - "default": "" + "line": 48 }, { "name": "models", "type": "list[OllamaModelInfo]", - "default": "" + "line": 49 } ], - "line": 47, - "doc": "" + "line": 47 }, { "name": "AdminUserCreateRequest", @@ -6415,26 +6148,25 @@ { "name": "email", "type": "str", - "default": "" + "line": 110 }, { "name": "password", "type": "str", - "default": "" + "line": 111 }, { "name": "full_name", "type": "str", - "default": "''" + "line": 112 }, { "name": "role", "type": "str", - "default": "'staff'" + "line": 113 } ], - "line": 109, - "doc": "" + "line": 109 }, { "name": "AdminUserCreateResponse", @@ -6445,31 +6177,30 @@ { "name": "id", "type": "str", - "default": "" + "line": 117 }, { "name": "email", "type": "str", - "default": "" + "line": 118 }, { "name": "full_name", "type": "str", - "default": "" + "line": 119 }, { "name": "role", "type": "str", - "default": "" + "line": 120 }, { "name": "is_active", "type": "bool", - "default": "" + "line": 121 } ], - "line": 116, - "doc": "" + "line": 116 }, { "name": "UserUpdateRequest", @@ -6480,26 +6211,25 @@ { "name": "full_name", "type": "str | None", - "default": "None" + "line": 171 }, { "name": "role", "type": "str | None", - "default": "None" + "line": 172 }, { "name": "department_id", "type": "uuid.UUID | None", - "default": "None" + "line": 173 }, { "name": "is_active", "type": "bool | None", - "default": "None" + "line": 174 } ], - "line": 170, - "doc": "" + "line": 170 }, { "name": "CoverageGapResponse", @@ -6510,157 +6240,139 @@ { "name": "jurisdictions_without_rules", "type": "list[str]", - "default": "" + "line": 447 }, { "name": "departments_without_staff", "type": "list[dict]", - "default": "" + "line": 448 }, { "name": "uncovered_categories", "type": "list[str]", - "default": "" + "line": 449 }, { "name": "total_gaps", "type": "int", - "default": "" + "line": 450 } ], - "line": 446, - "doc": "" + "line": 446 } ], "configuration": [] }, { - "source": "installed-owned-source/app/analytics/__init__.py", + "source": "backend/townlight_records/analytics/__init__.py", "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "bytes": 0, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/analytics/router.py", - "sha256": "a82bc140c0e152301bc9583a8a291974876f068eb3a4fac1b342056ecb217316", + "source": "backend/townlight_records/analytics/router.py", + "sha256": "00ee39251e533e36b4a1575742f01c926962684da22e2d4ee38e6f7df0547ddb", + "bytes": 4668, "routes": [ { "method": "GET", - "path": "/analytics/operational", - "router": "router", - "prefix_resolved": false, - "name": "get_operational_metrics", - "signature": "session: AsyncSession=Depends(get_async_session), user=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 33, - "doc": "", - "decorator": "router.get('/analytics/operational', response_model=OperationalMetrics)", - "errors": [] + "declared_path": "/analytics/operational", + "function": "get_operational_metrics", + "line": 33 } ], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/audit/__init__.py", - "sha256": "35d25b33770f3cd458121ab4d8a6cdb87c32e7b8282bb674c8bf93bca6a5d82d", + "source": "backend/townlight_records/audit/__init__.py", + "sha256": "3ddf6263d5c1e6ad92aa12edcbbcc2ad66b106927c173af9de08f84cb7629456", + "bytes": 289, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/audit/logger.py", - "sha256": "1ad570f68753023d56827f8fa672822e50e234d32259b218682b815ee02cd0e8", + "source": "backend/townlight_records/audit/logger.py", + "sha256": "07d4df47196956592865809f7958e43e93df35965b925be6c5aaa111070d266c", + "bytes": 4371, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/audit/middleware.py", - "sha256": "c9283a66fbe43933edf30895e9b242380a99769127bd6536937dd56652e01a96", + "source": "backend/townlight_records/audit/middleware.py", + "sha256": "c72be74ac13fa28d39c6bc7bf8800b6135ac5f6ebc573842d5bb1ba8e84532a5", + "bytes": 3722, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/audit/router.py", - "sha256": "fc933066a2355e924c0f7c359d9249591c0f8024eadc455246b4b0b536f7d67f", + "source": "backend/townlight_records/audit/router.py", + "sha256": "51e6968c08755248e2455679fefc95ad7598ead1257b4a4599c51386c510e9d8", + "bytes": 4296, "routes": [ { "method": "GET", - "path": "/audit/logs", - "router": "router", - "prefix_resolved": true, - "name": "list_audit_logs", - "signature": "query: AuditLogQuery=Depends(), session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 16, - "doc": "", - "decorator": "router.get('/logs', response_model=list[AuditLogRead])", - "errors": [] + "declared_path": "/logs", + "function": "list_audit_logs", + "line": 16 }, { "method": "GET", - "path": "/audit/verify", - "router": "router", - "prefix_resolved": true, - "name": "verify_audit_chain", - "signature": "session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 40, - "doc": "", - "decorator": "router.get('/verify', response_model=AuditChainVerification)", - "errors": [] + "declared_path": "/verify", + "function": "verify_audit_chain", + "line": 40 }, { "method": "GET", - "path": "/audit/export", - "router": "router", - "prefix_resolved": true, - "name": "export_audit_logs", - "signature": "format: str='json', start_date: str | None=None, end_date: str | None=None, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 51, - "doc": "", - "decorator": "router.get('/export')", - "errors": [] + "declared_path": "/export", + "function": "export_audit_logs", + "line": 51 } ], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/auth/__init__.py", - "sha256": "40ae31146583108d88187effd6cdc081314021177425b6bdb1cb7b72530d5c4b", + "source": "backend/townlight_records/auth/__init__.py", + "sha256": "a6c03f9992f7fce6cb888319b1b8c35f44b7a23a0d35e3551fc4e509d55993e9", + "bytes": 338, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/auth/backend.py", - "sha256": "5a91017634252d0e8c959fa1ec1ae2163b118a4901ecc0bb1233448e8ca498bb", + "source": "backend/townlight_records/auth/backend.py", + "sha256": "6142da3d361c4b887b3d5b0c302d000ab191825b0210f19ad1adc8f4cc5bd698", + "bytes": 484, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/auth/department_authority.py", - "sha256": "f234cf04a5755dc3c0bd76230ef5145d4e7d26876c21b6776924ed95ea3e80eb", + "source": "backend/townlight_records/auth/department_authority.py", + "sha256": "29f23607e37228874cb979cc77d6876cb12c729edd83e9bbf5d493a2aad22e2a", + "bytes": 5708, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/auth/dependencies.py", - "sha256": "28390a14cf9b4550ed09772d0f8c922e4e27cfb75639dd7d853dbeea1e28433d", + "source": "backend/townlight_records/auth/dependencies.py", + "sha256": "8f1383e2a53f5b4c8f1953b16afc2c3ee7265e5b019e59eb66982781fd997168", + "bytes": 9676, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/auth/desktop_session.py", - "sha256": "ce8ff9e910ca8b7f36d8c8616a65d593d48fba3588538edfa6731ea6ada8a36b", + "source": "backend/townlight_records/auth/desktop_session.py", + "sha256": "7e0afb097a616c6a7cd2d849cf19c5492f03eaced768cf22c62c8a09224a1deb", + "bytes": 5466, "routes": [], "models": [ { @@ -6670,54 +6382,57 @@ { "name": "email", "type": "str", - "default": "" + "line": 40 }, { "name": "display_name", "type": "str", - "default": "" + "line": 41 }, { "name": "role", "type": "str", - "default": "" + "line": 42 }, { "name": "expires_at_unix_seconds", "type": "int", - "default": "" + "line": 43 } ], - "line": 39, - "doc": "" + "line": 39 } ], "configuration": [] }, { - "source": "installed-owned-source/app/auth/manager.py", - "sha256": "337f7d5b6d89973c352259c21512da56e6308a6e3e6967f035a31916b52c2bbb", + "source": "backend/townlight_records/auth/manager.py", + "sha256": "084693e045ce0b372cdc9d8f8876b5157bd986efd2441960fe99587b9ae7c322", + "bytes": 1806, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/auth/native_identity.py", - "sha256": "3d2536b13f38c52d93c4ab54887bf232a3b9181fe1b485165e1fd6a81fe687d0", + "source": "backend/townlight_records/auth/native_identity.py", + "sha256": "7af0c7ab99fa521182e45a4751226f287f82a561d3f8c75fc946341aa3bd3a78", + "bytes": 2187, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/auth/router.py", - "sha256": "9574ed42379df9ef05d9c13409c01f715538e00bb9e3c884b884cd2c1c8495fc", + "source": "backend/townlight_records/auth/router.py", + "sha256": "85f0c1ed229ffecbfb44f0e431e208e5c9dfa6d93e506ee1c6ce38aaed5766f6", + "bytes": 1256, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/auth/suite_session.py", - "sha256": "126a453ff01029cfe7abbbb5a3ecbf6c3ba562957ce929eb7854ff682576d071", + "source": "backend/townlight_records/auth/suite_session.py", + "sha256": "619bcec9da9202cb710ec2ee2390931dcf059230cf77dbafd7a56eadf2d4d902", + "bytes": 9870, "routes": [], "models": [ { @@ -6727,21 +6442,20 @@ { "name": "email", "type": "str", - "default": "" + "line": 181 }, { "name": "roles", "type": "frozenset[str]", - "default": "" + "line": 182 }, { "name": "must_change_password", "type": "bool", - "default": "False" + "line": 183 } ], - "line": 180, - "doc": "" + "line": 180 }, { "name": "SuiteSession", @@ -6750,21 +6464,20 @@ { "name": "subject", "type": "str", - "default": "" + "line": 188 }, { "name": "roles", "type": "frozenset[str]", - "default": "" + "line": 189 }, { "name": "session_id", "type": "str", - "default": "" + "line": 190 } ], - "line": 187, - "doc": "" + "line": 187 }, { "name": "Principal", @@ -6773,162 +6486,112 @@ { "name": "subject", "type": "str", - "default": "" + "line": 86 }, { "name": "roles", "type": "frozenset[str]", - "default": "" + "line": 87 }, { "name": "session_id", "type": "str", - "default": "" + "line": 88 } ], - "line": 85, - "doc": "" + "line": 85 } ], "configuration": [] }, { - "source": "installed-owned-source/app/catalog/__init__.py", + "source": "backend/townlight_records/catalog/__init__.py", "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "bytes": 0, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/catalog/loader.py", - "sha256": "8ec0239d327824d28d18425904c64ef2bbfc2d04c65a4c5deb64904d5354912d", + "source": "backend/townlight_records/catalog/loader.py", + "sha256": "8f4dd60317e034e7bea3b2099a0bcefa31b1bfe4227abd7e338da39cf843bcd0", + "bytes": 740, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/catalog/router.py", - "sha256": "8720ef17e4106e738c2ed3672af4051dfe36b617a9da8eae8fa54a9c23de13d8", + "source": "backend/townlight_records/catalog/router.py", + "sha256": "4c70d6a6ab91e2f3d0fef8c7106dbb37d9aa5097645143efcdbfc7eb60509678", + "bytes": 1719, "routes": [ { "method": "GET", - "path": "/catalog/domains", - "router": "router", - "prefix_resolved": false, - "name": "list_domains", - "signature": "session: AsyncSession=Depends(get_async_session), user=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 12, - "doc": "", - "decorator": "router.get('/catalog/domains')", - "errors": [] + "declared_path": "/catalog/domains", + "function": "list_domains", + "line": 12 }, { "method": "GET", - "path": "/catalog/systems", - "router": "router", - "prefix_resolved": false, - "name": "list_systems", - "signature": "domain: str | None=None, session: AsyncSession=Depends(get_async_session), user=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 16, - "doc": "", - "decorator": "router.get('/catalog/systems')", - "errors": [] + "declared_path": "/catalog/systems", + "function": "list_systems", + "line": 16 }, { "method": "GET", - "path": "/catalog/connectors", - "router": "router", - "prefix_resolved": false, - "name": "list_connectors", - "signature": "domain: str, session: AsyncSession=Depends(get_async_session), user=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 20, - "doc": "", - "decorator": "router.get('/catalog/connectors')", - "errors": [] + "declared_path": "/catalog/connectors", + "function": "list_connectors", + "line": 20 }, { "method": "POST", - "path": "/catalog/load", - "router": "router", - "prefix_resolved": false, - "name": "trigger_catalog_load", - "signature": "session: AsyncSession=Depends(get_async_session), user=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 24, - "doc": "", - "decorator": "router.post('/catalog/load', status_code=200)", - "errors": [ - "HTTPException(409, 'Catalog missing, changed or incomplete; existing data preserved. Review a new catalog version.')" - ] + "declared_path": "/catalog/load", + "function": "trigger_catalog_load", + "line": 24 } ], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/city_profile/__init__.py", + "source": "backend/townlight_records/city_profile/__init__.py", "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "bytes": 0, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/city_profile/router.py", - "sha256": "e0b9d83c16dcb8e6ad6b2ca3bd2c4300ff0aa9ff89609a7f5bd7cc5dde835682", + "source": "backend/townlight_records/city_profile/router.py", + "sha256": "6c52879ffdaa3cc1064a4c4706e65fd102a9eee574a27eac7a69f6d0566d2bb7", + "bytes": 3731, "routes": [ { "method": "GET", - "path": "/city-profile", - "router": "router", - "prefix_resolved": false, - "name": "get_city_profile", - "signature": "session: AsyncSession=Depends(get_async_session), user=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 32, - "doc": "", - "decorator": "router.get('/city-profile', response_model=CityProfileRead | None)", - "errors": [] + "declared_path": "/city-profile", + "function": "get_city_profile", + "line": 32 }, { "method": "POST", - "path": "/city-profile", - "router": "router", - "prefix_resolved": false, - "name": "create_city_profile", - "signature": "data: CityProfileCreate, session: AsyncSession=Depends(get_async_session), user=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 42, - "doc": "", - "decorator": "router.post('/city-profile', response_model=CityProfileRead, status_code=201)", - "errors": [ - "HTTPException(409, 'City profile already exists. Use PATCH to update.')" - ] + "declared_path": "/city-profile", + "function": "create_city_profile", + "line": 42 }, { "method": "PATCH", - "path": "/city-profile", - "router": "router", - "prefix_resolved": false, - "name": "update_city_profile", - "signature": "data: CityProfileUpdate, session: AsyncSession=Depends(get_async_session), user=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 76, - "doc": "", - "decorator": "router.patch('/city-profile', response_model=CityProfileRead)", - "errors": [ - "HTTPException(404, 'No city profile exists. Use POST to create one.')" - ] + "declared_path": "/city-profile", + "function": "update_city_profile", + "line": 76 } ], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/config.py", - "sha256": "52725fbeb02c75717ae638e8d0cdf2d527656fb8bac5b5b5572d48d6e794a1c5", + "source": "backend/townlight_records/config.py", + "sha256": "4f64a49ba5c4a4ebe87ac89ab65875121e416fcc21e76c8ed675bba0e7c0fc87", + "bytes": 5871, "routes": [], "models": [ { @@ -6940,323 +6603,266 @@ { "name": "database_url", "type": "str", - "default": "'postgresql+asyncpg://townlight_records:townlight_records@postgres:5432/townlight_records'" + "line": 25 }, { "name": "jwt_secret", "type": "str", - "default": "'CHANGE-ME'" + "line": 26 }, { "name": "jwt_secret_file", "type": "str", - "default": "'/run/secrets/jwt_secret'" + "line": 31 }, { "name": "jwt_lifetime_seconds", "type": "int", - "default": "3600" + "line": 32 }, { "name": "first_admin_email", "type": "str", - "default": "'admin@example.gov'" + "line": 33 }, { "name": "first_admin_password", "type": "str", - "default": "'CHANGE-ME'" + "line": 34 }, { "name": "first_admin_password_file", "type": "str", - "default": "'/run/secrets/first_admin_password'" + "line": 35 }, { "name": "ollama_base_url", "type": "str", - "default": "'http://ollama:11434'" + "line": 36 }, { "name": "redis_url", "type": "str", - "default": "'redis://redis:6379/0'" + "line": 37 }, { "name": "audit_retention_days", "type": "int", - "default": "1095" + "line": 38 }, { "name": "cors_origins", "type": "list[str]", - "default": "['http://localhost:8080']" + "line": 39 }, { "name": "embedding_model", "type": "str", - "default": "'nomic-embed-text'" + "line": 40 }, { "name": "chat_model", "type": "str", - "default": "'gemma4:e4b'" + "line": 43 }, { "name": "vision_model", "type": "str", - "default": "'gemma4:e4b'" + "line": 44 }, { "name": "smtp_host", "type": "str", - "default": "''" + "line": 46 }, { "name": "smtp_port", "type": "int", - "default": "587" + "line": 47 }, { "name": "smtp_username", "type": "str", - "default": "''" + "line": 48 }, { "name": "smtp_password", "type": "str", - "default": "''" + "line": 49 }, { "name": "smtp_from_email", "type": "str", - "default": "'noreply@townlight_records.local'" + "line": 50 }, { "name": "smtp_use_tls", "type": "bool", - "default": "True" + "line": 51 }, { "name": "connector_host_allowlist", "type": "Annotated[list[str], NoDecode]", - "default": "[]" + "line": 54 }, { "name": "portal_mode", "type": "Literal['public', 'private']", - "default": "'private'" + "line": 57 }, { "name": "encryption_key", "type": "str", - "default": "'CHANGE-ME-generate-with-fernet-generate-key'" + "line": 60 }, { "name": "testing", "type": "bool", - "default": "False" + "line": 62 }, { "name": "authority_scope_id", "type": "str", - "default": "''" + "line": 68 } ], - "line": 24, - "doc": "" + "line": 24 } ], "configuration": [] }, { - "source": "installed-owned-source/app/connectors/__init__.py", - "sha256": "858f35a785e1714492e27337991099f9891ab9e0b6325427213d0458b7e7508f", + "source": "backend/townlight_records/connectors/__init__.py", + "sha256": "9b4171a560153689a6f3035e04488a64a7d2d3737f4c9b022861d63f4fb6c9a9", + "bytes": 1007, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/connectors/base.py", - "sha256": "61772e641cda2c08df5c95ce7cbefe725b550b1fd67f54cb550ea847c9927688", + "source": "backend/townlight_records/connectors/base.py", + "sha256": "6c3572d2dc3b25f164128d7afb03e61404c6ec9c9d48fabb58cf0e5379775dcf", + "bytes": 2311, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/connectors/file_system.py", - "sha256": "d61c6ed4b906cb10697949ed9810ce14853301af1706cc02ba6605fec1d385a6", + "source": "backend/townlight_records/connectors/file_system.py", + "sha256": "91ce9a5a885b84047004370fe100708865149330ae16da0fc3d55751126fe834", + "bytes": 5185, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/connectors/imap_email.py", - "sha256": "a6353f14d4f083e999e089bd8c536438a9355ac0bab5c94b03ab30f4f0ef084d", + "source": "backend/townlight_records/connectors/imap_email.py", + "sha256": "6f0f3d997589d65c4b49d8841607c746387e9e446a632a048d757e648e7119cc", + "bytes": 12290, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/connectors/manual_drop.py", - "sha256": "4130a495cb691d56d6c9cc493bf85edb520f86c89846a241ed216ca652b4d2ac", + "source": "backend/townlight_records/connectors/manual_drop.py", + "sha256": "9634d200ed3675eb33c9ccdf47aec5f1f77cc190b9e3d19e84ec11973abb26b8", + "bytes": 7967, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/connectors/odbc.py", - "sha256": "636c23aa66537775c674efe095a1c9e27dc670a6370a742e325c1ea5039243db", + "source": "backend/townlight_records/connectors/odbc.py", + "sha256": "aa146a1e79f99bb5e34c95c17cd6388807c5a4237efd2b4454ac6e8e8308e3de", + "bytes": 9537, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/connectors/rest_api.py", - "sha256": "52e26ea1923a25ed7704f090e37745be39a0fb80e38a4b5cdb315a08d16373f2", + "source": "backend/townlight_records/connectors/rest_api.py", + "sha256": "316af4c35a98267c84c35969afb51804cb19251a9c8b7505211840929e39114f", + "bytes": 13235, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/connectors/retry.py", - "sha256": "bba511cd51d7727835e24540b5c8c4660dbab43776d34cbaf2a618b207c36726", + "source": "backend/townlight_records/connectors/retry.py", + "sha256": "41d845b0020b8df86c6838368b01830821c468cb5ecd631dca562074067c4806", + "bytes": 1298, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/database.py", - "sha256": "cbf900a24999134b812e06749cd897a8f36e1885a05fb6b837363788ae2e990f", + "source": "backend/townlight_records/database.py", + "sha256": "a82e34395f940bf9d9ccf476b6585a220e23028d15050bbbeb12340b168a2793", + "bytes": 992, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/datasources/__init__.py", - "sha256": "f8a2f02b77cc7a4a879305cceee97e5ee272213e93c635792e42a1c3e5afaa75", + "source": "backend/townlight_records/datasources/__init__.py", + "sha256": "e2821093f99faacc298a371e1a5269722f13ffee98c8112f9090ca2690ed39c4", + "bytes": 113, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/datasources/router.py", - "sha256": "67dc17fea9f4259bcf8c4f376c447bdcd775ae59fd6e805a981873fe87bf36c4", + "source": "backend/townlight_records/datasources/router.py", + "sha256": "63ac5050984e6b35efef6374050b294a9b2fcbb64fd4ad2302eda33062af66b5", + "bytes": 17257, "routes": [ { "method": "POST", - "path": "/datasources/", - "router": "router", - "prefix_resolved": true, - "name": "create_datasource", - "signature": "data: DataSourceCreate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 70, - "doc": "", - "decorator": "router.post('/', response_model=DataSourceAdminRead, status_code=201)", - "errors": [ - "HTTPException(status_code=409, detail='Name already taken')" - ] + "declared_path": "/", + "function": "create_datasource", + "line": 70 }, { "method": "GET", - "path": "/datasources/", - "router": "router", - "prefix_resolved": true, - "name": "list_datasources", - "signature": "session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 89, - "doc": "", - "decorator": "router.get('/', response_model=list[DataSourceRead])", - "errors": [] + "declared_path": "/", + "function": "list_datasources", + "line": 89 }, { "method": "PATCH", - "path": "/datasources/{source_id}", - "router": "router", - "prefix_resolved": true, - "name": "update_datasource", - "signature": "source_id: uuid.UUID, data: DataSourceUpdate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 137, - "doc": "", - "decorator": "router.patch('/{source_id}', response_model=DataSourceAdminRead)", - "errors": [ - "HTTPException(status_code=404, detail='Data source not found')" - ] - }, - { - "method": "POST", - "path": "/datasources/{source_id}/ingest", - "router": "router", - "prefix_resolved": true, - "name": "trigger_ingestion", - "signature": "source_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 156, - "doc": "", - "decorator": "router.post('/{source_id}/ingest')", - "errors": [ - "HTTPException(status_code=404, detail='Data source not found')" - ] - }, - { - "method": "POST", - "path": "/datasources/upload", - "router": "router", - "prefix_resolved": true, - "name": "upload_file", - "signature": "file: UploadFile=File(...), session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 165, - "doc": "", - "decorator": "router.post('/upload')", - "errors": [ - "HTTPException(status_code=413, detail='File too large (max 100 MB)')" - ] - }, - { - "method": "POST", - "path": "/datasources/documents/{document_id}/re-ingest", - "router": "router", - "prefix_resolved": true, - "name": "re_ingest_document", - "signature": "document_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 201, - "doc": "Re-ingest a failed document. Resets status to pending and queues for processing.", - "decorator": "router.post('/documents/{document_id}/re-ingest')", - "errors": [ - "HTTPException(status_code=404, detail='Document not found')", - "HTTPException(status_code=400, detail=f'Can only re-ingest failed documents (current: {doc.ingestion_status.value})')" - ] - }, - { - "method": "GET", - "path": "/datasources/stats", - "router": "router", - "prefix_resolved": true, - "name": "ingestion_stats", - "signature": "session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 236, - "doc": "", - "decorator": "router.get('/stats', response_model=IngestionStats)", - "errors": [] - }, - { - "method": "POST", - "path": "/datasources/test-connection", - "router": "router", - "prefix_resolved": true, - "name": "test_connection", - "signature": "body: TestConnectionRequest, user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 277, - "doc": "Test connectivity to a data source without persisting anything.\n\nThis endpoint validates the connection parameters and attempts a test\nconnection. Credentials are NOT persisted, NOT logged, and NOT returned.", - "decorator": "router.post('/test-connection', response_model=TestConnectionResponse)", - "errors": [] + "declared_path": "/{source_id}", + "function": "update_datasource", + "line": 137 + }, + { + "method": "POST", + "declared_path": "/{source_id}/ingest", + "function": "trigger_ingestion", + "line": 156 + }, + { + "method": "POST", + "declared_path": "/upload", + "function": "upload_file", + "line": 165 + }, + { + "method": "POST", + "declared_path": "/documents/{document_id}/re-ingest", + "function": "re_ingest_document", + "line": 201 + }, + { + "method": "GET", + "declared_path": "/stats", + "function": "ingestion_stats", + "line": 236 + }, + { + "method": "POST", + "declared_path": "/test-connection", + "function": "test_connection", + "line": 277 } ], "models": [ @@ -7269,46 +6875,45 @@ { "name": "source_type", "type": "str", - "default": "" + "line": 256 }, { "name": "host", "type": "str | None", - "default": "None" + "line": 257 }, { "name": "port", "type": "int | None", - "default": "None" + "line": 258 }, { "name": "path", "type": "str | None", - "default": "None" + "line": 259 }, { "name": "username", "type": "str | None", - "default": "None" + "line": 260 }, { "name": "password", "type": "str | None", - "default": "None" + "line": 261 }, { "name": "rest_api_config", "type": "dict[str, Any] | None", - "default": "None" + "line": 263 }, { "name": "odbc_config", "type": "dict[str, Any] | None", - "default": "None" + "line": 264 } ], - "line": 250, - "doc": "Dedicated schema for test-connection. NOT the create schema.\n\nSecurity: credentials in this request body are never persisted, never\nwritten to audit logs, and never returned in the response." + "line": 250 }, { "name": "TestConnectionResponse", @@ -7319,678 +6924,333 @@ { "name": "success", "type": "bool", - "default": "" + "line": 268 }, { "name": "message", "type": "str", - "default": "" + "line": 269 }, { "name": "latency_ms", "type": "int | None", - "default": "None" + "line": 270 }, { "name": "status", "type": "str | None", - "default": "None" + "line": 271 }, { "name": "warning", "type": "str | None", - "default": "None" + "line": 272 }, { "name": "differing_keys", "type": "list[str] | None", - "default": "None" + "line": 273 } ], - "line": 267, - "doc": "" + "line": 267 } ], "configuration": [] }, { - "source": "installed-owned-source/app/datasources/sync_failures_router.py", - "sha256": "6d942272770c5968245a2c2455883971eef01afd28c3fb6620efcf435ae0daa5", + "source": "backend/townlight_records/datasources/sync_failures_router.py", + "sha256": "49a80a2a4516476d7b7996076667f5eaac93e2ec7739a0567d529471f20b607d", + "bytes": 5440, "routes": [ { "method": "GET", - "path": "/datasources/{source_id}/sync-failures", - "router": "router", - "prefix_resolved": true, - "name": "list_sync_failures", - "signature": "source_id: uuid.UUID, status: Optional[str]=Query(None, description='Filter by status'), limit: int=Query(50, ge=1, le=500), offset: int=Query(0, ge=0), db: AsyncSession=Depends(get_async_session), current_user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 26, - "doc": "", - "decorator": "router.get('/{source_id}/sync-failures', response_model=list[SyncFailureRead])", - "errors": [] + "declared_path": "/{source_id}/sync-failures", + "function": "list_sync_failures", + "line": 26 }, { "method": "POST", - "path": "/datasources/{source_id}/sync-failures/{failure_id}/retry", - "router": "router", - "prefix_resolved": true, - "name": "retry_sync_failure", - "signature": "source_id: uuid.UUID, failure_id: uuid.UUID, db: AsyncSession=Depends(get_async_session), current_user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 43, - "doc": "", - "decorator": "router.post('/{source_id}/sync-failures/{failure_id}/retry')", - "errors": [ - "HTTPException(status_code=404, detail='Sync failure not found')" - ] + "declared_path": "/{source_id}/sync-failures/{failure_id}/retry", + "function": "retry_sync_failure", + "line": 43 }, { "method": "POST", - "path": "/datasources/{source_id}/sync-failures/{failure_id}/dismiss", - "router": "router", - "prefix_resolved": true, - "name": "dismiss_sync_failure", - "signature": "source_id: uuid.UUID, failure_id: uuid.UUID, db: AsyncSession=Depends(get_async_session), current_user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 59, - "doc": "", - "decorator": "router.post('/{source_id}/sync-failures/{failure_id}/dismiss')", - "errors": [ - "HTTPException(status_code=404, detail='Sync failure not found')" - ] + "declared_path": "/{source_id}/sync-failures/{failure_id}/dismiss", + "function": "dismiss_sync_failure", + "line": 59 }, { "method": "POST", - "path": "/datasources/{source_id}/sync-failures/retry-all", - "router": "router", - "prefix_resolved": true, - "name": "retry_all_sync_failures", - "signature": "source_id: uuid.UUID, status: str=Query(..., description='Status to reset \u2014 required'), db: AsyncSession=Depends(get_async_session), current_user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 76, - "doc": "", - "decorator": "router.post('/{source_id}/sync-failures/retry-all')", - "errors": [] + "declared_path": "/{source_id}/sync-failures/retry-all", + "function": "retry_all_sync_failures", + "line": 76 }, { "method": "POST", - "path": "/datasources/{source_id}/sync-failures/dismiss-all", - "router": "router", - "prefix_resolved": true, - "name": "dismiss_all_sync_failures", - "signature": "source_id: uuid.UUID, status: str=Query(..., description='Status to dismiss \u2014 required'), db: AsyncSession=Depends(get_async_session), current_user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 97, - "doc": "", - "decorator": "router.post('/{source_id}/sync-failures/dismiss-all')", - "errors": [] + "declared_path": "/{source_id}/sync-failures/dismiss-all", + "function": "dismiss_all_sync_failures", + "line": 97 }, { "method": "POST", - "path": "/datasources/{source_id}/unpause", - "router": "router", - "prefix_resolved": true, - "name": "unpause_source", - "signature": "source_id: uuid.UUID, db: AsyncSession=Depends(get_async_session), current_user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 120, - "doc": "", - "decorator": "router.post('/{source_id}/unpause')", - "errors": [ - "HTTPException(status_code=404, detail='Data source not found')" - ] + "declared_path": "/{source_id}/unpause", + "function": "unpause_source", + "line": 120 }, { "method": "GET", - "path": "/datasources/{source_id}/sync-run-log", - "router": "router", - "prefix_resolved": true, - "name": "get_sync_run_log", - "signature": "source_id: uuid.UUID, limit: int=Query(20, ge=1, le=100), db: AsyncSession=Depends(get_async_session), current_user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 137, - "doc": "", - "decorator": "router.get('/{source_id}/sync-run-log', response_model=list[SyncRunLogRead])", - "errors": [] + "declared_path": "/{source_id}/sync-run-log", + "function": "get_sync_run_log", + "line": 137 } ], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/departments/__init__.py", + "source": "backend/townlight_records/departments/__init__.py", "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "bytes": 0, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/departments/router.py", - "sha256": "1c5f50b50572ecd7003903f2d3e9433027c86ebffe5a44d821b2e5ed05f0a39d", + "source": "backend/townlight_records/departments/router.py", + "sha256": "ae8357aa76ef96d76d42a176fd862fa854cdf01897a05517147386678e9a024b", + "bytes": 4453, "routes": [ { "method": "POST", - "path": "/departments/", - "router": "router", - "prefix_resolved": true, - "name": "create_department", - "signature": "data: DepartmentCreate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 18, - "doc": "", - "decorator": "router.post('/', response_model=DepartmentRead, status_code=201)", - "errors": [ - "HTTPException(status_code=409, detail='Department code already exists')" - ] - }, - { - "method": "GET", - "path": "/departments/", - "router": "router", - "prefix_resolved": true, - "name": "list_departments", - "signature": "session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 43, - "doc": "", - "decorator": "router.get('/', response_model=list[DepartmentRead])", - "errors": [] - }, - { - "method": "GET", - "path": "/departments/{dept_id}", - "router": "router", - "prefix_resolved": true, - "name": "get_department", - "signature": "dept_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 54, - "doc": "", - "decorator": "router.get('/{dept_id}', response_model=DepartmentRead)", - "errors": [ - "HTTPException(status_code=404, detail='Department not found')" - ] + "declared_path": "/", + "function": "create_department", + "line": 18 + }, + { + "method": "GET", + "declared_path": "/", + "function": "list_departments", + "line": 43 + }, + { + "method": "GET", + "declared_path": "/{dept_id}", + "function": "get_department", + "line": 54 }, { "method": "PATCH", - "path": "/departments/{dept_id}", - "router": "router", - "prefix_resolved": true, - "name": "update_department", - "signature": "dept_id: uuid.UUID, data: DepartmentUpdate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 66, - "doc": "", - "decorator": "router.patch('/{dept_id}', response_model=DepartmentRead)", - "errors": [ - "HTTPException(status_code=404, detail='Department not found')", - "HTTPException(status_code=409, detail='Department code already exists')" - ] + "declared_path": "/{dept_id}", + "function": "update_department", + "line": 66 }, { "method": "DELETE", - "path": "/departments/{dept_id}", - "router": "router", - "prefix_resolved": true, - "name": "delete_department", - "signature": "dept_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 100, - "doc": "", - "decorator": "router.delete('/{dept_id}', status_code=204)", - "errors": [ - "HTTPException(status_code=404, detail='Department not found')", - "HTTPException(status_code=409, detail=f'Cannot delete department with {user_count} assigned users')" - ] + "declared_path": "/{dept_id}", + "function": "delete_department", + "line": 100 } ], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/desktop_bridge/__init__.py", + "source": "backend/townlight_records/desktop_bridge/__init__.py", "sha256": "707138dfa41f7f4e91957a523e3c3394ce52803778c5b278b3cc77d4a5b1c30f", + "bytes": 79, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/desktop_bridge/projection.py", - "sha256": "5267b17ae6be18258ea0e225ffb0d53c56aeaf674d9426856b8db804f801008c", + "source": "backend/townlight_records/desktop_bridge/projection.py", + "sha256": "b75009be22c4cbfa916303d711c5300e132121b36fba3775564f9b1c8893eaa4", + "bytes": 10584, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/desktop_bridge/records.py", - "sha256": "407b2ca9974caa761c00daee3b585ca915c2fe649a69a0dd58f42342b39821d1", + "source": "backend/townlight_records/desktop_bridge/records.py", + "sha256": "428bb99456414f4d7a4c806aeb2e360a7c48450b41b8af4bc24a35574f370c15", + "bytes": 3548, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/desktop_bridge/router.py", - "sha256": "7c02e0a222c36aecb84b105a918309a811f40249c3f55756d87cfa2646c4ef1b", + "source": "backend/townlight_records/desktop_bridge/router.py", + "sha256": "1b1cb6afce568f1ab81c991396ac27684eb06b11b1a0ab37192a8c9382c533fb", + "bytes": 33950, "routes": [ { "method": "GET", - "path": "/desktop/v1/public/records-state", - "router": "router", - "prefix_resolved": true, - "name": "public_records_state", - "signature": "request: Request, session: AsyncSession=Depends(get_async_session)", - "returns": "", - "line": 134, - "doc": "", - "decorator": "router.get('/public/records-state', dependencies=[Depends(native_public_shell)], response_model=RecordsStateRead)", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/public/requests", - "router": "router", - "prefix_resolved": true, - "name": "public_records_intake", - "signature": "data: PublicIntake, request: Request, session: AsyncSession=Depends(get_async_session)", - "returns": "", - "line": 144, - "doc": "", - "decorator": "router.post('/public/requests', dependencies=[Depends(native_public_shell)])", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/public/lookup", - "router": "router", - "prefix_resolved": true, - "name": "public_records_lookup", - "signature": "data: PublicLookup, request: Request, session: AsyncSession=Depends(get_async_session)", - "returns": "", - "line": 153, - "doc": "", - "decorator": "router.post('/public/lookup', dependencies=[Depends(native_public_shell)])", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/public/messages", - "router": "router", - "prefix_resolved": true, - "name": "public_records_message", - "signature": "data: PublicMessage, request: Request, session: AsyncSession=Depends(get_async_session)", - "returns": "", - "line": 160, - "doc": "", - "decorator": "router.post('/public/messages', dependencies=[Depends(native_public_shell)])", - "errors": [ - "HTTPException(400, str(error))" - ] - }, - { - "method": "POST", - "path": "/desktop/v1/permitting-sources/search", - "router": "router", - "prefix_resolved": true, - "name": "search_permitting_sources", - "signature": "data: MeetingsSearch, request: Request, actor: User=Depends(native_records_user)", - "returns": "", - "line": 204, - "doc": "", - "decorator": "router.post('/permitting-sources/search')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/requests/{request_id}/permitting-sources", - "router": "router", - "prefix_resolved": true, - "name": "attach_permitting_source", - "signature": "request_id: uuid.UUID, data: MeetingsSourceSelection, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", - "returns": "", - "line": 213, - "doc": "", - "decorator": "router.post('/requests/{request_id}/permitting-sources', response_model=RecordsOperationRead)", - "errors": [ - "HTTPException(404, 'Records request not found.')", - "HTTPException(404, 'Reviewed Permitting copy not found or no longer permitted.')", - "HTTPException(409, 'Permitting source changed; search again before attaching.')", - "HTTPException(422, 'Source attachment not confirmed; existing evidence retained.')" - ] - }, - { - "method": "POST", - "path": "/desktop/v1/inspections-sources/search", - "router": "router", - "prefix_resolved": true, - "name": "search_inspections_sources", - "signature": "data: MeetingsSearch, request: Request, actor: User=Depends(native_records_user)", - "returns": "", - "line": 239, - "doc": "", - "decorator": "router.post('/inspections-sources/search')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/requests/{request_id}/inspections-sources", - "router": "router", - "prefix_resolved": true, - "name": "attach_inspections_source", - "signature": "request_id: uuid.UUID, data: MeetingsSourceSelection, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", - "returns": "", - "line": 248, - "doc": "", - "decorator": "router.post('/requests/{request_id}/inspections-sources', response_model=RecordsOperationRead)", - "errors": [ - "HTTPException(404, 'Records request not found.')", - "HTTPException(404, 'Reviewed Inspections copy not found or no longer permitted.')", - "HTTPException(409, 'Inspections source changed; search again before attaching.')", - "HTTPException(422, 'Source attachment not confirmed; existing evidence retained.')" - ] - }, - { - "method": "POST", - "path": "/desktop/v1/planning-sources/search", - "router": "router", - "prefix_resolved": true, - "name": "search_planning_sources", - "signature": "data: MeetingsSearch, request: Request, actor: User=Depends(native_records_user)", - "returns": "", - "line": 274, - "doc": "", - "decorator": "router.post('/planning-sources/search')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/requests/{request_id}/planning-sources", - "router": "router", - "prefix_resolved": true, - "name": "attach_planning_source", - "signature": "request_id: uuid.UUID, data: MeetingsSourceSelection, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", - "returns": "", - "line": 283, - "doc": "", - "decorator": "router.post('/requests/{request_id}/planning-sources', response_model=RecordsOperationRead)", - "errors": [ - "HTTPException(404, 'Records request not found.')", - "HTTPException(404, 'Permitted Planning source not found.')", - "HTTPException(409, 'Planning source changed; search again before attaching.')", - "HTTPException(422, 'Source attachment not confirmed; existing evidence retained.')" - ] - }, - { - "method": "POST", - "path": "/desktop/v1/zoning-sources/search", - "router": "router", - "prefix_resolved": true, - "name": "search_zoning_sources", - "signature": "data: MeetingsSearch, request: Request, actor: User=Depends(native_records_user)", - "returns": "", - "line": 310, - "doc": "", - "decorator": "router.post('/zoning-sources/search')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/requests/{request_id}/zoning-sources", - "router": "router", - "prefix_resolved": true, - "name": "attach_zoning_source", - "signature": "request_id: uuid.UUID, data: MeetingsSourceSelection, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", - "returns": "", - "line": 319, - "doc": "", - "decorator": "router.post('/requests/{request_id}/zoning-sources', response_model=RecordsOperationRead)", - "errors": [ - "HTTPException(404, 'Records request not found.')", - "HTTPException(404, 'Permitted Zoning source not found.')", - "HTTPException(409, 'Zoning source changed; search again before attaching.')", - "HTTPException(422, 'Source attachment not confirmed; existing evidence retained.')" - ] - }, - { - "method": "GET", - "path": "/desktop/v1/records-state", - "router": "router", - "prefix_resolved": true, - "name": "get_native_records_state", - "signature": "session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", - "returns": "", - "line": 346, - "doc": "", - "decorator": "router.get('/records-state', response_model=RecordsStateRead)", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/meetings-sources/search", - "router": "router", - "prefix_resolved": true, - "name": "search_meetings_sources", - "signature": "data: MeetingsSearch, request: Request, actor: User=Depends(native_records_user)", - "returns": "", - "line": 355, - "doc": "", - "decorator": "router.post('/meetings-sources/search')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/requests/{request_id}/meetings-sources", - "router": "router", - "prefix_resolved": true, - "name": "attach_meetings_source", - "signature": "request_id: uuid.UUID, data: MeetingsSourceSelection, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", - "returns": "", - "line": 364, - "doc": "", - "decorator": "router.post('/requests/{request_id}/meetings-sources', response_model=RecordsOperationRead)", - "errors": [ - "HTTPException(404, 'Records request not found.')", - "HTTPException(404, 'Permitted Meetings source not found.')", - "HTTPException(409, 'Meetings source changed; search again before attaching.')", - "HTTPException(422, 'Source attachment not confirmed; existing evidence retained.')" - ] - }, - { - "method": "POST", - "path": "/desktop/v1/code-sources/search", - "router": "router", - "prefix_resolved": true, - "name": "search_code_sources", - "signature": "data: CodeSearch, request: Request, actor: User=Depends(native_records_user)", - "returns": "", - "line": 389, - "doc": "", - "decorator": "router.post('/code-sources/search')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/requests/{request_id}/code-sources", - "router": "router", - "prefix_resolved": true, - "name": "attach_code_source", - "signature": "request_id: uuid.UUID, data: CodeSourceSelection, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", - "returns": "", - "line": 398, - "doc": "", - "decorator": "router.post('/requests/{request_id}/code-sources', response_model=RecordsOperationRead)", - "errors": [ - "HTTPException(404, 'Records request not found.')", - "HTTPException(404, 'Permitted Code source not found.')", - "HTTPException(409, 'Code source changed; search again before attaching.')", - "HTTPException(422, 'Source attachment not confirmed; existing evidence retained.')" - ] - }, - { - "method": "POST", - "path": "/desktop/v1/notifications/{notification_id}/sent", - "router": "router", - "prefix_resolved": true, - "name": "mark_native_notification_sent", - "signature": "notification_id: uuid.UUID, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", - "returns": "", - "line": 423, - "doc": "", - "decorator": "router.post('/notifications/{notification_id}/sent', response_model=RecordsStateRead)", - "errors": [ - "HTTPException(404, 'Records notification not found.')", - "HTTPException(400, 'This local notification is already marked sent.')" - ] - }, - { - "method": "POST", - "path": "/desktop/v1/requests/{request_id}/documents", - "router": "router", - "prefix_resolved": true, - "name": "attach_native_document", - "signature": "request_id: uuid.UUID, data: AttachDocument, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", - "returns": "", - "line": 443, - "doc": "", - "decorator": "router.post('/requests/{request_id}/documents', response_model=RecordsOperationRead)", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/requests/{request_id}/documents/{attachment_id}/release-copy", - "router": "router", - "prefix_resolved": true, - "name": "attach_native_release_copy", - "signature": "request_id: uuid.UUID, attachment_id: uuid.UUID, data: AttachReleaseCopy, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", - "returns": "", - "line": 453, - "doc": "", - "decorator": "router.post('/requests/{request_id}/documents/{attachment_id}/release-copy', response_model=RecordsOperationRead)", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/requests/{request_id}/artifacts", - "router": "router", - "prefix_resolved": true, - "name": "prepare_native_artifact", - "signature": "request_id: uuid.UUID, data: PrepareArtifact, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", - "returns": "", - "line": 463, - "doc": "", - "decorator": "router.post('/requests/{request_id}/artifacts', response_model=ArtifactPlan)", - "errors": [ - "HTTPException(404, 'Records request not found.')", - "HTTPException(400, str(error))" - ] - }, - { - "method": "POST", - "path": "/desktop/v1/requests/{request_id}/artifacts/{artifact_id}/complete", - "router": "router", - "prefix_resolved": true, - "name": "complete_native_artifact", - "signature": "request_id: uuid.UUID, artifact_id: uuid.UUID, data: CompleteArtifact, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", - "returns": "", - "line": 481, - "doc": "", - "decorator": "router.post('/requests/{request_id}/artifacts/{artifact_id}/complete', response_model=RecordsOperationRead)", - "errors": [ - "HTTPException(404, 'Records request not found.')", - "HTTPException(400, str(error))" - ] - }, - { - "method": "POST", - "path": "/desktop/v1/requests", - "router": "router", - "prefix_resolved": true, - "name": "create_native_request", - "signature": "data: StaffRecordsIntake, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", - "returns": "", - "line": 500, - "doc": "", - "decorator": "router.post('/requests', response_model=NativeRequestRead, status_code=201)", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/requests/{request_id}", - "router": "router", - "prefix_resolved": true, - "name": "get_native_request", - "signature": "request_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", - "returns": "", - "line": 521, - "doc": "", - "decorator": "router.get('/requests/{request_id}', response_model=NativeRequestRead)", - "errors": [ - "HTTPException(404, 'Records request not found.')" - ] - }, - { - "method": "GET", - "path": "/desktop/v1/requests/{request_id}/view", - "router": "router", - "prefix_resolved": true, - "name": "get_native_request_view", - "signature": "request_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", - "returns": "", - "line": 537, - "doc": "", - "decorator": "router.get('/requests/{request_id}/view', response_model=RecordsView)", - "errors": [ - "HTTPException(404, 'Records request not found.')" - ] - }, - { - "method": "GET", - "path": "/desktop/v1/requests/{request_id}/draft-context", - "router": "router", - "prefix_resolved": true, - "name": "native_draft_context", - "signature": "request_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", - "returns": "", - "line": 549, - "doc": "", - "decorator": "router.get('/requests/{request_id}/draft-context')", - "errors": [ - "HTTPException(404, 'Records request not found.')", - "HTTPException(400, str(error))" - ] - }, - { - "method": "POST", - "path": "/desktop/v1/requests/{request_id}/generated-draft", - "router": "router", - "prefix_resolved": true, - "name": "native_generated_draft", - "signature": "request_id: uuid.UUID, data: GeneratedDraft, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", - "returns": "", - "line": 575, - "doc": "", - "decorator": "router.post('/requests/{request_id}/generated-draft', response_model=RecordsOperationRead)", - "errors": [ - "HTTPException(404, 'Records request not found.')", - "HTTPException(409, 'The draft changed during generation. Refresh before generating again.')", - "HTTPException(400, str(error))" - ] - }, - { - "method": "POST", - "path": "/desktop/v1/requests/{request_id}/actions", - "router": "router", - "prefix_resolved": true, - "name": "native_request_operation", - "signature": "request_id: uuid.UUID, command: RecordsCommand, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", - "returns": "", - "line": 605, - "doc": "", - "decorator": "router.post('/requests/{request_id}/actions', response_model=RecordsOperationRead)", - "errors": [ - "HTTPException(404, 'Records request not found.')", - "HTTPException(400, str(error))" - ] + "declared_path": "/public/records-state", + "function": "public_records_state", + "line": 135 + }, + { + "method": "POST", + "declared_path": "/public/requests", + "function": "public_records_intake", + "line": 145 + }, + { + "method": "POST", + "declared_path": "/public/lookup", + "function": "public_records_lookup", + "line": 154 + }, + { + "method": "POST", + "declared_path": "/public/messages", + "function": "public_records_message", + "line": 161 + }, + { + "method": "POST", + "declared_path": "/permitting-sources/search", + "function": "search_permitting_sources", + "line": 205 + }, + { + "method": "POST", + "declared_path": "/requests/{request_id}/permitting-sources", + "function": "attach_permitting_source", + "line": 214 + }, + { + "method": "POST", + "declared_path": "/inspections-sources/search", + "function": "search_inspections_sources", + "line": 240 + }, + { + "method": "POST", + "declared_path": "/requests/{request_id}/inspections-sources", + "function": "attach_inspections_source", + "line": 249 + }, + { + "method": "POST", + "declared_path": "/planning-sources/search", + "function": "search_planning_sources", + "line": 275 + }, + { + "method": "POST", + "declared_path": "/requests/{request_id}/planning-sources", + "function": "attach_planning_source", + "line": 284 + }, + { + "method": "POST", + "declared_path": "/zoning-sources/search", + "function": "search_zoning_sources", + "line": 311 + }, + { + "method": "POST", + "declared_path": "/requests/{request_id}/zoning-sources", + "function": "attach_zoning_source", + "line": 320 + }, + { + "method": "GET", + "declared_path": "/records-state", + "function": "get_native_records_state", + "line": 347 + }, + { + "method": "POST", + "declared_path": "/meetings-sources/search", + "function": "search_meetings_sources", + "line": 356 + }, + { + "method": "POST", + "declared_path": "/requests/{request_id}/meetings-sources", + "function": "attach_meetings_source", + "line": 365 + }, + { + "method": "POST", + "declared_path": "/code-sources/search", + "function": "search_code_sources", + "line": 390 + }, + { + "method": "POST", + "declared_path": "/requests/{request_id}/code-sources", + "function": "attach_code_source", + "line": 399 + }, + { + "method": "POST", + "declared_path": "/notifications/{notification_id}/sent", + "function": "mark_native_notification_sent", + "line": 424 + }, + { + "method": "POST", + "declared_path": "/requests/{request_id}/documents", + "function": "attach_native_document", + "line": 444 + }, + { + "method": "POST", + "declared_path": "/requests/{request_id}/documents/{attachment_id}/release-copy", + "function": "attach_native_release_copy", + "line": 454 + }, + { + "method": "POST", + "declared_path": "/requests/{request_id}/artifacts", + "function": "prepare_native_artifact", + "line": 464 + }, + { + "method": "POST", + "declared_path": "/requests/{request_id}/artifacts/{artifact_id}/complete", + "function": "complete_native_artifact", + "line": 482 + }, + { + "method": "POST", + "declared_path": "/requests", + "function": "create_native_request", + "line": 501 + }, + { + "method": "GET", + "declared_path": "/requests/{request_id}", + "function": "get_native_request", + "line": 522 + }, + { + "method": "GET", + "declared_path": "/requests/{request_id}/view", + "function": "get_native_request_view", + "line": 538 + }, + { + "method": "GET", + "declared_path": "/requests/{request_id}/draft-context", + "function": "native_draft_context", + "line": 550 + }, + { + "method": "POST", + "declared_path": "/requests/{request_id}/generated-draft", + "function": "native_generated_draft", + "line": 576 + }, + { + "method": "POST", + "declared_path": "/requests/{request_id}/actions", + "function": "native_request_operation", + "line": 606 } ], "models": [ @@ -8003,11 +7263,10 @@ { "name": "query", "type": "str", - "default": "Field(min_length=1, max_length=500)" + "line": 41 } ], - "line": 38, - "doc": "" + "line": 39 }, { "name": "MeetingsSourceSelection", @@ -8018,16 +7277,15 @@ { "name": "source_id", "type": "str", - "default": "Field(min_length=1, max_length=200)" + "line": 46 }, { "name": "expected_sha256", "type": "str", - "default": "Field(pattern='^[0-9a-f]{64}$')" + "line": 47 } ], - "line": 43, - "doc": "" + "line": 44 }, { "name": "CodeSearch", @@ -8038,16 +7296,15 @@ { "name": "query", "type": "str", - "default": "Field(min_length=1, max_length=500)" + "line": 52 }, { "name": "as_of", "type": "date | None", - "default": "None" + "line": 53 } ], - "line": 49, - "doc": "" + "line": 50 }, { "name": "CodeSourceSelection", @@ -8058,28 +7315,28 @@ { "name": "source_id", "type": "str", - "default": "Field(min_length=1, max_length=200)" + "line": 58 }, { "name": "expected_sha256", "type": "str", - "default": "Field(pattern='^[0-9a-f]{64}$')" + "line": 59 }, { "name": "as_of", "type": "date | None", - "default": "None" + "line": 60 } ], - "line": 55, - "doc": "" + "line": 56 } ], "configuration": [] }, { - "source": "installed-owned-source/app/desktop_bridge/schemas.py", - "sha256": "753dd5474d532912bc50118fe9add74613cbc3b17a062dd93681309ac590926d", + "source": "backend/townlight_records/desktop_bridge/schemas.py", + "sha256": "d7bbbba21363b6b997d92011653010ae9a63c2be0c81844d7527068ac3435237", + "bytes": 13499, "routes": [], "models": [ { @@ -8091,26 +7348,25 @@ { "name": "requester", "type": "str", - "default": "Field(min_length=1)" + "line": 14 }, { "name": "summary", "type": "str", - "default": "Field(min_length=1)" + "line": 15 }, { "name": "deadline", "type": "str", - "default": "" + "line": 16 }, { "name": "deadlineBasis", "type": "str", - "default": "''" + "line": 17 } ], - "line": 10, - "doc": "Existing native create-records-request input; no caller-supplied actor." + "line": 10 }, { "name": "NativeRequestRead", @@ -8121,36 +7377,35 @@ { "name": "desktop_id", "type": "str | None", - "default": "" + "line": 29 }, { "name": "public_tracking_number", "type": "str | None", - "default": "" + "line": 30 }, { "name": "submitted_via", "type": "str", - "default": "" + "line": 31 }, { "name": "deadline_label", "type": "str", - "default": "" + "line": 32 }, { "name": "deadline_basis", "type": "str", - "default": "" + "line": 33 }, { "name": "deadline_reviewed_at", "type": "datetime | None", - "default": "" + "line": 34 } ], - "line": 28, - "doc": "" + "line": 28 }, { "name": "AssignmentPayload", @@ -8161,11 +7416,10 @@ { "name": "assignedTo", "type": "str", - "default": "Field(min_length=1)" + "line": 42 } ], - "line": 41, - "doc": "" + "line": 41 }, { "name": "DeadlinePayload", @@ -8176,16 +7430,15 @@ { "name": "deadline", "type": "str", - "default": "" + "line": 46 }, { "name": "deadlineBasis", "type": "str", - "default": "Field(min_length=1)" + "line": 47 } ], - "line": 45, - "doc": "" + "line": 45 }, { "name": "CalculateDeadlinePayload", @@ -8196,31 +7449,30 @@ { "name": "deadlineReceivedDate", "type": "str", - "default": "" + "line": 53 }, { "name": "deadlineRuleName", "type": "str", - "default": "Field(min_length=1)" + "line": 54 }, { "name": "deadlineDayCount", "type": "str", - "default": "" + "line": 55 }, { "name": "deadlineDayType", "type": "str", - "default": "" + "line": 56 }, { "name": "deadlineBasis", "type": "str", - "default": "Field(min_length=1)" + "line": 57 } ], - "line": 52, - "doc": "" + "line": 52 }, { "name": "ClarificationPayload", @@ -8231,11 +7483,10 @@ { "name": "clarificationNote", "type": "str", - "default": "Field(min_length=1)" + "line": 78 } ], - "line": 77, - "doc": "" + "line": 77 }, { "name": "MessagePayload", @@ -8246,11 +7497,10 @@ { "name": "requestMessageBody", "type": "str", - "default": "Field(min_length=1)" + "line": 82 } ], - "line": 81, - "doc": "" + "line": 81 }, { "name": "SearchNotePayload", @@ -8261,16 +7511,15 @@ { "name": "sourceNote", "type": "str", - "default": "Field(min_length=1)" + "line": 86 }, { "name": "citation", "type": "str", - "default": "''" + "line": 87 } ], - "line": 85, - "doc": "" + "line": 85 }, { "name": "SearchReceiptPayload", @@ -8281,41 +7530,40 @@ { "name": "searchQuery", "type": "str", - "default": "Field(min_length=1)" + "line": 91 }, { "name": "searchLocations", "type": "str", - "default": "Field(min_length=1)" + "line": 92 }, { "name": "searchResultTitle", "type": "str", - "default": "Field(min_length=1)" + "line": 93 }, { "name": "searchResultCitation", "type": "str", - "default": "Field(min_length=1)" + "line": 94 }, { "name": "searchResultSummary", "type": "str", - "default": "Field(min_length=1)" + "line": 95 }, { "name": "searchResultStatus", "type": "str", - "default": "''" + "line": 96 }, { "name": "searchReviewer", "type": "str", - "default": "''" + "line": 97 } ], - "line": 90, - "doc": "" + "line": 90 }, { "name": "ExemptionNotePayload", @@ -8326,11 +7574,10 @@ { "name": "exemptionNote", "type": "str", - "default": "Field(min_length=1)" + "line": 101 } ], - "line": 100, - "doc": "" + "line": 100 }, { "name": "ExemptionDecisionPayload", @@ -8341,36 +7588,35 @@ { "name": "exemptionSource", "type": "str", - "default": "Field(min_length=1)" + "line": 105 }, { "name": "exemptionKind", "type": "str", - "default": "Field(min_length=1)" + "line": 106 }, { "name": "exemptionFinding", "type": "str", - "default": "Field(min_length=1)" + "line": 107 }, { "name": "exemptionDecision", "type": "Literal['release', 'redact', 'exempt']", - "default": "" + "line": 108 }, { "name": "exemptionBasis", "type": "str", - "default": "Field(min_length=1)" + "line": 109 }, { "name": "exemptionReviewer", "type": "str", - "default": "''" + "line": 110 } ], - "line": 104, - "doc": "" + "line": 104 }, { "name": "FeeEstimatePayload", @@ -8381,11 +7627,10 @@ { "name": "feeEstimate", "type": "str", - "default": "Field(min_length=1)" + "line": 119 } ], - "line": 118, - "doc": "" + "line": 118 }, { "name": "FeeLinePayload", @@ -8396,21 +7641,20 @@ { "name": "feeLineDescription", "type": "str", - "default": "Field(min_length=1)" + "line": 123 }, { "name": "feeScheduleBasis", "type": "str", - "default": "Field(min_length=1)" + "line": 124 }, { "name": "feeLineAmount", "type": "str", - "default": "" + "line": 125 } ], - "line": 122, - "doc": "" + "line": 122 }, { "name": "FeeWaiverPayload", @@ -8421,11 +7665,10 @@ { "name": "feeWaiverReason", "type": "str", - "default": "Field(min_length=1)" + "line": 141 } ], - "line": 140, - "doc": "" + "line": 140 }, { "name": "DraftPayload", @@ -8436,16 +7679,15 @@ { "name": "responseDraft", "type": "str", - "default": "Field(min_length=1)" + "line": 145 }, { "name": "citation", "type": "str", - "default": "''" + "line": 146 } ], - "line": 144, - "doc": "" + "line": 144 }, { "name": "ApprovalPayload", @@ -8456,11 +7698,10 @@ { "name": "approvalNote", "type": "str", - "default": "''" + "line": 150 } ], - "line": 149, - "doc": "" + "line": 149 }, { "name": "AssignCommand", @@ -8471,16 +7712,15 @@ { "name": "action", "type": "Literal['assign-records-request']", - "default": "" + "line": 154 }, { "name": "payload", "type": "AssignmentPayload", - "default": "" + "line": 155 } ], - "line": 153, - "doc": "" + "line": 153 }, { "name": "DeadlineCommand", @@ -8491,16 +7731,15 @@ { "name": "action", "type": "Literal['set-records-deadline']", - "default": "" + "line": 159 }, { "name": "payload", "type": "DeadlinePayload", - "default": "" + "line": 160 } ], - "line": 158, - "doc": "" + "line": 158 }, { "name": "CalculateDeadlineCommand", @@ -8511,16 +7750,15 @@ { "name": "action", "type": "Literal['calculate-records-deadline']", - "default": "" + "line": 164 }, { "name": "payload", "type": "CalculateDeadlinePayload", - "default": "" + "line": 165 } ], - "line": 163, - "doc": "" + "line": 163 }, { "name": "ClarificationCommand", @@ -8531,16 +7769,15 @@ { "name": "action", "type": "Literal['request-records-clarification']", - "default": "" + "line": 169 }, { "name": "payload", "type": "ClarificationPayload", - "default": "" + "line": 170 } ], - "line": 168, - "doc": "" + "line": 168 }, { "name": "MessageCommand", @@ -8551,16 +7788,15 @@ { "name": "action", "type": "Literal['add-records-message']", - "default": "" + "line": 174 }, { "name": "payload", "type": "MessagePayload", - "default": "" + "line": 175 } ], - "line": 173, - "doc": "" + "line": 173 }, { "name": "SearchNoteCommand", @@ -8571,16 +7807,15 @@ { "name": "action", "type": "Literal['record-records-search']", - "default": "" + "line": 179 }, { "name": "payload", "type": "SearchNotePayload", - "default": "" + "line": 180 } ], - "line": 178, - "doc": "" + "line": 178 }, { "name": "SearchReceiptCommand", @@ -8591,16 +7826,15 @@ { "name": "action", "type": "Literal['record-records-search-session']", - "default": "" + "line": 184 }, { "name": "payload", "type": "SearchReceiptPayload", - "default": "" + "line": 185 } ], - "line": 183, - "doc": "" + "line": 183 }, { "name": "ExemptionNoteCommand", @@ -8611,16 +7845,15 @@ { "name": "action", "type": "Literal['add-records-exemption-review']", - "default": "" + "line": 189 }, { "name": "payload", "type": "ExemptionNotePayload", - "default": "" + "line": 190 } ], - "line": 188, - "doc": "" + "line": 188 }, { "name": "ExemptionDecisionCommand", @@ -8631,16 +7864,15 @@ { "name": "action", "type": "Literal['add-records-exemption-decision']", - "default": "" + "line": 194 }, { "name": "payload", "type": "ExemptionDecisionPayload", - "default": "" + "line": 195 } ], - "line": 193, - "doc": "" + "line": 193 }, { "name": "FeeEstimateCommand", @@ -8651,16 +7883,15 @@ { "name": "action", "type": "Literal['estimate-records-fee']", - "default": "" + "line": 199 }, { "name": "payload", "type": "FeeEstimatePayload", - "default": "" + "line": 200 } ], - "line": 198, - "doc": "" + "line": 198 }, { "name": "FeeLineCommand", @@ -8671,16 +7902,15 @@ { "name": "action", "type": "Literal['add-records-fee-line']", - "default": "" + "line": 204 }, { "name": "payload", "type": "FeeLinePayload", - "default": "" + "line": 205 } ], - "line": 203, - "doc": "" + "line": 203 }, { "name": "FeeWaiverCommand", @@ -8691,16 +7921,15 @@ { "name": "action", "type": "Literal['waive-records-fee']", - "default": "" + "line": 209 }, { "name": "payload", "type": "FeeWaiverPayload", - "default": "" + "line": 210 } ], - "line": 208, - "doc": "" + "line": 208 }, { "name": "DraftCommand", @@ -8711,16 +7940,15 @@ { "name": "action", "type": "Literal['draft-records-response']", - "default": "" + "line": 214 }, { "name": "payload", "type": "DraftPayload", - "default": "" + "line": 215 } ], - "line": 213, - "doc": "" + "line": 213 }, { "name": "ApprovalCommand", @@ -8731,16 +7959,15 @@ { "name": "action", "type": "Literal['approve-records-response']", - "default": "" + "line": 219 }, { "name": "payload", "type": "ApprovalPayload", - "default": "Field(default_factory=ApprovalPayload)" + "line": 220 } ], - "line": 218, - "doc": "" + "line": 218 }, { "name": "FinishCommand", @@ -8751,16 +7978,15 @@ { "name": "action", "type": "Literal['fulfill-records-request', 'close-records-request']", - "default": "" + "line": 224 }, { "name": "payload", "type": "NativePayload", - "default": "Field(default_factory=NativePayload)" + "line": 225 } ], - "line": 223, - "doc": "" + "line": 223 }, { "name": "TimelineView", @@ -8771,31 +7997,30 @@ { "name": "id", "type": "str", - "default": "" + "line": 242 }, { "name": "action", "type": "str", - "default": "" + "line": 243 }, { "name": "actor", "type": "str", - "default": "" + "line": 244 }, { "name": "note", "type": "str", - "default": "" + "line": 245 }, { "name": "created_at_unix_seconds", "type": "int", - "default": "" + "line": 246 } ], - "line": 241, - "doc": "" + "line": 241 }, { "name": "PublicStatusView", @@ -8806,31 +8031,30 @@ { "name": "id", "type": "str", - "default": "" + "line": 250 }, { "name": "label", "type": "str", - "default": "" + "line": 251 }, { "name": "summary", "type": "str", - "default": "" + "line": 252 }, { "name": "status", "type": "str", - "default": "" + "line": 253 }, { "name": "created_at_unix_seconds", "type": "int", - "default": "" + "line": 254 } ], - "line": 249, - "doc": "" + "line": 249 }, { "name": "MessageView", @@ -8841,36 +8065,35 @@ { "name": "id", "type": "str", - "default": "" + "line": 258 }, { "name": "author", "type": "str", - "default": "" + "line": 259 }, { "name": "author_role", "type": "str", - "default": "" + "line": 260 }, { "name": "body", "type": "str", - "default": "" + "line": 261 }, { "name": "visibility", "type": "str", - "default": "" + "line": 262 }, { "name": "created_at_unix_seconds", "type": "int", - "default": "" + "line": 263 } ], - "line": 257, - "doc": "" + "line": 257 }, { "name": "FeeLineView", @@ -8881,31 +8104,30 @@ { "name": "id", "type": "str", - "default": "" + "line": 267 }, { "name": "description", "type": "str", - "default": "" + "line": 268 }, { "name": "schedule_basis", "type": "str", - "default": "" + "line": 269 }, { "name": "amount_cents", "type": "int", - "default": "" + "line": 270 }, { "name": "created_at_unix_seconds", "type": "int", - "default": "" + "line": 271 } ], - "line": 266, - "doc": "" + "line": 266 }, { "name": "ExemptionDecisionView", @@ -8916,46 +8138,45 @@ { "name": "id", "type": "str", - "default": "" + "line": 275 }, { "name": "source", "type": "str", - "default": "" + "line": 276 }, { "name": "kind", "type": "str", - "default": "" + "line": 277 }, { "name": "finding", "type": "str", - "default": "" + "line": 278 }, { "name": "decision", "type": "Literal['release', 'redact', 'exempt']", - "default": "" + "line": 279 }, { "name": "basis", "type": "str", - "default": "" + "line": 280 }, { "name": "reviewer", "type": "str", - "default": "" + "line": 281 }, { "name": "created_at_unix_seconds", "type": "int", - "default": "" + "line": 282 } ], - "line": 274, - "doc": "" + "line": 274 }, { "name": "SearchResultView", @@ -8966,31 +8187,30 @@ { "name": "id", "type": "str", - "default": "" + "line": 286 }, { "name": "title", "type": "str", - "default": "" + "line": 287 }, { "name": "citation", "type": "str", - "default": "" + "line": 288 }, { "name": "summary", "type": "str", - "default": "" + "line": 289 }, { "name": "status", "type": "str", - "default": "" + "line": 290 } ], - "line": 285, - "doc": "" + "line": 285 }, { "name": "SearchReceiptView", @@ -9001,36 +8221,35 @@ { "name": "id", "type": "str", - "default": "" + "line": 294 }, { "name": "query", "type": "str", - "default": "" + "line": 295 }, { "name": "locations", "type": "str", - "default": "" + "line": 296 }, { "name": "reviewer", "type": "str", - "default": "" + "line": 297 }, { "name": "results", "type": "list[SearchResultView]", - "default": "" + "line": 298 }, { "name": "created_at_unix_seconds", "type": "int", - "default": "" + "line": 299 } ], - "line": 293, - "doc": "" + "line": 293 }, { "name": "RecordsView", @@ -9041,171 +8260,170 @@ { "name": "request_id", "type": "str", - "default": "" + "line": 304 }, { "name": "id", "type": "str", - "default": "" + "line": 305 }, { "name": "public_tracking_number", "type": "str", - "default": "" + "line": 306 }, { "name": "requester", "type": "str", - "default": "" + "line": 307 }, { "name": "requester_contact", "type": "str", - "default": "" + "line": 308 }, { "name": "submitted_via", "type": "str", - "default": "" + "line": 309 }, { "name": "summary", "type": "str", - "default": "" + "line": 310 }, { "name": "deadline", "type": "str", - "default": "" + "line": 311 }, { "name": "deadline_basis", "type": "str", - "default": "" + "line": 312 }, { "name": "status", "type": "str", - "default": "" + "line": 313 }, { "name": "assigned_to", "type": "str", - "default": "" + "line": 314 }, { "name": "clarification_notes", "type": "list[str]", - "default": "" + "line": 315 }, { "name": "search_notes", "type": "list[str]", - "default": "" + "line": 316 }, { "name": "search_sessions", "type": "list[SearchReceiptView]", - "default": "" + "line": 317 }, { "name": "exemption_reviews", "type": "list[str]", - "default": "" + "line": 318 }, { "name": "exemption_decisions", "type": "list[ExemptionDecisionView]", - "default": "" + "line": 319 }, { "name": "fee_estimate", "type": "str", - "default": "" + "line": 320 }, { "name": "fee_line_items", "type": "list[FeeLineView]", - "default": "" + "line": 321 }, { "name": "fee_waiver_reason", "type": "str", - "default": "" + "line": 322 }, { "name": "citations", "type": "list[str]", - "default": "" + "line": 323 }, { "name": "response_draft", "type": "str", - "default": "" + "line": 324 }, { "name": "approval_notes", "type": "list[str]", - "default": "" + "line": 325 }, { "name": "exports", "type": "list[str]", - "default": "" + "line": 326 }, { "name": "documents", "type": "list['RecordsDocumentView']", - "default": "Field(default_factory=list)" + "line": 327 }, { "name": "release_packages", "type": "list['ReleasePackageView']", - "default": "Field(default_factory=list)" + "line": 328 }, { "name": "timeline", "type": "list[TimelineView]", - "default": "" + "line": 329 }, { "name": "public_status_events", "type": "list[PublicStatusView]", - "default": "" + "line": 330 }, { "name": "messages", "type": "list[MessageView]", - "default": "" + "line": 331 }, { "name": "deadline_reviewed_at_unix_seconds", "type": "int | None", - "default": "" + "line": 332 }, { "name": "approved_at_unix_seconds", "type": "int | None", - "default": "" + "line": 333 }, { "name": "fulfilled_at_unix_seconds", "type": "int | None", - "default": "" + "line": 334 }, { "name": "closed_at_unix_seconds", "type": "int | None", - "default": "" + "line": 335 }, { "name": "created_at_unix_seconds", "type": "int", - "default": "" + "line": 336 } ], - "line": 302, - "doc": "" + "line": 302 }, { "name": "RecordsOperationRead", @@ -9216,21 +8434,20 @@ { "name": "action", "type": "str", - "default": "" + "line": 340 }, { "name": "message", "type": "str", - "default": "" + "line": 341 }, { "name": "request", "type": "RecordsView", - "default": "" + "line": 342 } ], - "line": 339, - "doc": "" + "line": 339 }, { "name": "RecordsStateRead", @@ -9241,31 +8458,30 @@ { "name": "demo_fixture", "type": "dict | None", - "default": "None" + "line": 346 }, { "name": "records_requests", "type": "list[RecordsView]", - "default": "" + "line": 347 }, { "name": "notification_events", "type": "list['NotificationView']", - "default": "Field(default_factory=list)" + "line": 348 }, { "name": "publication_events", "type": "list['PublicationView']", - "default": "Field(default_factory=list)" + "line": 349 }, { "name": "audit_entries", "type": "list['AuditView']", - "default": "Field(default_factory=list)" + "line": 350 } ], - "line": 345, - "doc": "" + "line": 345 }, { "name": "ManagedFileReceipt", @@ -9276,31 +8492,30 @@ { "name": "original_path", "type": "str", - "default": "Field(min_length=1)" + "line": 354 }, { "name": "stored_path", "type": "str", - "default": "Field(min_length=1)" + "line": 355 }, { "name": "file_name", "type": "str", - "default": "Field(min_length=1, max_length=500)" + "line": 356 }, { "name": "sha256", "type": "str", - "default": "Field(pattern='^[0-9a-f]{64}$')" + "line": 357 }, { "name": "size_bytes", "type": "int", - "default": "Field(ge=0, le=2147483647, strict=True)" + "line": 358 } ], - "line": 353, - "doc": "" + "line": 353 }, { "name": "AttachDocument", @@ -9311,21 +8526,20 @@ { "name": "title", "type": "str", - "default": "Field(min_length=1)" + "line": 362 }, { "name": "citation", "type": "str", - "default": "''" + "line": 363 }, { "name": "file", "type": "ManagedFileReceipt", - "default": "" + "line": 364 } ], - "line": 361, - "doc": "" + "line": 361 }, { "name": "AttachReleaseCopy", @@ -9336,26 +8550,25 @@ { "name": "status", "type": "Literal['release-ready copy', 'redacted copy']", - "default": "" + "line": 368 }, { "name": "note", "type": "str", - "default": "''" + "line": 369 }, { "name": "added_by", "type": "str", - "default": "''" + "line": 370 }, { "name": "file", "type": "ManagedFileReceipt", - "default": "" + "line": 371 } ], - "line": 367, - "doc": "" + "line": 367 }, { "name": "RecordsDocumentView", @@ -9366,106 +8579,105 @@ { "name": "id", "type": "str", - "default": "" + "line": 375 }, { "name": "attachment_id", "type": "str", - "default": "" + "line": 376 }, { "name": "title", "type": "str", - "default": "" + "line": 377 }, { "name": "original_path", "type": "str", - "default": "" + "line": 378 }, { "name": "stored_path", "type": "str", - "default": "" + "line": 379 }, { "name": "citation", "type": "str", - "default": "" + "line": 380 }, { "name": "sha256", "type": "str", - "default": "" + "line": 381 }, { "name": "size_bytes", "type": "int", - "default": "" + "line": 382 }, { "name": "status", "type": "str", - "default": "" + "line": 383 }, { "name": "added_by", "type": "str", - "default": "" + "line": 384 }, { "name": "created_at_unix_seconds", "type": "int", - "default": "" + "line": 385 }, { "name": "release_original_path", "type": "str", - "default": "''" + "line": 386 }, { "name": "release_stored_path", "type": "str", - "default": "''" + "line": 387 }, { "name": "release_file_name", "type": "str", - "default": "''" + "line": 388 }, { "name": "release_sha256", "type": "str", - "default": "''" + "line": 389 }, { "name": "release_size_bytes", "type": "int", - "default": "0" + "line": 390 }, { "name": "release_status", "type": "str", - "default": "''" + "line": 391 }, { "name": "release_note", "type": "str", - "default": "''" + "line": 392 }, { "name": "release_added_by", "type": "str", - "default": "''" + "line": 393 }, { "name": "release_added_at_unix_seconds", "type": "int | None", - "default": "None" + "line": 394 } ], - "line": 374, - "doc": "" + "line": 374 }, { "name": "ReleasePackageView", @@ -9476,56 +8688,55 @@ { "name": "id", "type": "str", - "default": "" + "line": 398 }, { "name": "export_path", "type": "str", - "default": "" + "line": 399 }, { "name": "package_hash", "type": "str", - "default": "" + "line": 400 }, { "name": "document_count", "type": "int", - "default": "" + "line": 401 }, { "name": "release_artifact_count", "type": "int", - "default": "" + "line": 402 }, { "name": "search_session_count", "type": "int", - "default": "" + "line": 403 }, { "name": "release_count", "type": "int", - "default": "" + "line": 404 }, { "name": "redacted_count", "type": "int", - "default": "" + "line": 405 }, { "name": "exempt_count", "type": "int", - "default": "" + "line": 406 }, { "name": "created_at_unix_seconds", "type": "int", - "default": "" + "line": 407 } ], - "line": 397, - "doc": "" + "line": 397 }, { "name": "PrepareArtifact", @@ -9536,11 +8747,10 @@ { "name": "kind", "type": "Literal['response', 'release-package']", - "default": "" + "line": 411 } ], - "line": 410, - "doc": "" + "line": 410 }, { "name": "ArtifactPlan", @@ -9551,31 +8761,30 @@ { "name": "artifact_id", "type": "str", - "default": "" + "line": 415 }, { "name": "file_name", "type": "str", - "default": "" + "line": 416 }, { "name": "content", "type": "str", - "default": "" + "line": 417 }, { "name": "sha256", "type": "str", - "default": "" + "line": 418 }, { "name": "created_at_unix_seconds", "type": "int", - "default": "" + "line": 419 } ], - "line": 414, - "doc": "" + "line": 414 }, { "name": "CompleteArtifact", @@ -9586,11 +8795,10 @@ { "name": "export_path", "type": "str", - "default": "Field(min_length=1)" + "line": 423 } ], - "line": 422, - "doc": "" + "line": 422 }, { "name": "PublicIntake", @@ -9601,26 +8809,25 @@ { "name": "requester", "type": "str", - "default": "Field(min_length=1)" + "line": 427 }, { "name": "requesterContact", "type": "str", - "default": "Field(min_length=1)" + "line": 428 }, { "name": "summary", "type": "str", - "default": "Field(min_length=1)" + "line": 429 }, { "name": "deadline", "type": "str", - "default": "''" + "line": 430 } ], - "line": 426, - "doc": "" + "line": 426 }, { "name": "PublicLookup", @@ -9631,16 +8838,15 @@ { "name": "trackingNumber", "type": "str", - "default": "Field(min_length=1)" + "line": 434 }, { "name": "requesterContact", "type": "str", - "default": "Field(min_length=1)" + "line": 435 } ], - "line": 433, - "doc": "" + "line": 433 }, { "name": "PublicMessage", @@ -9651,11 +8857,10 @@ { "name": "publicRequestMessage", "type": "str", - "default": "Field(min_length=1)" + "line": 439 } ], - "line": 438, - "doc": "" + "line": 438 }, { "name": "GeneratedDraft", @@ -9666,21 +8871,20 @@ { "name": "text", "type": "str", - "default": "Field(min_length=1)" + "line": 443 }, { "name": "model", "type": "str", - "default": "Field(min_length=1)" + "line": 444 }, { "name": "previous_response_sha256", "type": "str", - "default": "Field(pattern='^[0-9a-f]{64}$')" + "line": 445 } ], - "line": 442, - "doc": "" + "line": 442 }, { "name": "NotificationView", @@ -9691,61 +8895,60 @@ { "name": "id", "type": "str", - "default": "" + "line": 449 }, { "name": "notification_id", "type": "str", - "default": "" + "line": 450 }, { "name": "module_id", "type": "str", - "default": "" + "line": 451 }, { "name": "record_id", "type": "str", - "default": "" + "line": 452 }, { "name": "audience", "type": "str", - "default": "" + "line": 453 }, { "name": "channel", "type": "str", - "default": "" + "line": 454 }, { "name": "subject", "type": "str", - "default": "" + "line": 455 }, { "name": "body", "type": "str", - "default": "" + "line": 456 }, { "name": "status", "type": "str", - "default": "" + "line": 457 }, { "name": "created_at_unix_seconds", "type": "int", - "default": "" + "line": 458 }, { "name": "sent_at_unix_seconds", "type": "int | None", - "default": "" + "line": 459 } ], - "line": 448, - "doc": "" + "line": 448 }, { "name": "PublicationView", @@ -9756,51 +8959,50 @@ { "name": "id", "type": "str", - "default": "" + "line": 463 }, { "name": "source_module", "type": "str", - "default": "" + "line": 464 }, { "name": "source_record_id", "type": "str", - "default": "" + "line": 465 }, { "name": "record_type", "type": "str", - "default": "" + "line": 466 }, { "name": "public_payload", "type": "str", - "default": "" + "line": 467 }, { "name": "payload_hash", "type": "str", - "default": "" + "line": 468 }, { "name": "published_at_unix_seconds", "type": "int", - "default": "" + "line": 469 }, { "name": "retracted_at_unix_seconds", "type": "int | None", - "default": "None" + "line": 470 }, { "name": "retracted_by", "type": "str", - "default": "''" + "line": 471 } ], - "line": 462, - "doc": "" + "line": 462 }, { "name": "AuditView", @@ -9811,83 +9013,60 @@ { "name": "id", "type": "str", - "default": "" + "line": 475 }, { "name": "module_id", "type": "str", - "default": "" + "line": 476 }, { "name": "action", "type": "str", - "default": "" + "line": 477 }, { "name": "summary", "type": "str", - "default": "" + "line": 478 }, { "name": "created_at_unix_seconds", "type": "int", - "default": "" + "line": 479 }, { "name": "previous_hash", "type": "str", - "default": "" + "line": 480 }, { "name": "entry_hash", "type": "str", - "default": "" + "line": 481 } ], - "line": 474, - "doc": "" + "line": 474 } ], "configuration": [] }, { - "source": "installed-owned-source/app/desktop_bridge/station.py", - "sha256": "2f53398b6a897f804419ea5025895bb7dc468d8891dc553b20bb14cb5d0a8084", + "source": "backend/townlight_records/desktop_bridge/station.py", + "sha256": "4cdb8465053f61d2e63477a028b880d3524e4e37da0d99781ca88d616cc0b1b1", + "bytes": 9588, "routes": [ { "method": "GET", - "path": "/station/context", - "router": "router", - "prefix_resolved": false, - "name": "context", - "signature": "request: Request, capability: Literal['capture', 'read'], proof: str | None=Header(default=None, alias='X-Townlight-Session'), session: AsyncSession=Depends(get_async_session)", - "returns": "", - "line": 43, - "doc": "", - "decorator": "router.get('/station/context')", - "errors": [ - "HTTPException(403, 'This staff role cannot perform this Station operation')", - "HTTPException(401, str(exc))" - ] - }, - { - "method": "POST", - "path": "/requests/{request_id}/station-recordings", - "router": "router", - "prefix_resolved": false, - "name": "attach", - "signature": "request_id: UUID, data: Selection, request: Request, actor=Depends(station_actor), session: AsyncSession=Depends(get_async_session)", - "returns": "", - "line": 79, - "doc": "", - "decorator": "router.post('/requests/{request_id}/station-recordings', response_model=RecordsOperationRead)", - "errors": [ - "HTTPException(404, 'Records request not found')", - "HTTPException(409, str(exc))", - "HTTPException(422, 'Station evidence not attached; existing evidence preserved')", - "HTTPException(response.status_code, 'Station denied this recording')", - "HTTPException(409, 'Station recording is incomplete or changed; refresh selection')" - ] + "declared_path": "/station/context", + "function": "context", + "line": 43 + }, + { + "method": "POST", + "declared_path": "/requests/{request_id}/station-recordings", + "function": "attach", + "line": 79 } ], "models": [ @@ -9900,348 +9079,201 @@ { "name": "recording_id", "type": "UUID", - "default": "" + "line": 63 }, { "name": "expected_sha256", "type": "str", - "default": "Field(pattern='^[0-9a-f]{64}$')" + "line": 64 } ], - "line": 61, - "doc": "" + "line": 61 } ], "configuration": [ { - "variable": "TOWNLIGHT_STATION_URL", - "default": "''", + "environment": "TOWNLIGHT_STATION_URL", "line": 33 } ] }, { - "source": "installed-owned-source/app/documents/__init__.py", - "sha256": "2795a0001b651166674cb0b501f64e0030e84816d5b4335f3189529510e2b10b", + "source": "backend/townlight_records/documents/__init__.py", + "sha256": "74e2f6fddd8fadac3833b72a02396e5cb3c4d3d91211437e23005ecd24de61f0", + "bytes": 107, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/documents/router.py", - "sha256": "12c9facd2481a2294883f665516bd5e0bf3a487ee76c7eb747eb4b95aa80fefe", + "source": "backend/townlight_records/documents/router.py", + "sha256": "ade31f62c2483692bde64f5d009ba855d91fec8d34fbb5da9846d9689cd2d312", + "bytes": 3661, "routes": [ { "method": "GET", - "path": "/documents/", - "router": "router", - "prefix_resolved": true, - "name": "list_documents", - "signature": "source_id: uuid.UUID | None=None, status: IngestionStatus | None=None, limit: int=Query(default=50, le=500), offset: int=0, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 31, - "doc": "", - "decorator": "router.get('/', response_model=list[DocumentRead])", - "errors": [] + "declared_path": "/", + "function": "list_documents", + "line": 31 }, { "method": "GET", - "path": "/documents/{document_id}", - "router": "router", - "prefix_resolved": true, - "name": "get_document", - "signature": "document_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 47, - "doc": "", - "decorator": "router.get('/{document_id}', response_model=DocumentRead)", - "errors": [ - "HTTPException(status_code=404, detail='Document not found')" - ] + "declared_path": "/{document_id}", + "function": "get_document", + "line": 47 }, { "method": "GET", - "path": "/documents/{document_id}/chunks", - "router": "router", - "prefix_resolved": true, - "name": "list_chunks", - "signature": "document_id: uuid.UUID, limit: int=Query(default=50, le=500), offset: int=0, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 57, - "doc": "", - "decorator": "router.get('/{document_id}/chunks', response_model=list[DocumentChunkRead])", - "errors": [ - "HTTPException(status_code=404, detail='Document not found')" - ] + "declared_path": "/{document_id}/chunks", + "function": "list_chunks", + "line": 57 } ], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/exemptions/__init__.py", + "source": "backend/townlight_records/exemptions/__init__.py", "sha256": "2fd238ebecb0a427697f59094dad0d088962ebe3029a8a540d14957160714341", + "bytes": 30, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/exemptions/engine.py", - "sha256": "56001a7259c4ca1a206ee528ceced69bd2764534133db61b9fcf5d01a26a8253", + "source": "backend/townlight_records/exemptions/engine.py", + "sha256": "30b4bf307d9572b2c56492d6e3485dc8db083df47f20ef66d738cd3d01394e3b", + "bytes": 3197, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/exemptions/llm_reviewer.py", - "sha256": "ab13ae2f8dde8c66debff2f9276787887524f7bf785833fcddc569816b1be8b4", + "source": "backend/townlight_records/exemptions/llm_reviewer.py", + "sha256": "7af32fc1ed813d1ca2781261840b2004a5f7b641313fe93690e41ac7415a3cda", + "bytes": 2412, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/exemptions/patterns.py", - "sha256": "364df5cffdccda747ecbf9d69775f0cce92610c6b253b5b78b91a0ac409ef9eb", + "source": "backend/townlight_records/exemptions/patterns.py", + "sha256": "5f5ac114245cf4654be3361430d04f868be5ece128e07f15899d25c40eec3cb3", + "bytes": 600, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/exemptions/router.py", - "sha256": "4c35393f13a282194f4225b02e7b6d233b6e9b979371d6e318c7e5ed1df97dca", + "source": "backend/townlight_records/exemptions/router.py", + "sha256": "dc0cb9be6e398cba564196759232160ac1ccdb487163c0802e5eadf3201bd67d", + "bytes": 23419, "routes": [ { "method": "POST", - "path": "/exemptions/rules/", - "router": "router", - "prefix_resolved": true, - "name": "create_rule", - "signature": "data: ExemptionRuleCreate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 34, - "doc": "", - "decorator": "router.post('/rules/', response_model=ExemptionRuleRead, status_code=201)", - "errors": [] + "declared_path": "/rules/", + "function": "create_rule", + "line": 34 }, { "method": "GET", - "path": "/exemptions/rules/", - "router": "router", - "prefix_resolved": true, - "name": "list_rules", - "signature": "state_code: str | None=None, enabled: bool | None=None, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 61, - "doc": "", - "decorator": "router.get('/rules/', response_model=list[ExemptionRuleRead])", - "errors": [] + "declared_path": "/rules/", + "function": "list_rules", + "line": 61 }, { "method": "PATCH", - "path": "/exemptions/rules/{rule_id}", - "router": "router", - "prefix_resolved": true, - "name": "update_rule", - "signature": "rule_id: uuid.UUID, data: ExemptionRuleUpdate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 77, - "doc": "", - "decorator": "router.patch('/rules/{rule_id}', response_model=ExemptionRuleRead)", - "errors": [ - "HTTPException(status_code=404, detail='Rule not found')" - ] - }, - { - "method": "GET", - "path": "/exemptions/rules/{rule_id}/history", - "router": "router", - "prefix_resolved": true, - "name": "get_rule_history", - "signature": "rule_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 109, - "doc": "Get audit history for an exemption rule.", - "decorator": "router.get('/rules/{rule_id}/history')", - "errors": [ - "HTTPException(status_code=404, detail='Rule not found')" - ] - }, - { - "method": "POST", - "path": "/exemptions/rules/{rule_id}/test", - "router": "router", - "prefix_resolved": true, - "name": "test_rule", - "signature": "rule_id: uuid.UUID, body: RuleTestRequest, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 162, - "doc": "Test a rule against sample text. Returns match results.\n\nUses the `regex` library with timeout=2s to prevent ReDoS on\nadmin-entered patterns.", - "decorator": "router.post('/rules/{rule_id}/test', response_model=RuleTestResponse)", - "errors": [ - "HTTPException(status_code=404, detail='Rule not found')", - "HTTPException(status_code=422, detail=f'Invalid regex pattern: {e}')", - "HTTPException(status_code=408, detail='Regex execution timed out (possible catastrophic backtracking)')", - "HTTPException(status_code=400, detail='LLM-based rules cannot be tested with sample text \u2014 they require full document context.')" - ] - }, - { - "method": "POST", - "path": "/exemptions/scan/{request_id}", - "router": "router", - "prefix_resolved": true, - "name": "scan_for_exemptions", - "signature": "request_id: uuid.UUID, state_code: str=Query(default='CO', pattern='^[A-Z]{2}$'), use_llm: bool=False, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 228, - "doc": "Scan all documents attached to a request for exemptions.", - "decorator": "router.post('/scan/{request_id}')", - "errors": [ - "HTTPException(status_code=404, detail='Request not found')", - "HTTPException(status_code=422, detail=f'Scan incomplete: {exc}')" - ] - }, - { - "method": "GET", - "path": "/exemptions/flags/{request_id}", - "router": "router", - "prefix_resolved": true, - "name": "list_flags", - "signature": "request_id: uuid.UUID, status: FlagStatus | None=None, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 300, - "doc": "", - "decorator": "router.get('/flags/{request_id}', response_model=list[ExemptionFlagRead])", - "errors": [ - "HTTPException(status_code=404, detail='Request not found')" - ] + "declared_path": "/rules/{rule_id}", + "function": "update_rule", + "line": 77 }, { - "method": "PATCH", - "path": "/exemptions/flags/{flag_id}", - "router": "router", - "prefix_resolved": true, - "name": "review_flag", - "signature": "flag_id: uuid.UUID, data: ExemptionFlagReview, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 321, - "doc": "", - "decorator": "router.patch('/flags/{flag_id}', response_model=ExemptionFlagRead)", - "errors": [ - "HTTPException(status_code=404, detail='Flag not found')", - "HTTPException(status_code=400, detail='Status must be accepted, rejected, or reviewed')" - ] - }, - { - "method": "GET", - "path": "/exemptions/dashboard/accuracy", - "router": "router", - "prefix_resolved": true, - "name": "exemption_accuracy", - "signature": "department_id: uuid.UUID | None=None, date_from: datetime | None=None, date_to: datetime | None=None, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 365, - "doc": "Acceptance/rejection rates by category, optionally filtered by department.", - "decorator": "router.get('/dashboard/accuracy', response_model=list[ExemptionAccuracyReport])", - "errors": [] - }, - { - "method": "GET", - "path": "/exemptions/dashboard/export", - "router": "router", - "prefix_resolved": true, - "name": "export_flag_data", - "signature": "format: str='json', date_from: datetime | None=None, date_to: datetime | None=None, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 423, - "doc": "Export exemption flag data as JSON or CSV.", - "decorator": "router.get('/dashboard/export')", - "errors": [] - }, - { - "method": "GET", - "path": "/exemptions/dashboard", - "router": "router", - "prefix_resolved": true, - "name": "exemption_dashboard", - "signature": "session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 480, - "doc": "", - "decorator": "router.get('/dashboard', response_model=ExemptionDashboard)", - "errors": [] - }, - { - "method": "GET", - "path": "/exemptions/templates/", - "router": "router", - "prefix_resolved": true, - "name": "list_templates", - "signature": "template_type: str | None=None, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 519, - "doc": "", - "decorator": "router.get('/templates/', response_model=list[DisclosureTemplateRead])", - "errors": [] - }, - { - "method": "POST", - "path": "/exemptions/templates/", - "router": "router", - "prefix_resolved": true, - "name": "create_template", - "signature": "data: DisclosureTemplateCreate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 532, - "doc": "", - "decorator": "router.post('/templates/', response_model=DisclosureTemplateRead, status_code=201)", - "errors": [] - }, - { - "method": "GET", - "path": "/exemptions/templates/{template_id}/render", - "router": "router", - "prefix_resolved": true, - "name": "render_template", - "signature": "template_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 556, - "doc": "Render a template with city profile variables substituted.", - "decorator": "router.get('/templates/{template_id}/render', response_model=DisclosureTemplateRendered)", - "errors": [ - "HTTPException(status_code=404, detail='Template not found')" - ] + "method": "GET", + "declared_path": "/rules/{rule_id}/history", + "function": "get_rule_history", + "line": 109 }, { - "method": "PUT", - "path": "/exemptions/templates/{template_id}", - "router": "router", - "prefix_resolved": true, - "name": "update_template", - "signature": "template_id: uuid.UUID, data: DisclosureTemplateUpdate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 609, - "doc": "", - "decorator": "router.put('/templates/{template_id}', response_model=DisclosureTemplateRead)", - "errors": [ - "HTTPException(status_code=404, detail='Template not found')" - ] - } - ], - "models": [ + "method": "POST", + "declared_path": "/rules/{rule_id}/test", + "function": "test_rule", + "line": 162 + }, { - "name": "RuleTestRequest", - "bases": [ - "BaseModel" - ], - "fields": [ - { - "name": "sample_text", + "method": "POST", + "declared_path": "/scan/{request_id}", + "function": "scan_for_exemptions", + "line": 228 + }, + { + "method": "GET", + "declared_path": "/flags/{request_id}", + "function": "list_flags", + "line": 300 + }, + { + "method": "PATCH", + "declared_path": "/flags/{flag_id}", + "function": "review_flag", + "line": 321 + }, + { + "method": "GET", + "declared_path": "/dashboard/accuracy", + "function": "exemption_accuracy", + "line": 365 + }, + { + "method": "GET", + "declared_path": "/dashboard/export", + "function": "export_flag_data", + "line": 423 + }, + { + "method": "GET", + "declared_path": "/dashboard", + "function": "exemption_dashboard", + "line": 480 + }, + { + "method": "GET", + "declared_path": "/templates/", + "function": "list_templates", + "line": 519 + }, + { + "method": "POST", + "declared_path": "/templates/", + "function": "create_template", + "line": 532 + }, + { + "method": "GET", + "declared_path": "/templates/{template_id}/render", + "function": "render_template", + "line": 556 + }, + { + "method": "PUT", + "declared_path": "/templates/{template_id}", + "function": "update_template", + "line": 609 + } + ], + "models": [ + { + "name": "RuleTestRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "sample_text", "type": "str", - "default": "" + "line": 145 } ], - "line": 144, - "doc": "" + "line": 144 }, { "name": "RuleTestMatch", @@ -10252,21 +9284,20 @@ { "name": "matched_text", "type": "str", - "default": "" + "line": 149 }, { "name": "start", "type": "int", - "default": "" + "line": 150 }, { "name": "end", "type": "int", - "default": "" + "line": 151 } ], - "line": 148, - "doc": "" + "line": 148 }, { "name": "RuleTestResponse", @@ -10277,115 +9308,109 @@ { "name": "rule_id", "type": "uuid.UUID", - "default": "" + "line": 155 }, { "name": "rule_type", "type": "str", - "default": "" + "line": 156 }, { "name": "matched", "type": "bool", - "default": "" + "line": 157 }, { "name": "matches", "type": "list[RuleTestMatch]", - "default": "" + "line": 158 } ], - "line": 154, - "doc": "" + "line": 154 } ], "configuration": [] }, { - "source": "installed-owned-source/app/ingestion/__init__.py", - "sha256": "b9960370edcad325db1bbc1a812416b99100a86c1db220b67a69e46f503ec5ad", + "source": "backend/townlight_records/ingestion/__init__.py", + "sha256": "9c3fae7acafa2a6bf5606c309e174f71843ecd5ab7664fff292c26f821a73ff9", + "bytes": 279, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/ingestion/cron_utils.py", - "sha256": "63ca640af21a0a25da5e49ff745ffecb800dd18f4dd9e4ba886b123855334876", + "source": "backend/townlight_records/ingestion/cron_utils.py", + "sha256": "88fbff0706981ef7cf13a653e5e4589062f2f24e043a570f3c6edf37fabcbfcf", + "bytes": 342, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/ingestion/scheduler.py", - "sha256": "cf90a00bb1eafc4e3327499461afbab3bc2202a726b5871551fc8a5c1638e734", + "source": "backend/townlight_records/ingestion/scheduler.py", + "sha256": "3520c77698a46e84c731f486f0173c4158405f5bce73ce8f58c2ae6d759783d0", + "bytes": 9379, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/ingestion/sync_runner.py", - "sha256": "0cab2a9f8b4caf7f199796d9c748fc165a04ec95f6181960ef84f74956fb9488", + "source": "backend/townlight_records/ingestion/sync_runner.py", + "sha256": "7c987cafa060cfc2b1071c5a9ba2bc27fe3b567be8a03280490de0ca3c02228c", + "bytes": 10324, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/ingestion/tasks.py", - "sha256": "fb9dabc97a0ea8d8ddbceec5a2a98ef5cdbafb92eee41ecb702b4cb7860bddd9", + "source": "backend/townlight_records/ingestion/tasks.py", + "sha256": "14e604c42d3c04490750b8fe2b2e3947328683af8de7dc7e7cfdbbbcd547e5d4", + "bytes": 9094, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/llm/__init__.py", - "sha256": "0411eee4d07aefa5002fbec9e0d426ee45fd2f9e589b56803b1668f6493d51e5", + "source": "backend/townlight_records/llm/__init__.py", + "sha256": "3fd0a698f594b821b7cc3fbb267513521ec3dfcc026ec89add8a6d5072aea8d3", + "bytes": 3626, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/llm/client.py", - "sha256": "8504ba9c8ee46c902b4a6d9004dccce92f66f20b388c8a55484bb8324169ded1", + "source": "backend/townlight_records/llm/client.py", + "sha256": "99a211bbbb594681364b9941ca9adb2fc54ceaaaf3f210f63a62d1108187378e", + "bytes": 4660, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/llm/context_manager.py", - "sha256": "aec2aac65a8e04a4a754ff44a6c4b37afdbf46a24156d5092c98f57aea436cc0", + "source": "backend/townlight_records/llm/context_manager.py", + "sha256": "0353251e35fe1ffc3ce372db9086effca688e684a39fd04b7a33a3ecb459d058", + "bytes": 2705, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/main.py", - "sha256": "abb959c23054e8fdd12fb4918ea6c1149ef3cc7b1fee268697baf36f07af9fc2", + "source": "backend/townlight_records/main.py", + "sha256": "ab9eaeb2e79b64a37f8ff54315fe53a08c7be8be29ad1398b535a184688600d3", + "bytes": 11777, "routes": [ { "method": "GET", - "path": "/config/portal-mode", - "router": "app", - "prefix_resolved": true, - "name": "get_portal_mode", - "signature": "", - "returns": "PortalModeResponse", - "line": 210, - "doc": "", - "decorator": "app.get('/config/portal-mode', tags=['public'], response_model=PortalModeResponse, summary=\"Get the deployment's current portal posture.\")", - "errors": [] + "declared_path": "/config/portal-mode", + "function": "get_portal_mode", + "line": 210 }, { "method": "GET", - "path": "/health", - "router": "app", - "prefix_resolved": true, - "name": "health", - "signature": "", - "returns": "", - "line": 266, - "doc": "", - "decorator": "app.get('/health')", - "errors": [] + "declared_path": "/health", + "function": "health", + "line": 266 } ], "models": [ @@ -10398,25 +9423,26 @@ { "name": "mode", "type": "Literal['public', 'private']", - "default": "Field(description='Active portal posture for this deployment. ``public`` = minimal resident surface (landing + authenticated records-request submission + resident registration) reachable without staff auth. ``private`` = staff-only; no public routes, no resident self-registration.')" + "line": 25 } ], - "line": 17, - "doc": "T5D \u2014 schema for ``GET /config/portal-mode``.\n\nExposed to the frontend on boot so it can branch routing without a\nuser-identity lookup. The payload is intentionally the single field\nbelow \u2014 no staff config, no user state, no schema version." + "line": 17 } ], "configuration": [] }, { - "source": "installed-owned-source/app/models/__init__.py", - "sha256": "85380f990a3bf800137f3e67775ba042f57a8a6b54d304845f43e1cb2a0b80c5", + "source": "backend/townlight_records/models/__init__.py", + "sha256": "14747da85c6ac8c0648b8bae81ba4369d13875757a40e721fb5215a3fa9b6027", + "bytes": 2908, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/models/audit.py", - "sha256": "df56686024ce0b50fc6ffe0fe20d4775314cd3bd60302ae85d8b9f860ca053bb", + "source": "backend/townlight_records/models/audit.py", + "sha256": "9e489ecadf8d3c4635f177350a7d4a7407542b92fea08360fb811c9616d5b663", + "bytes": 1260, "routes": [], "models": [ { @@ -10428,63 +9454,63 @@ { "name": "id", "type": "Mapped[int]", - "default": "mapped_column(primary_key=True, autoincrement=True)" + "line": 14 }, { "name": "prev_hash", "type": "Mapped[str]", - "default": "mapped_column(String(64), default='0' * 64)" + "line": 15 }, { "name": "entry_hash", "type": "Mapped[str]", - "default": "mapped_column(String(64), index=True)" + "line": 16 }, { "name": "timestamp", "type": "Mapped[datetime]", - "default": "mapped_column(DateTime(timezone=True), server_default=func.now(), index=True)" + "line": 17 }, { "name": "user_id", "type": "Mapped[uuid.UUID | None]", - "default": "mapped_column(UUID(as_uuid=True), nullable=True, index=True)" + "line": 20 }, { "name": "action", "type": "Mapped[str]", - "default": "mapped_column(String(100), index=True)" + "line": 23 }, { "name": "resource_type", "type": "Mapped[str]", - "default": "mapped_column(String(100), index=True)" + "line": 24 }, { "name": "resource_id", "type": "Mapped[str | None]", - "default": "mapped_column(String(255), nullable=True)" + "line": 25 }, { "name": "details", "type": "Mapped[dict | None]", - "default": "mapped_column(JSONB, nullable=True)" + "line": 26 }, { "name": "ai_generated", "type": "Mapped[bool]", - "default": "mapped_column(Boolean, default=False)" + "line": 27 } ], - "line": 11, - "doc": "" + "line": 11 } ], "configuration": [] }, { - "source": "installed-owned-source/app/models/city_profile.py", - "sha256": "cc91186429d3a0afe01cd36ec8dd97bda3aa99e6297d25aeeae81fafcc31fe04", + "source": "backend/townlight_records/models/city_profile.py", + "sha256": "a5a82b73398205fd303c2430fa31b9f5f67b21bc47f47f3a710618cbe6735b27", + "bytes": 1760, "routes": [], "models": [ { @@ -10496,83 +9522,83 @@ { "name": "id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(primary_key=True, default=uuid.uuid4)" + "line": 12 }, { "name": "city_name", "type": "Mapped[str]", - "default": "mapped_column(String(200))" + "line": 13 }, { "name": "state", "type": "Mapped[str | None]", - "default": "mapped_column(String(2))" + "line": 17 }, { "name": "county", "type": "Mapped[str | None]", - "default": "mapped_column(String(200))" + "line": 18 }, { "name": "population_band", "type": "Mapped[str | None]", - "default": "mapped_column(String(50))" + "line": 19 }, { "name": "email_platform", "type": "Mapped[str | None]", - "default": "mapped_column(String(50))" + "line": 20 }, { "name": "has_dedicated_it", "type": "Mapped[bool | None]", - "default": "mapped_column(Boolean)" + "line": 21 }, { "name": "monthly_request_volume", "type": "Mapped[str | None]", - "default": "mapped_column(String(20))" + "line": 22 }, { "name": "onboarding_status", "type": "Mapped[str]", - "default": "mapped_column(String(20), default='not_started')" + "line": 23 }, { "name": "profile_data", "type": "Mapped[dict]", - "default": "mapped_column(JSONB, default=dict)" + "line": 26 }, { "name": "gap_map", "type": "Mapped[dict]", - "default": "mapped_column(JSONB, default=dict)" + "line": 27 }, { "name": "created_at", "type": "Mapped[datetime]", - "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + "line": 28 }, { "name": "updated_at", "type": "Mapped[datetime]", - "default": "mapped_column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())" + "line": 31 }, { "name": "updated_by", "type": "Mapped[uuid.UUID | None]", - "default": "mapped_column(ForeignKey('users.id', ondelete='SET NULL'))" + "line": 34 } ], - "line": 9, - "doc": "" + "line": 9 } ], "configuration": [] }, { - "source": "installed-owned-source/app/models/connectors.py", - "sha256": "bd21d54690bdd9298d218ac973f29a2f14e2a4e59898784208d8f714ed33b032", + "source": "backend/townlight_records/models/connectors.py", + "sha256": "d5529083fbe39c77830dcda2cdcdeda0bb655cf447d6a4df9c8dd457a0b4fd26", + "bytes": 2136, "routes": [], "models": [ { @@ -10584,71 +9610,70 @@ { "name": "id", "type": "Mapped[int]", - "default": "mapped_column(Integer, primary_key=True, autoincrement=True)" + "line": 11 }, { "name": "domain", "type": "Mapped[str]", - "default": "mapped_column(String(100))" + "line": 12 }, { "name": "function", "type": "Mapped[str]", - "default": "mapped_column(String(200))" + "line": 13 }, { "name": "vendor_name", "type": "Mapped[str]", - "default": "mapped_column(String(200))" + "line": 14 }, { "name": "vendor_version", "type": "Mapped[str | None]", - "default": "mapped_column(String(50))" + "line": 15 }, { "name": "access_protocol", "type": "Mapped[str]", - "default": "mapped_column(String(50))" + "line": 16 }, { "name": "data_shape", "type": "Mapped[str]", - "default": "mapped_column(String(50))" + "line": 17 }, { "name": "common_record_types", "type": "Mapped[dict]", - "default": "mapped_column(JSONB, default=list)" + "line": 18 }, { "name": "redaction_tier", "type": "Mapped[int]", - "default": "mapped_column(Integer, default=1)" + "line": 19 }, { "name": "discovery_hints", "type": "Mapped[dict]", - "default": "mapped_column(JSONB, default=dict)" + "line": 20 }, { "name": "connector_template_id", "type": "Mapped[int | None]", - "default": "mapped_column(Integer)" + "line": 21 }, { "name": "catalog_version", "type": "Mapped[str]", - "default": "mapped_column(String(20))" + "line": 22 }, { "name": "created_at", "type": "Mapped[datetime]", - "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + "line": 23 } ], - "line": 8, - "doc": "" + "line": 8 }, { "name": "ConnectorTemplate", @@ -10659,68 +9684,68 @@ { "name": "id", "type": "Mapped[int]", - "default": "mapped_column(Integer, primary_key=True, autoincrement=True)" + "line": 31 }, { "name": "vendor_name", "type": "Mapped[str]", - "default": "mapped_column(String(200))" + "line": 32 }, { "name": "protocol", "type": "Mapped[str]", - "default": "mapped_column(String(50))" + "line": 33 }, { "name": "auth_method", "type": "Mapped[str]", - "default": "mapped_column(String(50))" + "line": 34 }, { "name": "config_schema", "type": "Mapped[dict]", - "default": "mapped_column(JSONB, default=dict)" + "line": 36 }, { "name": "default_sync_schedule", "type": "Mapped[str | None]", - "default": "mapped_column(String(50))" + "line": 37 }, { "name": "default_rate_limit", "type": "Mapped[int | None]", - "default": "mapped_column(Integer)" + "line": 38 }, { "name": "redaction_tier", "type": "Mapped[int]", - "default": "mapped_column(Integer, default=1)" + "line": 39 }, { "name": "setup_instructions", "type": "Mapped[str | None]", - "default": "mapped_column(Text)" + "line": 40 }, { "name": "created_at", "type": "Mapped[datetime]", - "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + "line": 41 }, { "name": "catalog_version", "type": "Mapped[str]", - "default": "mapped_column(String(20))" + "line": 44 } ], - "line": 28, - "doc": "" + "line": 28 } ], "configuration": [] }, { - "source": "installed-owned-source/app/models/departments.py", - "sha256": "95df980295f111a89ec3197370eb7ebe5a67881871a9016ce9bee7a2741ed173", + "source": "backend/townlight_records/models/departments.py", + "sha256": "38c905bcca9df892e9d0aeb1e1e7d89789a49449a741a3df071679d7c5b18ff6", + "bytes": 638, "routes": [], "models": [ { @@ -10732,38 +9757,38 @@ { "name": "id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(primary_key=True, default=uuid.uuid4)" + "line": 11 }, { "name": "name", "type": "Mapped[str]", - "default": "mapped_column(String(200))" + "line": 12 }, { "name": "code", "type": "Mapped[str]", - "default": "mapped_column(String(20), unique=True)" + "line": 13 }, { "name": "contact_email", "type": "Mapped[str | None]", - "default": "mapped_column(String(255))" + "line": 14 }, { "name": "created_at", "type": "Mapped[datetime]", - "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + "line": 15 } ], - "line": 8, - "doc": "" + "line": 8 } ], "configuration": [] }, { - "source": "installed-owned-source/app/models/document.py", - "sha256": "bcde5a7d50bc74ef2bb6d078e210366ca78b2c2ae9cc072ff72c6f727d9c78a7", + "source": "backend/townlight_records/models/document.py", + "sha256": "5c3594b8d9b9e6a7124e9dd4cc7c03f5786110608acf6945680efbf49c6e829a", + "bytes": 7997, "routes": [], "models": [ { @@ -10775,131 +9800,130 @@ { "name": "id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)" + "line": 75 }, { "name": "name", "type": "Mapped[str]", - "default": "mapped_column(String(255), unique=True)" + "line": 76 }, { "name": "source_type", "type": "Mapped[SourceType]", - "default": "mapped_column(Enum(SourceType, name='source_type', create_type=False, values_callable=lambda e: [m.value for m in e]))" + "line": 77 }, { "name": "connection_config", "type": "Mapped[dict]", - "default": "mapped_column(EncryptedJSONB, default=dict)" + "line": 83 }, { "name": "is_active", "type": "Mapped[bool]", - "default": "mapped_column(Boolean, default=True)" + "line": 84 }, { "name": "created_by", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True), ForeignKey('users.id'))" + "line": 85 }, { "name": "created_at", "type": "Mapped[datetime]", - "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + "line": 86 }, { "name": "last_ingestion_at", "type": "Mapped[datetime | None]", - "default": "mapped_column(DateTime(timezone=True), nullable=True)" + "line": 87 }, { "name": "discovered_source_id", "type": "Mapped[uuid.UUID | None]", - "default": "mapped_column(nullable=True)" + "line": 90 }, { "name": "connector_template_id", "type": "Mapped[int | None]", - "default": "mapped_column(Integer, nullable=True)" + "line": 91 }, { "name": "sync_schedule", "type": "Mapped[str | None]", - "default": "mapped_column(String(50), nullable=True)" + "line": 92 }, { "name": "schedule_enabled", "type": "Mapped[bool]", - "default": "mapped_column(Boolean, default=True, server_default='true')" + "line": 93 }, { "name": "last_sync_at", "type": "Mapped[datetime | None]", - "default": "mapped_column(DateTime(timezone=True), nullable=True)" + "line": 94 }, { "name": "last_sync_cursor", "type": "Mapped[str | None]", - "default": "mapped_column(String, nullable=True)" + "line": 95 }, { "name": "last_sync_status", "type": "Mapped[str | None]", - "default": "mapped_column(String(20), nullable=True)" + "line": 96 }, { "name": "consecutive_failure_count", "type": "Mapped[int]", - "default": "mapped_column(Integer, default=0, server_default='0')" + "line": 98 }, { "name": "last_error_message", "type": "Mapped[str | None]", - "default": "mapped_column(String(500), nullable=True)" + "line": 99 }, { "name": "last_error_at", "type": "Mapped[datetime | None]", - "default": "mapped_column(DateTime(timezone=True), nullable=True)" + "line": 100 }, { "name": "sync_paused", "type": "Mapped[bool]", - "default": "mapped_column(Boolean, default=False, server_default='false')" + "line": 101 }, { "name": "sync_paused_at", "type": "Mapped[datetime | None]", - "default": "mapped_column(DateTime(timezone=True), nullable=True)" + "line": 102 }, { "name": "sync_paused_reason", "type": "Mapped[str | None]", - "default": "mapped_column(String(200), nullable=True)" + "line": 103 }, { "name": "retry_batch_size", "type": "Mapped[int | None]", - "default": "mapped_column(Integer, nullable=True)" + "line": 104 }, { "name": "retry_time_limit_seconds", "type": "Mapped[int | None]", - "default": "mapped_column(Integer, nullable=True)" + "line": 105 }, { "name": "health_status", "type": "Mapped[str | None]", - "default": "mapped_column(String(20), nullable=True)" + "line": 106 }, { "name": "schema_hash", "type": "Mapped[str | None]", - "default": "mapped_column(String(64), nullable=True)" + "line": 107 } ], - "line": 72, - "doc": "" + "line": 72 }, { "name": "Document", @@ -10910,101 +9934,100 @@ { "name": "id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)" + "line": 113 }, { "name": "source_id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True), ForeignKey('data_sources.id'), index=True)" + "line": 114 }, { "name": "source_path", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 115 }, { "name": "filename", "type": "Mapped[str]", - "default": "mapped_column(String(500))" + "line": 116 }, { "name": "file_type", "type": "Mapped[str]", - "default": "mapped_column(String(50))" + "line": 117 }, { "name": "file_hash", "type": "Mapped[str]", - "default": "mapped_column(String(64), index=True)" + "line": 118 }, { "name": "file_size", "type": "Mapped[int]", - "default": "mapped_column(Integer, default=0)" + "line": 119 }, { "name": "ingestion_status", "type": "Mapped[IngestionStatus]", - "default": "mapped_column(Enum(IngestionStatus, name='ingestion_status', create_type=False, values_callable=lambda e: [m.value for m in e]), default=IngestionStatus.PENDING)" + "line": 120 }, { "name": "ingestion_error", "type": "Mapped[str | None]", - "default": "mapped_column(Text, nullable=True)" + "line": 121 }, { "name": "chunk_count", "type": "Mapped[int]", - "default": "mapped_column(Integer, default=0)" + "line": 122 }, { "name": "ingested_at", "type": "Mapped[datetime | None]", - "default": "mapped_column(DateTime(timezone=True), nullable=True)" + "line": 123 }, { "name": "metadata_", "type": "Mapped[dict | None]", - "default": "mapped_column('metadata', JSONB, nullable=True)" + "line": 124 }, { "name": "connector_type", "type": "Mapped[str | None]", - "default": "mapped_column(String(20), nullable=True)" + "line": 127 }, { "name": "updated_at", "type": "Mapped[datetime | None]", - "default": "mapped_column(DateTime(timezone=True), nullable=True)" + "line": 128 }, { "name": "display_name", "type": "Mapped[str | None]", - "default": "mapped_column(String(500), nullable=True)" + "line": 131 }, { "name": "department_id", "type": "Mapped[uuid.UUID | None]", - "default": "mapped_column(nullable=True)" + "line": 132 }, { "name": "redaction_status", "type": "Mapped[str]", - "default": "mapped_column(String(20), server_default='none')" + "line": 133 }, { "name": "derivative_path", "type": "Mapped[str | None]", - "default": "mapped_column(String(1000), nullable=True)" + "line": 134 }, { "name": "original_locked", "type": "Mapped[bool]", - "default": "mapped_column(Boolean, server_default='false')" + "line": 135 } ], - "line": 110, - "doc": "" + "line": 110 }, { "name": "DocumentChunk", @@ -11015,48 +10038,48 @@ { "name": "id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)" + "line": 143 }, { "name": "document_id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True), ForeignKey('documents.id', ondelete='CASCADE'), index=True)" + "line": 144 }, { "name": "chunk_index", "type": "Mapped[int]", - "default": "mapped_column(Integer)" + "line": 145 }, { "name": "content_text", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 146 }, { "name": "embedding", "type": "Mapped[list | None]", - "default": "mapped_column(Vector(768), nullable=True)" + "line": 147 }, { "name": "token_count", "type": "Mapped[int]", - "default": "mapped_column(Integer, default=0)" + "line": 148 }, { "name": "page_number", "type": "Mapped[int | None]", - "default": "mapped_column(Integer, nullable=True)" + "line": 149 } ], - "line": 140, - "doc": "" + "line": 140 } ], "configuration": [] }, { - "source": "installed-owned-source/app/models/exemption.py", - "sha256": "19c6c9f126eb03fd77139619f1e2a6c6af89d67af7e90d2139644dc909e9f7e3", + "source": "backend/townlight_records/models/exemption.py", + "sha256": "754ec1c88d23535bb2ed6538d3d42e3062fc9e81d69e2b63edebaf3debad3c5c", + "bytes": 3812, "routes": [], "models": [ { @@ -11068,56 +10091,55 @@ { "name": "id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)" + "line": 28 }, { "name": "state_code", "type": "Mapped[str]", - "default": "mapped_column(String(2), index=True)" + "line": 29 }, { "name": "category", "type": "Mapped[str]", - "default": "mapped_column(String(100), index=True)" + "line": 30 }, { "name": "rule_type", "type": "Mapped[RuleType]", - "default": "mapped_column(Enum(RuleType, name='rule_type', create_type=False, values_callable=lambda e: [m.value for m in e]))" + "line": 31 }, { "name": "rule_definition", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 34 }, { "name": "description", "type": "Mapped[str | None]", - "default": "mapped_column(Text, nullable=True)" + "line": 35 }, { "name": "enabled", "type": "Mapped[bool]", - "default": "mapped_column(Boolean, default=True)" + "line": 36 }, { "name": "version", "type": "Mapped[int]", - "default": "mapped_column(Integer, default=1)" + "line": 37 }, { "name": "created_by", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True), ForeignKey('users.id'))" + "line": 38 }, { "name": "created_at", "type": "Mapped[datetime]", - "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + "line": 39 } ], - "line": 25, - "doc": "" + "line": 25 }, { "name": "ExemptionFlag", @@ -11128,86 +10150,85 @@ { "name": "id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)" + "line": 45 }, { "name": "chunk_id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True), ForeignKey('document_chunks.id'), index=True)" + "line": 46 }, { "name": "rule_id", "type": "Mapped[uuid.UUID | None]", - "default": "mapped_column(UUID(as_uuid=True), ForeignKey('exemption_rules.id'), nullable=True, index=True)" + "line": 47 }, { "name": "request_id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True), ForeignKey('records_requests.id'), index=True)" + "line": 48 }, { "name": "category", "type": "Mapped[str]", - "default": "mapped_column(String(100))" + "line": 49 }, { "name": "matched_text", "type": "Mapped[str | None]", - "default": "mapped_column(Text, nullable=True)" + "line": 50 }, { "name": "confidence", "type": "Mapped[float]", - "default": "mapped_column(Float, default=1.0)" + "line": 51 }, { "name": "status", "type": "Mapped[FlagStatus]", - "default": "mapped_column(Enum(FlagStatus, name='flag_status', create_type=False, values_callable=lambda e: [m.value for m in e]), default=FlagStatus.FLAGGED)" + "line": 52 }, { "name": "reviewed_by", "type": "Mapped[uuid.UUID | None]", - "default": "mapped_column(UUID(as_uuid=True), ForeignKey('users.id'), nullable=True)" + "line": 56 }, { "name": "reviewed_at", "type": "Mapped[datetime | None]", - "default": "mapped_column(DateTime(timezone=True), nullable=True)" + "line": 57 }, { "name": "review_reason", "type": "Mapped[str | None]", - "default": "mapped_column(Text, nullable=True)" + "line": 58 }, { "name": "created_at", "type": "Mapped[datetime]", - "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + "line": 59 }, { "name": "review_note", "type": "Mapped[str | None]", - "default": "mapped_column(Text, nullable=True)" + "line": 62 }, { "name": "detection_tier", "type": "Mapped[int | None]", - "default": "mapped_column(Integer, nullable=True)" + "line": 63 }, { "name": "detection_method", "type": "Mapped[str | None]", - "default": "mapped_column(String(50), nullable=True)" + "line": 64 }, { "name": "auto_detected", "type": "Mapped[bool]", - "default": "mapped_column(Boolean, server_default='false')" + "line": 65 } ], - "line": 42, - "doc": "" + "line": 42 }, { "name": "DisclosureTemplate", @@ -11218,48 +10239,48 @@ { "name": "id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)" + "line": 71 }, { "name": "template_type", "type": "Mapped[str]", - "default": "mapped_column(String(100))" + "line": 72 }, { "name": "state_code", "type": "Mapped[str | None]", - "default": "mapped_column(String(2), nullable=True)" + "line": 73 }, { "name": "content", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 74 }, { "name": "version", "type": "Mapped[int]", - "default": "mapped_column(Integer, default=1)" + "line": 75 }, { "name": "updated_by", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True), ForeignKey('users.id'))" + "line": 76 }, { "name": "updated_at", "type": "Mapped[datetime]", - "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + "line": 77 } ], - "line": 68, - "doc": "" + "line": 68 } ], "configuration": [] }, { - "source": "installed-owned-source/app/models/fees.py", - "sha256": "8b6cc691265769ccd53ba6376b96c584c0a9d2bb6e55fe79a276ea1265ed2a7d", + "source": "backend/townlight_records/models/fees.py", + "sha256": "25eeff4b1e8180fdf218dc3382fefea2b141f851c2b9fdd84f01157079c795c2", + "bytes": 3103, "routes": [], "models": [ { @@ -11271,46 +10292,45 @@ { "name": "id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(primary_key=True, default=uuid.uuid4)" + "line": 11 }, { "name": "jurisdiction", "type": "Mapped[str]", - "default": "mapped_column(String(100))" + "line": 12 }, { "name": "fee_type", "type": "Mapped[str]", - "default": "mapped_column(String(50))" + "line": 13 }, { "name": "amount", "type": "Mapped[float]", - "default": "mapped_column(Numeric(10, 2))" + "line": 14 }, { "name": "description", "type": "Mapped[str | None]", - "default": "mapped_column(String(500))" + "line": 15 }, { "name": "effective_date", "type": "Mapped[date]", - "default": "mapped_column(Date)" + "line": 16 }, { "name": "created_by", "type": "Mapped[uuid.UUID | None]", - "default": "mapped_column(ForeignKey('users.id', ondelete='SET NULL'))" + "line": 17 }, { "name": "created_at", "type": "Mapped[datetime]", - "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + "line": 20 } ], - "line": 8, - "doc": "" + "line": 8 }, { "name": "FeeWaiver", @@ -11321,56 +10341,55 @@ { "name": "id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(primary_key=True, default=uuid.uuid4)" + "line": 28 }, { "name": "request_id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(ForeignKey('records_requests.id', ondelete='CASCADE'))" + "line": 29 }, { "name": "waiver_type", "type": "Mapped[str]", - "default": "mapped_column(String(50))" + "line": 32 }, { "name": "reason", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 33 }, { "name": "status", "type": "Mapped[str]", - "default": "mapped_column(String(20), default='pending')" + "line": 34 }, { "name": "requested_by", "type": "Mapped[uuid.UUID | None]", - "default": "mapped_column(ForeignKey('users.id', ondelete='SET NULL'))" + "line": 35 }, { "name": "reviewed_by", "type": "Mapped[uuid.UUID | None]", - "default": "mapped_column(ForeignKey('users.id', ondelete='SET NULL'), nullable=True)" + "line": 38 }, { "name": "review_notes", "type": "Mapped[str | None]", - "default": "mapped_column(String(2000), nullable=True)" + "line": 41 }, { "name": "created_at", "type": "Mapped[datetime]", - "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + "line": 42 }, { "name": "reviewed_at", "type": "Mapped[datetime | None]", - "default": "mapped_column(DateTime(timezone=True), nullable=True)" + "line": 45 } ], - "line": 25, - "doc": "" + "line": 25 }, { "name": "FeeLineItem", @@ -11381,73 +10400,73 @@ { "name": "id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(primary_key=True, default=uuid.uuid4)" + "line": 53 }, { "name": "request_id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(ForeignKey('records_requests.id', ondelete='CASCADE'))" + "line": 54 }, { "name": "fee_schedule_id", "type": "Mapped[uuid.UUID | None]", - "default": "mapped_column(ForeignKey('fee_schedules.id', ondelete='SET NULL'))" + "line": 57 }, { "name": "description", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 60 }, { "name": "quantity", "type": "Mapped[int]", - "default": "mapped_column(Integer, default=1)" + "line": 61 }, { "name": "unit_price", "type": "Mapped[float]", - "default": "mapped_column(Numeric(21, 2))" + "line": 62 }, { "name": "total", "type": "Mapped[float]", - "default": "mapped_column(Numeric(21, 2))" + "line": 63 }, { "name": "status", "type": "Mapped[str]", - "default": "mapped_column(String(20), default='estimated')" + "line": 64 }, { "name": "created_at", "type": "Mapped[datetime]", - "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + "line": 65 }, { "name": "legacy_id", "type": "Mapped[str | None]", - "default": "mapped_column(Text)" + "line": 68 }, { "name": "position", "type": "Mapped[int | None]", - "default": "mapped_column(Integer)" + "line": 69 }, { "name": "schedule_basis", "type": "Mapped[str]", - "default": "mapped_column(Text, server_default='')" + "line": 70 } ], - "line": 50, - "doc": "" + "line": 50 } ], "configuration": [] }, { - "source": "installed-owned-source/app/models/notifications.py", - "sha256": "f42e1facfadb8d4538b89f85a213142efc18e17be2bde95ac665b94d5704ad8c", + "source": "backend/townlight_records/models/notifications.py", + "sha256": "12ca15c1d16e951ad550f8a2f57e196ea122e65f80e6ffa51622e4aec25910f1", + "bytes": 2140, "routes": [], "models": [ { @@ -11459,46 +10478,45 @@ { "name": "id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(primary_key=True, default=uuid.uuid4)" + "line": 11 }, { "name": "event_type", "type": "Mapped[str]", - "default": "mapped_column(String(50), unique=True)" + "line": 12 }, { "name": "channel", "type": "Mapped[str]", - "default": "mapped_column(String(20))" + "line": 13 }, { "name": "subject_template", "type": "Mapped[str]", - "default": "mapped_column(String(500))" + "line": 14 }, { "name": "body_template", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 15 }, { "name": "is_active", "type": "Mapped[bool]", - "default": "mapped_column(Boolean, default=True)" + "line": 16 }, { "name": "created_by", "type": "Mapped[uuid.UUID | None]", - "default": "mapped_column(ForeignKey('users.id', ondelete='SET NULL'))" + "line": 17 }, { "name": "created_at", "type": "Mapped[datetime]", - "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + "line": 20 } ], - "line": 8, - "doc": "" + "line": 8 }, { "name": "NotificationLog", @@ -11509,83 +10527,83 @@ { "name": "id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(primary_key=True, default=uuid.uuid4)" + "line": 28 }, { "name": "template_id", "type": "Mapped[uuid.UUID | None]", - "default": "mapped_column(ForeignKey('notification_templates.id', ondelete='SET NULL'))" + "line": 29 }, { "name": "recipient_email", "type": "Mapped[str]", - "default": "mapped_column(String(255))" + "line": 32 }, { "name": "request_id", "type": "Mapped[uuid.UUID | None]", - "default": "mapped_column(ForeignKey('records_requests.id', ondelete='SET NULL'))" + "line": 33 }, { "name": "channel", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 36 }, { "name": "subject", "type": "Mapped[str | None]", - "default": "mapped_column(Text, nullable=True)" + "line": 37 }, { "name": "body", "type": "Mapped[str | None]", - "default": "mapped_column(Text, nullable=True)" + "line": 38 }, { "name": "status", "type": "Mapped[str]", - "default": "mapped_column(String(20), default='queued')" + "line": 39 }, { "name": "sent_at", "type": "Mapped[datetime | None]", - "default": "mapped_column(DateTime(timezone=True))" + "line": 40 }, { "name": "error_message", "type": "Mapped[str | None]", - "default": "mapped_column(Text)" + "line": 41 }, { "name": "created_at", "type": "Mapped[datetime]", - "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + "line": 42 }, { "name": "legacy_id", "type": "Mapped[str | None]", - "default": "mapped_column(Text)" + "line": 45 }, { "name": "module_id", "type": "Mapped[str | None]", - "default": "mapped_column(Text)" + "line": 46 }, { "name": "audience", "type": "Mapped[str | None]", - "default": "mapped_column(Text)" + "line": 47 } ], - "line": 25, - "doc": "" + "line": 25 } ], "configuration": [] }, { - "source": "installed-owned-source/app/models/records_artifacts.py", - "sha256": "bb3c7d9b5e796686c3731db8577009d00378a14feec56f8d46360bd8660d3130", + "source": "backend/townlight_records/models/records_artifacts.py", + "sha256": "b1a5d007e9631a552859eae35eee34680a7366be8c2b96cca1e78c2c163feed8", + "bytes": 2142, "routes": [], "models": [ { @@ -11597,96 +10615,95 @@ { "name": "id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(primary_key=True, default=uuid.uuid4)" + "line": 11 }, { "name": "request_id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(ForeignKey('records_requests.id'), index=True)" + "line": 12 }, { "name": "legacy_id", "type": "Mapped[str | None]", - "default": "mapped_column(Text)" + "line": 13 }, { "name": "position", "type": "Mapped[int | None]", - "default": "mapped_column(Integer)" + "line": 14 }, { "name": "kind", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 15 }, { "name": "content", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 16 }, { "name": "sha256", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 17 }, { "name": "response_sha256", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 18 }, { "name": "export_path", "type": "Mapped[str | None]", - "default": "mapped_column(Text, unique=True)" + "line": 19 }, { "name": "actor_id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(ForeignKey('users.id'))" + "line": 20 }, { "name": "document_count", "type": "Mapped[int]", - "default": "mapped_column(Integer)" + "line": 21 }, { "name": "release_artifact_count", "type": "Mapped[int]", - "default": "mapped_column(Integer)" + "line": 22 }, { "name": "search_session_count", "type": "Mapped[int]", - "default": "mapped_column(Integer)" + "line": 23 }, { "name": "release_count", "type": "Mapped[int]", - "default": "mapped_column(Integer)" + "line": 24 }, { "name": "redacted_count", "type": "Mapped[int]", - "default": "mapped_column(Integer)" + "line": 25 }, { "name": "exempt_count", "type": "Mapped[int]", - "default": "mapped_column(Integer)" + "line": 26 }, { "name": "created_at", "type": "Mapped[datetime]", - "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + "line": 27 }, { "name": "completed_at", "type": "Mapped[datetime | None]", - "default": "mapped_column(DateTime(timezone=True))" + "line": 28 } ], - "line": 9, - "doc": "" + "line": 9 }, { "name": "RequestPublication", @@ -11697,48 +10714,48 @@ { "name": "id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(primary_key=True, default=uuid.uuid4)" + "line": 33 }, { "name": "request_id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(ForeignKey('records_requests.id'), index=True)" + "line": 34 }, { "name": "legacy_id", "type": "Mapped[str | None]", - "default": "mapped_column(Text)" + "line": 35 }, { "name": "payload", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 36 }, { "name": "payload_hash", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 37 }, { "name": "actor_id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(ForeignKey('users.id'))" + "line": 38 }, { "name": "created_at", "type": "Mapped[datetime]", - "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + "line": 39 } ], - "line": 31, - "doc": "" + "line": 31 } ], "configuration": [] }, { - "source": "installed-owned-source/app/models/records_evidence.py", - "sha256": "acadc29d3b93a2432c2c752b05f9c61e649c7d94fe29948b8dab4c46ffd421dd", + "source": "backend/townlight_records/models/records_evidence.py", + "sha256": "19b70c91e104240516583c37143e7926d66d891214e321eb57b9831a8a92435b", + "bytes": 2430, "routes": [], "models": [ { @@ -11750,41 +10767,40 @@ { "name": "id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(primary_key=True, default=uuid.uuid4)" + "line": 23 }, { "name": "request_id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(ForeignKey('records_requests.id', ondelete='CASCADE'), index=True)" + "line": 24 }, { "name": "kind", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 27 }, { "name": "position", "type": "Mapped[int]", - "default": "mapped_column(Integer)" + "line": 28 }, { "name": "content", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 29 }, { "name": "actor_id", "type": "Mapped[uuid.UUID | None]", - "default": "mapped_column(ForeignKey('users.id', ondelete='SET NULL'))" + "line": 30 }, { "name": "created_at", "type": "Mapped[datetime]", - "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + "line": 31 } ], - "line": 16, - "doc": "" + "line": 16 }, { "name": "RequestExemptionDecision", @@ -11795,78 +10811,78 @@ { "name": "id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(primary_key=True, default=uuid.uuid4)" + "line": 40 }, { "name": "request_id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(ForeignKey('records_requests.id', ondelete='CASCADE'), index=True)" + "line": 41 }, { "name": "flag_id", "type": "Mapped[uuid.UUID | None]", - "default": "mapped_column(ForeignKey('exemption_flags.id'))" + "line": 44 }, { "name": "legacy_id", "type": "Mapped[str | None]", - "default": "mapped_column(Text)" + "line": 45 }, { "name": "position", "type": "Mapped[int]", - "default": "mapped_column(Integer)" + "line": 46 }, { "name": "source", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 47 }, { "name": "kind", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 48 }, { "name": "finding", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 49 }, { "name": "decision", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 50 }, { "name": "basis", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 51 }, { "name": "reviewer_label", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 52 }, { "name": "actor_id", "type": "Mapped[uuid.UUID | None]", - "default": "mapped_column(ForeignKey('users.id', ondelete='SET NULL'))" + "line": 53 }, { "name": "created_at", "type": "Mapped[datetime]", - "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + "line": 54 } ], - "line": 34, - "doc": "" + "line": 34 } ], "configuration": [] }, { - "source": "installed-owned-source/app/models/records_files.py", - "sha256": "8bceb23febbb492b13035ea12a9219d32741d397668d920a52b31f0e323b15f7", + "source": "backend/townlight_records/models/records_files.py", + "sha256": "f09db07cce4a4bc8223c9e6dbedcf7dd5c6fc6a0aefe4b9db6468ece30310253", + "bytes": 2003, "routes": [], "models": [ { @@ -11878,51 +10894,50 @@ { "name": "id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(ForeignKey('request_documents.id'), primary_key=True)" + "line": 15 }, { "name": "request_id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(ForeignKey('records_requests.id'), index=True)" + "line": 16 }, { "name": "legacy_id", "type": "Mapped[str | None]", - "default": "mapped_column(Text)" + "line": 17 }, { "name": "position", "type": "Mapped[int]", - "default": "mapped_column(Integer)" + "line": 18 }, { "name": "title", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 19 }, { "name": "original_path", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 20 }, { "name": "citation", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 21 }, { "name": "added_by", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 22 }, { "name": "created_at", "type": "Mapped[datetime]", - "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + "line": 23 } ], - "line": 12, - "doc": "" + "line": 12 }, { "name": "RequestReleaseCopy", @@ -11933,83 +10948,83 @@ { "name": "id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(primary_key=True, default=uuid.uuid4)" + "line": 29 }, { "name": "request_id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(ForeignKey('records_requests.id'), index=True)" + "line": 30 }, { "name": "attachment_id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(ForeignKey('request_file_evidence.id'), index=True)" + "line": 31 }, { "name": "original_path", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 32 }, { "name": "stored_path", "type": "Mapped[str]", - "default": "mapped_column(Text, unique=True)" + "line": 33 }, { "name": "file_name", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 34 }, { "name": "sha256", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 35 }, { "name": "size_bytes", "type": "Mapped[int]", - "default": "mapped_column(BigInteger)" + "line": 36 }, { "name": "status", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 37 }, { "name": "note", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 38 }, { "name": "added_by", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 39 }, { "name": "actor_id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(ForeignKey('users.id'))" + "line": 40 }, { "name": "position", "type": "Mapped[int]", - "default": "mapped_column(Integer)" + "line": 41 }, { "name": "created_at", "type": "Mapped[datetime]", - "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + "line": 42 } ], - "line": 26, - "doc": "" + "line": 26 } ], "configuration": [] }, { - "source": "installed-owned-source/app/models/request.py", - "sha256": "f88185889b139ac38de9a0d77449db246b22fef58f1743d25c7d2116c718ae76", + "source": "backend/townlight_records/models/request.py", + "sha256": "928047bcbe719cbe6e007b7bd77c30325b467a3bc5d46aec367dac0b40b41653", + "bytes": 5826, "routes": [], "models": [ { @@ -12021,186 +11036,185 @@ { "name": "id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)" + "line": 34 }, { "name": "requester_name", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 35 }, { "name": "requester_email", "type": "Mapped[str | None]", - "default": "mapped_column(String(320), nullable=True)" + "line": 36 }, { "name": "date_received", "type": "Mapped[datetime]", - "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + "line": 37 }, { "name": "statutory_deadline", "type": "Mapped[datetime | None]", - "default": "mapped_column(DateTime(timezone=True), nullable=True)" + "line": 38 }, { "name": "description", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 39 }, { "name": "status", "type": "Mapped[RequestStatus]", - "default": "mapped_column(Enum(RequestStatus, name='request_status', create_type=False, values_callable=lambda e: [m.value for m in e]), default=RequestStatus.RECEIVED)" + "line": 40 }, { "name": "assigned_to", "type": "Mapped[uuid.UUID | None]", - "default": "mapped_column(UUID(as_uuid=True), ForeignKey('users.id'), nullable=True)" + "line": 44 }, { "name": "created_by", "type": "Mapped[uuid.UUID | None]", - "default": "mapped_column(UUID(as_uuid=True), ForeignKey('users.id'))" + "line": 45 }, { "name": "created_at", "type": "Mapped[datetime]", - "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + "line": 46 }, { "name": "response_draft", "type": "Mapped[str | None]", - "default": "mapped_column(Text, nullable=True)" + "line": 47 }, { "name": "review_notes", "type": "Mapped[str | None]", - "default": "mapped_column(Text, nullable=True)" + "line": 48 }, { "name": "requester_phone", "type": "Mapped[str | None]", - "default": "mapped_column(String(50), nullable=True)" + "line": 51 }, { "name": "requester_type", "type": "Mapped[str | None]", - "default": "mapped_column(String(20), nullable=True)" + "line": 52 }, { "name": "scope_assessment", "type": "Mapped[str | None]", - "default": "mapped_column(String(20), nullable=True)" + "line": 53 }, { "name": "department_id", "type": "Mapped[uuid.UUID | None]", - "default": "mapped_column(nullable=True)" + "line": 54 }, { "name": "estimated_fee", "type": "Mapped[float | None]", - "default": "mapped_column(Numeric(21, 2), nullable=True)" + "line": 55 }, { "name": "fee_status", "type": "Mapped[str | None]", - "default": "mapped_column(String(20), nullable=True)" + "line": 56 }, { "name": "fee_waiver_requested", "type": "Mapped[bool]", - "default": "mapped_column(Boolean, server_default='false')" + "line": 57 }, { "name": "priority", "type": "Mapped[str]", - "default": "mapped_column(String(20), server_default='normal')" + "line": 58 }, { "name": "closed_at", "type": "Mapped[datetime | None]", - "default": "mapped_column(DateTime(timezone=True), nullable=True)" + "line": 59 }, { "name": "closure_reason", "type": "Mapped[str | None]", - "default": "mapped_column(String(500), nullable=True)" + "line": 60 }, { "name": "desktop_id", "type": "Mapped[str | None]", - "default": "mapped_column(Text, unique=True, nullable=True)" + "line": 64 }, { "name": "public_tracking_number", "type": "Mapped[str | None]", - "default": "mapped_column(Text, unique=True, nullable=True)" + "line": 65 }, { "name": "requester_contact", "type": "Mapped[str]", - "default": "mapped_column(Text, server_default='')" + "line": 66 }, { "name": "submitted_via", "type": "Mapped[str]", - "default": "mapped_column(Text, server_default='')" + "line": 67 }, { "name": "deadline_label", "type": "Mapped[str]", - "default": "mapped_column(Text, server_default='')" + "line": 68 }, { "name": "deadline_basis", "type": "Mapped[str]", - "default": "mapped_column(Text, server_default='')" + "line": 69 }, { "name": "deadline_reviewed_at", "type": "Mapped[datetime | None]", - "default": "mapped_column(DateTime(timezone=True))" + "line": 70 }, { "name": "display_status", "type": "Mapped[str | None]", - "default": "mapped_column(Text)" + "line": 71 }, { "name": "assigned_label", "type": "Mapped[str]", - "default": "mapped_column(Text, server_default='')" + "line": 72 }, { "name": "fee_estimate_text", "type": "Mapped[str]", - "default": "mapped_column(Text, server_default='')" + "line": 73 }, { "name": "fee_waiver_reason", "type": "Mapped[str]", - "default": "mapped_column(Text, server_default='')" + "line": 74 }, { "name": "approved_at", "type": "Mapped[datetime | None]", - "default": "mapped_column(DateTime(timezone=True))" + "line": 75 }, { "name": "approved_response_sha256", "type": "Mapped[str | None]", - "default": "mapped_column(String(64))" + "line": 76 }, { "name": "fulfilled_at", "type": "Mapped[datetime | None]", - "default": "mapped_column(DateTime(timezone=True))" + "line": 77 } ], - "line": 31, - "doc": "" + "line": 31 }, { "name": "RequestDocument", @@ -12211,46 +11225,45 @@ { "name": "id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)" + "line": 83 }, { "name": "request_id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True), ForeignKey('records_requests.id'), index=True)" + "line": 84 }, { "name": "document_id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True), ForeignKey('documents.id'), index=True)" + "line": 85 }, { "name": "relevance_note", "type": "Mapped[str | None]", - "default": "mapped_column(Text, nullable=True)" + "line": 86 }, { "name": "exemption_flags", "type": "Mapped[dict | None]", - "default": "mapped_column(JSONB, nullable=True)" + "line": 87 }, { "name": "inclusion_status", "type": "Mapped[InclusionStatus]", - "default": "mapped_column(Enum(InclusionStatus, name='inclusion_status', create_type=False, values_callable=lambda e: [m.value for m in e]), default=InclusionStatus.PENDING)" + "line": 88 }, { "name": "attached_at", "type": "Mapped[datetime]", - "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + "line": 92 }, { "name": "attached_by", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True), ForeignKey('users.id'))" + "line": 93 } ], - "line": 80, - "doc": "" + "line": 80 }, { "name": "DocumentCache", @@ -12261,43 +11274,43 @@ { "name": "id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)" + "line": 99 }, { "name": "document_id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True), ForeignKey('documents.id'), index=True)" + "line": 100 }, { "name": "request_id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True), ForeignKey('records_requests.id'), index=True)" + "line": 101 }, { "name": "cached_file_path", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 102 }, { "name": "file_size", "type": "Mapped[int]", - "default": "mapped_column(Integer, default=0)" + "line": 103 }, { "name": "cached_at", "type": "Mapped[datetime]", - "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + "line": 104 } ], - "line": 96, - "doc": "" + "line": 96 } ], "configuration": [] }, { - "source": "installed-owned-source/app/models/request_workflow.py", - "sha256": "cc297a448c7f2de9ef1e31d7d94d24494efeeac7165f1d466e94aecfb7807b64", + "source": "backend/townlight_records/models/request_workflow.py", + "sha256": "77d4ac696507834c2e2bbc73c025a48988af29189930072c7d3a4240574df6f4", + "bytes": 4059, "routes": [], "models": [ { @@ -12309,61 +11322,60 @@ { "name": "id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(primary_key=True, default=uuid.uuid4)" + "line": 11 }, { "name": "request_id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(ForeignKey('records_requests.id', ondelete='CASCADE'), index=True)" + "line": 12 }, { "name": "event_type", "type": "Mapped[str]", - "default": "mapped_column(String(50))" + "line": 15 }, { "name": "actor_id", "type": "Mapped[uuid.UUID | None]", - "default": "mapped_column(ForeignKey('users.id', ondelete='SET NULL'))" + "line": 20 }, { "name": "actor_role", "type": "Mapped[str | None]", - "default": "mapped_column(String(50))" + "line": 23 }, { "name": "description", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 24 }, { "name": "internal_note", "type": "Mapped[str | None]", - "default": "mapped_column(Text)" + "line": 25 }, { "name": "created_at", "type": "Mapped[datetime]", - "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + "line": 26 }, { "name": "legacy_id", "type": "Mapped[str | None]", - "default": "mapped_column(Text)" + "line": 29 }, { "name": "actor_label", "type": "Mapped[str | None]", - "default": "mapped_column(Text)" + "line": 30 }, { "name": "position", "type": "Mapped[int | None]", - "default": "mapped_column(Integer)" + "line": 31 } ], - "line": 8, - "doc": "" + "line": 8 }, { "name": "RequestPublicStatus", @@ -12374,46 +11386,45 @@ { "name": "id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(primary_key=True, default=uuid.uuid4)" + "line": 37 }, { "name": "request_id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(ForeignKey('records_requests.id', ondelete='CASCADE'), index=True)" + "line": 38 }, { "name": "legacy_id", "type": "Mapped[str | None]", - "default": "mapped_column(Text)" + "line": 41 }, { "name": "label", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 42 }, { "name": "summary", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 43 }, { "name": "status", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 44 }, { "name": "created_at", "type": "Mapped[datetime]", - "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + "line": 45 }, { "name": "position", "type": "Mapped[int | None]", - "default": "mapped_column(Integer)" + "line": 48 } ], - "line": 34, - "doc": "" + "line": 34 }, { "name": "RequestMessage", @@ -12424,56 +11435,55 @@ { "name": "id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(primary_key=True, default=uuid.uuid4)" + "line": 54 }, { "name": "request_id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(ForeignKey('records_requests.id', ondelete='CASCADE'), index=True)" + "line": 55 }, { "name": "sender_type", "type": "Mapped[str]", - "default": "mapped_column(String(20))" + "line": 58 }, { "name": "sender_id", "type": "Mapped[uuid.UUID | None]", - "default": "mapped_column(ForeignKey('users.id', ondelete='SET NULL'))" + "line": 59 }, { "name": "message_text", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 62 }, { "name": "is_internal", "type": "Mapped[bool]", - "default": "mapped_column(Boolean, default=False)" + "line": 63 }, { "name": "created_at", "type": "Mapped[datetime]", - "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + "line": 64 }, { "name": "legacy_id", "type": "Mapped[str | None]", - "default": "mapped_column(Text)" + "line": 67 }, { "name": "sender_label", "type": "Mapped[str | None]", - "default": "mapped_column(Text)" + "line": 68 }, { "name": "position", "type": "Mapped[int | None]", - "default": "mapped_column(Integer)" + "line": 69 } ], - "line": 51, - "doc": "" + "line": 51 }, { "name": "ResponseLetter", @@ -12484,63 +11494,63 @@ { "name": "id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(primary_key=True, default=uuid.uuid4)" + "line": 75 }, { "name": "request_id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(ForeignKey('records_requests.id', ondelete='CASCADE'), index=True)" + "line": 76 }, { "name": "template_id", "type": "Mapped[uuid.UUID | None]", - "default": "mapped_column(ForeignKey('disclosure_templates.id', ondelete='SET NULL'))" + "line": 79 }, { "name": "generated_content", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 82 }, { "name": "edited_content", "type": "Mapped[str | None]", - "default": "mapped_column(Text)" + "line": 83 }, { "name": "status", "type": "Mapped[str]", - "default": "mapped_column(String(20), default='draft')" + "line": 84 }, { "name": "generated_by", "type": "Mapped[uuid.UUID | None]", - "default": "mapped_column(ForeignKey('users.id', ondelete='SET NULL'))" + "line": 85 }, { "name": "approved_by", "type": "Mapped[uuid.UUID | None]", - "default": "mapped_column(ForeignKey('users.id', ondelete='SET NULL'))" + "line": 88 }, { "name": "sent_at", "type": "Mapped[datetime | None]", - "default": "mapped_column(DateTime(timezone=True))" + "line": 91 }, { "name": "created_at", "type": "Mapped[datetime]", - "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + "line": 92 } ], - "line": 72, - "doc": "" + "line": 72 } ], "configuration": [] }, { - "source": "installed-owned-source/app/models/search.py", - "sha256": "e1f7499d2042fcae621e817878b1cf12bd53e5b55ebbaae33d8c24e29de275c9", + "source": "backend/townlight_records/models/search.py", + "sha256": "64caa51b723290050a78027fd5de3667d214cc24dce5f3dc250f9a3ce4588bf6", + "bytes": 2764, "routes": [], "models": [ { @@ -12552,21 +11562,20 @@ { "name": "id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)" + "line": 14 }, { "name": "user_id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True), ForeignKey('users.id'), index=True)" + "line": 15 }, { "name": "created_at", "type": "Mapped[datetime]", - "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + "line": 16 } ], - "line": 11, - "doc": "" + "line": 11 }, { "name": "SearchQuery", @@ -12577,66 +11586,65 @@ { "name": "id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)" + "line": 22 }, { "name": "session_id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True), ForeignKey('search_sessions.id'), index=True)" + "line": 23 }, { "name": "query_text", "type": "Mapped[str]", - "default": "mapped_column(Text)" + "line": 24 }, { "name": "filters", "type": "Mapped[dict | None]", - "default": "mapped_column(JSONB, nullable=True)" + "line": 25 }, { "name": "results_count", "type": "Mapped[int]", - "default": "mapped_column(Integer, default=0)" + "line": 26 }, { "name": "synthesized_answer", "type": "Mapped[str | None]", - "default": "mapped_column(Text, nullable=True)" + "line": 27 }, { "name": "created_at", "type": "Mapped[datetime]", - "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + "line": 28 }, { "name": "request_id", "type": "Mapped[uuid.UUID | None]", - "default": "mapped_column(UUID(as_uuid=True), ForeignKey('records_requests.id'), index=True)" + "line": 29 }, { "name": "legacy_id", "type": "Mapped[str | None]", - "default": "mapped_column(Text)" + "line": 32 }, { "name": "position", "type": "Mapped[int | None]", - "default": "mapped_column(Integer)" + "line": 33 }, { "name": "locations", "type": "Mapped[str | None]", - "default": "mapped_column(Text)" + "line": 34 }, { "name": "reviewer_label", "type": "Mapped[str | None]", - "default": "mapped_column(Text)" + "line": 35 } ], - "line": 19, - "doc": "" + "line": 19 }, { "name": "SearchResult", @@ -12647,68 +11655,68 @@ { "name": "id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)" + "line": 41 }, { "name": "query_id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True), ForeignKey('search_queries.id'), index=True)" + "line": 42 }, { "name": "chunk_id", "type": "Mapped[uuid.UUID | None]", - "default": "mapped_column(UUID(as_uuid=True), ForeignKey('document_chunks.id'), index=True)" + "line": 45 }, { "name": "similarity_score", "type": "Mapped[float | None]", - "default": "mapped_column(Float)" + "line": 46 }, { "name": "rank", "type": "Mapped[int]", - "default": "mapped_column(Integer)" + "line": 47 }, { "name": "normalized_score", "type": "Mapped[int | None]", - "default": "mapped_column(Integer, nullable=True)" + "line": 50 }, { "name": "legacy_id", "type": "Mapped[str | None]", - "default": "mapped_column(Text)" + "line": 51 }, { "name": "title", "type": "Mapped[str | None]", - "default": "mapped_column(Text)" + "line": 52 }, { "name": "citation", "type": "Mapped[str | None]", - "default": "mapped_column(Text)" + "line": 53 }, { "name": "summary", "type": "Mapped[str | None]", - "default": "mapped_column(Text)" + "line": 54 }, { "name": "review_status", "type": "Mapped[str | None]", - "default": "mapped_column(Text)" + "line": 55 } ], - "line": 38, - "doc": "" + "line": 38 } ], "configuration": [] }, { - "source": "installed-owned-source/app/models/service_account.py", - "sha256": "594cbd1dfeea0bf026341f1a427f4e96a362f75c11a7cc0df7fb7e3a8363a311", + "source": "backend/townlight_records/models/service_account.py", + "sha256": "a6a9b3d1735156d13603ed3128723a1fb5985795ab6e0919c450a4e63824c3b1", + "bytes": 1074, "routes": [], "models": [ { @@ -12720,48 +11728,48 @@ { "name": "id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)" + "line": 14 }, { "name": "name", "type": "Mapped[str]", - "default": "mapped_column(String(255), unique=True)" + "line": 17 }, { "name": "api_key_hash", "type": "Mapped[str]", - "default": "mapped_column(String(255))" + "line": 18 }, { "name": "role", "type": "Mapped[UserRole]", - "default": "mapped_column(Enum(UserRole, name='user_role', create_type=False, values_callable=lambda e: [m.value for m in e]), default=UserRole.READ_ONLY)" + "line": 19 }, { "name": "created_by", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True), ForeignKey('users.id'))" + "line": 23 }, { "name": "created_at", "type": "Mapped[datetime]", - "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + "line": 26 }, { "name": "is_active", "type": "Mapped[bool]", - "default": "mapped_column(default=True)" + "line": 29 } ], - "line": 11, - "doc": "" + "line": 11 } ], "configuration": [] }, { - "source": "installed-owned-source/app/models/sync_failure.py", - "sha256": "d31b87435c855f632b9b6d746eeec477d4f3811a95017401d0b1c3db4d506eb0", + "source": "backend/townlight_records/models/sync_failure.py", + "sha256": "c5feb986cc08f3fe85f780170741213efc12740cf561f174a003cf9a5eb3cbc2", + "bytes": 3057, "routes": [], "models": [ { @@ -12773,71 +11781,70 @@ { "name": "id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)" + "line": 18 }, { "name": "source_id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True), ForeignKey('data_sources.id', ondelete='CASCADE'), nullable=False)" + "line": 19 }, { "name": "source_path", "type": "Mapped[str]", - "default": "mapped_column(Text, nullable=False)" + "line": 22 }, { "name": "error_message", "type": "Mapped[str | None]", - "default": "mapped_column(Text, nullable=True)" + "line": 23 }, { "name": "error_class", "type": "Mapped[str | None]", - "default": "mapped_column(String(200), nullable=True)" + "line": 24 }, { "name": "http_status_code", "type": "Mapped[int | None]", - "default": "mapped_column(Integer, nullable=True)" + "line": 25 }, { "name": "retry_count", "type": "Mapped[int]", - "default": "mapped_column(Integer, default=0, nullable=False)" + "line": 26 }, { "name": "status", "type": "Mapped[str]", - "default": "mapped_column(String(20), nullable=False, default='retrying')" + "line": 27 }, { "name": "first_failed_at", "type": "Mapped[datetime]", - "default": "mapped_column(DateTime(timezone=True), nullable=False, server_default=func.now())" + "line": 31 }, { "name": "last_retried_at", "type": "Mapped[datetime | None]", - "default": "mapped_column(DateTime(timezone=True), nullable=True)" + "line": 34 }, { "name": "resolved_at", "type": "Mapped[datetime | None]", - "default": "mapped_column(DateTime(timezone=True), nullable=True)" + "line": 35 }, { "name": "dismissed_at", "type": "Mapped[datetime | None]", - "default": "mapped_column(DateTime(timezone=True), nullable=True)" + "line": 36 }, { "name": "dismissed_by", "type": "Mapped[uuid.UUID | None]", - "default": "mapped_column(UUID(as_uuid=True), ForeignKey('users.id'), nullable=True)" + "line": 37 } ], - "line": 15, - "doc": "" + "line": 15 }, { "name": "SyncRunLog", @@ -12848,58 +11855,58 @@ { "name": "id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)" + "line": 50 }, { "name": "source_id", "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True), ForeignKey('data_sources.id', ondelete='CASCADE'), nullable=False)" + "line": 51 }, { "name": "started_at", "type": "Mapped[datetime]", - "default": "mapped_column(DateTime(timezone=True), nullable=False, server_default=func.now())" + "line": 54 }, { "name": "finished_at", "type": "Mapped[datetime | None]", - "default": "mapped_column(DateTime(timezone=True), nullable=True)" + "line": 57 }, { "name": "status", "type": "Mapped[str | None]", - "default": "mapped_column(String(20), nullable=True)" + "line": 58 }, { "name": "records_attempted", "type": "Mapped[int]", - "default": "mapped_column(Integer, default=0)" + "line": 59 }, { "name": "records_succeeded", "type": "Mapped[int]", - "default": "mapped_column(Integer, default=0)" + "line": 60 }, { "name": "records_failed", "type": "Mapped[int]", - "default": "mapped_column(Integer, default=0)" + "line": 61 }, { "name": "error_summary", "type": "Mapped[str | None]", - "default": "mapped_column(Text, nullable=True)" + "line": 62 } ], - "line": 47, - "doc": "" + "line": 47 } ], "configuration": [] }, { - "source": "installed-owned-source/app/models/user.py", + "source": "backend/townlight_records/models/user.py", "sha256": "39603bc8063007391d478b52165d2ae8d4bf0c5f1a1d7f716b78ff94754b2c82", + "bytes": 1292, "routes": [], "models": [ { @@ -12912,156 +11919,122 @@ { "name": "full_name", "type": "Mapped[str]", - "default": "mapped_column(default='')" + "line": 26 }, { "name": "role", "type": "Mapped[UserRole]", - "default": "mapped_column(Enum(UserRole, name='user_role', create_type=False, values_callable=lambda e: [m.value for m in e]), default=UserRole.STAFF)" + "line": 27 }, { "name": "created_at", "type": "Mapped[datetime]", - "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + "line": 31 }, { "name": "last_login", "type": "Mapped[datetime | None]", - "default": "mapped_column(DateTime(timezone=True), nullable=True)" + "line": 34 }, { "name": "must_change_password", "type": "Mapped[bool]", - "default": "mapped_column(Boolean, nullable=False, default=False, server_default='false')" + "line": 37 }, { "name": "department_id", "type": "Mapped[uuid.UUID | None]", - "default": "mapped_column(ForeignKey('departments.id'), nullable=True)" + "line": 42 } ], - "line": 23, - "doc": "" + "line": 23 } ], "configuration": [] }, { - "source": "installed-owned-source/app/notifications/__init__.py", + "source": "backend/townlight_records/notifications/__init__.py", "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "bytes": 0, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/notifications/router.py", - "sha256": "ac77bd461ee941a84117eb93935464dc2c908ba96c3e2c613d80bd28088d5009", + "source": "backend/townlight_records/notifications/router.py", + "sha256": "adf8fb319f45c2c1bf6b9580ed3b918ca8a74f56dfd1d36d621b2de2ae4d57ea", + "bytes": 4369, "routes": [ { "method": "GET", - "path": "/notifications/templates", - "router": "router", - "prefix_resolved": false, - "name": "list_templates", - "signature": "session: AsyncSession=Depends(get_async_session), user=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 22, - "doc": "List all notification templates.", - "decorator": "router.get('/notifications/templates', response_model=list[NotificationTemplateRead])", - "errors": [] + "declared_path": "/notifications/templates", + "function": "list_templates", + "line": 22 }, { "method": "POST", - "path": "/notifications/templates", - "router": "router", - "prefix_resolved": false, - "name": "create_template", - "signature": "payload: NotificationTemplateCreate, session: AsyncSession=Depends(get_async_session), user=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 38, - "doc": "Create a new notification template (admin only).", - "decorator": "router.post('/notifications/templates', response_model=NotificationTemplateRead, status_code=201)", - "errors": [ - "HTTPException(status_code=409, detail=f\"Template for event_type '{payload.event_type}' already exists\")" - ] + "declared_path": "/notifications/templates", + "function": "create_template", + "line": 38 }, { "method": "PATCH", - "path": "/notifications/templates/{template_id}", - "router": "router", - "prefix_resolved": false, - "name": "update_template", - "signature": "template_id: uuid.UUID, payload: NotificationTemplateUpdate, session: AsyncSession=Depends(get_async_session), user=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 83, - "doc": "Update a notification template (admin only).", - "decorator": "router.patch('/notifications/templates/{template_id}', response_model=NotificationTemplateRead)", - "errors": [ - "HTTPException(status_code=404, detail='Template not found')", - "HTTPException(status_code=400, detail='No fields to update')" - ] + "declared_path": "/notifications/templates/{template_id}", + "function": "update_template", + "line": 83 }, { "method": "GET", - "path": "/notifications/log", - "router": "router", - "prefix_resolved": false, - "name": "list_notification_log", - "signature": "limit: int=Query(default=50, le=200), request_id: uuid.UUID | None=Query(default=None), session: AsyncSession=Depends(get_async_session), user=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 116, - "doc": "List recent notification log entries.", - "decorator": "router.get('/notifications/log', response_model=list[NotificationLogRead])", - "errors": [] + "declared_path": "/notifications/log", + "function": "list_notification_log", + "line": 116 } ], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/notifications/service.py", - "sha256": "0672a6a7a60bc09c4b1bfe29d7046f93fef36ea48b09a2ff3b898bdf66ad0965", + "source": "backend/townlight_records/notifications/service.py", + "sha256": "6c7e33ddb59503ebcd530df56efee8d26a31b4b3c1a95c0c238eff10423102e4", + "bytes": 3160, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/notifications/smtp_delivery.py", - "sha256": "4dc26331949c01537173b6bb5c91d5f4d23419e73e46d1600fe289053904e544", + "source": "backend/townlight_records/notifications/smtp_delivery.py", + "sha256": "084b7b456f9f665b67f55d3789e0427b2750c7f3b343de1be718acc0e79f4f6b", + "bytes": 3599, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/notifications/sync_notifications.py", - "sha256": "8dee67dcfacd3182afbba6a1ed874e7029a0f2a7aef5a619fcec353dc569b778", + "source": "backend/townlight_records/notifications/sync_notifications.py", + "sha256": "6bbd902f3bd5344014e3a641d082e87ed59a316f6d8c26f7981dcb7abf2ee8b0", + "bytes": 4457, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/onboarding/__init__.py", - "sha256": "410f27365a45a5cad7e8a8b23a63e6312fcc6ba18b9f3cfb8ecf782940f7fc49", + "source": "backend/townlight_records/onboarding/__init__.py", + "sha256": "fd55411077ca22c07b7f527df218bc85624000d5c3699cfa8fe341a86b125ea4", + "bytes": 112, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/onboarding/router.py", - "sha256": "fd107d538b24379eb31a08e39927eec2486df5d383c20b6f23af9adbb3299ff4", + "source": "backend/townlight_records/onboarding/router.py", + "sha256": "dedc72d16f1d1ceab430a8249bca91aca9b72bed92a63e0da4d76a48c2def1a6", + "bytes": 7179, "routes": [ { "method": "POST", - "path": "/onboarding/interview", - "router": "router", - "prefix_resolved": true, - "name": "get_next_question", - "signature": "body: InterviewRequest, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 113, - "doc": "Generate the next onboarding question and persist the last answer.", - "decorator": "router.post('/interview', response_model=InterviewResponse)", - "errors": [] + "declared_path": "/interview", + "function": "get_next_question", + "line": 113 } ], "models": [ @@ -13074,21 +12047,20 @@ { "name": "last_answer", "type": "str | None", - "default": "None" + "line": 64 }, { "name": "last_field", "type": "str | None", - "default": "None" + "line": 65 }, { "name": "skipped_fields", "type": "list[str] | None", - "default": "None" + "line": 70 } ], - "line": 63, - "doc": "" + "line": 63 }, { "name": "InterviewResponse", @@ -13099,63 +12071,57 @@ { "name": "question", "type": "str", - "default": "" + "line": 74 }, { "name": "target_field", "type": "str | None", - "default": "" + "line": 75 }, { "name": "all_complete", "type": "bool", - "default": "" + "line": 76 }, { "name": "completed_fields", "type": "list[str]", - "default": "" + "line": 77 }, { "name": "onboarding_status", "type": "str", - "default": "" + "line": 78 }, { "name": "skipped_fields", "type": "list[str]", - "default": "" + "line": 79 } ], - "line": 73, - "doc": "" + "line": 73 } ], "configuration": [] }, { - "source": "installed-owned-source/app/public/__init__.py", - "sha256": "9b2399a19ebba72002567e091d5d5bc56a158640e121328fa89365823d0607f9", + "source": "backend/townlight_records/public/__init__.py", + "sha256": "07555697e80697fc9c90de3b9cff2b5c07dfe57210ce0aa82570f34003f11292", + "bytes": 632, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/public/router.py", - "sha256": "1b688edd6b2ed2334bd6c113c4c30e47748ce98bc12c6c70e716f81b8acc23ea", + "source": "backend/townlight_records/public/router.py", + "sha256": "127bd6046eada11ea0195f6f9c7489a16343ff55a417b8d8ecf84e511028d46f", + "bytes": 6923, "routes": [ { "method": "POST", - "path": "/requests", - "router": "router", - "prefix_resolved": false, - "name": "submit_public_request", - "signature": "body: PublicRequestSubmitBody, user: User=Depends(_require_public_role), session: AsyncSession=Depends(get_async_session)", - "returns": "PublicRequestSubmitResponse", - "line": 115, - "doc": "Create a records request on behalf of the signed-in PUBLIC user.\n\nThe request lands in :class:`RequestStatus.RECEIVED` with\n``created_by`` = the authenticated resident's id. ``requester_name``\nand ``requester_email`` are copied from the user record so staff\nreviewers see the submitter's registered identity verbatim. An audit\nlog entry is written with ``action=\"public.requests.create\"`` for\nfull traceability.", - "decorator": "router.post('/requests', response_model=PublicRequestSubmitResponse, status_code=status.HTTP_201_CREATED, summary='Submit a records request as an authenticated resident.')", - "errors": [] + "declared_path": "/requests", + "function": "submit_public_request", + "line": 115 } ], "models": [ @@ -13168,16 +12134,15 @@ { "name": "description", "type": "str", - "default": "Field(min_length=10, max_length=10000, description='Plain-language description of the records being requested. At least 10 characters; the staff reviewer reads this verbatim.')" + "line": 56 }, { "name": "phone", "type": "str | None", - "default": "Field(default=None, max_length=50, description='Optional contact phone number.')" + "line": 64 } ], - "line": 47, - "doc": "Minimal public submission payload.\n\nThe authenticated ``UserRole.PUBLIC`` user's ``full_name`` and ``email``\nare reused for ``requester_name`` / ``requester_email`` (they already\nown that identity via self-registration). Only the free-form\ndescription and optional phone are collected here." + "line": 47 }, { "name": "PublicRequestSubmitResponse", @@ -13188,452 +12153,233 @@ { "name": "request_id", "type": "uuid.UUID", - "default": "" + "line": 80 }, { "name": "status", "type": "RequestStatus", - "default": "" + "line": 81 }, { "name": "submitted_at", "type": "datetime", - "default": "" + "line": 82 }, { "name": "message", "type": "str", - "default": "" + "line": 83 } ], - "line": 71, - "doc": "What the resident sees after submitting.\n\nThe tracking id is the database UUID of the request \u2014 the resident\ncan reference it when contacting the records office. Expanded\ntrack-my-request functionality (status page, timeline view,\ndownloads) is explicitly out of T5D scope." + "line": 71 } ], "configuration": [] }, { - "source": "installed-owned-source/app/requests/__init__.py", - "sha256": "10f4a38349943e0adc86d6b60e935616b29948f77c0a1c4ea7c3ccf94b70f2e3", + "source": "backend/townlight_records/requests/__init__.py", + "sha256": "474d14c31d2bb164d90cd89a4982df6987e0c15fb8ed8f663cf112fb03332b8f", + "bytes": 104, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/requests/artifacts.py", - "sha256": "e557ecc8cfd265bfcb76b4b06de38fcaf6eb75ed3dbba6d21fe65f481bbbf8a1", + "source": "backend/townlight_records/requests/artifacts.py", + "sha256": "86793936796cb95d48b7775d2f942cca7e5cca77dde0c8d022221b41b6cf4e22", + "bytes": 12278, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/requests/deadline_check.py", - "sha256": "d5d734204bf8ef783d8d619b07df8884ab3cf2987bffcf57daa6d55a3431eb5a", + "source": "backend/townlight_records/requests/deadline_check.py", + "sha256": "6244989403cc69f8cc89686d5e8664e3c580fced03ca793704a2397e8987d332", + "bytes": 5055, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/requests/files.py", - "sha256": "f5c2703a70c076b963f1116a0779d354479c65cb734bc921a4197c72694c8eec", + "source": "backend/townlight_records/requests/files.py", + "sha256": "af54c3d331dc1dedeece351d2cd07ece06c1c6e1295bbb42315eaf4503752da5", + "bytes": 7540, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/requests/meeting_sources.py", - "sha256": "5694a2e0b345cf684261ef54cc205e5ec1aaeb0125c2c77c0c4a1cf2899feb79", + "source": "backend/townlight_records/requests/meeting_sources.py", + "sha256": "8b1122476099897bd85c0a345a2fe8ff21e1d60962c0b9fd0899956359fa76ea", + "bytes": 2609, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/requests/native_public.py", - "sha256": "0f9995ccc14fd61e49f51474fc2fcbcc52696b9102c1bd65b227fe135ea5e6cc", + "source": "backend/townlight_records/requests/native_public.py", + "sha256": "926db3331f9606977db57b36301521dd462cc5e6a5436425979734678e77ede7", + "bytes": 6497, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/requests/planning_sources.py", - "sha256": "b62831d83e129a974bec04ee10fd71cfd15c8940f5c5c4dd11794b8f51cbd8d8", + "source": "backend/townlight_records/requests/planning_sources.py", + "sha256": "4ba709347e0a34b24664d7890aaed2d6de8800d73520eba65a139700749f8dcb", + "bytes": 1920, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/requests/router.py", - "sha256": "f29526862e9e3adae5cb288a59644fa9d10f0e62fdb0e41602286d715c529199", + "source": "backend/townlight_records/requests/router.py", + "sha256": "ada18d3fcc66780a458764bf34c50d546748accd9791bd83edb5b95e4299968f", + "bytes": 48717, "routes": [ { "method": "POST", - "path": "/requests/", - "router": "router", - "prefix_resolved": true, - "name": "create_request", - "signature": "data: RequestCreate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 85, - "doc": "", - "decorator": "router.post('/', response_model=RequestRead, status_code=201)", - "errors": [] + "declared_path": "/", + "function": "create_request", + "line": 85 }, { "method": "GET", - "path": "/requests/", - "router": "router", - "prefix_resolved": true, - "name": "list_requests", - "signature": "status: RequestStatus | None=None, assigned_to: uuid.UUID | None=None, limit: int=50, offset: int=0, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.LIAISON))", - "returns": "", - "line": 104, - "doc": "", - "decorator": "router.get('/', response_model=list[RequestRead])", - "errors": [] + "declared_path": "/", + "function": "list_requests", + "line": 104 }, { "method": "GET", - "path": "/requests/stats", - "router": "router", - "prefix_resolved": true, - "name": "request_stats", - "signature": "session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.LIAISON))", - "returns": "", - "line": 136, - "doc": "", - "decorator": "router.get('/stats', response_model=RequestStats)", - "errors": [] + "declared_path": "/stats", + "function": "request_stats", + "line": 136 }, { "method": "GET", - "path": "/requests/{request_id}", - "router": "router", - "prefix_resolved": true, - "name": "get_request", - "signature": "request_id: uuid.UUID, request: Request, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.LIAISON))", - "returns": "", - "line": 189, - "doc": "", - "decorator": "router.get('/{request_id}', response_model=RequestRead)", - "errors": [ - "HTTPException(status_code=404, detail='Request not found')" - ] + "declared_path": "/{request_id}", + "function": "get_request", + "line": 189 }, { "method": "PATCH", - "path": "/requests/{request_id}", - "router": "router", - "prefix_resolved": true, - "name": "update_request", - "signature": "request_id: uuid.UUID, data: RequestUpdate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 211, - "doc": "", - "decorator": "router.patch('/{request_id}', response_model=RequestRead)", - "errors": [ - "HTTPException(status_code=404, detail='Request not found')", - "HTTPException(status_code=400, detail=f'Cannot transition from {req.status.value} to {data.status.value}')" - ] - }, - { - "method": "POST", - "path": "/requests/{request_id}/documents", - "router": "router", - "prefix_resolved": true, - "name": "attach_document", - "signature": "request_id: uuid.UUID, data: RequestDocumentAdd, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 275, - "doc": "", - "decorator": "router.post('/{request_id}/documents', response_model=RequestDocumentRead, status_code=201)", - "errors": [ - "HTTPException(status_code=404, detail='Request not found')", - "HTTPException(status_code=404, detail='Document not found')", - "HTTPException(status_code=409, detail='Document already attached')" - ] - }, - { - "method": "GET", - "path": "/requests/{request_id}/documents", - "router": "router", - "prefix_resolved": true, - "name": "list_attached_documents", - "signature": "request_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 342, - "doc": "", - "decorator": "router.get('/{request_id}/documents', response_model=list[RequestDocumentRead])", - "errors": [ - "HTTPException(status_code=404, detail='Request not found')" - ] + "declared_path": "/{request_id}", + "function": "update_request", + "line": 211 + }, + { + "method": "POST", + "declared_path": "/{request_id}/documents", + "function": "attach_document", + "line": 275 + }, + { + "method": "GET", + "declared_path": "/{request_id}/documents", + "function": "list_attached_documents", + "line": 342 }, { "method": "DELETE", - "path": "/requests/{request_id}/documents/{doc_id}", - "router": "router", - "prefix_resolved": true, - "name": "remove_document", - "signature": "request_id: uuid.UUID, doc_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 363, - "doc": "", - "decorator": "router.delete('/{request_id}/documents/{doc_id}', status_code=204)", - "errors": [ - "HTTPException(status_code=404, detail='Request not found')", - "HTTPException(status_code=404, detail='Attachment not found')" - ] - }, - { - "method": "POST", - "path": "/requests/{request_id}/submit-review", - "router": "router", - "prefix_resolved": true, - "name": "submit_for_review", - "signature": "request_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 395, - "doc": "", - "decorator": "router.post('/{request_id}/submit-review', response_model=RequestRead)", - "errors": [ - "HTTPException(status_code=404, detail='Request not found')", - "HTTPException(status_code=400, detail=f'Cannot submit for review from status {req.status.value}')" - ] - }, - { - "method": "POST", - "path": "/requests/{request_id}/ready-for-release", - "router": "router", - "prefix_resolved": true, - "name": "mark_ready_for_release", - "signature": "request_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.REVIEWER))", - "returns": "", - "line": 437, - "doc": "", - "decorator": "router.post('/{request_id}/ready-for-release', response_model=RequestRead)", - "errors": [ - "HTTPException(status_code=404, detail='Request not found')", - "HTTPException(status_code=400, detail=f\"Can only mark ready for release from 'in_review' status, current: {req.status.value}\")" - ] - }, - { - "method": "POST", - "path": "/requests/{request_id}/approve", - "router": "router", - "prefix_resolved": true, - "name": "approve_request", - "signature": "request_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.REVIEWER))", - "returns": "", - "line": 481, - "doc": "", - "decorator": "router.post('/{request_id}/approve', response_model=RequestRead)", - "errors": [ - "HTTPException(status_code=404, detail='Request not found')", - "HTTPException(status_code=400, detail=f\"Can only approve from 'drafted' or 'ready_for_release' status, current: {req.status.value}\")" - ] - }, - { - "method": "POST", - "path": "/requests/{request_id}/reject", - "router": "router", - "prefix_resolved": true, - "name": "reject_request", - "signature": "request_id: uuid.UUID, reason: str='', session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.REVIEWER))", - "returns": "", - "line": 525, - "doc": "", - "decorator": "router.post('/{request_id}/reject', response_model=RequestRead)", - "errors": [ - "HTTPException(status_code=404, detail='Request not found')", - "HTTPException(status_code=400, detail=\"Can only reject from 'in_review' status\")" - ] - }, - { - "method": "GET", - "path": "/requests/{request_id}/timeline", - "router": "router", - "prefix_resolved": true, - "name": "get_timeline", - "signature": "request_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 571, - "doc": "", - "decorator": "router.get('/{request_id}/timeline', response_model=list[TimelineEventRead])", - "errors": [ - "HTTPException(status_code=404, detail='Request not found')" - ] - }, - { - "method": "POST", - "path": "/requests/{request_id}/timeline", - "router": "router", - "prefix_resolved": true, - "name": "add_timeline_event", - "signature": "request_id: uuid.UUID, event: TimelineEventCreate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 590, - "doc": "", - "decorator": "router.post('/{request_id}/timeline', response_model=TimelineEventRead, status_code=201)", - "errors": [ - "HTTPException(status_code=404, detail='Request not found')" - ] - }, - { - "method": "GET", - "path": "/requests/{request_id}/messages", - "router": "router", - "prefix_resolved": true, - "name": "get_messages", - "signature": "request_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 622, - "doc": "", - "decorator": "router.get('/{request_id}/messages', response_model=list[MessageRead])", - "errors": [ - "HTTPException(status_code=404, detail='Request not found')" - ] - }, - { - "method": "POST", - "path": "/requests/{request_id}/messages", - "router": "router", - "prefix_resolved": true, - "name": "add_message", - "signature": "request_id: uuid.UUID, msg: MessageCreate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 641, - "doc": "", - "decorator": "router.post('/{request_id}/messages', response_model=MessageRead, status_code=201)", - "errors": [ - "HTTPException(status_code=404, detail='Request not found')" - ] - }, - { - "method": "GET", - "path": "/requests/{request_id}/fees", - "router": "router", - "prefix_resolved": true, - "name": "get_fees", - "signature": "request_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 672, - "doc": "", - "decorator": "router.get('/{request_id}/fees', response_model=list[FeeLineItemRead])", - "errors": [ - "HTTPException(status_code=404, detail='Request not found')" - ] - }, - { - "method": "POST", - "path": "/requests/{request_id}/fees", - "router": "router", - "prefix_resolved": true, - "name": "add_fee", - "signature": "request_id: uuid.UUID, fee: FeeLineItemCreate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 692, - "doc": "", - "decorator": "router.post('/{request_id}/fees', response_model=FeeLineItemRead, status_code=201)", - "errors": [ - "HTTPException(status_code=404, detail='Request not found')" - ] - }, - { - "method": "POST", - "path": "/requests/{request_id}/estimate-fees", - "router": "router", - "prefix_resolved": true, - "name": "estimate_fees", - "signature": "request_id: uuid.UUID, body: FeeEstimateRequest, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 748, - "doc": "Estimate fees based on staff-entered page count and fee schedule.\n\nPage count is a manual staff estimate \u2014 not inferred from ingested docs.", - "decorator": "router.post('/{request_id}/estimate-fees', response_model=FeeEstimateResponse)", - "errors": [ - "HTTPException(status_code=404, detail='Request not found')", - "HTTPException(status_code=404, detail='Fee schedule not found')" - ] - }, - { - "method": "POST", - "path": "/requests/{request_id}/fee-waiver", - "router": "router", - "prefix_resolved": true, - "name": "create_fee_waiver", - "signature": "request_id: uuid.UUID, body: FeeWaiverCreateRequest, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 803, - "doc": "Request a fee waiver for this records request.", - "decorator": "router.post('/{request_id}/fee-waiver', response_model=FeeWaiverReadResponse, status_code=201)", - "errors": [ - "HTTPException(status_code=404, detail='Request not found')", - "HTTPException(status_code=422, detail=f'Invalid waiver_type: {body.waiver_type}')" - ] + "declared_path": "/{request_id}/documents/{doc_id}", + "function": "remove_document", + "line": 363 + }, + { + "method": "POST", + "declared_path": "/{request_id}/submit-review", + "function": "submit_for_review", + "line": 395 + }, + { + "method": "POST", + "declared_path": "/{request_id}/ready-for-release", + "function": "mark_ready_for_release", + "line": 437 + }, + { + "method": "POST", + "declared_path": "/{request_id}/approve", + "function": "approve_request", + "line": 481 + }, + { + "method": "POST", + "declared_path": "/{request_id}/reject", + "function": "reject_request", + "line": 525 + }, + { + "method": "GET", + "declared_path": "/{request_id}/timeline", + "function": "get_timeline", + "line": 571 + }, + { + "method": "POST", + "declared_path": "/{request_id}/timeline", + "function": "add_timeline_event", + "line": 590 + }, + { + "method": "GET", + "declared_path": "/{request_id}/messages", + "function": "get_messages", + "line": 622 + }, + { + "method": "POST", + "declared_path": "/{request_id}/messages", + "function": "add_message", + "line": 641 + }, + { + "method": "GET", + "declared_path": "/{request_id}/fees", + "function": "get_fees", + "line": 672 + }, + { + "method": "POST", + "declared_path": "/{request_id}/fees", + "function": "add_fee", + "line": 692 + }, + { + "method": "POST", + "declared_path": "/{request_id}/estimate-fees", + "function": "estimate_fees", + "line": 748 + }, + { + "method": "POST", + "declared_path": "/{request_id}/fee-waiver", + "function": "create_fee_waiver", + "line": 803 }, { "method": "PATCH", - "path": "/requests/{request_id}/fee-waiver/{waiver_id}", - "router": "router", - "prefix_resolved": true, - "name": "review_fee_waiver", - "signature": "request_id: uuid.UUID, waiver_id: uuid.UUID, body: FeeWaiverReviewRequest, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.REVIEWER))", - "returns": "", - "line": 848, - "doc": "Approve or deny a fee waiver. Reviewer/Admin only.", - "decorator": "router.patch('/{request_id}/fee-waiver/{waiver_id}', response_model=FeeWaiverReadResponse)", - "errors": [ - "HTTPException(status_code=404, detail='Request not found')", - "HTTPException(status_code=404, detail='Fee waiver not found')", - "HTTPException(status_code=422, detail=\"Status must be 'approved' or 'denied'\")" - ] - }, - { - "method": "POST", - "path": "/requests/{request_id}/response-letter", - "router": "router", - "prefix_resolved": true, - "name": "generate_response_letter", - "signature": "request_id: uuid.UUID, data: ResponseLetterCreate | None=None, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 1138, - "doc": "Generate a draft response letter for a records request.\n\nAttempts LLM generation via Ollama first; falls back to a structured\ntemplate if the LLM is unavailable.", - "decorator": "router.post('/{request_id}/response-letter', response_model=ResponseLetterRead, status_code=201)", - "errors": [ - "HTTPException(status_code=404, detail='Request not found')" - ] - }, - { - "method": "GET", - "path": "/requests/{request_id}/response-letter", - "router": "router", - "prefix_resolved": true, - "name": "get_response_letter", - "signature": "request_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 1203, - "doc": "Get the latest response letter for a request.", - "decorator": "router.get('/{request_id}/response-letter', response_model=ResponseLetterRead)", - "errors": [ - "HTTPException(status_code=404, detail='Request not found')", - "HTTPException(status_code=404, detail='No response letter found for this request')" - ] + "declared_path": "/{request_id}/fee-waiver/{waiver_id}", + "function": "review_fee_waiver", + "line": 848 + }, + { + "method": "POST", + "declared_path": "/{request_id}/response-letter", + "function": "generate_response_letter", + "line": 1138 + }, + { + "method": "GET", + "declared_path": "/{request_id}/response-letter", + "function": "get_response_letter", + "line": 1203 }, { "method": "PATCH", - "path": "/requests/{request_id}/response-letter/{letter_id}", - "router": "router", - "prefix_resolved": true, - "name": "update_response_letter", - "signature": "request_id: uuid.UUID, letter_id: uuid.UUID, data: ResponseLetterUpdate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 1232, - "doc": "Update a response letter's edited content or status.\n\nStatus changes to 'approved' require REVIEWER role.", - "decorator": "router.patch('/{request_id}/response-letter/{letter_id}', response_model=ResponseLetterRead)", - "errors": [ - "HTTPException(status_code=404, detail='Request not found')", - "HTTPException(status_code=404, detail='Response letter not found')", - "HTTPException(status_code=400, detail='Invalid status. Must be draft, approved, or sent')", - "HTTPException(status_code=403, detail='Only reviewers or admins can approve response letters')" - ] + "declared_path": "/{request_id}/response-letter/{letter_id}", + "function": "update_response_letter", + "line": 1232 } ], "models": [ @@ -13646,16 +12392,15 @@ { "name": "page_count", "type": "int", - "default": "" + "line": 735 }, { "name": "fee_schedule_id", "type": "uuid.UUID", - "default": "" + "line": 736 } ], - "line": 734, - "doc": "" + "line": 734 }, { "name": "FeeEstimateResponse", @@ -13666,31 +12411,30 @@ { "name": "page_count", "type": "int", - "default": "" + "line": 740 }, { "name": "unit_price", "type": "float", - "default": "" + "line": 741 }, { "name": "total", "type": "float", - "default": "" + "line": 742 }, { "name": "fee_type", "type": "str", - "default": "" + "line": 743 }, { "name": "description", "type": "str", - "default": "" + "line": 744 } ], - "line": 739, - "doc": "" + "line": 739 }, { "name": "FeeWaiverCreateRequest", @@ -13701,16 +12445,15 @@ { "name": "waiver_type", "type": "str", - "default": "" + "line": 781 }, { "name": "reason", "type": "str", - "default": "" + "line": 782 } ], - "line": 780, - "doc": "" + "line": 780 }, { "name": "FeeWaiverReadResponse", @@ -13721,41 +12464,40 @@ { "name": "id", "type": "uuid.UUID", - "default": "" + "line": 786 }, { "name": "request_id", "type": "uuid.UUID", - "default": "" + "line": 787 }, { "name": "waiver_type", "type": "str", - "default": "" + "line": 788 }, { "name": "reason", "type": "str", - "default": "" + "line": 789 }, { "name": "status", "type": "str", - "default": "" + "line": 790 }, { "name": "review_notes", "type": "str | None", - "default": "None" + "line": 791 }, { "name": "created_at", "type": "str", - "default": "" + "line": 792 } ], - "line": 785, - "doc": "" + "line": 785 }, { "name": "FeeWaiverReviewRequest", @@ -13766,29 +12508,28 @@ { "name": "status", "type": "str", - "default": "" + "line": 798 }, { "name": "review_notes", "type": "str | None", - "default": "None" + "line": 799 } ], - "line": 797, - "doc": "" + "line": 797 } ], "configuration": [ { - "variable": "LLM_MODEL", - "default": "", + "environment": "LLM_MODEL", "line": 992 } ] }, { - "source": "installed-owned-source/app/requests/service.py", - "sha256": "117aa98e60d09824799b2696dfce65d9ade7d60b58a35df3e8664add3cccca66", + "source": "backend/townlight_records/requests/service.py", + "sha256": "2e3d98c29dad218f7a32a1eecf013170071413a246d21180426f0fdb2a6e275c", + "bytes": 5015, "routes": [], "models": [ { @@ -13798,58 +12539,58 @@ { "name": "requester_name", "type": "str", - "default": "" + "line": 20 }, { "name": "description", "type": "str", - "default": "" + "line": 21 }, { "name": "requester_email", "type": "str | None", - "default": "None" + "line": 22 }, { "name": "requester_phone", "type": "str | None", - "default": "None" + "line": 23 }, { "name": "requester_type", "type": "str | None", - "default": "None" + "line": 24 }, { "name": "statutory_deadline", "type": "datetime | None", - "default": "None" + "line": 25 }, { "name": "priority", "type": "str", - "default": "'normal'" + "line": 26 }, { "name": "scope_assessment", "type": "str | None", - "default": "None" + "line": 27 }, { "name": "department_id", "type": "uuid.UUID | None", - "default": "None" + "line": 28 } ], - "line": 19, - "doc": "" + "line": 19 } ], "configuration": [] }, { - "source": "installed-owned-source/app/requests/workflow.py", - "sha256": "3d0ec7c9e4dd987beab5c1ca89f7b4c8e45f0a24075b64ce7694be50a901a72b", + "source": "backend/townlight_records/requests/workflow.py", + "sha256": "fbffbf4434cdeecd92d3828fa92690360f01fb809f1f7aec501d42aef56d161a", + "bytes": 18267, "routes": [], "models": [ { @@ -13859,30 +12600,31 @@ { "name": "user", "type": "User", - "default": "" + "line": 26 }, { "name": "role", "type": "str", - "default": "" + "line": 27 } ], - "line": 25, - "doc": "" + "line": 25 } ], "configuration": [] }, { - "source": "installed-owned-source/app/schemas/__init__.py", + "source": "backend/townlight_records/schemas/__init__.py", "sha256": "7cd5688441a82abcca61eda136c29d767a8043bb0a3f7d9f0696a6443f675372", + "bytes": 18, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/schemas/analytics.py", + "source": "backend/townlight_records/schemas/analytics.py", "sha256": "1b2f2d7507f1057d010c203ec7c7fa6037d7adfd1e5be4b7323402dca5693a69", + "bytes": 411, "routes": [], "models": [ { @@ -13894,63 +12636,63 @@ { "name": "average_response_time_days", "type": "float | None", - "default": "" + "line": 5 }, { "name": "median_response_time_days", "type": "float | None", - "default": "" + "line": 6 }, { "name": "requests_by_status", "type": "dict[str, int]", - "default": "" + "line": 7 }, { "name": "requests_by_department", "type": "dict[str, int]", - "default": "" + "line": 8 }, { "name": "deadline_compliance_rate", "type": "float", - "default": "" + "line": 9 }, { "name": "total_open", "type": "int", - "default": "" + "line": 10 }, { "name": "total_closed", "type": "int", - "default": "" + "line": 11 }, { "name": "total_overdue", "type": "int", - "default": "" + "line": 12 }, { "name": "clarification_frequency", "type": "float", - "default": "" + "line": 13 }, { "name": "top_request_topics", "type": "list[str]", - "default": "" + "line": 14 } ], - "line": 4, - "doc": "" + "line": 4 } ], "configuration": [] }, { - "source": "installed-owned-source/app/schemas/audit.py", + "source": "backend/townlight_records/schemas/audit.py", "sha256": "95b0e336b85ffdb37079359ab68aa04b9ed974e964dc9a943cbef132f99e327d", + "bytes": 767, "routes": [], "models": [ { @@ -13962,56 +12704,55 @@ { "name": "id", "type": "int", - "default": "" + "line": 8 }, { "name": "prev_hash", "type": "str", - "default": "" + "line": 9 }, { "name": "entry_hash", "type": "str", - "default": "" + "line": 10 }, { "name": "timestamp", "type": "datetime", - "default": "" + "line": 11 }, { "name": "user_id", "type": "uuid.UUID | None", - "default": "" + "line": 12 }, { "name": "action", "type": "str", - "default": "" + "line": 13 }, { "name": "resource_type", "type": "str", - "default": "" + "line": 14 }, { "name": "resource_id", "type": "str | None", - "default": "" + "line": 15 }, { "name": "details", "type": "dict | None", - "default": "" + "line": 16 }, { "name": "ai_generated", "type": "bool", - "default": "" + "line": 17 } ], - "line": 7, - "doc": "" + "line": 7 }, { "name": "AuditLogQuery", @@ -14022,41 +12763,40 @@ { "name": "action", "type": "str | None", - "default": "None" + "line": 23 }, { "name": "resource_type", "type": "str | None", - "default": "None" + "line": 24 }, { "name": "user_id", "type": "uuid.UUID | None", - "default": "None" + "line": 25 }, { "name": "start_date", "type": "datetime | None", - "default": "None" + "line": 26 }, { "name": "end_date", "type": "datetime | None", - "default": "None" + "line": 27 }, { "name": "limit", "type": "int", - "default": "Field(default=50, le=200)" + "line": 28 }, { "name": "offset", "type": "int", - "default": "0" + "line": 29 } ], - "line": 22, - "doc": "" + "line": 22 }, { "name": "AuditChainVerification", @@ -14067,28 +12807,28 @@ { "name": "is_valid", "type": "bool", - "default": "" + "line": 33 }, { "name": "entries_checked", "type": "int", - "default": "" + "line": 34 }, { "name": "error_message", "type": "str", - "default": "" + "line": 35 } ], - "line": 32, - "doc": "" + "line": 32 } ], "configuration": [] }, { - "source": "installed-owned-source/app/schemas/city_profile.py", + "source": "backend/townlight_records/schemas/city_profile.py", "sha256": "b3187fb30ee67b36d4eb2794c2e36b31a49f01b9ad53b0db1a0d9bf87b2c2b2d", + "bytes": 1627, "routes": [], "models": [ { @@ -14100,51 +12840,50 @@ { "name": "city_name", "type": "str", - "default": "" + "line": 8 }, { "name": "state", "type": "str | None", - "default": "None" + "line": 13 }, { "name": "county", "type": "str | None", - "default": "None" + "line": 14 }, { "name": "population_band", "type": "str | None", - "default": "None" + "line": 15 }, { "name": "email_platform", "type": "str | None", - "default": "None" + "line": 16 }, { "name": "has_dedicated_it", "type": "bool | None", - "default": "None" + "line": 17 }, { "name": "monthly_request_volume", "type": "str | None", - "default": "None" + "line": 18 }, { "name": "profile_data", "type": "dict", - "default": "{}" + "line": 19 }, { "name": "gap_map", "type": "dict", - "default": "{}" + "line": 20 } ], - "line": 7, - "doc": "" + "line": 7 }, { "name": "CityProfileRead", @@ -14155,71 +12894,70 @@ { "name": "id", "type": "uuid.UUID", - "default": "" + "line": 25 }, { "name": "city_name", "type": "str", - "default": "" + "line": 26 }, { "name": "state", "type": "str | None", - "default": "" + "line": 29 }, { "name": "county", "type": "str | None", - "default": "" + "line": 30 }, { "name": "population_band", "type": "str | None", - "default": "" + "line": 31 }, { "name": "email_platform", "type": "str | None", - "default": "" + "line": 32 }, { "name": "has_dedicated_it", "type": "bool | None", - "default": "" + "line": 33 }, { "name": "monthly_request_volume", "type": "str | None", - "default": "" + "line": 34 }, { "name": "onboarding_status", "type": "str", - "default": "" + "line": 35 }, { "name": "profile_data", "type": "dict", - "default": "" + "line": 36 }, { "name": "gap_map", "type": "dict", - "default": "" + "line": 37 }, { "name": "created_at", "type": "datetime", - "default": "" + "line": 38 }, { "name": "updated_at", "type": "datetime", - "default": "" + "line": 39 } ], - "line": 23, - "doc": "" + "line": 23 }, { "name": "CityProfileUpdate", @@ -14230,70 +12968,71 @@ { "name": "city_name", "type": "str | None", - "default": "None" + "line": 43 }, { "name": "state", "type": "str | None", - "default": "None" + "line": 44 }, { "name": "county", "type": "str | None", - "default": "None" + "line": 45 }, { "name": "population_band", "type": "str | None", - "default": "None" + "line": 46 }, { "name": "email_platform", "type": "str | None", - "default": "None" + "line": 47 }, { "name": "has_dedicated_it", "type": "bool | None", - "default": "None" + "line": 48 }, { "name": "monthly_request_volume", "type": "str | None", - "default": "None" + "line": 49 }, { "name": "onboarding_status", "type": "str | None", - "default": "None" + "line": 50 }, { "name": "profile_data", "type": "dict | None", - "default": "None" + "line": 51 }, { "name": "gap_map", "type": "dict | None", - "default": "None" + "line": 52 } ], - "line": 42, - "doc": "" + "line": 42 } ], "configuration": [] }, { - "source": "installed-owned-source/app/schemas/connectors/__init__.py", - "sha256": "bc0d25288808206c0bad0ff842e9e68f6aa298f194cec977e540cc20438d79ec", + "source": "backend/townlight_records/schemas/connectors/__init__.py", + "sha256": "726eb96cca0ac51b015962c6574003a61edc9d81ad95c486d2f102749aeba0e1", + "bytes": 388, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/schemas/connectors/odbc.py", - "sha256": "d21cc39b1dc8567b6615bf14c3ff1a44c43cbedd851ce27acfe52e92015ede65", + "source": "backend/townlight_records/schemas/connectors/odbc.py", + "sha256": "7f90488d1774fdb632ed8a70cf34567966b823dded7e4ed49b71c66cd7cff2cf", + "bytes": 2296, "routes": [], "models": [ { @@ -14305,53 +13044,53 @@ { "name": "connector_type", "type": "Literal['odbc']", - "default": "'odbc'" + "line": 18 }, { "name": "connection_string", "type": "str", - "default": "" + "line": 20 }, { "name": "table_name", "type": "str", - "default": "" + "line": 21 }, { "name": "pk_column", "type": "str", - "default": "" + "line": 22 }, { "name": "modified_column", "type": "Optional[str]", - "default": "None" + "line": 23 }, { "name": "columns", "type": "Optional[list[str]]", - "default": "None" + "line": 24 }, { "name": "batch_size", "type": "int", - "default": "Field(default=500, ge=1, le=10000)" + "line": 26 }, { "name": "max_row_bytes", "type": "int", - "default": "Field(default=10485760, ge=1)" + "line": 27 } ], - "line": 17, - "doc": "" + "line": 17 } ], "configuration": [] }, { - "source": "installed-owned-source/app/schemas/connectors/rest_api.py", - "sha256": "a14767ee188a3ff4ca34b54f73f5c6059a146628d559de016402e3b3cf04793b", + "source": "backend/townlight_records/schemas/connectors/rest_api.py", + "sha256": "26bc9b8c7f3cd8d4bfdd99114486bc7b0aa926f42af3aba73754e4b8d21d3db7", + "bytes": 2769, "routes": [], "models": [ { @@ -14363,153 +13102,153 @@ { "name": "connector_type", "type": "Literal['rest_api']", - "default": "'rest_api'" + "line": 6 }, { "name": "base_url", "type": "AnyHttpUrl", - "default": "" + "line": 9 }, { "name": "endpoint_path", "type": "str", - "default": "Field(default='/', description='Path appended to base_url')" + "line": 10 }, { "name": "auth_method", "type": "Literal['none', 'api_key', 'bearer', 'oauth2', 'basic']", - "default": "" + "line": 13 }, { "name": "api_key", "type": "Optional[str]", - "default": "None" + "line": 14 }, { "name": "key_location", "type": "Literal['header', 'query']", - "default": "'header'" + "line": 15 }, { "name": "key_header", "type": "str", - "default": "'X-API-Key'" + "line": 16 }, { "name": "token", "type": "Optional[str]", - "default": "None" + "line": 17 }, { "name": "client_id", "type": "Optional[str]", - "default": "None" + "line": 18 }, { "name": "client_secret", "type": "Optional[str]", - "default": "None" + "line": 19 }, { "name": "token_url", "type": "Optional[AnyHttpUrl]", - "default": "None" + "line": 20 }, { "name": "username", "type": "Optional[str]", - "default": "None" + "line": 21 }, { "name": "password", "type": "Optional[str]", - "default": "None" + "line": 22 }, { "name": "pagination_style", "type": "Literal['none', 'page', 'offset', 'cursor']", - "default": "'none'" + "line": 25 }, { "name": "page_param", "type": "str", - "default": "'page'" + "line": 26 }, { "name": "offset_param", "type": "str", - "default": "'offset'" + "line": 27 }, { "name": "limit_param", "type": "str", - "default": "'limit'" + "line": 28 }, { "name": "page_size", "type": "int", - "default": "Field(default=100, ge=1, le=10000)" + "line": 29 }, { "name": "cursor_field", "type": "str", - "default": "'next'" + "line": 30 }, { "name": "response_format", "type": "Literal['json', 'xml', 'csv']", - "default": "'json'" + "line": 33 }, { "name": "results_field", "type": "Optional[str]", - "default": "None" + "line": 34 }, { "name": "data_key", "type": "Optional[str]", - "default": "None" + "line": 37 }, { "name": "id_field", "type": "str", - "default": "'id'" + "line": 38 }, { "name": "envelope_excludes", "type": "list[str]", - "default": "[]" + "line": 39 }, { "name": "since_field", "type": "Optional[str]", - "default": "None" + "line": 42 }, { "name": "since_format", "type": "str", - "default": "'%Y-%m-%dT%H:%M:%SZ'" + "line": 43 }, { "name": "max_records", "type": "int", - "default": "Field(default=10000, ge=1)" + "line": 46 }, { "name": "max_response_bytes", "type": "int", - "default": "Field(default=52428800, ge=1)" + "line": 47 } ], - "line": 5, - "doc": "" + "line": 5 } ], "configuration": [] }, { - "source": "installed-owned-source/app/schemas/department.py", + "source": "backend/townlight_records/schemas/department.py", "sha256": "5e45ab7a46abbb6a40e6c7d22b928aa65bdc0fabab5a424ee988fd31ec672c30", + "bytes": 486, "routes": [], "models": [ { @@ -14521,21 +13260,20 @@ { "name": "name", "type": "str", - "default": "" + "line": 7 }, { "name": "code", "type": "str", - "default": "" + "line": 8 }, { "name": "contact_email", "type": "str | None", - "default": "None" + "line": 9 } ], - "line": 6, - "doc": "" + "line": 6 }, { "name": "DepartmentRead", @@ -14546,31 +13284,30 @@ { "name": "id", "type": "uuid.UUID", - "default": "" + "line": 13 }, { "name": "name", "type": "str", - "default": "" + "line": 14 }, { "name": "code", "type": "str", - "default": "" + "line": 15 }, { "name": "contact_email", "type": "str | None", - "default": "" + "line": 16 }, { "name": "created_at", "type": "datetime", - "default": "" + "line": 17 } ], - "line": 12, - "doc": "" + "line": 12 }, { "name": "DepartmentUpdate", @@ -14581,28 +13318,28 @@ { "name": "name", "type": "str | None", - "default": "None" + "line": 22 }, { "name": "code", "type": "str | None", - "default": "None" + "line": 23 }, { "name": "contact_email", "type": "str | None", - "default": "None" + "line": 24 } ], - "line": 21, - "doc": "" + "line": 21 } ], "configuration": [] }, { - "source": "installed-owned-source/app/schemas/document.py", - "sha256": "139e5160eac328e5d5499c935a2ee4bbc8a7eee5a24cfe1fc7e08b1aca0fbc8a", + "source": "backend/townlight_records/schemas/document.py", + "sha256": "372c267701130f9e9a3e73833b81514f2d8753abcfe91f5f546ce919534b180c", + "bytes": 3191, "routes": [], "models": [ { @@ -14614,31 +13351,30 @@ { "name": "name", "type": "str", - "default": "" + "line": 8 }, { "name": "source_type", "type": "SourceType", - "default": "" + "line": 9 }, { "name": "connection_config", "type": "dict", - "default": "{}" + "line": 10 }, { "name": "sync_schedule", "type": "str | None", - "default": "None" + "line": 11 }, { "name": "schedule_enabled", "type": "bool", - "default": "True" + "line": 12 } ], - "line": 7, - "doc": "" + "line": 7 }, { "name": "DataSourceRead", @@ -14649,101 +13385,100 @@ { "name": "id", "type": "uuid.UUID", - "default": "" + "line": 25 }, { "name": "name", "type": "str", - "default": "" + "line": 26 }, { "name": "source_type", "type": "SourceType", - "default": "" + "line": 27 }, { "name": "sync_schedule", "type": "str | None", - "default": "None" + "line": 28 }, { "name": "schedule_enabled", "type": "bool", - "default": "True" + "line": 29 }, { "name": "next_sync_at", "type": "datetime | None", - "default": "None" + "line": 30 }, { "name": "is_active", "type": "bool", - "default": "" + "line": 31 }, { "name": "created_by", "type": "uuid.UUID", - "default": "" + "line": 32 }, { "name": "created_at", "type": "datetime", - "default": "" + "line": 33 }, { "name": "last_ingestion_at", "type": "datetime | None", - "default": "" + "line": 34 }, { "name": "last_sync_at", "type": "datetime | None", - "default": "None" + "line": 35 }, { "name": "last_sync_status", "type": "str | None", - "default": "None" + "line": 36 }, { "name": "last_error_message", "type": "str | None", - "default": "None" + "line": 37 }, { "name": "consecutive_failure_count", "type": "int", - "default": "0" + "line": 38 }, { "name": "sync_paused", "type": "bool", - "default": "False" + "line": 39 }, { "name": "health_status", "type": "str", - "default": "'healthy'" + "line": 40 }, { "name": "active_failure_count", "type": "int", - "default": "0" + "line": 41 }, { "name": "connector_type", "type": "str | None", - "default": "None" + "line": 42 }, { "name": "updated_at", "type": "datetime | None", - "default": "None" + "line": 43 } ], - "line": 23, - "doc": "Redacted datasource shape \u2014 safe for non-admin roles. connection_config omitted." + "line": 23 }, { "name": "DataSourceAdminRead", @@ -14754,11 +13489,10 @@ { "name": "connection_config", "type": "dict", - "default": "" + "line": 54 } ], - "line": 52, - "doc": "Full datasource shape including connection_config. Returned only by admin-gated endpoints." + "line": 52 }, { "name": "DataSourceUpdate", @@ -14769,31 +13503,30 @@ { "name": "name", "type": "str | None", - "default": "None" + "line": 58 }, { "name": "connection_config", "type": "dict | None", - "default": "None" + "line": 59 }, { "name": "sync_schedule", "type": "str | None", - "default": "None" + "line": 60 }, { "name": "schedule_enabled", "type": "bool | None", - "default": "None" + "line": 61 }, { "name": "is_active", "type": "bool | None", - "default": "None" + "line": 62 } ], - "line": 57, - "doc": "" + "line": 57 }, { "name": "DocumentRead", @@ -14804,71 +13537,70 @@ { "name": "id", "type": "uuid.UUID", - "default": "" + "line": 74 }, { "name": "source_id", "type": "uuid.UUID", - "default": "" + "line": 75 }, { "name": "source_path", "type": "str", - "default": "" + "line": 76 }, { "name": "filename", "type": "str", - "default": "" + "line": 77 }, { "name": "file_type", "type": "str", - "default": "" + "line": 78 }, { "name": "file_hash", "type": "str", - "default": "" + "line": 79 }, { "name": "file_size", "type": "int", - "default": "" + "line": 80 }, { "name": "ingestion_status", "type": "IngestionStatus", - "default": "" + "line": 81 }, { "name": "ingestion_error", "type": "str | None", - "default": "" + "line": 82 }, { "name": "chunk_count", "type": "int", - "default": "" + "line": 83 }, { "name": "ingested_at", "type": "datetime | None", - "default": "" + "line": 84 }, { "name": "connector_type", "type": "str | None", - "default": "None" + "line": 85 }, { "name": "updated_at", "type": "datetime | None", - "default": "None" + "line": 86 } ], - "line": 73, - "doc": "" + "line": 73 }, { "name": "DocumentChunkRead", @@ -14879,36 +13611,35 @@ { "name": "id", "type": "uuid.UUID", - "default": "" + "line": 91 }, { "name": "document_id", "type": "uuid.UUID", - "default": "" + "line": 92 }, { "name": "chunk_index", "type": "int", - "default": "" + "line": 93 }, { "name": "content_text", "type": "str", - "default": "" + "line": 94 }, { "name": "token_count", "type": "int", - "default": "" + "line": 95 }, { "name": "page_number", "type": "int | None", - "default": "" + "line": 96 } ], - "line": 90, - "doc": "" + "line": 90 }, { "name": "IngestionStats", @@ -14919,38 +13650,38 @@ { "name": "total_sources", "type": "int", - "default": "" + "line": 101 }, { "name": "active_sources", "type": "int", - "default": "" + "line": 102 }, { "name": "total_documents", "type": "int", - "default": "" + "line": 103 }, { "name": "documents_by_status", "type": "dict[str, int]", - "default": "" + "line": 104 }, { "name": "total_chunks", "type": "int", - "default": "" + "line": 105 } ], - "line": 100, - "doc": "" + "line": 100 } ], "configuration": [] }, { - "source": "installed-owned-source/app/schemas/exemption.py", - "sha256": "7cd5c0e1d1c2eaca8dace50b570ac06832765cbb3c3df148b84d3a12188f4664", + "source": "backend/townlight_records/schemas/exemption.py", + "sha256": "ecdb2535bcbd322b3e356d21207c59f461b83dbfc7e1bb5e13e30322698f24a4", + "bytes": 2352, "routes": [], "models": [ { @@ -14962,36 +13693,35 @@ { "name": "state_code", "type": "str", - "default": "" + "line": 9 }, { "name": "category", "type": "str", - "default": "" + "line": 10 }, { "name": "rule_type", "type": "RuleType", - "default": "" + "line": 11 }, { "name": "rule_definition", "type": "str", - "default": "" + "line": 12 }, { "name": "description", "type": "str | None", - "default": "None" + "line": 13 }, { "name": "enabled", "type": "bool", - "default": "True" + "line": 14 } ], - "line": 8, - "doc": "" + "line": 8 }, { "name": "ExemptionRuleRead", @@ -15002,56 +13732,55 @@ { "name": "id", "type": "uuid.UUID", - "default": "" + "line": 18 }, { "name": "state_code", "type": "str", - "default": "" + "line": 19 }, { "name": "category", "type": "str", - "default": "" + "line": 20 }, { "name": "rule_type", "type": "RuleType", - "default": "" + "line": 21 }, { "name": "rule_definition", "type": "str", - "default": "" + "line": 22 }, { "name": "description", "type": "str | None", - "default": "" + "line": 23 }, { "name": "enabled", "type": "bool", - "default": "" + "line": 24 }, { "name": "version", "type": "int", - "default": "1" + "line": 25 }, { "name": "created_by", "type": "uuid.UUID", - "default": "" + "line": 26 }, { "name": "created_at", "type": "datetime", - "default": "" + "line": 27 } ], - "line": 17, - "doc": "" + "line": 17 }, { "name": "ExemptionRuleUpdate", @@ -15062,21 +13791,20 @@ { "name": "rule_definition", "type": "str | None", - "default": "None" + "line": 32 }, { "name": "description", "type": "str | None", - "default": "None" + "line": 33 }, { "name": "enabled", "type": "bool | None", - "default": "None" + "line": 34 } ], - "line": 31, - "doc": "" + "line": 31 }, { "name": "ExemptionFlagRead", @@ -15087,66 +13815,65 @@ { "name": "id", "type": "uuid.UUID", - "default": "" + "line": 38 }, { "name": "chunk_id", "type": "uuid.UUID", - "default": "" + "line": 39 }, { "name": "rule_id", "type": "uuid.UUID | None", - "default": "" + "line": 40 }, { "name": "request_id", "type": "uuid.UUID", - "default": "" + "line": 41 }, { "name": "category", "type": "str", - "default": "" + "line": 42 }, { "name": "matched_text", "type": "str | None", - "default": "" + "line": 43 }, { "name": "confidence", "type": "float", - "default": "" + "line": 44 }, { "name": "status", "type": "FlagStatus", - "default": "" + "line": 45 }, { "name": "reviewed_by", "type": "uuid.UUID | None", - "default": "" + "line": 46 }, { "name": "reviewed_at", "type": "datetime | None", - "default": "" + "line": 47 }, { "name": "review_reason", "type": "str | None", - "default": "" + "line": 48 }, { "name": "created_at", "type": "datetime", - "default": "" + "line": 49 } ], - "line": 37, - "doc": "" + "line": 37 }, { "name": "ExemptionFlagReview", @@ -15157,16 +13884,15 @@ { "name": "status", "type": "FlagStatus", - "default": "" + "line": 54 }, { "name": "review_reason", "type": "str | None", - "default": "None" + "line": 55 } ], - "line": 53, - "doc": "" + "line": 53 }, { "name": "DisclosureTemplateCreate", @@ -15177,21 +13903,20 @@ { "name": "template_type", "type": "str", - "default": "" + "line": 59 }, { "name": "state_code", "type": "str | None", - "default": "None" + "line": 60 }, { "name": "content", "type": "str", - "default": "" + "line": 61 } ], - "line": 58, - "doc": "" + "line": 58 }, { "name": "DisclosureTemplateRead", @@ -15202,41 +13927,40 @@ { "name": "id", "type": "uuid.UUID", - "default": "" + "line": 65 }, { "name": "template_type", "type": "str", - "default": "" + "line": 66 }, { "name": "state_code", "type": "str | None", - "default": "" + "line": 67 }, { "name": "content", "type": "str", - "default": "" + "line": 68 }, { "name": "version", "type": "int", - "default": "" + "line": 69 }, { "name": "updated_by", "type": "uuid.UUID", - "default": "" + "line": 70 }, { "name": "updated_at", "type": "datetime", - "default": "" + "line": 71 } ], - "line": 64, - "doc": "" + "line": 64 }, { "name": "ExemptionDashboard", @@ -15247,36 +13971,35 @@ { "name": "total_flags", "type": "int", - "default": "" + "line": 76 }, { "name": "by_status", "type": "dict[str, int]", - "default": "" + "line": 77 }, { "name": "by_category", "type": "dict[str, int]", - "default": "" + "line": 78 }, { "name": "acceptance_rate", "type": "float", - "default": "" + "line": 79 }, { "name": "total_rules", "type": "int", - "default": "" + "line": 80 }, { "name": "active_rules", "type": "int", - "default": "" + "line": 81 } ], - "line": 75, - "doc": "" + "line": 75 }, { "name": "ExemptionAccuracyReport", @@ -15287,36 +14010,35 @@ { "name": "category", "type": "str", - "default": "" + "line": 85 }, { "name": "total_flags", "type": "int", - "default": "" + "line": 86 }, { "name": "accepted", "type": "int", - "default": "" + "line": 87 }, { "name": "rejected", "type": "int", - "default": "" + "line": 88 }, { "name": "pending", "type": "int", - "default": "" + "line": 89 }, { "name": "acceptance_rate", "type": "float", - "default": "" + "line": 90 } ], - "line": 84, - "doc": "" + "line": 84 }, { "name": "DisclosureTemplateRendered", @@ -15327,26 +14049,25 @@ { "name": "id", "type": "uuid.UUID", - "default": "" + "line": 94 }, { "name": "template_type", "type": "str", - "default": "" + "line": 95 }, { "name": "rendered_content", "type": "str", - "default": "" + "line": 96 }, { "name": "has_unresolved_variables", "type": "bool", - "default": "" + "line": 97 } ], - "line": 93, - "doc": "" + "line": 93 }, { "name": "DisclosureTemplateUpdate", @@ -15357,23 +14078,23 @@ { "name": "content", "type": "str | None", - "default": "None" + "line": 101 }, { "name": "state_code", "type": "str | None", - "default": "None" + "line": 102 } ], - "line": 100, - "doc": "" + "line": 100 } ], "configuration": [] }, { - "source": "installed-owned-source/app/schemas/fee_schedule.py", + "source": "backend/townlight_records/schemas/fee_schedule.py", "sha256": "132fca7b2f2484f924464e8c01bec43674d8a6fc579202849cf73e43630adf70", + "bytes": 700, "routes": [], "models": [ { @@ -15385,31 +14106,30 @@ { "name": "jurisdiction", "type": "str", - "default": "" + "line": 7 }, { "name": "fee_type", "type": "str", - "default": "" + "line": 8 }, { "name": "amount", "type": "float", - "default": "" + "line": 9 }, { "name": "description", "type": "str | None", - "default": "None" + "line": 10 }, { "name": "effective_date", "type": "date | None", - "default": "None" + "line": 11 } ], - "line": 6, - "doc": "" + "line": 6 }, { "name": "FeeScheduleRead", @@ -15420,46 +14140,45 @@ { "name": "id", "type": "uuid.UUID", - "default": "" + "line": 15 }, { "name": "jurisdiction", "type": "str", - "default": "" + "line": 16 }, { "name": "fee_type", "type": "str", - "default": "" + "line": 17 }, { "name": "amount", "type": "float", - "default": "" + "line": 18 }, { "name": "description", "type": "str | None", - "default": "" + "line": 19 }, { "name": "effective_date", "type": "date | None", - "default": "" + "line": 20 }, { "name": "created_by", "type": "uuid.UUID | None", - "default": "" + "line": 21 }, { "name": "created_at", "type": "datetime", - "default": "" + "line": 22 } ], - "line": 14, - "doc": "" + "line": 14 }, { "name": "FeeScheduleUpdate", @@ -15470,33 +14189,33 @@ { "name": "fee_type", "type": "str | None", - "default": "None" + "line": 27 }, { "name": "amount", "type": "float | None", - "default": "None" + "line": 28 }, { "name": "description", "type": "str | None", - "default": "None" + "line": 29 }, { "name": "effective_date", "type": "date | None", - "default": "None" + "line": 30 } ], - "line": 26, - "doc": "" + "line": 26 } ], "configuration": [] }, { - "source": "installed-owned-source/app/schemas/notifications.py", + "source": "backend/townlight_records/schemas/notifications.py", "sha256": "61d74c4b0977679c0739a374997ae5d49792d47f0f469baf6c422b77fd993fa3", + "bytes": 928, "routes": [], "models": [ { @@ -15508,26 +14227,25 @@ { "name": "event_type", "type": "str", - "default": "" + "line": 8 }, { "name": "channel", "type": "str", - "default": "'email'" + "line": 9 }, { "name": "subject_template", "type": "str", - "default": "" + "line": 10 }, { "name": "body_template", "type": "str", - "default": "" + "line": 11 } ], - "line": 7, - "doc": "" + "line": 7 }, { "name": "NotificationTemplateRead", @@ -15538,41 +14256,40 @@ { "name": "id", "type": "uuid.UUID", - "default": "" + "line": 17 }, { "name": "event_type", "type": "str", - "default": "" + "line": 18 }, { "name": "channel", "type": "str", - "default": "" + "line": 19 }, { "name": "subject_template", "type": "str", - "default": "" + "line": 20 }, { "name": "body_template", "type": "str", - "default": "" + "line": 21 }, { "name": "is_active", "type": "bool", - "default": "" + "line": 22 }, { "name": "created_at", "type": "datetime", - "default": "" + "line": 23 } ], - "line": 14, - "doc": "" + "line": 14 }, { "name": "NotificationTemplateUpdate", @@ -15583,21 +14300,20 @@ { "name": "subject_template", "type": "str | None", - "default": "None" + "line": 27 }, { "name": "body_template", "type": "str | None", - "default": "None" + "line": 28 }, { "name": "is_active", "type": "bool | None", - "default": "None" + "line": 29 } ], - "line": 26, - "doc": "" + "line": 26 }, { "name": "NotificationLogRead", @@ -15608,58 +14324,58 @@ { "name": "id", "type": "uuid.UUID", - "default": "" + "line": 35 }, { "name": "template_id", "type": "uuid.UUID | None", - "default": "" + "line": 36 }, { "name": "recipient_email", "type": "str", - "default": "" + "line": 37 }, { "name": "request_id", "type": "uuid.UUID | None", - "default": "" + "line": 38 }, { "name": "channel", "type": "str", - "default": "" + "line": 39 }, { "name": "status", "type": "str", - "default": "" + "line": 40 }, { "name": "sent_at", "type": "datetime | None", - "default": "" + "line": 41 }, { "name": "error_message", "type": "str | None", - "default": "" + "line": 42 }, { "name": "created_at", "type": "datetime", - "default": "" + "line": 43 } ], - "line": 32, - "doc": "" + "line": 32 } ], "configuration": [] }, { - "source": "installed-owned-source/app/schemas/request.py", - "sha256": "7c632f8eaaa7198a74edf0860e25fcf2ef3fa8c8a5eb15fd55f633089787b8cd", + "source": "backend/townlight_records/schemas/request.py", + "sha256": "d98eea27470287dc25498bce26cd6e2594b812585113428b8647d8f5ce1e0980", + "bytes": 4229, "routes": [], "models": [ { @@ -15671,51 +14387,50 @@ { "name": "requester_name", "type": "str", - "default": "Field(..., max_length=255)" + "line": 9 }, { "name": "requester_email", "type": "str | None", - "default": "Field(None, max_length=255)" + "line": 10 }, { "name": "requester_phone", "type": "str | None", - "default": "Field(None, max_length=50)" + "line": 11 }, { "name": "requester_type", "type": "str | None", - "default": "Field(None, max_length=100)" + "line": 12 }, { "name": "description", "type": "str", - "default": "Field(..., max_length=10000)" + "line": 13 }, { "name": "statutory_deadline", "type": "datetime | None", - "default": "None" + "line": 14 }, { "name": "priority", "type": "str", - "default": "'normal'" + "line": 15 }, { "name": "scope_assessment", "type": "str | None", - "default": "Field(None, pattern='^(narrow|moderate|broad)$')" + "line": 16 }, { "name": "department_id", "type": "uuid.UUID | None", - "default": "None" + "line": 17 } ], - "line": 8, - "doc": "" + "line": 8 }, { "name": "RequestRead", @@ -15726,116 +14441,115 @@ { "name": "id", "type": "uuid.UUID", - "default": "" + "line": 21 }, { "name": "requester_name", "type": "str", - "default": "" + "line": 22 }, { "name": "requester_email", "type": "str | None", - "default": "" + "line": 23 }, { "name": "requester_phone", "type": "str | None", - "default": "None" + "line": 24 }, { "name": "requester_type", "type": "str | None", - "default": "None" + "line": 25 }, { "name": "date_received", "type": "datetime", - "default": "" + "line": 26 }, { "name": "statutory_deadline", "type": "datetime | None", - "default": "" + "line": 27 }, { "name": "description", "type": "str", - "default": "" + "line": 28 }, { "name": "status", "type": "RequestStatus", - "default": "" + "line": 29 }, { "name": "assigned_to", "type": "uuid.UUID | None", - "default": "" + "line": 30 }, { "name": "created_by", "type": "uuid.UUID | None", - "default": "" + "line": 31 }, { "name": "created_at", "type": "datetime", - "default": "" + "line": 32 }, { "name": "response_draft", "type": "str | None", - "default": "" + "line": 33 }, { "name": "review_notes", "type": "str | None", - "default": "" + "line": 34 }, { "name": "department_id", "type": "uuid.UUID | None", - "default": "None" + "line": 35 }, { "name": "estimated_fee", "type": "float | None", - "default": "None" + "line": 36 }, { "name": "fee_status", "type": "str | None", - "default": "None" + "line": 37 }, { "name": "fee_waiver_requested", "type": "bool", - "default": "False" + "line": 38 }, { "name": "priority", "type": "str", - "default": "'normal'" + "line": 39 }, { "name": "scope_assessment", "type": "str | None", - "default": "None" + "line": 40 }, { "name": "closed_at", "type": "datetime | None", - "default": "None" + "line": 41 }, { "name": "closure_reason", "type": "str | None", - "default": "None" + "line": 42 } ], - "line": 20, - "doc": "" + "line": 20 }, { "name": "RequestUpdate", @@ -15846,36 +14560,35 @@ { "name": "description", "type": "str | None", - "default": "None" + "line": 48 }, { "name": "status", "type": "RequestStatus | None", - "default": "None" + "line": 49 }, { "name": "assigned_to", "type": "uuid.UUID | None", - "default": "None" + "line": 50 }, { "name": "response_draft", "type": "str | None", - "default": "None" + "line": 51 }, { "name": "statutory_deadline", "type": "datetime | None", - "default": "None" + "line": 52 }, { "name": "scope_assessment", "type": "str | None", - "default": "None" + "line": 53 } ], - "line": 47, - "doc": "" + "line": 47 }, { "name": "RequestDocumentAdd", @@ -15886,16 +14599,15 @@ { "name": "document_id", "type": "uuid.UUID", - "default": "" + "line": 57 }, { "name": "relevance_note", "type": "str | None", - "default": "None" + "line": 58 } ], - "line": 56, - "doc": "" + "line": 56 }, { "name": "RequestDocumentRead", @@ -15906,46 +14618,45 @@ { "name": "id", "type": "uuid.UUID", - "default": "" + "line": 62 }, { "name": "request_id", "type": "uuid.UUID", - "default": "" + "line": 63 }, { "name": "document_id", "type": "uuid.UUID", - "default": "" + "line": 64 }, { "name": "relevance_note", "type": "str | None", - "default": "" + "line": 65 }, { "name": "exemption_flags", "type": "dict | None", - "default": "" + "line": 66 }, { "name": "inclusion_status", "type": "InclusionStatus", - "default": "" + "line": 67 }, { "name": "attached_at", "type": "datetime", - "default": "" + "line": 68 }, { "name": "attached_by", "type": "uuid.UUID", - "default": "" + "line": 69 } ], - "line": 61, - "doc": "" + "line": 61 }, { "name": "RequestStats", @@ -15956,26 +14667,25 @@ { "name": "total_requests", "type": "int", - "default": "" + "line": 75 }, { "name": "by_status", "type": "dict[str, int]", - "default": "" + "line": 76 }, { "name": "approaching_deadline", "type": "int", - "default": "" + "line": 77 }, { "name": "overdue", "type": "int", - "default": "" + "line": 78 } ], - "line": 74, - "doc": "" + "line": 74 }, { "name": "TimelineEventCreate", @@ -15986,21 +14696,20 @@ { "name": "event_type", "type": "str", - "default": "" + "line": 82 }, { "name": "description", "type": "str", - "default": "" + "line": 83 }, { "name": "internal_note", "type": "str | None", - "default": "None" + "line": 84 } ], - "line": 81, - "doc": "" + "line": 81 }, { "name": "TimelineEventRead", @@ -16011,46 +14720,45 @@ { "name": "id", "type": "uuid.UUID", - "default": "" + "line": 89 }, { "name": "request_id", "type": "uuid.UUID", - "default": "" + "line": 90 }, { "name": "event_type", "type": "str", - "default": "" + "line": 91 }, { "name": "actor_id", "type": "uuid.UUID | None", - "default": "" + "line": 92 }, { "name": "actor_role", "type": "str | None", - "default": "" + "line": 93 }, { "name": "description", "type": "str", - "default": "" + "line": 94 }, { "name": "internal_note", "type": "str | None", - "default": "" + "line": 95 }, { "name": "created_at", "type": "datetime", - "default": "" + "line": 96 } ], - "line": 87, - "doc": "" + "line": 87 }, { "name": "MessageCreate", @@ -16061,16 +14769,15 @@ { "name": "message_text", "type": "str", - "default": "" + "line": 100 }, { "name": "is_internal", "type": "bool", - "default": "False" + "line": 101 } ], - "line": 99, - "doc": "" + "line": 99 }, { "name": "MessageRead", @@ -16081,41 +14788,40 @@ { "name": "id", "type": "uuid.UUID", - "default": "" + "line": 106 }, { "name": "request_id", "type": "uuid.UUID", - "default": "" + "line": 107 }, { "name": "sender_type", "type": "str", - "default": "" + "line": 108 }, { "name": "sender_id", "type": "uuid.UUID | None", - "default": "" + "line": 109 }, { "name": "message_text", "type": "str", - "default": "" + "line": 110 }, { "name": "is_internal", "type": "bool", - "default": "" + "line": 111 }, { "name": "created_at", "type": "datetime", - "default": "" + "line": 112 } ], - "line": 104, - "doc": "" + "line": 104 }, { "name": "FeeLineItemCreate", @@ -16126,26 +14832,25 @@ { "name": "description", "type": "str", - "default": "" + "line": 116 }, { "name": "quantity", "type": "int", - "default": "1" + "line": 117 }, { "name": "unit_price", "type": "float", - "default": "" + "line": 118 }, { "name": "fee_schedule_id", "type": "uuid.UUID | None", - "default": "None" + "line": 119 } ], - "line": 115, - "doc": "" + "line": 115 }, { "name": "FeeLineItemRead", @@ -16156,51 +14861,50 @@ { "name": "id", "type": "uuid.UUID", - "default": "" + "line": 124 }, { "name": "request_id", "type": "uuid.UUID", - "default": "" + "line": 125 }, { "name": "fee_schedule_id", "type": "uuid.UUID | None", - "default": "" + "line": 126 }, { "name": "description", "type": "str", - "default": "" + "line": 127 }, { "name": "quantity", "type": "int", - "default": "" + "line": 128 }, { "name": "unit_price", "type": "float", - "default": "" + "line": 129 }, { "name": "total", "type": "float", - "default": "" + "line": 130 }, { "name": "status", "type": "str", - "default": "" + "line": 131 }, { "name": "created_at", "type": "datetime", - "default": "" + "line": 132 } ], - "line": 122, - "doc": "" + "line": 122 }, { "name": "ResponseLetterCreate", @@ -16211,11 +14915,10 @@ { "name": "template_id", "type": "uuid.UUID | None", - "default": "None" + "line": 139 } ], - "line": 138, - "doc": "" + "line": 138 }, { "name": "ResponseLetterRead", @@ -16226,56 +14929,55 @@ { "name": "id", "type": "uuid.UUID", - "default": "" + "line": 144 }, { "name": "request_id", "type": "uuid.UUID", - "default": "" + "line": 145 }, { "name": "template_id", "type": "uuid.UUID | None", - "default": "" + "line": 146 }, { "name": "generated_content", "type": "str", - "default": "" + "line": 147 }, { "name": "edited_content", "type": "str | None", - "default": "" + "line": 148 }, { "name": "status", "type": "str", - "default": "" + "line": 149 }, { "name": "generated_by", "type": "uuid.UUID | None", - "default": "" + "line": 150 }, { "name": "approved_by", "type": "uuid.UUID | None", - "default": "" + "line": 151 }, { "name": "sent_at", "type": "datetime | None", - "default": "" + "line": 152 }, { "name": "created_at", "type": "datetime", - "default": "" + "line": 153 } ], - "line": 142, - "doc": "" + "line": 142 }, { "name": "ResponseLetterUpdate", @@ -16286,23 +14988,23 @@ { "name": "edited_content", "type": "str | None", - "default": "None" + "line": 157 }, { "name": "status", "type": "str | None", - "default": "None" + "line": 158 } ], - "line": 156, - "doc": "" + "line": 156 } ], "configuration": [] }, { - "source": "installed-owned-source/app/schemas/search.py", + "source": "backend/townlight_records/schemas/search.py", "sha256": "13a5c1913290f2d1b4c9447c3b3d4d1046038e146c2b11a97a03e1bb895b3015", + "bytes": 1150, "routes": [], "models": [ { @@ -16314,31 +15016,30 @@ { "name": "query", "type": "str", - "default": "" + "line": 7 }, { "name": "session_id", "type": "uuid.UUID | None", - "default": "None" + "line": 8 }, { "name": "filters", "type": "dict | None", - "default": "None" + "line": 9 }, { "name": "limit", "type": "int", - "default": "Field(default=10, le=50)" + "line": 10 }, { "name": "synthesize", "type": "bool", - "default": "False" + "line": 11 } ], - "line": 6, - "doc": "" + "line": 6 }, { "name": "SearchResultItem", @@ -16349,51 +15050,50 @@ { "name": "chunk_id", "type": "uuid.UUID", - "default": "" + "line": 15 }, { "name": "document_id", "type": "uuid.UUID", - "default": "" + "line": 16 }, { "name": "filename", "type": "str", - "default": "" + "line": 17 }, { "name": "file_type", "type": "str", - "default": "" + "line": 18 }, { "name": "source_path", "type": "str", - "default": "" + "line": 19 }, { "name": "page_number", "type": "int | None", - "default": "" + "line": 20 }, { "name": "content_text", "type": "str", - "default": "" + "line": 21 }, { "name": "similarity_score", "type": "float", - "default": "" + "line": 22 }, { "name": "rank", "type": "int", - "default": "" + "line": 23 } ], - "line": 14, - "doc": "" + "line": 14 }, { "name": "SearchResponse", @@ -16404,41 +15104,40 @@ { "name": "query_id", "type": "uuid.UUID", - "default": "" + "line": 29 }, { "name": "session_id", "type": "uuid.UUID", - "default": "" + "line": 30 }, { "name": "query_text", "type": "str", - "default": "" + "line": 31 }, { "name": "results", "type": "list[SearchResultItem]", - "default": "" + "line": 32 }, { "name": "results_count", "type": "int", - "default": "" + "line": 33 }, { "name": "synthesized_answer", "type": "str | None", - "default": "None" + "line": 34 }, { "name": "ai_generated", "type": "bool", - "default": "False" + "line": 35 } ], - "line": 28, - "doc": "" + "line": 28 }, { "name": "SearchSessionRead", @@ -16449,26 +15148,25 @@ { "name": "id", "type": "uuid.UUID", - "default": "" + "line": 39 }, { "name": "user_id", "type": "uuid.UUID", - "default": "" + "line": 40 }, { "name": "created_at", "type": "datetime", - "default": "" + "line": 41 }, { "name": "queries", "type": "list[dict]", - "default": "[]" + "line": 42 } ], - "line": 38, - "doc": "" + "line": 38 }, { "name": "SearchFilterOptions", @@ -16479,33 +15177,33 @@ { "name": "file_types", "type": "list[str]", - "default": "" + "line": 48 }, { "name": "source_names", "type": "list[str]", - "default": "" + "line": 49 }, { "name": "departments", "type": "list[dict]", - "default": "[]" + "line": 50 }, { "name": "date_range", "type": "dict | None", - "default": "None" + "line": 51 } ], - "line": 47, - "doc": "" + "line": 47 } ], "configuration": [] }, { - "source": "installed-owned-source/app/schemas/service_account.py", - "sha256": "998b5de7ba31a8800d2feb6379c5eaa00747bccd23c05ce99863a42b0951a37f", + "source": "backend/townlight_records/schemas/service_account.py", + "sha256": "0fe0918fc3daa11c37d371119d8a875c6d9061f82f005517efade03b19ec4210", + "bytes": 721, "routes": [], "models": [ { @@ -16517,16 +15215,15 @@ { "name": "name", "type": "str", - "default": "" + "line": 10 }, { "name": "role", "type": "UserRole", - "default": "UserRole.READ_ONLY" + "line": 11 } ], - "line": 9, - "doc": "" + "line": 9 }, { "name": "ServiceAccountRead", @@ -16537,36 +15234,35 @@ { "name": "id", "type": "uuid.UUID", - "default": "" + "line": 15 }, { "name": "name", "type": "str", - "default": "" + "line": 16 }, { "name": "role", "type": "UserRole", - "default": "" + "line": 17 }, { "name": "created_by", "type": "uuid.UUID", - "default": "" + "line": 18 }, { "name": "created_at", "type": "datetime", - "default": "" + "line": 19 }, { "name": "is_active", "type": "bool", - "default": "" + "line": 20 } ], - "line": 14, - "doc": "" + "line": 14 }, { "name": "ServiceAccountCreated", @@ -16577,11 +15273,10 @@ { "name": "api_key", "type": "str", - "default": "" + "line": 27 } ], - "line": 25, - "doc": "Returned only on creation \u2014 includes the plaintext API key (shown once)." + "line": 25 }, { "name": "ServiceAccountUpdate", @@ -16592,23 +15287,23 @@ { "name": "role", "type": "UserRole | None", - "default": "None" + "line": 31 }, { "name": "is_active", "type": "bool | None", - "default": "None" + "line": 32 } ], - "line": 30, - "doc": "" + "line": 30 } ], "configuration": [] }, { - "source": "installed-owned-source/app/schemas/sync_failure.py", + "source": "backend/townlight_records/schemas/sync_failure.py", "sha256": "7d0f1052aba113868dc3439ef78b85b8d9941cf243eb7224ca12e1d9019f9971", + "bytes": 905, "routes": [], "models": [ { @@ -16620,66 +15315,65 @@ { "name": "id", "type": "uuid.UUID", - "default": "" + "line": 9 }, { "name": "source_id", "type": "uuid.UUID", - "default": "" + "line": 10 }, { "name": "source_path", "type": "str", - "default": "" + "line": 11 }, { "name": "error_message", "type": "str | None", - "default": "" + "line": 12 }, { "name": "error_class", "type": "str | None", - "default": "" + "line": 13 }, { "name": "http_status_code", "type": "int | None", - "default": "" + "line": 14 }, { "name": "retry_count", "type": "int", - "default": "" + "line": 15 }, { "name": "status", "type": "str", - "default": "" + "line": 16 }, { "name": "first_failed_at", "type": "datetime", - "default": "" + "line": 17 }, { "name": "last_retried_at", "type": "datetime | None", - "default": "" + "line": 18 }, { "name": "dismissed_at", "type": "datetime | None", - "default": "" + "line": 19 }, { "name": "dismissed_by", "type": "uuid.UUID | None", - "default": "" + "line": 20 } ], - "line": 8, - "doc": "" + "line": 8 }, { "name": "SyncRunLogRead", @@ -16690,58 +15384,58 @@ { "name": "id", "type": "uuid.UUID", - "default": "" + "line": 25 }, { "name": "source_id", "type": "uuid.UUID", - "default": "" + "line": 26 }, { "name": "started_at", "type": "datetime", - "default": "" + "line": 27 }, { "name": "finished_at", "type": "datetime | None", - "default": "" + "line": 28 }, { "name": "status", "type": "str | None", - "default": "" + "line": 29 }, { "name": "records_attempted", "type": "int", - "default": "" + "line": 30 }, { "name": "records_succeeded", "type": "int", - "default": "" + "line": 31 }, { "name": "records_failed", "type": "int", - "default": "" + "line": 32 }, { "name": "error_summary", "type": "str | None", - "default": "" + "line": 33 } ], - "line": 24, - "doc": "" + "line": 24 } ], "configuration": [] }, { - "source": "installed-owned-source/app/schemas/user.py", - "sha256": "95cee0fce572e5c68f21453c6d2ae145f4a44a7aa9e3b7a3e1d6393eebf5bf06", + "source": "backend/townlight_records/schemas/user.py", + "sha256": "313f8c6927c142239ccfd22d5960378a77bb973a84e7c936052d4a77ae3507b5", + "bytes": 3200, "routes": [], "models": [ { @@ -16753,36 +15447,35 @@ { "name": "full_name", "type": "str", - "default": "" + "line": 11 }, { "name": "role", "type": "UserRole", - "default": "" + "line": 12 }, { "name": "created_at", "type": "datetime", - "default": "" + "line": 13 }, { "name": "last_login", "type": "datetime | None", - "default": "" + "line": 14 }, { "name": "must_change_password", "type": "bool", - "default": "False" + "line": 15 }, { "name": "department_id", "type": "uuid.UUID | None", - "default": "None" + "line": 16 } ], - "line": 10, - "doc": "" + "line": 10 }, { "name": "UserCreate", @@ -16793,16 +15486,15 @@ { "name": "full_name", "type": "str", - "default": "''" + "line": 36 }, { "name": "role", "type": "UserRole", - "default": "UserRole.PUBLIC" + "line": 37 } ], - "line": 19, - "doc": "Self-registration schema for the public ``/auth/register`` endpoint.\n\nRole is forced server-side, never honored from the request payload:\n* In ``PORTAL_MODE=public``: role \u2192 ``UserRole.PUBLIC`` (residents who\n register via the public surface get the minimal public role, never\n STAFF).\n* In ``PORTAL_MODE=private``: ``/auth/register`` is not mounted at all,\n so this schema is unreachable in private mode. The fallback value here\n matches the private-mode non-assignability posture (PUBLIC, not STAFF)\n \u2014 which also corrects a pre-existing bug where self-register was\n silently forced to STAFF regardless of caller intent.\n\nAdmin-driven user creation (including explicit STAFF/REVIEWER/LIAISON/\nREAD_ONLY assignments) goes through ``/admin/users`` via\n:class:`AdminUserCreate`." + "line": 19 }, { "name": "AdminUserCreate", @@ -16813,21 +15505,20 @@ { "name": "full_name", "type": "str", - "default": "''" + "line": 56 }, { "name": "role", "type": "UserRole", - "default": "UserRole.STAFF" + "line": 57 }, { "name": "department_id", "type": "uuid.UUID | None", - "default": "None" + "line": 58 } ], - "line": 54, - "doc": "Schema for admin-only user creation endpoint. Role IS caller-supplied." + "line": 54 }, { "name": "UserUpdate", @@ -16838,16 +15529,15 @@ { "name": "full_name", "type": "str | None", - "default": "None" + "line": 62 }, { "name": "role", "type": "UserRole | None", - "default": "None" + "line": 63 } ], - "line": 61, - "doc": "" + "line": 61 }, { "name": "UserSelfUpdate", @@ -16858,25 +15548,26 @@ { "name": "full_name", "type": "str | None", - "default": "None" + "line": 73 } ], - "line": 66, - "doc": "Schema for user self-update via PATCH /users/me.\n\nExcludes role and department_id. Any payload containing those fields is\nrejected at parse time (HTTP 422). Role and department changes require\nadmin privileges via /admin/users/{id}." + "line": 66 } ], "configuration": [] }, { - "source": "installed-owned-source/app/search/__init__.py", + "source": "backend/townlight_records/search/__init__.py", "sha256": "6d5a53e92963972bce100511001cfc78b65a347390a47b4273c0c62f7a88ccc9", + "bytes": 24, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/search/engine.py", - "sha256": "ff3c9ca2fba3293400ed1d5f4056e5a47a8673f443061b703abdace1e309d454", + "source": "backend/townlight_records/search/engine.py", + "sha256": "64f383a27cdafc56c200a352fa29dc9548fda0bbf61e1a45a67fb80f649d48ec", + "bytes": 5570, "routes": [], "models": [ { @@ -16886,4594 +15577,4969 @@ { "name": "chunk_id", "type": "uuid.UUID", - "default": "" + "line": 14 }, { "name": "document_id", "type": "uuid.UUID", - "default": "" + "line": 15 }, { "name": "filename", "type": "str", - "default": "" + "line": 16 }, { "name": "file_type", "type": "str", - "default": "" + "line": 17 }, { "name": "source_path", "type": "str", - "default": "" + "line": 18 }, { "name": "page_number", "type": "int | None", - "default": "" + "line": 19 }, { "name": "content_text", "type": "str", - "default": "" + "line": 20 }, { "name": "similarity_score", "type": "float", - "default": "" + "line": 21 }, { "name": "rank", "type": "int", - "default": "" + "line": 22 } ], - "line": 13, - "doc": "" + "line": 13 } ], "configuration": [] }, { - "source": "installed-owned-source/app/search/router.py", - "sha256": "904441f2323a86199c42d647e5935c4f78bbb973c5c20a9b35e1bcc929691891", + "source": "backend/townlight_records/search/router.py", + "sha256": "52942b33b4869a3c22ed9417723e1854a69161bf4dbaa4deeeaaad16cdd4eb65", + "bytes": 10957, "routes": [ { "method": "POST", - "path": "/search/query", - "router": "router", - "prefix_resolved": true, - "name": "execute_search", - "signature": "req: SearchRequest, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.LIAISON))", - "returns": "", - "line": 28, - "doc": "Execute a hybrid search query. Optionally synthesize an LLM answer.", - "decorator": "router.post('/query', response_model=SearchResponse)", - "errors": [ - "HTTPException(status_code=404, detail='Search session not found')" - ] + "declared_path": "/query", + "function": "execute_search", + "line": 28 }, { "method": "GET", - "path": "/search/sessions", - "router": "router", - "prefix_resolved": true, - "name": "list_sessions", - "signature": "limit: int=20, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 141, - "doc": "List the current user's search sessions.", - "decorator": "router.get('/sessions', response_model=list[SearchSessionRead])", - "errors": [] + "declared_path": "/sessions", + "function": "list_sessions", + "line": 141 }, { "method": "GET", - "path": "/search/sessions/{session_id}", - "router": "router", - "prefix_resolved": true, - "name": "get_session", - "signature": "session_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 191, - "doc": "Get a search session with its query history.", - "decorator": "router.get('/sessions/{session_id}', response_model=SearchSessionRead)", - "errors": [ - "HTTPException(status_code=404, detail='Search session not found')" - ] + "declared_path": "/sessions/{session_id}", + "function": "get_session", + "line": 191 }, { "method": "GET", - "path": "/search/filters", - "router": "router", - "prefix_resolved": true, - "name": "get_filter_options", - "signature": "session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 226, - "doc": "Get available filter values for search.", - "decorator": "router.get('/filters', response_model=SearchFilterOptions)", - "errors": [] + "declared_path": "/filters", + "function": "get_filter_options", + "line": 226 }, { "method": "GET", - "path": "/search/export", - "router": "router", - "prefix_resolved": true, - "name": "export_search_results", - "signature": "query: str, format: str='csv', department_id: str | None=None, file_type: str | None=None, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", - "returns": "", - "line": 270, - "doc": "Export search results as CSV. Runs a search and streams the results.", - "decorator": "router.get('/export')", - "errors": [] + "declared_path": "/export", + "function": "export_search_results", + "line": 270 } ], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/search/synthesizer.py", - "sha256": "427e73f0cf9752fb347f7769751e7e14a522fcc6bebeb1b785440ad0f5b7e254", + "source": "backend/townlight_records/search/synthesizer.py", + "sha256": "a29ee927d6f8edf0cab05acd4d3dd523455e2eabd6f500af164d31e0372f73f8", + "bytes": 1908, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/security/__init__.py", + "source": "backend/townlight_records/security/__init__.py", "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "bytes": 0, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/security/at_rest.py", - "sha256": "ae75ffc5d633a6d99180bb61e0d01f2084af917565f67cfc5a5ab1d0a055b554", + "source": "backend/townlight_records/security/at_rest.py", + "sha256": "63ecb19f92893043fd7ee5619a8ef86a8f37642cd009f4660288e9ef4f2852dd", + "bytes": 1021, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/security/host_validator.py", - "sha256": "2890b06c3440118166ca36640d0d7d06b81224eb3e540e021721712fe3c967a8", + "source": "backend/townlight_records/security/host_validator.py", + "sha256": "dd87585491ae8c118c2cd80127a297bc28e60e9015fd573251af393566b1320e", + "bytes": 710, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/seed/__init__.py", - "sha256": "94373caf66af4bff649d9b77dee25b4a9f03f57ba8cc507c02f889baa1d48575", + "source": "backend/townlight_records/seed/__init__.py", + "sha256": "bcc25a55282ceffdac66ff70179d6a3dd07cb4333c89d568f98cc2204321e1b0", + "bytes": 317, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/seed/first_boot.py", - "sha256": "88b0f011853f6f60f7d488bfebe0dde96209a8d3243a08b731e4a6f682bab40b", + "source": "backend/townlight_records/seed/first_boot.py", + "sha256": "40b50e2e4b7f6d90f4ca2ad8fc753e4e2cf32a72b74580136ee570a5d19369ac", + "bytes": 9964, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/service_accounts/__init__.py", - "sha256": "724c131242497b5d06cb96ed27573bdd2de4f098babe79129e6f1e20d9a5b76b", + "source": "backend/townlight_records/service_accounts/__init__.py", + "sha256": "2fa2428653459da5eb92239760502d74190c9183dcade5b408ec89f25bdcc040", + "bytes": 130, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/service_accounts/router.py", - "sha256": "c6632fc265846154c9a537070390de2c47c3d2d92c78e6fb8fb352f32ad3bf30", + "source": "backend/townlight_records/service_accounts/router.py", + "sha256": "a23f0364a75cfe413b75afc99825023a5e04649bc59f0be8c722da33da7046a3", + "bytes": 3582, "routes": [ { "method": "POST", - "path": "/service-accounts/", - "router": "router", - "prefix_resolved": true, - "name": "create_service_account", - "signature": "data: ServiceAccountCreate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 29, - "doc": "", - "decorator": "router.post('/', response_model=ServiceAccountCreated, status_code=201)", - "errors": [ - "HTTPException(status_code=409, detail='Name already taken')" - ] + "declared_path": "/", + "function": "create_service_account", + "line": 29 }, { "method": "GET", - "path": "/service-accounts/", - "router": "router", - "prefix_resolved": true, - "name": "list_service_accounts", - "signature": "session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 72, - "doc": "", - "decorator": "router.get('/', response_model=list[ServiceAccountRead])", - "errors": [] + "declared_path": "/", + "function": "list_service_accounts", + "line": 72 }, { "method": "PATCH", - "path": "/service-accounts/{account_id}", - "router": "router", - "prefix_resolved": true, - "name": "update_service_account", - "signature": "account_id: uuid.UUID, data: ServiceAccountUpdate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", - "returns": "", - "line": 81, - "doc": "", - "decorator": "router.patch('/{account_id}', response_model=ServiceAccountRead)", - "errors": [ - "HTTPException(status_code=404, detail='Service account not found')" - ] + "declared_path": "/{account_id}", + "function": "update_service_account", + "line": 81 } ], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/worker.py", - "sha256": "6b33f496ba32184cc049e6cc5c6398c2e42f1b30c51bea52ae67e768da880829", + "source": "backend/townlight_records/worker.py", + "sha256": "f87595f97cbc50b71ec7f8bbef0733410688b739f5e3fe842212ac9ea4fd4053", + "bytes": 700, "routes": [], "models": [], "configuration": [] } - ], - "bridge": [ - { - "source": "installed-owned-source/app/desktop_bridge/__init__.py", - "sha256": "707138dfa41f7f4e91957a523e3c3394ce52803778c5b278b3cc77d4a5b1c30f", - "routes": [], - "models": [], - "configuration": [] - }, + ] + }, + "meetings": { + "repository": "townlight/meetings", + "repository_head": "581ca739e03e7a4d1161cd8c5edf1d36115f9ee6", + "working_tree_modified": true, + "principal_import": "townlight_meetings", + "source": [ { - "source": "installed-owned-source/app/desktop_bridge/projection.py", - "sha256": "5267b17ae6be18258ea0e225ffb0d53c56aeaf674d9426856b8db804f801008c", + "source": "townlight_meetings/__init__.py", + "sha256": "8222ea6324b101351522144baf63d9cf9359781fe8da2a5b591cc84da16846f5", + "bytes": 68, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/app/desktop_bridge/records.py", - "sha256": "407b2ca9974caa761c00daee3b585ca915c2fe649a69a0dd58f42342b39821d1", + "source": "townlight_meetings/agenda_intake.py", + "sha256": "1f7832c7036b2563762bec042f226c5e0abe69d5f02e34fd7de141813b6f85fa", + "bytes": 11673, "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/app/desktop_bridge/router.py", - "sha256": "7c02e0a222c36aecb84b105a918309a811f40249c3f55756d87cfa2646c4ef1b", - "routes": [ - { - "method": "GET", - "path": "/desktop/v1/public/records-state", - "router": "router", - "prefix_resolved": true, - "name": "public_records_state", - "signature": "request: Request, session: AsyncSession=Depends(get_async_session)", - "returns": "", - "line": 134, - "doc": "", - "decorator": "router.get('/public/records-state', dependencies=[Depends(native_public_shell)], response_model=RecordsStateRead)", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/public/requests", - "router": "router", - "prefix_resolved": true, - "name": "public_records_intake", - "signature": "data: PublicIntake, request: Request, session: AsyncSession=Depends(get_async_session)", - "returns": "", - "line": 144, - "doc": "", - "decorator": "router.post('/public/requests', dependencies=[Depends(native_public_shell)])", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/public/lookup", - "router": "router", - "prefix_resolved": true, - "name": "public_records_lookup", - "signature": "data: PublicLookup, request: Request, session: AsyncSession=Depends(get_async_session)", - "returns": "", - "line": 153, - "doc": "", - "decorator": "router.post('/public/lookup', dependencies=[Depends(native_public_shell)])", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/public/messages", - "router": "router", - "prefix_resolved": true, - "name": "public_records_message", - "signature": "data: PublicMessage, request: Request, session: AsyncSession=Depends(get_async_session)", - "returns": "", - "line": 160, - "doc": "", - "decorator": "router.post('/public/messages', dependencies=[Depends(native_public_shell)])", - "errors": [ - "HTTPException(400, str(error))" - ] - }, - { - "method": "POST", - "path": "/desktop/v1/permitting-sources/search", - "router": "router", - "prefix_resolved": true, - "name": "search_permitting_sources", - "signature": "data: MeetingsSearch, request: Request, actor: User=Depends(native_records_user)", - "returns": "", - "line": 204, - "doc": "", - "decorator": "router.post('/permitting-sources/search')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/requests/{request_id}/permitting-sources", - "router": "router", - "prefix_resolved": true, - "name": "attach_permitting_source", - "signature": "request_id: uuid.UUID, data: MeetingsSourceSelection, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", - "returns": "", - "line": 213, - "doc": "", - "decorator": "router.post('/requests/{request_id}/permitting-sources', response_model=RecordsOperationRead)", - "errors": [ - "HTTPException(404, 'Records request not found.')", - "HTTPException(404, 'Reviewed Permitting copy not found or no longer permitted.')", - "HTTPException(409, 'Permitting source changed; search again before attaching.')", - "HTTPException(422, 'Source attachment not confirmed; existing evidence retained.')" - ] - }, - { - "method": "POST", - "path": "/desktop/v1/inspections-sources/search", - "router": "router", - "prefix_resolved": true, - "name": "search_inspections_sources", - "signature": "data: MeetingsSearch, request: Request, actor: User=Depends(native_records_user)", - "returns": "", - "line": 239, - "doc": "", - "decorator": "router.post('/inspections-sources/search')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/requests/{request_id}/inspections-sources", - "router": "router", - "prefix_resolved": true, - "name": "attach_inspections_source", - "signature": "request_id: uuid.UUID, data: MeetingsSourceSelection, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", - "returns": "", - "line": 248, - "doc": "", - "decorator": "router.post('/requests/{request_id}/inspections-sources', response_model=RecordsOperationRead)", - "errors": [ - "HTTPException(404, 'Records request not found.')", - "HTTPException(404, 'Reviewed Inspections copy not found or no longer permitted.')", - "HTTPException(409, 'Inspections source changed; search again before attaching.')", - "HTTPException(422, 'Source attachment not confirmed; existing evidence retained.')" - ] - }, - { - "method": "POST", - "path": "/desktop/v1/planning-sources/search", - "router": "router", - "prefix_resolved": true, - "name": "search_planning_sources", - "signature": "data: MeetingsSearch, request: Request, actor: User=Depends(native_records_user)", - "returns": "", - "line": 274, - "doc": "", - "decorator": "router.post('/planning-sources/search')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/requests/{request_id}/planning-sources", - "router": "router", - "prefix_resolved": true, - "name": "attach_planning_source", - "signature": "request_id: uuid.UUID, data: MeetingsSourceSelection, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", - "returns": "", - "line": 283, - "doc": "", - "decorator": "router.post('/requests/{request_id}/planning-sources', response_model=RecordsOperationRead)", - "errors": [ - "HTTPException(404, 'Records request not found.')", - "HTTPException(404, 'Permitted Planning source not found.')", - "HTTPException(409, 'Planning source changed; search again before attaching.')", - "HTTPException(422, 'Source attachment not confirmed; existing evidence retained.')" - ] - }, - { - "method": "POST", - "path": "/desktop/v1/zoning-sources/search", - "router": "router", - "prefix_resolved": true, - "name": "search_zoning_sources", - "signature": "data: MeetingsSearch, request: Request, actor: User=Depends(native_records_user)", - "returns": "", - "line": 310, - "doc": "", - "decorator": "router.post('/zoning-sources/search')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/requests/{request_id}/zoning-sources", - "router": "router", - "prefix_resolved": true, - "name": "attach_zoning_source", - "signature": "request_id: uuid.UUID, data: MeetingsSourceSelection, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", - "returns": "", - "line": 319, - "doc": "", - "decorator": "router.post('/requests/{request_id}/zoning-sources', response_model=RecordsOperationRead)", - "errors": [ - "HTTPException(404, 'Records request not found.')", - "HTTPException(404, 'Permitted Zoning source not found.')", - "HTTPException(409, 'Zoning source changed; search again before attaching.')", - "HTTPException(422, 'Source attachment not confirmed; existing evidence retained.')" - ] - }, - { - "method": "GET", - "path": "/desktop/v1/records-state", - "router": "router", - "prefix_resolved": true, - "name": "get_native_records_state", - "signature": "session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", - "returns": "", - "line": 346, - "doc": "", - "decorator": "router.get('/records-state', response_model=RecordsStateRead)", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/meetings-sources/search", - "router": "router", - "prefix_resolved": true, - "name": "search_meetings_sources", - "signature": "data: MeetingsSearch, request: Request, actor: User=Depends(native_records_user)", - "returns": "", - "line": 355, - "doc": "", - "decorator": "router.post('/meetings-sources/search')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/requests/{request_id}/meetings-sources", - "router": "router", - "prefix_resolved": true, - "name": "attach_meetings_source", - "signature": "request_id: uuid.UUID, data: MeetingsSourceSelection, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", - "returns": "", - "line": 364, - "doc": "", - "decorator": "router.post('/requests/{request_id}/meetings-sources', response_model=RecordsOperationRead)", - "errors": [ - "HTTPException(404, 'Records request not found.')", - "HTTPException(404, 'Permitted Meetings source not found.')", - "HTTPException(409, 'Meetings source changed; search again before attaching.')", - "HTTPException(422, 'Source attachment not confirmed; existing evidence retained.')" - ] - }, - { - "method": "POST", - "path": "/desktop/v1/code-sources/search", - "router": "router", - "prefix_resolved": true, - "name": "search_code_sources", - "signature": "data: CodeSearch, request: Request, actor: User=Depends(native_records_user)", - "returns": "", - "line": 389, - "doc": "", - "decorator": "router.post('/code-sources/search')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/requests/{request_id}/code-sources", - "router": "router", - "prefix_resolved": true, - "name": "attach_code_source", - "signature": "request_id: uuid.UUID, data: CodeSourceSelection, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", - "returns": "", - "line": 398, - "doc": "", - "decorator": "router.post('/requests/{request_id}/code-sources', response_model=RecordsOperationRead)", - "errors": [ - "HTTPException(404, 'Records request not found.')", - "HTTPException(404, 'Permitted Code source not found.')", - "HTTPException(409, 'Code source changed; search again before attaching.')", - "HTTPException(422, 'Source attachment not confirmed; existing evidence retained.')" - ] - }, - { - "method": "POST", - "path": "/desktop/v1/notifications/{notification_id}/sent", - "router": "router", - "prefix_resolved": true, - "name": "mark_native_notification_sent", - "signature": "notification_id: uuid.UUID, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", - "returns": "", - "line": 423, - "doc": "", - "decorator": "router.post('/notifications/{notification_id}/sent', response_model=RecordsStateRead)", - "errors": [ - "HTTPException(404, 'Records notification not found.')", - "HTTPException(400, 'This local notification is already marked sent.')" - ] - }, - { - "method": "POST", - "path": "/desktop/v1/requests/{request_id}/documents", - "router": "router", - "prefix_resolved": true, - "name": "attach_native_document", - "signature": "request_id: uuid.UUID, data: AttachDocument, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", - "returns": "", - "line": 443, - "doc": "", - "decorator": "router.post('/requests/{request_id}/documents', response_model=RecordsOperationRead)", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/requests/{request_id}/documents/{attachment_id}/release-copy", - "router": "router", - "prefix_resolved": true, - "name": "attach_native_release_copy", - "signature": "request_id: uuid.UUID, attachment_id: uuid.UUID, data: AttachReleaseCopy, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", - "returns": "", - "line": 453, - "doc": "", - "decorator": "router.post('/requests/{request_id}/documents/{attachment_id}/release-copy', response_model=RecordsOperationRead)", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/requests/{request_id}/artifacts", - "router": "router", - "prefix_resolved": true, - "name": "prepare_native_artifact", - "signature": "request_id: uuid.UUID, data: PrepareArtifact, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", - "returns": "", - "line": 463, - "doc": "", - "decorator": "router.post('/requests/{request_id}/artifacts', response_model=ArtifactPlan)", - "errors": [ - "HTTPException(404, 'Records request not found.')", - "HTTPException(400, str(error))" - ] - }, - { - "method": "POST", - "path": "/desktop/v1/requests/{request_id}/artifacts/{artifact_id}/complete", - "router": "router", - "prefix_resolved": true, - "name": "complete_native_artifact", - "signature": "request_id: uuid.UUID, artifact_id: uuid.UUID, data: CompleteArtifact, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", - "returns": "", - "line": 481, - "doc": "", - "decorator": "router.post('/requests/{request_id}/artifacts/{artifact_id}/complete', response_model=RecordsOperationRead)", - "errors": [ - "HTTPException(404, 'Records request not found.')", - "HTTPException(400, str(error))" - ] - }, - { - "method": "POST", - "path": "/desktop/v1/requests", - "router": "router", - "prefix_resolved": true, - "name": "create_native_request", - "signature": "data: StaffRecordsIntake, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", - "returns": "", - "line": 500, - "doc": "", - "decorator": "router.post('/requests', response_model=NativeRequestRead, status_code=201)", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/requests/{request_id}", - "router": "router", - "prefix_resolved": true, - "name": "get_native_request", - "signature": "request_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", - "returns": "", - "line": 521, - "doc": "", - "decorator": "router.get('/requests/{request_id}', response_model=NativeRequestRead)", - "errors": [ - "HTTPException(404, 'Records request not found.')" - ] - }, - { - "method": "GET", - "path": "/desktop/v1/requests/{request_id}/view", - "router": "router", - "prefix_resolved": true, - "name": "get_native_request_view", - "signature": "request_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", - "returns": "", - "line": 537, - "doc": "", - "decorator": "router.get('/requests/{request_id}/view', response_model=RecordsView)", - "errors": [ - "HTTPException(404, 'Records request not found.')" - ] - }, - { - "method": "GET", - "path": "/desktop/v1/requests/{request_id}/draft-context", - "router": "router", - "prefix_resolved": true, - "name": "native_draft_context", - "signature": "request_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", - "returns": "", - "line": 549, - "doc": "", - "decorator": "router.get('/requests/{request_id}/draft-context')", - "errors": [ - "HTTPException(404, 'Records request not found.')", - "HTTPException(400, str(error))" - ] - }, - { - "method": "POST", - "path": "/desktop/v1/requests/{request_id}/generated-draft", - "router": "router", - "prefix_resolved": true, - "name": "native_generated_draft", - "signature": "request_id: uuid.UUID, data: GeneratedDraft, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", - "returns": "", - "line": 575, - "doc": "", - "decorator": "router.post('/requests/{request_id}/generated-draft', response_model=RecordsOperationRead)", - "errors": [ - "HTTPException(404, 'Records request not found.')", - "HTTPException(409, 'The draft changed during generation. Refresh before generating again.')", - "HTTPException(400, str(error))" - ] - }, - { - "method": "POST", - "path": "/desktop/v1/requests/{request_id}/actions", - "router": "router", - "prefix_resolved": true, - "name": "native_request_operation", - "signature": "request_id: uuid.UUID, command: RecordsCommand, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", - "returns": "", - "line": 605, - "doc": "", - "decorator": "router.post('/requests/{request_id}/actions', response_model=RecordsOperationRead)", - "errors": [ - "HTTPException(404, 'Records request not found.')", - "HTTPException(400, str(error))" - ] - } - ], "models": [ { - "name": "MeetingsSearch", - "bases": [ - "BaseModel" - ], + "name": "AgendaIntakeItem", + "bases": [], "fields": [ { - "name": "query", + "name": "id", "type": "str", - "default": "Field(min_length=1, max_length=500)" - } - ], - "line": 38, - "doc": "" - }, - { - "name": "MeetingsSourceSelection", - "bases": [ - "BaseModel" - ], - "fields": [ + "line": 54 + }, { - "name": "source_id", + "name": "title", "type": "str", - "default": "Field(min_length=1, max_length=200)" + "line": 55 }, { - "name": "expected_sha256", + "name": "department_name", "type": "str", - "default": "Field(pattern='^[0-9a-f]{64}$')" - } - ], - "line": 43, - "doc": "" - }, - { - "name": "CodeSearch", - "bases": [ - "BaseModel" - ], - "fields": [ + "line": 56 + }, { - "name": "query", + "name": "submitted_by", "type": "str", - "default": "Field(min_length=1, max_length=500)" + "line": 57 }, { - "name": "as_of", - "type": "date | None", - "default": "None" - } - ], - "line": 49, - "doc": "" - }, - { - "name": "CodeSourceSelection", - "bases": [ - "BaseModel" - ], - "fields": [ + "name": "summary", + "type": "str", + "line": 58 + }, { - "name": "source_id", + "name": "status", "type": "str", - "default": "Field(min_length=1, max_length=200)" + "line": 59 }, { - "name": "expected_sha256", + "name": "readiness_status", "type": "str", - "default": "Field(pattern='^[0-9a-f]{64}$')" + "line": 60 }, { - "name": "as_of", - "type": "date | None", - "default": "None" + "name": "source_references", + "type": "list[dict]", + "line": 61 + }, + { + "name": "reviewer", + "type": "str | None", + "line": 62 + }, + { + "name": "review_notes", + "type": "str | None", + "line": 63 + }, + { + "name": "promoted_agenda_item_id", + "type": "str | None", + "line": 64 + }, + { + "name": "promoted_at", + "type": "datetime | None", + "line": 65 + }, + { + "name": "promotion_audit_hash", + "type": "str | None", + "line": 66 + }, + { + "name": "last_audit_hash", + "type": "str", + "line": 67 + }, + { + "name": "created_at", + "type": "datetime", + "line": 68 + }, + { + "name": "updated_at", + "type": "datetime", + "line": 69 } ], - "line": 55, - "doc": "" + "line": 51 } ], "configuration": [] }, { - "source": "installed-owned-source/app/desktop_bridge/schemas.py", - "sha256": "753dd5474d532912bc50118fe9add74613cbc3b17a062dd93681309ac590926d", + "source": "townlight_meetings/agenda_lifecycle.py", + "sha256": "aae33ddd60b2d18abfdc7cb83ab5eef396b68c882676da3e2fe0eb74d41f23a2", + "bytes": 16632, "routes": [], "models": [ { - "name": "StaffRecordsIntake", - "bases": [ - "BaseModel" - ], + "name": "TransitionResult", + "bases": [], "fields": [ { - "name": "requester", - "type": "str", - "default": "Field(min_length=1)" + "name": "allowed", + "type": "bool", + "line": 40 }, { - "name": "summary", - "type": "str", - "default": "Field(min_length=1)" + "name": "http_status", + "type": "int", + "line": 41 }, { - "name": "deadline", + "name": "message", "type": "str", - "default": "" + "line": 42 }, { - "name": "deadlineBasis", + "name": "fix", "type": "str", - "default": "''" + "line": 43 + }, + { + "name": "audit_entry", + "type": "dict[str, object]", + "line": 44 } ], - "line": 10, - "doc": "Existing native create-records-request input; no caller-supplied actor." + "line": 39 }, { - "name": "NativeRequestRead", - "bases": [ - "RequestRead" - ], + "name": "AgendaItemRecord", + "bases": [], "fields": [ { - "name": "desktop_id", - "type": "str | None", - "default": "" + "name": "id", + "type": "str", + "line": 49 }, { - "name": "public_tracking_number", - "type": "str | None", - "default": "" + "name": "title", + "type": "str", + "line": 50 }, { - "name": "submitted_via", + "name": "department_name", "type": "str", - "default": "" + "line": 51 }, { - "name": "deadline_label", + "name": "status", "type": "str", - "default": "" + "line": 52 }, { - "name": "deadline_basis", - "type": "str", - "default": "" + "name": "audit_entries", + "type": "list[dict[str, object]]", + "line": 53 }, { - "name": "deadline_reviewed_at", - "type": "datetime | None", - "default": "" + "name": "meeting_id", + "type": "str | None", + "line": 54 } ], - "line": 28, - "doc": "" - }, + "line": 48 + } + ], + "configuration": [] + }, + { + "source": "townlight_meetings/cc7_completeness.py", + "sha256": "01318cfddf4cd5a50515e5243299625c6f88c7cfdf39c4f798fa03f68049ac49", + "bytes": 6539, + "routes": [], + "models": [ { - "name": "AssignmentPayload", - "bases": [ - "NativePayload" - ], + "name": "ApiCategory", + "bases": [], "fields": [ { - "name": "assignedTo", + "name": "id", "type": "str", - "default": "Field(min_length=1)" - } - ], - "line": 41, - "doc": "" - }, - { - "name": "DeadlinePayload", - "bases": [ - "NativePayload" - ], - "fields": [ + "line": 13 + }, { - "name": "deadline", + "name": "label", "type": "str", - "default": "" + "line": 14 }, { - "name": "deadlineBasis", + "name": "paths", + "type": "tuple[str, ...]", + "line": 15 + }, + { + "name": "protected", + "type": "bool", + "line": 16 + }, + { + "name": "auth_scope", "type": "str", - "default": "Field(min_length=1)" + "line": 17 } ], - "line": 45, - "doc": "" + "line": 12 }, { - "name": "CalculateDeadlinePayload", - "bases": [ - "NativePayload" - ], + "name": "FrontendPage", + "bases": [], "fields": [ { - "name": "deadlineReceivedDate", - "type": "str", - "default": "" - }, - { - "name": "deadlineRuleName", + "name": "id", "type": "str", - "default": "Field(min_length=1)" + "line": 22 }, { - "name": "deadlineDayCount", + "name": "label", "type": "str", - "default": "" + "line": 23 }, { - "name": "deadlineDayType", + "name": "surface", "type": "str", - "default": "" + "line": 24 }, { - "name": "deadlineBasis", - "type": "str", - "default": "Field(min_length=1)" + "name": "evidence_states", + "type": "tuple[str, ...]", + "line": 25 } ], - "line": 52, - "doc": "" - }, + "line": 21 + } + ], + "configuration": [] + }, + { + "source": "townlight_meetings/connector_import_sync.py", + "sha256": "97fa12b052cd8eab7e337a3ddfb945677d7c6345f2a9cd7a2152509183afc0f0", + "bytes": 4664, + "routes": [], + "models": [ { - "name": "ClarificationPayload", - "bases": [ - "NativePayload" - ], + "name": "ImportAttempt", + "bases": [], "fields": [ { - "name": "clarificationNote", + "name": "connector", "type": "str", - "default": "Field(min_length=1)" - } - ], - "line": 77, - "doc": "" - }, - { - "name": "MessagePayload", - "bases": [ - "NativePayload" - ], - "fields": [ + "line": 15 + }, { - "name": "requestMessageBody", - "type": "str", - "default": "Field(min_length=1)" - } - ], - "line": 81, - "doc": "" - }, - { - "name": "SearchNotePayload", - "bases": [ - "NativePayload" - ], - "fields": [ + "name": "payload_path", + "type": "Path", + "line": 16 + }, { - "name": "sourceNote", + "name": "ok", + "type": "bool", + "line": 17 + }, + { + "name": "message", "type": "str", - "default": "Field(min_length=1)" + "line": 18 }, { - "name": "citation", + "name": "fix", "type": "str", - "default": "''" + "line": 19 + }, + { + "name": "normalized", + "type": "dict[str, Any] | None", + "line": 20 } ], - "line": 85, - "doc": "" - }, + "line": 14 + } + ], + "configuration": [] + }, + { + "source": "townlight_meetings/connectors.py", + "sha256": "0e2e3b30400b2dda8d7d216a4396634efbdabbfa76f64adcda7d003beaf94af5", + "bytes": 570, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_meetings/demo_seed.py", + "sha256": "cfae73282a8bf76ee27b79693a724d383afef9617e590189b5678a92c01809a3", + "bytes": 15324, + "routes": [], + "models": [ { - "name": "SearchReceiptPayload", + "name": "DemoSeedSummary", "bases": [ - "NativePayload" + "TypedDict" ], "fields": [ { - "name": "searchQuery", + "name": "city", "type": "str", - "default": "Field(min_length=1)" + "line": 38 }, { - "name": "searchLocations", - "type": "str", - "default": "Field(min_length=1)" + "name": "meeting_body_count", + "type": "int", + "line": 39 }, { - "name": "searchResultTitle", - "type": "str", - "default": "Field(min_length=1)" + "name": "meeting_count", + "type": "int", + "line": 40 }, { - "name": "searchResultCitation", - "type": "str", - "default": "Field(min_length=1)" + "name": "agenda_intake_count", + "type": "int", + "line": 41 }, { - "name": "searchResultSummary", - "type": "str", - "default": "Field(min_length=1)" + "name": "packet_count", + "type": "int", + "line": 42 }, { - "name": "searchResultStatus", - "type": "str", - "default": "''" + "name": "notice_count", + "type": "int", + "line": 43 }, { - "name": "searchReviewer", - "type": "str", - "default": "''" - } - ], - "line": 90, - "doc": "" - }, - { - "name": "ExemptionNotePayload", - "bases": [ - "NativePayload" - ], - "fields": [ + "name": "motion_count", + "type": "int", + "line": 44 + }, { - "name": "exemptionNote", + "name": "minutes_draft_count", + "type": "int", + "line": 45 + }, + { + "name": "public_record_count", + "type": "int", + "line": 46 + }, + { + "name": "primary_meeting_id", "type": "str", - "default": "Field(min_length=1)" + "line": 47 } ], - "line": 100, - "doc": "" - }, + "line": 35 + } + ], + "configuration": [] + }, + { + "source": "townlight_meetings/desktop_delivery.py", + "sha256": "88a1c62a24a3e6d16b3ade8d2f4f6f0fcc9c9efd6eeee316651f2d76f496a0cd", + "bytes": 5156, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_meetings/integration_contracts.py", + "sha256": "1d674363f0d07151c19594f8f2fbaa25997a35cad27749508b744238a5e838dc", + "bytes": 16241, + "routes": [], + "models": [ { - "name": "ExemptionDecisionPayload", - "bases": [ - "NativePayload" - ], + "name": "IntegrationCheck", + "bases": [], "fields": [ { - "name": "exemptionSource", - "type": "str", - "default": "Field(min_length=1)" - }, - { - "name": "exemptionKind", + "name": "contract_id", "type": "str", - "default": "Field(min_length=1)" + "line": 20 }, { - "name": "exemptionFinding", + "name": "scenario", "type": "str", - "default": "Field(min_length=1)" + "line": 21 }, { - "name": "exemptionDecision", - "type": "Literal['release', 'redact', 'exempt']", - "default": "" + "name": "ok", + "type": "bool", + "line": 22 }, { - "name": "exemptionBasis", + "name": "message", "type": "str", - "default": "Field(min_length=1)" + "line": 23 }, { - "name": "exemptionReviewer", + "name": "fix", "type": "str", - "default": "''" + "line": 24 } ], - "line": 104, - "doc": "" + "line": 17 }, { - "name": "FeeEstimatePayload", - "bases": [ - "NativePayload" - ], + "name": "IntegrationContract", + "bases": [], "fields": [ { - "name": "feeEstimate", + "name": "id", "type": "str", - "default": "Field(min_length=1)" - } - ], - "line": 118, - "doc": "" - }, - { - "name": "FeeLinePayload", - "bases": [ - "NativePayload" - ], - "fields": [ + "line": 40 + }, { - "name": "feeLineDescription", + "name": "label", "type": "str", - "default": "Field(min_length=1)" + "line": 41 }, { - "name": "feeScheduleBasis", - "type": "str", - "default": "Field(min_length=1)" + "name": "status", + "type": "IntegrationStatus", + "line": 42 }, { - "name": "feeLineAmount", + "name": "mode", "type": "str", - "default": "" - } + "line": 43 + }, + { + "name": "proof_model", + "type": "Literal['live_wire_validation', 'in_process_boundary_validation']", + "line": 44 + }, + { + "name": "dependent_module_required", + "type": "bool", + "line": 45 + }, + { + "name": "network_calls", + "type": "bool", + "line": 46 + }, + { + "name": "contract_artifact", + "type": "str", + "line": 47 + }, + { + "name": "supported_operations", + "type": "tuple[str, ...]", + "line": 48 + }, + { + "name": "absent_dependency_behavior", + "type": "str", + "line": 49 + }, + { + "name": "operator_fix", + "type": "str", + "line": 50 + }, + { + "name": "adversarial_scenarios", + "type": "tuple[str, ...]", + "line": 51 + } + ], + "line": 37 + } + ], + "configuration": [] + }, + { + "source": "townlight_meetings/main.py", + "sha256": "411f2e69ac62e75e1b680ed7fd2954b159f6d0db1919da6ccceae9b646fdcb09", + "bytes": 148590, + "routes": [ + { + "method": "GET", + "declared_path": "/", + "function": "root", + "line": 492 + }, + { + "method": "GET", + "declared_path": "/health", + "function": "health", + "line": 550 + }, + { + "method": "GET", + "declared_path": "/favicon.ico", + "function": "favicon", + "line": 561 + }, + { + "method": "GET", + "declared_path": "/staff", + "function": "staff_dashboard", + "line": 567 + }, + { + "method": "GET", + "declared_path": "/public", + "function": "public_portal", + "line": 617 + }, + { + "method": "GET", + "declared_path": "/staff/session", + "function": "staff_session", + "line": 623 + }, + { + "method": "GET", + "declared_path": "/staff/login", + "function": "staff_login", + "line": 705 + }, + { + "method": "GET", + "declared_path": "/staff/oidc/callback", + "function": "staff_oidc_callback", + "line": 763 + }, + { + "method": "GET", + "declared_path": "/staff/logout", + "function": "staff_logout", + "line": 861 + }, + { + "method": "POST", + "declared_path": "/staff/logout", + "function": "staff_logout", + "line": 861 + }, + { + "method": "GET", + "declared_path": "/staff/auth-readiness", + "function": "staff_auth_readiness", + "line": 873 + }, + { + "method": "GET", + "declared_path": "/admin/config", + "function": "admin_config", + "line": 935 + }, + { + "method": "GET", + "declared_path": "/integrations/readiness", + "function": "integrations_readiness", + "line": 968 + }, + { + "method": "GET", + "declared_path": "/admin/prompts", + "function": "admin_prompts", + "line": 975 + }, + { + "method": "POST", + "declared_path": "/agenda-items", + "function": "create_agenda_item", + "line": 1009 + }, + { + "method": "GET", + "declared_path": "/agenda-items/{item_id}", + "function": "get_agenda_item", + "line": 1018 + }, + { + "method": "POST", + "declared_path": "/agenda-items/{item_id}/transitions", + "function": "transition_agenda_item", + "line": 1027 + }, + { + "method": "GET", + "declared_path": "/agenda-items/{item_id}/audit", + "function": "get_agenda_item_audit", + "line": 1058 + }, + { + "method": "POST", + "declared_path": "/agenda-intake", + "function": "submit_agenda_intake_item", + "line": 1067 + }, + { + "method": "GET", + "declared_path": "/agenda-intake", + "function": "list_agenda_intake_items", + "line": 1080 + }, + { + "method": "POST", + "declared_path": "/agenda-intake/{item_id}/review", + "function": "review_agenda_intake_item", + "line": 1093 + }, + { + "method": "POST", + "declared_path": "/agenda-intake/{item_id}/promote", + "function": "promote_agenda_intake_item", + "line": 1116 + }, + { + "method": "POST", + "declared_path": "/meetings/{meeting_id}/staff-reports", + "function": "create_staff_report", + "line": 1193 + }, + { + "method": "GET", + "declared_path": "/meetings/{meeting_id}/staff-reports", + "function": "list_staff_reports", + "line": 1222 + }, + { + "method": "POST", + "declared_path": "/meeting-bodies", + "function": "create_meeting_body", + "line": 1246 + }, + { + "method": "GET", + "declared_path": "/meeting-bodies", + "function": "list_meeting_bodies", + "line": 1257 + }, + { + "method": "GET", + "declared_path": "/meeting-bodies/{body_id}", + "function": "get_meeting_body", + "line": 1268 + }, + { + "method": "PATCH", + "declared_path": "/meeting-bodies/{body_id}", + "function": "update_meeting_body", + "line": 1278 + }, + { + "method": "DELETE", + "declared_path": "/meeting-bodies/{body_id}", + "function": "deactivate_meeting_body", + "line": 1296 + }, + { + "method": "POST", + "declared_path": "/meetings", + "function": "create_meeting", + "line": 1306 + }, + { + "method": "GET", + "declared_path": "/meetings", + "function": "list_meetings", + "line": 1322 + }, + { + "method": "GET", + "declared_path": "/meetings/{meeting_id}", + "function": "get_meeting", + "line": 1329 + }, + { + "method": "PATCH", + "declared_path": "/meetings/{meeting_id}", + "function": "update_meeting_schedule", + "line": 1338 + }, + { + "method": "POST", + "declared_path": "/meetings/{meeting_id}/transitions", + "function": "transition_meeting", + "line": 1391 + }, + { + "method": "GET", + "declared_path": "/meetings/{meeting_id}/audit", + "function": "get_meeting_audit", + "line": 1424 + }, + { + "method": "POST", + "declared_path": "/meetings/{meeting_id}/packet-snapshots", + "function": "create_packet_snapshot", + "line": 1433 + }, + { + "method": "GET", + "declared_path": "/meetings/{meeting_id}/packet-snapshots", + "function": "list_packet_snapshots", + "line": 1449 + }, + { + "method": "POST", + "declared_path": "/meetings/{meeting_id}/packet-assemblies", + "function": "create_packet_assembly_record", + "line": 1463 + }, + { + "method": "GET", + "declared_path": "/meetings/{meeting_id}/packet-assemblies", + "function": "list_packet_assembly_records", + "line": 1489 + }, + { + "method": "POST", + "declared_path": "/packet-assemblies/{record_id}/finalize", + "function": "finalize_packet_assembly_record", + "line": 1503 + }, + { + "method": "POST", + "declared_path": "/meetings/{meeting_id}/export-bundle", + "function": "create_packet_export_bundle", + "line": 1524 + }, + { + "method": "POST", + "declared_path": "/meetings/{meeting_id}/notices/check", + "function": "check_notice_compliance", + "line": 1559 + }, + { + "method": "POST", + "declared_path": "/meetings/{meeting_id}/notice-checklists", + "function": "create_notice_checklist_record", + "line": 1577 + }, + { + "method": "GET", + "declared_path": "/meetings/{meeting_id}/notice-checklists", + "function": "list_notice_checklist_records", + "line": 1599 + }, + { + "method": "POST", + "declared_path": "/notice-checklists/{record_id}/posting-proof", + "function": "attach_notice_posting_proof", + "line": 1613 + }, + { + "method": "POST", + "declared_path": "/meetings/{meeting_id}/notices/post", + "function": "post_notice", + "line": 1635 + }, + { + "method": "POST", + "declared_path": "/meetings/{meeting_id}/motions", + "function": "capture_motion", + "line": 1653 + }, + { + "method": "GET", + "declared_path": "/meetings/{meeting_id}/motions", + "function": "list_motions", + "line": 1668 + }, + { + "method": "PUT", + "declared_path": "/motions/{motion_id}", + "function": "reject_motion_mutation", + "line": 1683 + }, + { + "method": "PATCH", + "declared_path": "/motions/{motion_id}", + "function": "reject_motion_mutation", + "line": 1683 + }, + { + "method": "POST", + "declared_path": "/motions/{motion_id}/corrections", + "function": "correct_motion", + "line": 1697 + }, + { + "method": "POST", + "declared_path": "/motions/{motion_id}/votes", + "function": "capture_vote", + "line": 1711 + }, + { + "method": "GET", + "declared_path": "/motions/{motion_id}/votes", + "function": "list_votes", + "line": 1728 + }, + { + "method": "PUT", + "declared_path": "/votes/{vote_id}", + "function": "reject_vote_mutation", + "line": 1743 + }, + { + "method": "PATCH", + "declared_path": "/votes/{vote_id}", + "function": "reject_vote_mutation", + "line": 1743 + }, + { + "method": "POST", + "declared_path": "/votes/{vote_id}/corrections", + "function": "correct_vote", + "line": 1757 + }, + { + "method": "POST", + "declared_path": "/meetings/{meeting_id}/action-items", + "function": "create_action_item", + "line": 1771 + }, + { + "method": "GET", + "declared_path": "/meetings/{meeting_id}/action-items", + "function": "list_action_items", + "line": 1809 + }, + { + "method": "POST", + "declared_path": "/meetings/{meeting_id}/ordinance-resolution-handoff", + "function": "create_ordinance_resolution_handoff", + "line": 2063 + }, + { + "method": "GET", + "declared_path": "/meetings/{meeting_id}/ordinance-resolution-handoff", + "function": "list_ordinance_resolution_handoffs", + "line": 2112 + }, + { + "method": "POST", + "declared_path": "/meetings/{meeting_id}/ordinance-resolution-handoff/retry", + "function": "retry_ordinance_resolution_handoff", + "line": 2125 + }, + { + "method": "POST", + "declared_path": "/meetings/{meeting_id}/minutes/drafts", + "function": "create_minutes_draft", + "line": 2159 + }, + { + "method": "POST", + "declared_path": "/meetings/{meeting_id}/minutes/ai-assist", + "function": "create_minutes_ai_assist", + "line": 2197 + }, + { + "method": "GET", + "declared_path": "/meetings/{meeting_id}/minutes/drafts", + "function": "list_minutes_drafts", + "line": 2243 + }, + { + "method": "POST", + "declared_path": "/minutes/{minute_id}/post", + "function": "reject_automatic_minutes_posting", + "line": 2257 + }, + { + "method": "POST", + "declared_path": "/meetings/{meeting_id}/transcripts", + "function": "create_transcript_record", + "line": 2271 + }, + { + "method": "GET", + "declared_path": "/meetings/{meeting_id}/transcripts", + "function": "list_transcript_records", + "line": 2295 + }, + { + "method": "POST", + "declared_path": "/meetings/{meeting_id}/public-record", + "function": "publish_public_record", + "line": 2309 + }, + { + "method": "POST", + "declared_path": "/imports/{connector_name}/meetings", + "function": "import_connector_meeting", + "line": 2347 + }, + { + "method": "POST", + "declared_path": "/vendor-live-sync/sources", + "function": "create_vendor_live_sync_source", + "line": 2365 + }, + { + "method": "GET", + "declared_path": "/vendor-live-sync/sources", + "function": "list_vendor_live_sync_sources", + "line": 2386 + }, + { + "method": "POST", + "declared_path": "/vendor-live-sync/sources/{source_id}/cursor-reset", + "function": "reset_vendor_live_sync_cursor", + "line": 2398 + }, + { + "method": "POST", + "declared_path": "/vendor-live-sync/sources/{source_id}/run-log", + "function": "record_vendor_live_sync_run", + "line": 2431 + }, + { + "method": "GET", + "declared_path": "/vendor-live-sync/sources/{source_id}/run-log", + "function": "list_vendor_live_sync_runs", + "line": 2463 + }, + { + "method": "GET", + "declared_path": "/public/meetings", + "function": "public_meetings", + "line": 2484 + }, + { + "method": "GET", + "declared_path": "/public/meetings/{record_id}", + "function": "public_meeting_detail", + "line": 2494 + }, + { + "method": "GET", + "declared_path": "/public/meetings/{record_id}/{document_kind}.txt", + "function": "public_meeting_download", + "line": 2503 + }, + { + "method": "POST", + "declared_path": "/public/meetings/{record_id}/comments", + "function": "submit_public_comment", + "line": 2530 + }, + { + "method": "GET", + "declared_path": "/public/meetings/{record_id}/comments", + "function": "list_public_comments", + "line": 2557 + }, + { + "method": "GET", + "declared_path": "/public-comments/review-queue", + "function": "list_public_comment_review_queue", + "line": 2567 + }, + { + "method": "GET", + "declared_path": "/public/archive/search", + "function": "public_archive_search", + "line": 2580 + } + ], + "models": [ + { + "name": "AgendaItemCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "title", + "type": "str", + "line": 239 + }, + { + "name": "department_name", + "type": "str", + "line": 240 + } + ], + "line": 238 + }, + { + "name": "AgendaItemTransitionRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "to_status", + "type": "str", + "line": 244 + }, + { + "name": "actor", + "type": "str", + "line": 245 + } + ], + "line": 243 + }, + { + "name": "AgendaIntakeCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "title", + "type": "str", + "line": 249 + }, + { + "name": "department_name", + "type": "str", + "line": 250 + }, + { + "name": "submitted_by", + "type": "str", + "line": 251 + }, + { + "name": "summary", + "type": "str", + "line": 252 + }, + { + "name": "source_references", + "type": "list[dict]", + "line": 253 + } + ], + "line": 248 + }, + { + "name": "AgendaIntakeReviewRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "reviewer", + "type": "str", + "line": 257 + }, + { + "name": "ready", + "type": "bool", + "line": 258 + }, + { + "name": "notes", + "type": "str", + "line": 259 + } + ], + "line": 256 + }, + { + "name": "AgendaIntakePromoteRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "reviewer", + "type": "str", + "line": 263 + }, + { + "name": "notes", + "type": "str", + "line": 264 + } + ], + "line": 262 + }, + { + "name": "StaffReportCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "title", + "type": "str", + "line": 268 + }, + { + "name": "department_name", + "type": "str", + "line": 269 + }, + { + "name": "author", + "type": "str", + "line": 270 + }, + { + "name": "summary", + "type": "str", + "line": 271 + }, + { + "name": "source_references", + "type": "list[dict]", + "line": 272 + }, + { + "name": "agenda_item_id", + "type": "str | None", + "line": 273 + }, + { + "name": "legal_reviewer", + "type": "str | None", + "line": 274 + } + ], + "line": 267 + }, + { + "name": "MeetingCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "title", + "type": "str", + "line": 278 + }, + { + "name": "meeting_type", + "type": "str", + "line": 279 + }, + { + "name": "scheduled_start", + "type": "str | None", + "line": 280 + }, + { + "name": "meeting_body_id", + "type": "str | None", + "line": 281 + }, + { + "name": "location", + "type": "str | None", + "line": 282 + } + ], + "line": 277 + }, + { + "name": "MeetingUpdate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "title", + "type": "str | None", + "line": 286 + }, + { + "name": "meeting_type", + "type": "str | None", + "line": 287 + }, + { + "name": "scheduled_start", + "type": "str | None", + "line": 288 + }, + { + "name": "meeting_body_id", + "type": "str | None", + "line": 289 + }, + { + "name": "location", + "type": "str | None", + "line": 290 + }, + { + "name": "actor", + "type": "str", + "line": 291 + } + ], + "line": 285 + }, + { + "name": "MeetingBodyCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "name", + "type": "str", + "line": 295 + }, + { + "name": "body_type", + "type": "str", + "line": 296 + }, + { + "name": "is_active", + "type": "bool", + "line": 297 + } + ], + "line": 294 + }, + { + "name": "MeetingBodyUpdate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "name", + "type": "str | None", + "line": 301 + }, + { + "name": "body_type", + "type": "str | None", + "line": 302 + }, + { + "name": "is_active", + "type": "bool | None", + "line": 303 + } + ], + "line": 300 + }, + { + "name": "MeetingTransitionRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "to_status", + "type": "str", + "line": 307 + }, + { + "name": "actor", + "type": "str", + "line": 308 + }, + { + "name": "statutory_basis", + "type": "str | None", + "line": 309 + } + ], + "line": 306 + }, + { + "name": "PacketSnapshotCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "agenda_item_ids", + "type": "list[str]", + "line": 313 + }, + { + "name": "actor", + "type": "str", + "line": 314 + } + ], + "line": 312 + }, + { + "name": "PacketAssemblyCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "title", + "type": "str", + "line": 318 + }, + { + "name": "agenda_item_ids", + "type": "list[str]", + "line": 319 + }, + { + "name": "actor", + "type": "str", + "line": 320 + }, + { + "name": "source_references", + "type": "list[dict]", + "line": 321 + }, + { + "name": "citations", + "type": "list[dict]", + "line": 322 + } + ], + "line": 317 + }, + { + "name": "PacketAssemblyFinalizeRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "actor", + "type": "str", + "line": 326 + } + ], + "line": 325 + }, + { + "name": "PacketSourceCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "source_id", + "type": "str", + "line": 330 + }, + { + "name": "title", + "type": "str", + "line": 331 + }, + { + "name": "kind", + "type": "str", + "line": 332 + }, + { + "name": "source_system", + "type": "str | None", + "line": 333 + }, + { + "name": "source_path", + "type": "str | None", + "line": 334 + }, + { + "name": "checksum", + "type": "str | None", + "line": 335 + }, + { + "name": "sensitivity_label", + "type": "str | None", + "line": 336 + }, + { + "name": "citation_label", + "type": "str | None", + "line": 337 + } + ], + "line": 329 + }, + { + "name": "PacketExportCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "bundle_name", + "type": "str", + "line": 341 + }, + { + "name": "actor", + "type": "str", + "line": 342 + }, + { + "name": "sources", + "type": "list[PacketSourceCreate]", + "line": 343 + }, + { + "name": "public_bundle", + "type": "bool", + "line": 344 + } + ], + "line": 340 + }, + { + "name": "NoticeComplianceRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "notice_type", + "type": "str", + "line": 348 + }, + { + "name": "posted_at", + "type": "datetime", + "line": 349 + }, + { + "name": "minimum_notice_hours", + "type": "int", + "line": 350 + }, + { + "name": "statutory_basis", + "type": "str | None", + "line": 351 + }, + { + "name": "approved_by", + "type": "str | None", + "line": 352 + } + ], + "line": 347 + }, + { + "name": "NoticeChecklistCreate", + "bases": [ + "NoticeComplianceRequest" + ], + "fields": [ + { + "name": "actor", + "type": "str", + "line": 356 + } + ], + "line": 355 + }, + { + "name": "NoticePostingProofCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "actor", + "type": "str", + "line": 360 + }, + { + "name": "posting_proof", + "type": "dict", + "line": 361 + } + ], + "line": 359 + }, + { + "name": "MotionCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "text", + "type": "str", + "line": 365 + }, + { + "name": "actor", + "type": "str", + "line": 366 + }, + { + "name": "agenda_item_id", + "type": "str | None", + "line": 367 + }, + { + "name": "seconded_by", + "type": "str | None", + "line": 368 + } + ], + "line": 364 + }, + { + "name": "MotionCorrectionCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "text", + "type": "str", + "line": 372 + }, + { + "name": "actor", + "type": "str", + "line": 373 + }, + { + "name": "reason", + "type": "str", + "line": 374 + } + ], + "line": 371 + }, + { + "name": "VoteCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "voter_name", + "type": "str", + "line": 378 + }, + { + "name": "vote", + "type": "str", + "line": 379 + }, + { + "name": "actor", + "type": "str", + "line": 380 + } + ], + "line": 377 + }, + { + "name": "VoteCorrectionCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "vote", + "type": "str", + "line": 384 + }, + { + "name": "actor", + "type": "str", + "line": 385 + }, + { + "name": "reason", + "type": "str", + "line": 386 + } + ], + "line": 383 + }, + { + "name": "ActionItemCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "description", + "type": "str", + "line": 390 + }, + { + "name": "actor", + "type": "str", + "line": 391 + }, + { + "name": "assigned_to", + "type": "str | None", + "line": 392 + }, + { + "name": "source_motion_id", + "type": "str | None", + "line": 393 + } + ], + "line": 389 + }, + { + "name": "SourceMaterialCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "source_id", + "type": "str", + "line": 397 + }, + { + "name": "label", + "type": "str", + "line": 398 + }, + { + "name": "text", + "type": "str", + "line": 399 + } + ], + "line": 396 + }, + { + "name": "MinutesSentenceCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "text", + "type": "str", + "line": 403 + }, + { + "name": "citations", + "type": "list[str]", + "line": 404 + } + ], + "line": 402 + }, + { + "name": "MinutesDraftCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "model", + "type": "str", + "line": 408 + }, + { + "name": "prompt_version", + "type": "str", + "line": 409 + }, + { + "name": "human_approver", + "type": "str", + "line": 410 + }, + { + "name": "source_materials", + "type": "list[SourceMaterialCreate]", + "line": 411 + }, + { + "name": "sentences", + "type": "list[MinutesSentenceCreate]", + "line": 412 + } + ], + "line": 407 + }, + { + "name": "MinutesAiAssistCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "model", + "type": "str", + "line": 416 + }, + { + "name": "prompt_version", + "type": "str", + "line": 417 + }, + { + "name": "human_approver", + "type": "str", + "line": 418 + }, + { + "name": "source_materials", + "type": "list[SourceMaterialCreate]", + "line": 419 + }, + { + "name": "instruction", + "type": "str", + "line": 420 + } + ], + "line": 415 + }, + { + "name": "TranscriptCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "actor", + "type": "str", + "line": 427 + }, + { + "name": "source_label", + "type": "str", + "line": 428 + }, + { + "name": "transcript_text", + "type": "str", + "line": 429 + }, + { + "name": "public_release_requested", + "type": "bool", + "line": 430 + }, + { + "name": "closed_session", + "type": "bool", + "line": 431 + } + ], + "line": 426 + }, + { + "name": "OrdinanceResolutionHandoffCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "item_type", + "type": "str", + "line": 435 + }, + { + "name": "title", + "type": "str", + "line": 436 + }, + { + "name": "actor", + "type": "str", + "line": 437 + }, + { + "name": "legal_reviewer", + "type": "str", + "line": 438 + }, + { + "name": "text", + "type": "str", + "line": 439 + }, + { + "name": "source_motion_id", + "type": "str | None", + "line": 440 + }, + { + "name": "ordinance_number", + "type": "str | None", + "line": 441 + }, + { + "name": "resolution_number", + "type": "str | None", + "line": 442 + }, + { + "name": "source_references", + "type": "list[dict]", + "line": 443 + }, + { + "name": "affected_sections", + "type": "list[str]", + "line": 444 + }, + { + "name": "source_document_url", + "type": "str | None", + "line": 445 + }, + { + "name": "source_document_hash", + "type": "str | None", + "line": 446 + } + ], + "line": 434 + }, + { + "name": "OrdinanceResolutionHandoffRetry", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "handoff_id", + "type": "str | None", + "line": 450 + } + ], + "line": 449 + }, + { + "name": "PublicMeetingRecordCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "title", + "type": "str", + "line": 454 + }, + { + "name": "visibility", + "type": "str", + "line": 455 + }, + { + "name": "posted_agenda", + "type": "str", + "line": 456 + }, + { + "name": "posted_packet", + "type": "str", + "line": 457 + }, + { + "name": "approved_minutes", + "type": "str", + "line": 458 + }, + { + "name": "public_comment_enabled", + "type": "bool", + "line": 459 + }, + { + "name": "plain_language_summary", + "type": "str | None", + "line": 460 + }, + { + "name": "minutes_adopted_at", + "type": "str | None", + "line": 461 + }, + { + "name": "minutes_signed_by", + "type": "str | None", + "line": 462 + }, + { + "name": "closed_session_notes", + "type": "str | None", + "line": 463 + } + ], + "line": 453 + }, + { + "name": "PublicCommentCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "commenter_name", + "type": "str", + "line": 467 + }, + { + "name": "comment", + "type": "str", + "line": 468 + } + ], + "line": 466 + }, + { + "name": "VendorSyncSourceCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "connector", + "type": "str", + "line": 472 + }, + { + "name": "source_name", + "type": "str", + "line": 473 + }, + { + "name": "source_url", + "type": "str", + "line": 474 + }, + { + "name": "auth_method", + "type": "str", + "line": 475 + } + ], + "line": 471 + }, + { + "name": "VendorSyncRunRecordCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "records_discovered", + "type": "int", + "line": 479 + }, + { + "name": "records_succeeded", + "type": "int", + "line": 480 + }, + { + "name": "records_failed", + "type": "int", + "line": 481 + }, + { + "name": "retries_attempted", + "type": "int", + "line": 482 + }, + { + "name": "error_summary", + "type": "str | None", + "line": 483 + } + ], + "line": 478 + }, + { + "name": "VendorSyncCursorReset", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "cursor_at", + "type": "datetime | None", + "line": 487 + }, + { + "name": "reason", + "type": "str", + "line": 488 + } + ], + "line": 486 + } + ], + "configuration": [ + { + "environment": "TOWNLIGHT_MEETINGS_EXPORT_ROOT", + "line": 3457 + }, + { + "environment": "TOWNLIGHT_MEETINGS_AGENDA_INTAKE_DB_URL", + "line": 3463 + }, + { + "environment": "TOWNLIGHT_MEETINGS_AGENDA_ITEM_DB_URL", + "line": 3472 + }, + { + "environment": "TOWNLIGHT_MEETINGS_PACKET_ASSEMBLY_DB_URL", + "line": 3483 + }, + { + "environment": "TOWNLIGHT_MEETINGS_NOTICE_CHECKLIST_DB_URL", + "line": 3492 + }, + { + "environment": "TOWNLIGHT_MEETINGS_MEETING_BODY_DB_URL", + "line": 3501 + }, + { + "environment": "TOWNLIGHT_MEETINGS_MEETING_DB_URL", + "line": 3510 + }, + { + "environment": "TOWNLIGHT_MEETINGS_VENDOR_SYNC_DB_URL", + "line": 3521 + }, + { + "environment": "TOWNLIGHT_MEETINGS_MOTION_VOTE_DB_URL", + "line": 3530 + }, + { + "environment": "TOWNLIGHT_MEETINGS_MINUTES_DB_URL", + "line": 3541 + }, + { + "environment": "TOWNLIGHT_MEETINGS_PUBLIC_ARCHIVE_DB_URL", + "line": 3552 + }, + { + "environment": "TOWNLIGHT_MEETINGS_PUBLIC_ARCHIVE_DB_URL", + "line": 3563 + } + ] + }, + { + "source": "townlight_meetings/meeting_body.py", + "sha256": "8d942a6b5c5ee54118fad110a69342de050b3ade33d29d6ff7b816be169d4c52", + "bytes": 5165, + "routes": [], + "models": [ + { + "name": "MeetingBodyRecord", + "bases": [], + "fields": [ + { + "name": "id", + "type": "UUID", + "line": 32 + }, + { + "name": "name", + "type": "str", + "line": 33 + }, + { + "name": "body_type", + "type": "str", + "line": 34 + }, + { + "name": "is_active", + "type": "bool", + "line": 35 + }, + { + "name": "created_at", + "type": "datetime", + "line": 36 + }, + { + "name": "updated_at", + "type": "datetime", + "line": 37 + } + ], + "line": 29 + } + ], + "configuration": [] + }, + { + "source": "townlight_meetings/meeting_lifecycle.py", + "sha256": "8e85facc34e20861bf12bf4787094963057f731d908ba68c8369c347edcaee14", + "bytes": 22805, + "routes": [], + "models": [ + { + "name": "TransitionResult", + "bases": [], + "fields": [ + { + "name": "allowed", + "type": "bool", + "line": 75 + }, + { + "name": "http_status", + "type": "int", + "line": 76 + }, + { + "name": "message", + "type": "str", + "line": 77 + }, + { + "name": "fix", + "type": "str", + "line": 78 + }, + { + "name": "audit_entry", + "type": "dict[str, object]", + "line": 79 + } ], - "line": 122, - "doc": "" + "line": 74 }, { - "name": "FeeWaiverPayload", - "bases": [ - "NativePayload" - ], + "name": "MeetingRecord", + "bases": [], + "fields": [ + { + "name": "id", + "type": "str", + "line": 84 + }, + { + "name": "title", + "type": "str", + "line": 85 + }, + { + "name": "meeting_type", + "type": "str", + "line": 86 + }, + { + "name": "scheduled_start", + "type": "datetime | None", + "line": 87 + }, + { + "name": "meeting_body_id", + "type": "str | None", + "line": 88 + }, + { + "name": "location", + "type": "str | None", + "line": 89 + }, + { + "name": "status", + "type": "str", + "line": 90 + }, + { + "name": "audit_entries", + "type": "list[dict[str, object]]", + "line": 91 + } + ], + "line": 83 + } + ], + "configuration": [] + }, + { + "source": "townlight_meetings/migrations/__init__.py", + "sha256": "2f702ea1ab0e065bdfe893ab61f83640ed21e3d1ed0369c064c1220775ea3bc7", + "bytes": 53, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_meetings/migrations/alembic.ini", + "sha256": "92766d392cd23d39d3896a835c5e9377caf76545f263183e1dafaf90779203bb", + "bytes": 770, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_meetings/migrations/env.py", + "sha256": "2dac3fa33b6c23c15a3e22b0a047df52b21987faca89267dc220b9a45df75191", + "bytes": 2428, + "routes": [], + "models": [], + "configuration": [ + { + "environment": "DATABASE_URL", + "line": 24 + } + ] + }, + { + "source": "townlight_meetings/migrations/guards.py", + "sha256": "c15233f35fdb6aad0659926a9f86ce17ab2c05461c1ad5dda4797bb0a2ec5068", + "bytes": 514, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_meetings/migrations/versions/__init__.py", + "sha256": "0c884013c778ac8bcf273f0a0c5bc159f488c2213e5d9580519ca057e3f93b17", + "bytes": 54, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_meetings/migrations/versions/townlight_meetings_0001_schema.py", + "sha256": "0e0ce48ca01b2c4a26a71b78456256ae250ea441342e8c6f8e7d6ac15fbb2c39", + "bytes": 7272, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_meetings/migrations/versions/townlight_meetings_0002_agenda_intake_queue.py", + "sha256": "49a9425fe4a1bb816c536aeeba439e78e0f83a13de3b740c42e8745a8c27f7bb", + "bytes": 1490, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_meetings/migrations/versions/townlight_meetings_0003_packet_assembly_records.py", + "sha256": "9a75aa6a86e6e273944c702dc0528ed4b1932d352e248bc74738fa569cf3d223", + "bytes": 1666, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_meetings/migrations/versions/townlight_meetings_0004_notice_checklist_records.py", + "sha256": "9d48fdc8044458a30e95139831e1b72061943f9c819b0b3c0633f1152d378010", + "bytes": 1735, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_meetings/migrations/versions/townlight_meetings_0005_meeting_records.py", + "sha256": "24f50601c97f145ad6a959fc8e617806286cf2f9c5a959014c14e9ba5d81e204", + "bytes": 1169, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_meetings/migrations/versions/townlight_meetings_0006_agenda_item_lifecycle_records.py", + "sha256": "d4adce2b58d003d0320198f152cc1e69c3158512a6a19ce3b94e31fd464f9d9c", + "bytes": 1127, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_meetings/migrations/versions/townlight_meetings_0007_meeting_schedule_fields.py", + "sha256": "b6bec8f062dc9f032ffd7191fa04b2b477c0ce6adcd3bde80ae66c6a90746abd", + "bytes": 1489, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_meetings/migrations/versions/townlight_meetings_0008_agenda_intake_promotion.py", + "sha256": "ee3b2ea4b1240a5d3db4e257672b3aa167b8b6a0cc73e26ba483544ff2652192", + "bytes": 1834, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_meetings/migrations/versions/townlight_meetings_0009_vendor_sync_persistence.py", + "sha256": "5c5712c4cdeb9447e060ae6e0d465e2bf75f2c888d7d7702f180ca67be901048", + "bytes": 3709, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_meetings/migrations/versions/townlight_meetings_0010_vendor_sync_cursor.py", + "sha256": "a09f09862e8a279445feea66be71b26cff83c44ff272a0c15b95248ed7cadce3", + "bytes": 858, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_meetings/migrations/versions/townlight_meetings_0011_data_model_completion.py", + "sha256": "58a960f8a84cb532d39b4af9b3088360fe5507b028aebb64a11210b93c17e5b7", + "bytes": 9389, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_meetings/migrations/versions/townlight_meetings_0012_action_item_actor.py", + "sha256": "e4efccca64d15074c36296f4a2666e02110298de02c13f8ac772798089fd8a4c", + "bytes": 999, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_meetings/migrations/versions/townlight_meetings_0013_minutes_model_posted.py", + "sha256": "50a8125f9c7ea967f8187d0d2e06c592604e64953f6a452dfc96523ebb92df41", + "bytes": 1267, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_meetings/migrations/versions/townlight_meetings_0014_public_meeting_records.py", + "sha256": "ccc0bf6229a9c9a278ee57c7ea018744ac9125bc18d3f21636869a64b5ec6b15", + "bytes": 2153, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_meetings/migrations/versions/townlight_meetings_0015_capture_seq.py", + "sha256": "598bbab49533f1aba774703d83efd35776ec3a41107195030edbfca23d832584", + "bytes": 2348, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_meetings/migrations/versions/townlight_meetings_0016_archive_indexes.py", + "sha256": "72f55f23307d04c70502674a9b6f99a23497fa96c81cccad3b1a0eeb8316a3f5", + "bytes": 1891, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_meetings/migrations/versions/townlight_meetings_0017_meeting_authority.py", + "sha256": "a78e6c3dab3f60fe864846b68387e5961d2689bf3178f635a6ef9f9d5657743c", + "bytes": 2368, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_meetings/migrations/versions/townlight_meetings_0018_agenda_authority.py", + "sha256": "eee17737b39bc3ba6ca894b093265c222794de97e560720cb3780483b914ed02", + "bytes": 1738, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_meetings/migrations/versions/townlight_meetings_0019_minutes_decisions.py", + "sha256": "740f4f76740008ed0ff1f95f02b6b6d022542236d0978ee7a131f472fb7c14d7", + "bytes": 550, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_meetings/migrations/versions/townlight_meetings_0020_delivery_history.py", + "sha256": "7dc873a822e2f85f1d30380c55e86d6c32fd9aaf7b050595134c03396d8d50d7", + "bytes": 769, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_meetings/migrations/versions/townlight_meetings_0021_sources_archive.py", + "sha256": "bdfda03eb565680a2444b17bdb743dd1dff95e9c612f80accaab7f03c55b3121", + "bytes": 923, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_meetings/minutes.py", + "sha256": "2054ae33051ea48015f65b0c3caee89c3c12d43dcd8536c372cccbf6cf281e24", + "bytes": 18230, + "routes": [], + "models": [ + { + "name": "MinutesProvenance", + "bases": [], "fields": [ { - "name": "feeWaiverReason", + "name": "model", "type": "str", - "default": "Field(min_length=1)" - } - ], - "line": 140, - "doc": "" - }, - { - "name": "DraftPayload", - "bases": [ - "NativePayload" - ], - "fields": [ + "line": 27 + }, { - "name": "responseDraft", + "name": "prompt_version", "type": "str", - "default": "Field(min_length=1)" + "line": 28 }, { - "name": "citation", - "type": "str", - "default": "''" - } - ], - "line": 144, - "doc": "" - }, - { - "name": "ApprovalPayload", - "bases": [ - "NativePayload" - ], - "fields": [ + "name": "data_sources", + "type": "tuple[str, ...]", + "line": 29 + }, { - "name": "approvalNote", + "name": "human_approver", "type": "str", - "default": "''" + "line": 30 } ], - "line": 149, - "doc": "" + "line": 26 }, { - "name": "AssignCommand", - "bases": [ - "NativePayload" - ], + "name": "MinutesDraft", + "bases": [], "fields": [ { - "name": "action", - "type": "Literal['assign-records-request']", - "default": "" + "name": "id", + "type": "str", + "line": 43 }, { - "name": "payload", - "type": "AssignmentPayload", - "default": "" - } - ], - "line": 153, - "doc": "" - }, - { - "name": "DeadlineCommand", - "bases": [ - "NativePayload" - ], - "fields": [ - { - "name": "action", - "type": "Literal['set-records-deadline']", - "default": "" + "name": "meeting_id", + "type": "str", + "line": 44 }, { - "name": "payload", - "type": "DeadlinePayload", - "default": "" - } - ], - "line": 158, - "doc": "" - }, - { - "name": "CalculateDeadlineCommand", - "bases": [ - "NativePayload" - ], - "fields": [ - { - "name": "action", - "type": "Literal['calculate-records-deadline']", - "default": "" + "name": "status", + "type": "str", + "line": 45 }, { - "name": "payload", - "type": "CalculateDeadlinePayload", - "default": "" - } - ], - "line": 163, - "doc": "" - }, - { - "name": "ClarificationCommand", - "bases": [ - "NativePayload" - ], - "fields": [ - { - "name": "action", - "type": "Literal['request-records-clarification']", - "default": "" + "name": "sentences", + "type": "tuple[MinutesSentence, ...]", + "line": 46 }, { - "name": "payload", - "type": "ClarificationPayload", - "default": "" - } - ], - "line": 168, - "doc": "" - }, - { - "name": "MessageCommand", - "bases": [ - "NativePayload" - ], - "fields": [ - { - "name": "action", - "type": "Literal['add-records-message']", - "default": "" + "name": "source_materials", + "type": "tuple[SourceMaterial, ...]", + "line": 47 }, { - "name": "payload", - "type": "MessagePayload", - "default": "" - } - ], - "line": 173, - "doc": "" - }, - { - "name": "SearchNoteCommand", - "bases": [ - "NativePayload" - ], - "fields": [ + "name": "provenance", + "type": "MinutesProvenance", + "line": 48 + }, { - "name": "action", - "type": "Literal['record-records-search']", - "default": "" + "name": "adopted", + "type": "bool", + "line": 49 }, { - "name": "payload", - "type": "SearchNotePayload", - "default": "" - } - ], - "line": 178, - "doc": "" - }, - { - "name": "SearchReceiptCommand", - "bases": [ - "NativePayload" - ], - "fields": [ + "name": "posted", + "type": "bool", + "line": 50 + }, { - "name": "action", - "type": "Literal['record-records-search-session']", - "default": "" + "name": "signed_by", + "type": "str | None", + "line": 51 }, { - "name": "payload", - "type": "SearchReceiptPayload", - "default": "" + "name": "decision_history", + "type": "tuple[dict, ...]", + "line": 52 } ], - "line": 183, - "doc": "" + "line": 42 }, { - "name": "ExemptionNoteCommand", - "bases": [ - "NativePayload" - ], + "name": "MinutesValidationError", + "bases": [], "fields": [ { - "name": "action", - "type": "Literal['add-records-exemption-review']", - "default": "" + "name": "message", + "type": "str", + "line": 72 }, { - "name": "payload", - "type": "ExemptionNotePayload", - "default": "" + "name": "fix", + "type": "str", + "line": 73 } ], - "line": 188, - "doc": "" - }, + "line": 71 + } + ], + "configuration": [] + }, + { + "source": "townlight_meetings/mock_city_environment.py", + "sha256": "71c8698fa5b24cdf89b020e6aab68752563f6349b01d11ce38d20a06244f9cad", + "bytes": 32670, + "routes": [], + "models": [ { - "name": "ExemptionDecisionCommand", - "bases": [ - "NativePayload" - ], + "name": "MockCityHostileFixture", + "bases": [], "fields": [ { - "name": "action", - "type": "Literal['add-records-exemption-decision']", - "default": "" + "name": "area", + "type": "HostileArea", + "line": 50 }, { - "name": "payload", - "type": "ExemptionDecisionPayload", - "default": "" - } - ], - "line": 193, - "doc": "" - }, - { - "name": "FeeEstimateCommand", - "bases": [ - "NativePayload" - ], - "fields": [ - { - "name": "action", - "type": "Literal['estimate-records-fee']", - "default": "" + "name": "scenario", + "type": "str", + "line": 51 }, { - "name": "payload", - "type": "FeeEstimatePayload", - "default": "" - } - ], - "line": 198, - "doc": "" - }, - { - "name": "FeeLineCommand", - "bases": [ - "NativePayload" - ], - "fields": [ + "name": "target", + "type": "str", + "line": 52 + }, { - "name": "action", - "type": "Literal['add-records-fee-line']", - "default": "" + "name": "trigger", + "type": "str", + "line": 53 }, { - "name": "payload", - "type": "FeeLinePayload", - "default": "" - } - ], - "line": 203, - "doc": "" - }, - { - "name": "FeeWaiverCommand", - "bases": [ - "NativePayload" - ], - "fields": [ + "name": "expected_behavior", + "type": "str", + "line": 54 + }, { - "name": "action", - "type": "Literal['waive-records-fee']", - "default": "" + "name": "fix", + "type": "str", + "line": 55 }, { - "name": "payload", - "type": "FeeWaiverPayload", - "default": "" + "name": "sample", + "type": "dict[str, Any]", + "line": 56 } ], - "line": 208, - "doc": "" + "line": 47 }, { - "name": "DraftCommand", - "bases": [ - "NativePayload" - ], + "name": "MockCityHostileCheck", + "bases": [], "fields": [ { - "name": "action", - "type": "Literal['draft-records-response']", - "default": "" + "name": "area", + "type": "HostileArea", + "line": 74 }, { - "name": "payload", - "type": "DraftPayload", - "default": "" - } - ], - "line": 213, - "doc": "" - }, - { - "name": "ApprovalCommand", - "bases": [ - "NativePayload" - ], - "fields": [ + "name": "scenario", + "type": "str", + "line": 75 + }, { - "name": "action", - "type": "Literal['approve-records-response']", - "default": "" + "name": "target", + "type": "str", + "line": 76 }, { - "name": "payload", - "type": "ApprovalPayload", - "default": "Field(default_factory=ApprovalPayload)" - } - ], - "line": 218, - "doc": "" - }, - { - "name": "FinishCommand", - "bases": [ - "NativePayload" - ], - "fields": [ + "name": "ok", + "type": "bool", + "line": 77 + }, { - "name": "action", - "type": "Literal['fulfill-records-request', 'close-records-request']", - "default": "" + "name": "message", + "type": "str", + "line": 78 }, { - "name": "payload", - "type": "NativePayload", - "default": "Field(default_factory=NativePayload)" + "name": "fix", + "type": "str", + "line": 79 } ], - "line": 223, - "doc": "" - }, + "line": 71 + } + ], + "configuration": [] + }, + { + "source": "townlight_meetings/models.py", + "sha256": "5607a664757054913929de1cc5cc9a4f6cdce53ec73e93b4ef7e2eb9d4437195", + "bytes": 11996, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_meetings/motion_vote.py", + "sha256": "e94fb8bc6a02951c67aba8bd91e8be64f04dfe72197e147ae84339d04e53fc0b", + "bytes": 26765, + "routes": [], + "models": [ { - "name": "TimelineView", - "bases": [ - "NativeView" - ], + "name": "MotionRecord", + "bases": [], "fields": [ { "name": "id", "type": "str", - "default": "" + "line": 18 }, { - "name": "action", + "name": "meeting_id", "type": "str", - "default": "" + "line": 19 }, { - "name": "actor", + "name": "text", "type": "str", - "default": "" + "line": 20 }, { - "name": "note", + "name": "actor", "type": "str", - "default": "" + "line": 21 }, { - "name": "created_at_unix_seconds", - "type": "int", - "default": "" + "name": "agenda_item_id", + "type": "str | None", + "line": 22 + }, + { + "name": "seconded_by", + "type": "str | None", + "line": 23 + }, + { + "name": "correction_of_id", + "type": "str | None", + "line": 24 + }, + { + "name": "correction_reason", + "type": "str | None", + "line": 25 + }, + { + "name": "captured", + "type": "bool", + "line": 26 } ], - "line": 241, - "doc": "" + "line": 17 }, { - "name": "PublicStatusView", - "bases": [ - "NativeView" - ], + "name": "VoteRecord", + "bases": [], "fields": [ { "name": "id", "type": "str", - "default": "" + "line": 44 }, { - "name": "label", + "name": "motion_id", "type": "str", - "default": "" + "line": 45 }, { - "name": "summary", + "name": "voter_name", "type": "str", - "default": "" + "line": 46 }, { - "name": "status", + "name": "vote", "type": "str", - "default": "" + "line": 47 }, { - "name": "created_at_unix_seconds", - "type": "int", - "default": "" + "name": "actor", + "type": "str", + "line": 48 + }, + { + "name": "correction_of_id", + "type": "str | None", + "line": 49 + }, + { + "name": "correction_reason", + "type": "str | None", + "line": 50 + }, + { + "name": "captured", + "type": "bool", + "line": 51 } ], - "line": 249, - "doc": "" + "line": 43 }, { - "name": "MessageView", - "bases": [ - "NativeView" - ], + "name": "ActionItemRecord", + "bases": [], "fields": [ { "name": "id", "type": "str", - "default": "" + "line": 68 }, { - "name": "author", + "name": "meeting_id", "type": "str", - "default": "" + "line": 69 }, { - "name": "author_role", + "name": "description", "type": "str", - "default": "" + "line": 70 }, { - "name": "body", + "name": "actor", "type": "str", - "default": "" + "line": 71 }, { - "name": "visibility", - "type": "str", - "default": "" + "name": "assigned_to", + "type": "str | None", + "line": 72 }, { - "name": "created_at_unix_seconds", - "type": "int", - "default": "" + "name": "source_motion_id", + "type": "str | None", + "line": 73 + }, + { + "name": "status", + "type": "str", + "line": 74 } ], - "line": 257, - "doc": "" + "line": 67 }, { - "name": "FeeLineView", - "bases": [ - "NativeView" - ], + "name": "MeetingOutcomeSummary", + "bases": [], "fields": [ { - "name": "id", + "name": "meeting_id", "type": "str", - "default": "" + "line": 90 }, { - "name": "description", + "name": "motion_id", "type": "str", - "default": "" + "line": 91 }, { - "name": "schedule_basis", + "name": "text", "type": "str", - "default": "" + "line": 92 }, { - "name": "amount_cents", + "name": "actor", + "type": "str", + "line": 93 + }, + { + "name": "status", + "type": "str", + "line": 94 + }, + { + "name": "vote_count", "type": "int", - "default": "" + "line": 95 }, { - "name": "created_at_unix_seconds", + "name": "action_item_count", "type": "int", - "default": "" + "line": 96 } ], - "line": 266, - "doc": "" - }, + "line": 89 + } + ], + "configuration": [] + }, + { + "source": "townlight_meetings/notice_checklist.py", + "sha256": "53a49cd45e73aec06f89b7354f4b43fd4c3741ab095be39852339eb21989299a", + "bytes": 12416, + "routes": [], + "models": [ { - "name": "ExemptionDecisionView", - "bases": [ - "NativeView" - ], + "name": "NoticeChecklistRecord", + "bases": [], "fields": [ { "name": "id", "type": "str", - "default": "" + "line": 53 }, { - "name": "source", + "name": "meeting_id", "type": "str", - "default": "" + "line": 54 }, { - "name": "kind", + "name": "notice_type", "type": "str", - "default": "" + "line": 55 }, { - "name": "finding", + "name": "status", "type": "str", - "default": "" + "line": 56 }, { - "name": "decision", - "type": "Literal['release', 'redact', 'exempt']", - "default": "" + "name": "compliant", + "type": "bool", + "line": 57 }, { - "name": "basis", - "type": "str", - "default": "" + "name": "http_status", + "type": "int", + "line": 58 }, { - "name": "reviewer", - "type": "str", - "default": "" + "name": "warnings", + "type": "list[dict]", + "line": 59 }, { - "name": "created_at_unix_seconds", + "name": "deadline_at", + "type": "datetime", + "line": 60 + }, + { + "name": "posted_at", + "type": "datetime", + "line": 61 + }, + { + "name": "minimum_notice_hours", "type": "int", - "default": "" - } - ], - "line": 274, - "doc": "" - }, - { - "name": "SearchResultView", - "bases": [ - "NativeView" - ], - "fields": [ + "line": 62 + }, + { + "name": "statutory_basis", + "type": "str | None", + "line": 63 + }, + { + "name": "approved_by", + "type": "str | None", + "line": 64 + }, { - "name": "id", - "type": "str", - "default": "" + "name": "posting_proof", + "type": "dict | None", + "line": 65 }, { - "name": "title", + "name": "last_audit_hash", "type": "str", - "default": "" + "line": 66 }, { - "name": "citation", - "type": "str", - "default": "" + "name": "created_at", + "type": "datetime", + "line": 67 }, { - "name": "summary", - "type": "str", - "default": "" + "name": "updated_at", + "type": "datetime", + "line": 68 }, { - "name": "status", - "type": "str", - "default": "" + "name": "audit_entries", + "type": "list[dict]", + "line": 69 } ], - "line": 285, - "doc": "" - }, + "line": 50 + } + ], + "configuration": [] + }, + { + "source": "townlight_meetings/oidc_auth.py", + "sha256": "56e8cf18103a38230f8b77c27d86d0fd948adfcb5c1383056d676ed26979cf36", + "bytes": 14727, + "routes": [], + "models": [ { - "name": "SearchReceiptView", - "bases": [ - "NativeView" - ], + "name": "OidcStaffAuthConfig", + "bases": [], "fields": [ { - "name": "id", + "name": "provider", "type": "str", - "default": "" + "line": 22 }, { - "name": "query", + "name": "issuer", "type": "str", - "default": "" + "line": 23 }, { - "name": "locations", + "name": "audience", "type": "str", - "default": "" + "line": 24 }, { - "name": "reviewer", - "type": "str", - "default": "" + "name": "jwks_url", + "type": "str | None", + "line": 25 }, { - "name": "results", - "type": "list[SearchResultView]", - "default": "" + "name": "jwks_json", + "type": "str | None", + "line": 26 }, { - "name": "created_at_unix_seconds", - "type": "int", - "default": "" - } - ], - "line": 293, - "doc": "" - }, - { - "name": "RecordsView", - "bases": [ - "NativeView" - ], - "fields": [ + "name": "role_claims", + "type": "tuple[str, ...]", + "line": 27 + }, { - "name": "request_id", - "type": "str", - "default": "" + "name": "algorithms", + "type": "tuple[str, ...]", + "line": 28 }, { - "name": "id", - "type": "str", - "default": "" + "name": "authorization_url", + "type": "str | None", + "line": 29 }, { - "name": "public_tracking_number", - "type": "str", - "default": "" + "name": "token_url", + "type": "str | None", + "line": 30 }, { - "name": "requester", - "type": "str", - "default": "" + "name": "client_id", + "type": "str | None", + "line": 31 }, { - "name": "requester_contact", - "type": "str", - "default": "" + "name": "client_secret", + "type": "str | None", + "line": 32 }, { - "name": "submitted_via", + "name": "redirect_uri", + "type": "str | None", + "line": 33 + }, + { + "name": "session_cookie_secret", + "type": "str | None", + "line": 34 + } + ], + "line": 21 + } + ], + "configuration": [] + }, + { + "source": "townlight_meetings/packet_assembly.py", + "sha256": "053cbccbb5a8f2c61ab38c74a2a9e1cbfcdaedceadd30b745768935c75af68c6", + "bytes": 11617, + "routes": [], + "models": [ + { + "name": "PacketAssemblyRecord", + "bases": [], + "fields": [ + { + "name": "id", "type": "str", - "default": "" + "line": 54 }, { - "name": "summary", + "name": "meeting_id", "type": "str", - "default": "" + "line": 55 }, { - "name": "deadline", + "name": "packet_snapshot_id", "type": "str", - "default": "" + "line": 56 }, { - "name": "deadline_basis", + "name": "packet_version", + "type": "int", + "line": 57 + }, + { + "name": "title", "type": "str", - "default": "" + "line": 58 }, { "name": "status", "type": "str", - "default": "" + "line": 59 }, { - "name": "assigned_to", + "name": "actor", "type": "str", - "default": "" + "line": 60 }, { - "name": "clarification_notes", + "name": "agenda_item_ids", "type": "list[str]", - "default": "" + "line": 61 }, { - "name": "search_notes", - "type": "list[str]", - "default": "" + "name": "source_references", + "type": "list[dict]", + "line": 62 }, { - "name": "search_sessions", - "type": "list[SearchReceiptView]", - "default": "" + "name": "citations", + "type": "list[dict]", + "line": 63 }, { - "name": "exemption_reviews", - "type": "list[str]", - "default": "" + "name": "finalized_by", + "type": "str | None", + "line": 64 }, { - "name": "exemption_decisions", - "type": "list[ExemptionDecisionView]", - "default": "" + "name": "finalized_at", + "type": "datetime | None", + "line": 65 }, { - "name": "fee_estimate", + "name": "last_audit_hash", "type": "str", - "default": "" + "line": 66 }, { - "name": "fee_line_items", - "type": "list[FeeLineView]", - "default": "" + "name": "created_at", + "type": "datetime", + "line": 67 }, { - "name": "fee_waiver_reason", - "type": "str", - "default": "" + "name": "updated_at", + "type": "datetime", + "line": 68 }, { - "name": "citations", - "type": "list[str]", - "default": "" + "name": "snapshot_content", + "type": "list[dict]", + "line": 69 }, { - "name": "response_draft", + "name": "delivery_history", + "type": "list[dict]", + "line": 70 + }, + { + "name": "audit_entries", + "type": "list[dict]", + "line": 71 + } + ], + "line": 51 + } + ], + "configuration": [] + }, + { + "source": "townlight_meetings/packet_notice.py", + "sha256": "f6740f9e3a8e74e9e7c10ff91284df7cb8700f7c781f099bdb29f9492575f911", + "bytes": 18322, + "routes": [], + "models": [ + { + "name": "PacketSource", + "bases": [], + "fields": [ + { + "name": "source_id", "type": "str", - "default": "" + "line": 61 }, { - "name": "approval_notes", - "type": "list[str]", - "default": "" + "name": "title", + "type": "str", + "line": 62 }, { - "name": "exports", - "type": "list[str]", - "default": "" + "name": "kind", + "type": "str", + "line": 63 }, { - "name": "documents", - "type": "list['RecordsDocumentView']", - "default": "Field(default_factory=list)" + "name": "source_system", + "type": "str | None", + "line": 64 }, { - "name": "release_packages", - "type": "list['ReleasePackageView']", - "default": "Field(default_factory=list)" + "name": "source_path", + "type": "str | None", + "line": 65 }, { - "name": "timeline", - "type": "list[TimelineView]", - "default": "" + "name": "checksum", + "type": "str | None", + "line": 66 }, { - "name": "public_status_events", - "type": "list[PublicStatusView]", - "default": "" + "name": "sensitivity_label", + "type": "str | None", + "line": 67 }, { - "name": "messages", - "type": "list[MessageView]", - "default": "" + "name": "citation_label", + "type": "str | None", + "line": 68 + } + ], + "line": 58 + }, + { + "name": "PacketSnapshot", + "bases": [], + "fields": [ + { + "name": "id", + "type": "str", + "line": 93 }, { - "name": "deadline_reviewed_at_unix_seconds", - "type": "int | None", - "default": "" + "name": "meeting_id", + "type": "str", + "line": 94 }, { - "name": "approved_at_unix_seconds", - "type": "int | None", - "default": "" + "name": "version", + "type": "int", + "line": 95 }, { - "name": "fulfilled_at_unix_seconds", - "type": "int | None", - "default": "" + "name": "agenda_item_ids", + "type": "tuple[str, ...]", + "line": 96 }, { - "name": "closed_at_unix_seconds", - "type": "int | None", - "default": "" + "name": "actor", + "type": "str", + "line": 97 }, { - "name": "created_at_unix_seconds", - "type": "int", - "default": "" + "name": "created_at", + "type": "datetime", + "line": 98 } ], - "line": 302, - "doc": "" + "line": 92 }, { - "name": "RecordsOperationRead", - "bases": [ - "NativeView" - ], + "name": "PacketExportResult", + "bases": [], "fields": [ { - "name": "action", + "name": "meeting_id", "type": "str", - "default": "" + "line": 115 }, { - "name": "message", + "name": "bundle_path", "type": "str", - "default": "" + "line": 116 }, { - "name": "request", - "type": "RecordsView", - "default": "" - } - ], - "line": 339, - "doc": "" - }, - { - "name": "RecordsStateRead", - "bases": [ - "NativeView" - ], - "fields": [ + "name": "manifest_path", + "type": "str", + "line": 117 + }, { - "name": "demo_fixture", - "type": "dict | None", - "default": "None" + "name": "checksums_path", + "type": "str", + "line": 118 }, { - "name": "records_requests", - "type": "list[RecordsView]", - "default": "" + "name": "townlight_core_version", + "type": "str", + "line": 119 }, { - "name": "notification_events", - "type": "list['NotificationView']", - "default": "Field(default_factory=list)" + "name": "packet_version", + "type": "int", + "line": 120 }, { - "name": "publication_events", - "type": "list['PublicationView']", - "default": "Field(default_factory=list)" + "name": "audit_hash", + "type": "str", + "line": 121 }, { - "name": "audit_entries", - "type": "list['AuditView']", - "default": "Field(default_factory=list)" + "name": "generated_files", + "type": "tuple[str, ...]", + "line": 122 } ], - "line": 345, - "doc": "" + "line": 112 }, { - "name": "ManagedFileReceipt", - "bases": [ - "NativePayload" - ], + "name": "NoticeComplianceResult", + "bases": [], "fields": [ { - "name": "original_path", + "name": "meeting_id", "type": "str", - "default": "Field(min_length=1)" + "line": 344 }, { - "name": "stored_path", + "name": "notice_type", "type": "str", - "default": "Field(min_length=1)" + "line": 345 }, { - "name": "file_name", - "type": "str", - "default": "Field(min_length=1, max_length=500)" + "name": "scheduled_start", + "type": "datetime", + "line": 346 }, { - "name": "sha256", - "type": "str", - "default": "Field(pattern='^[0-9a-f]{64}$')" + "name": "posted_at", + "type": "datetime", + "line": 347 }, { - "name": "size_bytes", + "name": "minimum_notice_hours", "type": "int", - "default": "Field(ge=0, le=2147483647, strict=True)" - } - ], - "line": 353, - "doc": "" - }, - { - "name": "AttachDocument", - "bases": [ - "NativePayload" - ], - "fields": [ - { - "name": "title", - "type": "str", - "default": "Field(min_length=1)" + "line": 348 }, { - "name": "citation", - "type": "str", - "default": "''" + "name": "deadline_at", + "type": "datetime", + "line": 349 }, { - "name": "file", - "type": "ManagedFileReceipt", - "default": "" - } - ], - "line": 361, - "doc": "" - }, - { - "name": "AttachReleaseCopy", - "bases": [ - "NativePayload" - ], - "fields": [ + "name": "statutory_basis", + "type": "str | None", + "line": 350 + }, { - "name": "status", - "type": "Literal['release-ready copy', 'redacted copy']", - "default": "" + "name": "approved_by", + "type": "str | None", + "line": 351 }, { - "name": "note", - "type": "str", - "default": "''" + "name": "compliant", + "type": "bool", + "line": 352 }, { - "name": "added_by", - "type": "str", - "default": "''" + "name": "http_status", + "type": "int", + "line": 353 }, { - "name": "file", - "type": "ManagedFileReceipt", - "default": "" + "name": "warnings", + "type": "list[dict[str, str]]", + "line": 354 } ], - "line": 367, - "doc": "" + "line": 343 }, { - "name": "RecordsDocumentView", - "bases": [ - "NativeView" - ], + "name": "PostedNotice", + "bases": [], "fields": [ { "name": "id", "type": "str", - "default": "" + "line": 373 }, { - "name": "attachment_id", + "name": "result", + "type": "NoticeComplianceResult", + "line": 374 + } + ], + "line": 372 + } + ], + "configuration": [] + }, + { + "source": "townlight_meetings/prompt_evals.py", + "sha256": "5f7be9d93cd550d8b09877d1db9330fd30614140318b3d6425221c816f8c79dd", + "bytes": 5642, + "routes": [], + "models": [ + { + "name": "PromptEvalResult", + "bases": [], + "fields": [ + { + "name": "prompt_reference", "type": "str", - "default": "" + "line": 18 }, { - "name": "title", + "name": "provider", "type": "str", - "default": "" + "line": 19 }, { - "name": "original_path", - "type": "str", - "default": "" + "name": "offline", + "type": "bool", + "line": 20 }, { - "name": "stored_path", - "type": "str", - "default": "" + "name": "passed", + "type": "bool", + "line": 21 }, { - "name": "citation", + "name": "message", "type": "str", - "default": "" - }, + "line": 22 + } + ], + "line": 17 + } + ], + "configuration": [ + { + "environment": "TOWNLIGHT_CORE_LLM_PROVIDER", + "line": 128 + }, + { + "environment": "TOWNLIGHT_MEETINGS_EVAL_OFFLINE", + "line": 129 + } + ] + }, + { + "source": "townlight_meetings/prompt_library.py", + "sha256": "4bed68dc61c582fea26f61a36861dafe570d8a82b5c115c457eec19148759212", + "bytes": 10325, + "routes": [], + "models": [ + { + "name": "PromptEvaluation", + "bases": [], + "fields": [ { - "name": "sha256", + "name": "name", "type": "str", - "default": "" + "line": 35 }, { - "name": "size_bytes", - "type": "int", - "default": "" - }, + "name": "required_phrases", + "type": "tuple[str, ...]", + "line": 36 + } + ], + "line": 34 + }, + { + "name": "PromptDefinition", + "bases": [], + "fields": [ { - "name": "status", + "name": "id", "type": "str", - "default": "" + "line": 41 }, { - "name": "added_by", + "name": "version", "type": "str", - "default": "" - }, - { - "name": "created_at_unix_seconds", - "type": "int", - "default": "" + "line": 42 }, { - "name": "release_original_path", + "name": "provider", "type": "str", - "default": "''" + "line": 43 }, { - "name": "release_stored_path", + "name": "purpose", "type": "str", - "default": "''" + "line": 44 }, { - "name": "release_file_name", - "type": "str", - "default": "''" + "name": "required_variables", + "type": "tuple[str, ...]", + "line": 45 }, { - "name": "release_sha256", + "name": "system_prompt", "type": "str", - "default": "''" - }, - { - "name": "release_size_bytes", - "type": "int", - "default": "0" + "line": 46 }, { - "name": "release_status", + "name": "template", "type": "str", - "default": "''" + "line": 47 }, { - "name": "release_note", - "type": "str", - "default": "''" + "name": "evaluations", + "type": "tuple[PromptEvaluation, ...]", + "line": 48 }, { - "name": "release_added_by", - "type": "str", - "default": "''" + "name": "public_facing", + "type": "bool", + "line": 49 }, { - "name": "release_added_at_unix_seconds", - "type": "int | None", - "default": "None" + "name": "approval_required", + "type": "str | None", + "line": 50 } ], - "line": 374, - "doc": "" - }, + "line": 40 + } + ], + "configuration": [] + }, + { + "source": "townlight_meetings/public_archive.py", + "sha256": "cc16f9a752bd853688a04c001e4a867e53f329fce32776e0f93ff06679f8fab2", + "bytes": 28574, + "routes": [], + "models": [ { - "name": "ReleasePackageView", - "bases": [ - "NativeView" - ], + "name": "PublicMeetingRecord", + "bases": [], "fields": [ { "name": "id", "type": "str", - "default": "" + "line": 28 }, { - "name": "export_path", + "name": "meeting_id", "type": "str", - "default": "" + "line": 29 }, { - "name": "package_hash", + "name": "title", "type": "str", - "default": "" - }, - { - "name": "document_count", - "type": "int", - "default": "" - }, - { - "name": "release_artifact_count", - "type": "int", - "default": "" + "line": 30 }, { - "name": "search_session_count", - "type": "int", - "default": "" + "name": "visibility", + "type": "str", + "line": 31 }, { - "name": "release_count", - "type": "int", - "default": "" + "name": "posted_agenda", + "type": "str", + "line": 32 }, { - "name": "redacted_count", - "type": "int", - "default": "" + "name": "posted_packet", + "type": "str", + "line": 33 }, { - "name": "exempt_count", - "type": "int", - "default": "" + "name": "approved_minutes", + "type": "str", + "line": 34 }, { - "name": "created_at_unix_seconds", - "type": "int", - "default": "" - } - ], - "line": 397, - "doc": "" - }, - { - "name": "PrepareArtifact", - "bases": [ - "NativePayload" - ], - "fields": [ - { - "name": "kind", - "type": "Literal['response', 'release-package']", - "default": "" - } - ], - "line": 410, - "doc": "" - }, - { - "name": "ArtifactPlan", - "bases": [ - "NativeView" - ], - "fields": [ + "name": "public_comment_enabled", + "type": "bool", + "line": 35 + }, { - "name": "artifact_id", - "type": "str", - "default": "" + "name": "plain_language_summary", + "type": "str | None", + "line": 36 }, { - "name": "file_name", - "type": "str", - "default": "" + "name": "agenda_download_url", + "type": "str | None", + "line": 37 }, { - "name": "content", - "type": "str", - "default": "" + "name": "packet_download_url", + "type": "str | None", + "line": 38 }, { - "name": "sha256", - "type": "str", - "default": "" + "name": "minutes_download_url", + "type": "str | None", + "line": 39 }, { - "name": "created_at_unix_seconds", - "type": "int", - "default": "" - } - ], - "line": 414, - "doc": "" - }, - { - "name": "CompleteArtifact", - "bases": [ - "NativePayload" - ], - "fields": [ + "name": "minutes_adopted_at", + "type": "str | None", + "line": 40 + }, { - "name": "export_path", - "type": "str", - "default": "Field(min_length=1)" + "name": "minutes_signed_by", + "type": "str | None", + "line": 41 + }, + { + "name": "closed_session_notes", + "type": "str | None", + "line": 42 + }, + { + "name": "audit_entries", + "type": "list[dict]", + "line": 43 } ], - "line": 422, - "doc": "" + "line": 27 }, { - "name": "PublicIntake", - "bases": [ - "NativePayload" - ], + "name": "PublicCommentRecord", + "bases": [], "fields": [ { - "name": "requester", + "name": "id", "type": "str", - "default": "Field(min_length=1)" + "line": 70 }, { - "name": "requesterContact", + "name": "public_record_id", "type": "str", - "default": "Field(min_length=1)" + "line": 71 }, { - "name": "summary", + "name": "commenter_name", "type": "str", - "default": "Field(min_length=1)" + "line": 72 }, { - "name": "deadline", - "type": "str", - "default": "''" - } - ], - "line": 426, - "doc": "" - }, - { - "name": "PublicLookup", - "bases": [ - "NativePayload" - ], - "fields": [ - { - "name": "trackingNumber", + "name": "comment", "type": "str", - "default": "Field(min_length=1)" + "line": 73 }, { - "name": "requesterContact", + "name": "submitted_at", "type": "str", - "default": "Field(min_length=1)" - } - ], - "line": 433, - "doc": "" - }, - { - "name": "PublicMessage", - "bases": [ - "PublicLookup" - ], - "fields": [ + "line": 74 + }, { - "name": "publicRequestMessage", + "name": "status", "type": "str", - "default": "Field(min_length=1)" + "line": 75 } ], - "line": 438, - "doc": "" - }, + "line": 69 + } + ], + "configuration": [] + }, + { + "source": "townlight_meetings/public_ui.py", + "sha256": "3a5c15cf99279eb3bf66168902fe02b29ff5f4bfc13382535ff7222a5aa85ac6", + "bytes": 13818, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_meetings/records_sources.py", + "sha256": "7de91ba5712b2518ccc1d16780b008a7a1007f85d9b2074e7153a2b29b69f239", + "bytes": 1851, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_meetings/staff_ui.py", + "sha256": "42a675c24f34d4e48dc5e06cfab93c78623f70854171afda214df6d01f529552", + "bytes": 80954, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_meetings/suite_session_compat.py", + "sha256": "aad63f43710236fdbc6766b4eca1053d016c5e80a0c8ebfa174c9a69fb0f934c", + "bytes": 5898, + "routes": [], + "models": [ { - "name": "GeneratedDraft", - "bases": [ - "NativePayload" - ], + "name": "SuiteSessionPrincipal", + "bases": [], "fields": [ { - "name": "text", + "name": "subject", "type": "str", - "default": "Field(min_length=1)" + "line": 31 }, { - "name": "model", - "type": "str", - "default": "Field(min_length=1)" + "name": "roles", + "type": "frozenset[str]", + "line": 32 }, { - "name": "previous_response_sha256", + "name": "session_id", "type": "str", - "default": "Field(pattern='^[0-9a-f]{64}$')" + "line": 33 } ], - "line": 442, - "doc": "" - }, + "line": 28 + } + ], + "configuration": [] + }, + { + "source": "townlight_meetings/transcripts.py", + "sha256": "736ed66a6deb8554bb973410f315b3b7c83ab5bae96c5fe96a259536f0799e5a", + "bytes": 3358, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_meetings/vendor_delta.py", + "sha256": "a6ab9f820ff2541b93951e34ba18825f5901784b8b546dfc77e2eb47dee54d43", + "bytes": 358, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_meetings/vendor_live_sync.py", + "sha256": "5e3423fa73ea3d6c3ea2339fdd7cb050d35c3f26040ab3ea254dccc77e3224fe", + "bytes": 6024, + "routes": [], + "models": [ { - "name": "NotificationView", - "bases": [ - "NativeView" - ], + "name": "LiveSyncCheck", + "bases": [], "fields": [ { - "name": "id", - "type": "str", - "default": "" + "name": "status", + "type": "Literal['PASS', 'FAIL']", + "line": 50 }, { - "name": "notification_id", + "name": "name", "type": "str", - "default": "" + "line": 51 }, { - "name": "module_id", + "name": "message", "type": "str", - "default": "" + "line": 52 }, { - "name": "record_id", + "name": "fix", "type": "str", - "default": "" - }, + "line": 53 + } + ], + "line": 49 + }, + { + "name": "VendorLiveSyncConfig", + "bases": [], + "fields": [ { - "name": "audience", + "name": "connector", "type": "str", - "default": "" + "line": 58 }, { - "name": "channel", + "name": "source_url", "type": "str", - "default": "" + "line": 59 }, { - "name": "subject", - "type": "str", - "default": "" + "name": "auth_method", + "type": "AuthMethod", + "line": 60 + } + ], + "line": 57 + } + ], + "configuration": [] + }, + { + "source": "townlight_meetings/vendor_network_sync.py", + "sha256": "03d533069a867a5ba04e37564e56b823a4b213f55ecf1fbb4f8700925a72f0f3", + "bytes": 15115, + "routes": [], + "models": [ + { + "name": "VendorNetworkSyncAttempt", + "bases": [], + "fields": [ + { + "name": "ok", + "type": "bool", + "line": 32 }, { - "name": "body", + "name": "message", "type": "str", - "default": "" + "line": 33 }, { - "name": "status", + "name": "fix", "type": "str", - "default": "" + "line": 34 }, { - "name": "created_at_unix_seconds", - "type": "int", - "default": "" + "name": "external_meeting_id", + "type": "str | None", + "line": 35 }, { - "name": "sent_at_unix_seconds", - "type": "int | None", - "default": "" + "name": "error_class", + "type": "str | None", + "line": 36 } ], - "line": 448, - "doc": "" + "line": 31 }, { - "name": "PublicationView", - "bases": [ - "NativeView" - ], + "name": "VendorNetworkSyncReport", + "bases": [], "fields": [ { - "name": "id", - "type": "str", - "default": "" - }, - { - "name": "source_module", + "name": "source_id", "type": "str", - "default": "" + "line": 41 }, { - "name": "source_record_id", + "name": "connector", "type": "str", - "default": "" + "line": 42 }, { - "name": "record_type", - "type": "str", - "default": "" + "name": "network_calls", + "type": "bool", + "line": 43 }, { - "name": "public_payload", - "type": "str", - "default": "" + "name": "records_discovered", + "type": "int", + "line": 44 }, { - "name": "payload_hash", - "type": "str", - "default": "" + "name": "records_succeeded", + "type": "int", + "line": 45 }, { - "name": "published_at_unix_seconds", + "name": "records_failed", "type": "int", - "default": "" + "line": 46 }, { - "name": "retracted_at_unix_seconds", - "type": "int | None", - "default": "None" + "name": "run_status", + "type": "str | None", + "line": 47 }, { - "name": "retracted_by", - "type": "str", - "default": "''" - } - ], - "line": 462, - "doc": "" - }, - { - "name": "AuditView", - "bases": [ - "NativeView" - ], - "fields": [ - { - "name": "id", - "type": "str", - "default": "" + "name": "source_health_status", + "type": "str | None", + "line": 48 }, { - "name": "module_id", - "type": "str", - "default": "" + "name": "delta_request_url", + "type": "str | None", + "line": 49 }, { - "name": "action", - "type": "str", - "default": "" + "name": "cursor_param", + "type": "str | None", + "line": 50 }, { - "name": "summary", - "type": "str", - "default": "" + "name": "cursor_value", + "type": "str | None", + "line": 51 }, { - "name": "created_at_unix_seconds", - "type": "int", - "default": "" + "name": "cursor_advanced_at", + "type": "str | None", + "line": 52 }, { - "name": "previous_hash", + "name": "message", "type": "str", - "default": "" + "line": 53 }, { - "name": "entry_hash", + "name": "fix", "type": "str", - "default": "" - } - ], - "line": 474, - "doc": "" - } - ], - "configuration": [] - }, - { - "source": "installed-owned-source/app/desktop_bridge/station.py", - "sha256": "2f53398b6a897f804419ea5025895bb7dc468d8891dc553b20bb14cb5d0a8084", - "routes": [ - { - "method": "GET", - "path": "/station/context", - "router": "router", - "prefix_resolved": false, - "name": "context", - "signature": "request: Request, capability: Literal['capture', 'read'], proof: str | None=Header(default=None, alias='X-Townlight-Session'), session: AsyncSession=Depends(get_async_session)", - "returns": "", - "line": 43, - "doc": "", - "decorator": "router.get('/station/context')", - "errors": [ - "HTTPException(403, 'This staff role cannot perform this Station operation')", - "HTTPException(401, str(exc))" - ] - }, - { - "method": "POST", - "path": "/requests/{request_id}/station-recordings", - "router": "router", - "prefix_resolved": false, - "name": "attach", - "signature": "request_id: UUID, data: Selection, request: Request, actor=Depends(station_actor), session: AsyncSession=Depends(get_async_session)", - "returns": "", - "line": 79, - "doc": "", - "decorator": "router.post('/requests/{request_id}/station-recordings', response_model=RecordsOperationRead)", - "errors": [ - "HTTPException(404, 'Records request not found')", - "HTTPException(409, str(exc))", - "HTTPException(422, 'Station evidence not attached; existing evidence preserved')", - "HTTPException(response.status_code, 'Station denied this recording')", - "HTTPException(409, 'Station recording is incomplete or changed; refresh selection')" - ] - } - ], - "models": [ - { - "name": "Selection", - "bases": [ - "BaseModel" - ], - "fields": [ - { - "name": "recording_id", - "type": "UUID", - "default": "" + "line": 54 }, { - "name": "expected_sha256", - "type": "str", - "default": "Field(pattern='^[0-9a-f]{64}$')" + "name": "attempts", + "type": "list[VendorNetworkSyncAttempt]", + "line": 55 } ], - "line": 61, - "doc": "" + "line": 40 } ], - "configuration": [ - { - "variable": "TOWNLIGHT_STATION_URL", - "default": "''", - "line": 33 - } - ] - } - ] - }, - "meetings": { - "package": "townlight_meetings", - "source": [ - { - "source": "installed-owned-source/townlight_meetings/__init__.py", - "sha256": "e8c6f4d348bc657f507a748a9f941317ea223f13facbc6f71d5777872d472564", - "routes": [], - "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_meetings/agenda_intake.py", - "sha256": "efe504bf430447fdd19ee39fbeace4c03365c6bd5f967f29bba40bd3dd48cfd2", + "source": "townlight_meetings/vendor_sync_persistence.py", + "sha256": "5802f8231c3792e8b747b2aa44a098b7ba5aa57f2b51e3a5e3f2d7ceb2d8df19", + "bytes": 17427, "routes": [], "models": [ { - "name": "AgendaIntakeItem", + "name": "VendorSyncSourceRecord", "bases": [], "fields": [ { "name": "id", "type": "str", - "default": "" + "line": 82 }, { - "name": "title", + "name": "connector", "type": "str", - "default": "" + "line": 83 }, { - "name": "department_name", + "name": "source_name", "type": "str", - "default": "" + "line": 84 }, { - "name": "submitted_by", + "name": "source_url", "type": "str", - "default": "" + "line": 85 }, { - "name": "summary", + "name": "auth_method", "type": "str", - "default": "" + "line": 86 }, { - "name": "status", - "type": "str", - "default": "" + "name": "consecutive_failure_count", + "type": "int", + "line": 87 }, { - "name": "readiness_status", - "type": "str", - "default": "" + "name": "active_failure_count", + "type": "int", + "line": 88 }, { - "name": "source_references", - "type": "list[dict]", - "default": "" + "name": "sync_paused", + "type": "bool", + "line": 89 }, { - "name": "reviewer", - "type": "str | None", - "default": "" + "name": "sync_paused_at", + "type": "datetime | None", + "line": 90 }, { - "name": "review_notes", + "name": "sync_paused_reason", "type": "str | None", - "default": "" + "line": 91 }, { - "name": "promoted_agenda_item_id", + "name": "last_sync_status", "type": "str | None", - "default": "" + "line": 92 }, { - "name": "promoted_at", + "name": "last_error_at", "type": "datetime | None", - "default": "" + "line": 93 }, { - "name": "promotion_audit_hash", - "type": "str | None", - "default": "" - }, - { - "name": "last_audit_hash", - "type": "str", - "default": "" + "name": "last_success_cursor_at", + "type": "datetime | None", + "line": 94 }, { "name": "created_at", "type": "datetime", - "default": "" + "line": 95 }, { "name": "updated_at", "type": "datetime", - "default": "" + "line": 96 } ], - "line": 51, - "doc": "Department-submitted item waiting for staff readiness review." - } - ], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_meetings/agenda_lifecycle.py", - "sha256": "e1e3fb531ca432cbc94bb258454776b8f97112077c5bbcd7d015a6f82f751a14", - "routes": [], - "models": [ + "line": 81 + }, { - "name": "TransitionResult", + "name": "VendorSyncRunRecord", "bases": [], "fields": [ { - "name": "allowed", - "type": "bool", - "default": "" - }, - { - "name": "http_status", - "type": "int", - "default": "" + "name": "id", + "type": "str", + "line": 141 }, { - "name": "message", + "name": "source_id", "type": "str", - "default": "" + "line": 142 }, { - "name": "fix", + "name": "status", "type": "str", - "default": "" + "line": 143 }, { - "name": "audit_entry", - "type": "dict[str, object]", - "default": "" - } - ], - "line": 39, - "doc": "" - }, - { - "name": "AgendaItemRecord", - "bases": [], - "fields": [ + "name": "records_discovered", + "type": "int", + "line": 144 + }, { - "name": "id", - "type": "str", - "default": "" + "name": "records_succeeded", + "type": "int", + "line": 145 }, { - "name": "title", - "type": "str", - "default": "" + "name": "records_failed", + "type": "int", + "line": 146 }, { - "name": "department_name", - "type": "str", - "default": "" + "name": "retries_attempted", + "type": "int", + "line": 147 }, { - "name": "status", - "type": "str", - "default": "'DRAFTED'" + "name": "error_summary", + "type": "str | None", + "line": 148 }, { - "name": "audit_entries", - "type": "list[dict[str, object]]", - "default": "field(default_factory=list)" + "name": "started_at", + "type": "datetime", + "line": 149 }, { - "name": "meeting_id", - "type": "str | None", - "default": "None" + "name": "finished_at", + "type": "datetime", + "line": 150 } ], - "line": 48, - "doc": "" + "line": 140 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_meetings/cc7_completeness.py", - "sha256": "683d4ba8f4bf4a047e0e3d87725497f30da5210c4496e4586eecc20b1784a468", + "source": "townlight_meetings/worker.py", + "sha256": "19a5a6f39fb8c0e5d4da12dda8b8c6cabfad2566f8446875b2ff607c836d725e", + "bytes": 10175, + "routes": [], + "models": [], + "configuration": [ + { + "environment": "TOWNLIGHT_MEETINGS_REDIS_URL", + "line": 46 + } + ] + } + ] + }, + "code": { + "repository": "townlight/ordinances", + "repository_head": "53f0314e91d6c41ba073a4f764e95d438038767d", + "working_tree_modified": true, + "principal_import": "townlight_code", + "source": [ + { + "source": "townlight_code/__init__.py", + "sha256": "2c43921d2ff34bdcf86cfcbb9eae6733fbb701514ad741e877a0218ca7b8acca", + "bytes": 128, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_code/ai_answer.py", + "sha256": "25e5053a66a4cc9b6bdd943b8d94c67cee2d62fdbcf9033428b4a9bb07dd2043", + "bytes": 3927, "routes": [], "models": [ { - "name": "ApiCategory", + "name": "LocalLLMConfig", "bases": [], "fields": [ { - "name": "id", + "name": "provider", "type": "str", - "default": "" + "line": 19 }, { - "name": "label", + "name": "base_url", "type": "str", - "default": "" - }, - { - "name": "paths", - "type": "tuple[str, ...]", - "default": "" + "line": 20 }, { - "name": "protected", - "type": "bool", - "default": "" + "name": "model", + "type": "str", + "line": 21 }, { - "name": "auth_scope", - "type": "str", - "default": "'staff-only'" + "name": "timeout_seconds", + "type": "float", + "line": 22 } ], - "line": 12, - "doc": "" + "line": 18 + } + ], + "configuration": [ + { + "environment": "TOWNLIGHT_CODE_OLLAMA_URL", + "line": 28 }, { - "name": "FrontendPage", + "environment": "TOWNLIGHT_CODE_OLLAMA_TIMEOUT_SECONDS", + "line": 35 + }, + { + "environment": "TOWNLIGHT_CODE_AI_MODE", + "line": 27 + }, + { + "environment": "TOWNLIGHT_CODE_OLLAMA_MODEL", + "line": 34 + } + ] + }, + { + "source": "townlight_code/citation_contract.py", + "sha256": "988fbe7893bf0ec957b2a5f04d8871b2ae9c6c1244e3a2b4a68b491fed942f98", + "bytes": 2453, + "routes": [], + "models": [ + { + "name": "CitationRefusal", "bases": [], "fields": [ { - "name": "id", + "name": "reason", "type": "str", - "default": "" + "line": 13 }, { - "name": "label", + "name": "fix", "type": "str", - "default": "" + "line": 14 }, { - "name": "surface", + "name": "refusal_type", "type": "str", - "default": "" - }, - { - "name": "evidence_states", - "type": "tuple[str, ...]", - "default": "REQUIRED_VIEW_STATES" + "line": 15 } ], - "line": 21, - "doc": "" + "line": 10 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_meetings/connector_import_sync.py", - "sha256": "1d30954f15c9b6d8a9afb5ef9392b4a7475bfd7d926b040707380a7005b8f96e", + "source": "townlight_code/codifier_sync.py", + "sha256": "afc3b1ce364a0a77d70d554d29dc3a79e637f82a278ebb8c261082163ad8834e", + "bytes": 24683, "routes": [], "models": [ { - "name": "ImportAttempt", + "name": "CodifierDeltaPlan", + "bases": [], + "fields": [ + { + "name": "connector", + "type": "str", + "line": 59 + }, + { + "name": "request_url", + "type": "str", + "line": 60 + }, + { + "name": "delta_enabled", + "type": "bool", + "line": 61 + }, + { + "name": "cursor_param", + "type": "str | None", + "line": 62 + }, + { + "name": "cursor_value", + "type": "str | None", + "line": 63 + }, + { + "name": "message", + "type": "str", + "line": 64 + }, + { + "name": "fix", + "type": "str", + "line": 65 + } + ], + "line": 56 + }, + { + "name": "CodifierSyncSource", "bases": [], "fields": [ { - "name": "connector", + "name": "source_id", "type": "str", - "default": "" + "line": 83 }, { - "name": "payload_path", - "type": "Path", - "default": "" + "name": "connector", + "type": "str", + "line": 84 }, { - "name": "ok", - "type": "bool", - "default": "" + "name": "source_name", + "type": "str", + "line": 85 }, { - "name": "message", + "name": "source_url", "type": "str", - "default": "" + "line": 86 }, { - "name": "fix", + "name": "sync_schedule", "type": "str", - "default": "" + "line": 87 }, { - "name": "normalized", - "type": "dict[str, Any] | None", - "default": "None" - } - ], - "line": 14, - "doc": "" - } - ], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_meetings/connectors.py", - "sha256": "31c19cd11f63ae32db9b51f0da57ac5cc8b637a63a16c6b1287c10a7d5afda9d", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_meetings/demo_seed.py", - "sha256": "d983fb6b80310ce84a0c703f55b5b35e5ecb73f8b5f0c407bab1f9edf27f5cbb", - "routes": [], - "models": [ - { - "name": "DemoSeedSummary", - "bases": [ - "TypedDict" - ], - "fields": [ - { - "name": "city", - "type": "str", - "default": "" + "name": "allowlisted_hosts", + "type": "tuple[str, ...]", + "line": 88 }, { - "name": "meeting_body_count", - "type": "int", - "default": "" + "name": "last_successful_sync_at", + "type": "datetime | None", + "line": 89 }, { - "name": "meeting_count", - "type": "int", - "default": "" + "name": "last_attempted_sync_at", + "type": "datetime | None", + "line": 90 }, { - "name": "agenda_intake_count", - "type": "int", - "default": "" + "name": "last_import_job_id", + "type": "str | None", + "line": 91 }, { - "name": "packet_count", - "type": "int", - "default": "" + "name": "next_sync_at_recorded", + "type": "datetime | None", + "line": 92 }, { - "name": "notice_count", - "type": "int", - "default": "" + "name": "host_validation", + "type": "dict[str, Any]", + "line": 93 }, { - "name": "motion_count", - "type": "int", - "default": "" + "name": "delta_plan_history", + "type": "list[dict[str, Any]]", + "line": 94 }, { - "name": "minutes_draft_count", - "type": "int", - "default": "" + "name": "state", + "type": "SyncCircuitState", + "line": 95 + } + ], + "line": 80 + }, + { + "name": "CodifierSyncRun", + "bases": [], + "fields": [ + { + "name": "source", + "type": "CodifierSyncSource", + "line": 106 }, { - "name": "public_record_count", - "type": "int", - "default": "" + "name": "job_payload", + "type": "dict[str, Any]", + "line": 107 }, { - "name": "primary_meeting_id", - "type": "str", - "default": "" + "name": "delta_plan", + "type": "CodifierDeltaPlan", + "line": 108 } ], - "line": 35, - "doc": "Counts and representative ids produced by the demo seed." + "line": 103 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_meetings/desktop_delivery.py", - "sha256": "cbb7f44aee90b9ea16c60c1f64efffa8bb7204765d49a5ce80fe52e2670d384e", + "source": "townlight_code/fixtures/portland/code/13.10-purpose-and-definitions.txt", + "sha256": "e86888d89e29382a48f0276aaabb9f6dbfbdb6a8456c17f51b5cc947cbb53d51", + "bytes": 814, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_code/fixtures/portland/code/13.40-keeping-livestock.txt", + "sha256": "178245740c874fcc13a7a12f9534692e01e232d771959d198e93d2425e8f2d74", + "bytes": 995, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_code/frontend_dist/assets/index-aK7NGgo8.js", + "sha256": "2780361ddd2b444b2da05ca9e33be44f7645e83d21f1d28b20e4644229deefae", + "bytes": 198313, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_code/frontend_dist/assets/index-DhfojJY0.css", + "sha256": "6002a43b0b5fbae50c24bd238b9b90a9a79abb5fb29ac758a8f93bfe755f8f12", + "bytes": 3921, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_meetings/integration_contracts.py", - "sha256": "3899a7aad3af2464ab35d15fee07b952e130cb207a36d1a07dfb6986c67bd805", + "source": "townlight_code/frontend_dist/index.html", + "sha256": "43202d3699bc76ea94416777ff6f34654f179da57d4e03b5120390239a9578c4", + "bytes": 450, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_code/import_connectors.py", + "sha256": "77ca2b4da579a284ad3212126498fce7df28636e6b5df2648b0a364baa702024", + "bytes": 19826, "routes": [], "models": [ { - "name": "IntegrationCheck", + "name": "ImportJob", "bases": [], "fields": [ { - "name": "contract_id", - "type": "str", - "default": "" - }, - { - "name": "scenario", - "type": "str", - "default": "" - }, - { - "name": "ok", - "type": "bool", - "default": "" - }, - { - "name": "message", + "name": "job_id", "type": "str", - "default": "" + "line": 57 }, { - "name": "fix", - "type": "str", - "default": "" - } - ], - "line": 17, - "doc": "A no-network adversarial check for one integration contract." - }, - { - "name": "IntegrationContract", - "bases": [], - "fields": [ - { - "name": "id", + "name": "connector_type", "type": "str", - "default": "" + "line": 58 }, { - "name": "label", + "name": "actor", "type": "str", - "default": "" + "line": 59 }, { "name": "status", - "type": "IntegrationStatus", - "default": "" - }, - { - "name": "mode", "type": "str", - "default": "" - }, - { - "name": "proof_model", - "type": "Literal['live_wire_validation', 'in_process_boundary_validation']", - "default": "" + "line": 60 }, { - "name": "dependent_module_required", - "type": "bool", - "default": "" + "name": "retry_of", + "type": "str | None", + "line": 61 }, { - "name": "network_calls", - "type": "bool", - "default": "" + "name": "counts", + "type": "dict[str, int]", + "line": 62 }, { - "name": "contract_artifact", - "type": "str", - "default": "" + "name": "provenance", + "type": "dict[str, Any]", + "line": 63 }, { - "name": "supported_operations", - "type": "tuple[str, ...]", - "default": "" + "name": "failure", + "type": "dict[str, str] | None", + "line": 64 }, { - "name": "absent_dependency_behavior", - "type": "str", - "default": "" + "name": "source_id", + "type": "str | None", + "line": 65 }, { - "name": "operator_fix", - "type": "str", - "default": "" + "name": "created_at", + "type": "datetime", + "line": 66 }, { - "name": "adversarial_scenarios", - "type": "tuple[str, ...]", - "default": "" + "name": "completed_at", + "type": "datetime | None", + "line": 67 } ], - "line": 37, - "doc": "Operator-facing contract for an integration that may not exist yet." + "line": 54 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_meetings/main.py", - "sha256": "d224d17b9869739b6faaddcd7213e202f8b710f72cda402479c0c6a84e737285", + "source": "townlight_code/main.py", + "sha256": "08a9c16106b52ee8a5aeeee6ad00e1721c59e2c27c40d7e83b96b89256a15e3b", + "bytes": 88337, "routes": [ { "method": "GET", - "path": "/", - "router": "app", - "prefix_resolved": true, - "name": "root", - "signature": "", - "returns": "dict[str, str]", - "line": 492, - "doc": "Describe what the runtime foundation currently provides.", - "decorator": "app.get('/')", - "errors": [] - }, - { - "method": "GET", - "path": "/health", - "router": "app", - "prefix_resolved": true, - "name": "health", - "signature": "", - "returns": "dict[str, str]", - "line": 550, - "doc": "Provide a simple operational health check for IT staff.", - "decorator": "app.get('/health')", - "errors": [] - }, - { - "method": "GET", - "path": "/favicon.ico", - "router": "app", - "prefix_resolved": true, - "name": "favicon", - "signature": "", - "returns": "Response", - "line": 561, - "doc": "Return an empty public favicon response so browser QA stays console-clean.", - "decorator": "app.get('/favicon.ico', response_class=Response)", - "errors": [] - }, - { - "method": "GET", - "path": "/staff", - "router": "app", - "prefix_resolved": true, - "name": "staff_dashboard", - "signature": "", - "returns": "str", - "line": 567, - "doc": "Render the staff-facing workflow foundation.", - "decorator": "app.get('/staff', response_class=HTMLResponse)", - "errors": [] - }, - { - "method": "GET", - "path": "/public", - "router": "app", - "prefix_resolved": true, - "name": "public_portal", - "signature": "", - "returns": "str", - "line": 617, - "doc": "Render the resident-facing public portal shell.", - "decorator": "app.get('/public', response_class=HTMLResponse)", - "errors": [] - }, - { - "method": "GET", - "path": "/staff/session", - "router": "app", - "prefix_resolved": true, - "name": "staff_session", - "signature": "request: Request", - "returns": "dict[str, object]", - "line": 623, - "doc": "Describe the current staff access mode for the browser workflow shell.", - "decorator": "app.get('/staff/session')", - "errors": [ - "HTTPException(status_code=401, detail={'message': 'Staff authentication is required.', 'fix': f'The default {STAFF_AUTH_MODE_ENV_VAR}={STAFF_PROTECTED_MODE} denies anonymous staff writes. Configure bearer, trusted-header, or OIDC staff auth, or explicitly set {STAFF_AUTH_MODE_ENV_VAR}={STAFF_OPEN_MODE} only for local rehearsal.'}, headers={'WWW-Authenticate': 'Bearer'})", - "HTTPException(status_code=500, detail={'message': 'Staff session principal is missing.', 'fix': 'Retry the request with a configured bearer token or review staff auth middleware setup.'})" - ] - }, - { - "method": "GET", - "path": "/staff/login", - "router": "app", - "prefix_resolved": true, - "name": "staff_login", - "signature": "request: Request", - "returns": "RedirectResponse", - "line": 705, - "doc": "Start the municipal OIDC browser sign-in flow for staff users.", - "decorator": "app.get('/staff/login')", - "errors": [ - "HTTPException(status_code=400, detail={'message': 'OIDC browser sign-in is available only when staff auth mode is oidc.', 'fix': f'Set {STAFF_AUTH_MODE_ENV_VAR}={STAFF_OIDC_MODE} before using /staff/login.'})", - "HTTPException(status_code=503, detail={'message': 'OIDC browser sign-in is not fully configured.', 'fix': _oidc_browser_login_fix(missing)})" - ] - }, - { - "method": "GET", - "path": "/staff/oidc/callback", - "router": "app", - "prefix_resolved": true, - "name": "staff_oidc_callback", - "signature": "request: Request", - "returns": "RedirectResponse", - "line": 763, - "doc": "Complete the OIDC authorization-code callback and issue a staff session cookie.", - "decorator": "app.get('/staff/oidc/callback')", - "errors": [ - "HTTPException(status_code=400, detail={'message': 'OIDC callback received while staff auth mode is not oidc.', 'fix': f'Set {STAFF_AUTH_MODE_ENV_VAR}={STAFF_OIDC_MODE}, then restart sign-in from /staff/login.'})", - "HTTPException(status_code=400, detail={'message': 'OIDC provider returned a sign-in error.', 'fix': f\"Review the provider response '{callback_error}', then restart sign-in from /staff/login.\"})", - "HTTPException(status_code=400, detail={'message': 'OIDC sign-in state did not match.', 'fix': 'Restart sign-in from /staff/login. If this repeats, confirm cookies are allowed for the CivicMeetings host.'})", - "HTTPException(status_code=400, detail={'message': 'OIDC sign-in PKCE verifier is missing.', 'fix': 'Restart sign-in from /staff/login. If this repeats, confirm cookies are allowed for the CivicMeetings host.'})", - "HTTPException(status_code=400, detail={'message': 'OIDC callback did not include an authorization code.', 'fix': 'Restart sign-in from /staff/login and confirm the provider uses authorization-code flow.'})", - "HTTPException(status_code=503, detail={'message': 'OIDC browser sign-in is not fully configured.', 'fix': _oidc_browser_login_fix(missing)})", - "HTTPException(status_code=502, detail={'message': 'OIDC token response did not include an ID token or access token.', 'fix': 'Confirm the provider app registration issues an ID token or API access token for CivicMeetings.'})" - ] - }, - { - "method": "GET", - "path": "/staff/logout", - "router": "app", - "prefix_resolved": true, - "name": "staff_logout", - "signature": "request: Request", - "returns": "RedirectResponse", - "line": 861, - "doc": "Clear the local CivicMeetings staff browser session.", - "decorator": "app.get('/staff/logout')", - "errors": [] - }, - { - "method": "POST", - "path": "/staff/logout", - "router": "app", - "prefix_resolved": true, - "name": "staff_logout", - "signature": "request: Request", - "returns": "RedirectResponse", - "line": 861, - "doc": "Clear the local CivicMeetings staff browser session.", - "decorator": "app.post('/staff/logout')", - "errors": [] - }, - { - "method": "GET", - "path": "/staff/auth-readiness", - "router": "app", - "prefix_resolved": true, - "name": "staff_auth_readiness", - "signature": "", - "returns": "dict[str, object]", - "line": 873, - "doc": "Report whether the current staff auth mode is configured for safe use.", - "decorator": "app.get('/staff/auth-readiness')", - "errors": [] - }, - { - "method": "GET", - "path": "/admin/config", - "router": "app", - "prefix_resolved": true, - "name": "admin_config", - "signature": "", - "returns": "dict[str, object]", - "line": 935, - "doc": "Describe CC-7 runtime coverage and staff-auth configuration posture.", - "decorator": "app.get('/admin/config')", - "errors": [] - }, - { - "method": "GET", - "path": "/integrations/readiness", - "router": "app", - "prefix_resolved": true, - "name": "integrations_readiness", - "signature": "", - "returns": "dict[str, object]", - "line": 968, - "doc": "Report live or in-process integration boundary contracts.", - "decorator": "app.get('/integrations/readiness')", - "errors": [] - }, - { - "method": "GET", - "path": "/admin/prompts", - "router": "app", - "prefix_resolved": true, - "name": "admin_prompts", - "signature": "", - "returns": "dict[str, object]", - "line": 975, - "doc": "List prompt-library definitions and public approval gates for admins.", - "decorator": "app.get('/admin/prompts')", - "errors": [] - }, - { - "method": "POST", - "path": "/agenda-items", - "router": "app", - "prefix_resolved": true, - "name": "create_agenda_item", - "signature": "payload: AgendaItemCreate", - "returns": "dict[str, str]", - "line": 1009, - "doc": "Create a draft agenda item for lifecycle enforcement.", - "decorator": "app.post('/agenda-items', status_code=201)", - "errors": [] - }, - { - "method": "GET", - "path": "/agenda-items/{item_id}", - "router": "app", - "prefix_resolved": true, - "name": "get_agenda_item", - "signature": "item_id: str", - "returns": "dict[str, str]", - "line": 1018, - "doc": "Return the current agenda item state.", - "decorator": "app.get('/agenda-items/{item_id}')", - "errors": [ - "HTTPException(status_code=404, detail='Agenda item not found.')" - ] - }, - { - "method": "POST", - "path": "/agenda-items/{item_id}/transitions", - "router": "app", - "prefix_resolved": true, - "name": "transition_agenda_item", - "signature": "item_id: str, payload: AgendaItemTransitionRequest", - "returns": "dict[str, str]", - "line": 1027, - "doc": "Apply a canonical agenda item lifecycle transition.", - "decorator": "app.post('/agenda-items/{item_id}/transitions')", - "errors": [ - "HTTPException(status_code=404, detail='Agenda item not found.')", - "HTTPException(status_code=result.http_status, detail={'message': result.message, 'fix': result.fix, 'current_status': item.status, 'requested_status': payload.to_status})" - ] - }, - { - "method": "GET", - "path": "/agenda-items/{item_id}/audit", - "router": "app", - "prefix_resolved": true, - "name": "get_agenda_item_audit", - "signature": "item_id: str", - "returns": "dict[str, list[dict[str, object]]]", - "line": 1058, - "doc": "Return lifecycle audit entries for an agenda item.", - "decorator": "app.get('/agenda-items/{item_id}/audit')", - "errors": [ - "HTTPException(status_code=404, detail='Agenda item not found.')" - ] - }, - { - "method": "POST", - "path": "/agenda-intake", - "router": "app", - "prefix_resolved": true, - "name": "submit_agenda_intake_item", - "signature": "payload: AgendaIntakeCreate", - "returns": "dict", - "line": 1067, - "doc": "Submit a department agenda item into the database-backed staff queue.", - "decorator": "app.post('/agenda-intake', status_code=201)", - "errors": [] - }, - { - "method": "GET", - "path": "/agenda-intake", - "router": "app", - "prefix_resolved": true, - "name": "list_agenda_intake_items", - "signature": "readiness_status: str | None=None", - "returns": "dict[str, list[dict]]", - "line": 1080, - "doc": "List department-submitted agenda intake items awaiting staff review.", - "decorator": "app.get('/agenda-intake')", - "errors": [] - }, - { - "method": "POST", - "path": "/agenda-intake/{item_id}/review", - "router": "app", - "prefix_resolved": true, - "name": "review_agenda_intake_item", - "signature": "item_id: str, payload: AgendaIntakeReviewRequest", - "returns": "dict", - "line": 1093, - "doc": "Record clerk readiness review for an intake queue item.", - "decorator": "app.post('/agenda-intake/{item_id}/review')", - "errors": [ - "HTTPException(status_code=404, detail={'message': 'Agenda intake item not found.', 'fix': 'Submit the agenda item into the intake queue before review.'})" - ] - }, - { - "method": "POST", - "path": "/agenda-intake/{item_id}/promote", - "router": "app", - "prefix_resolved": true, - "name": "promote_agenda_intake_item", - "signature": "item_id: str, payload: AgendaIntakePromoteRequest, response: Response", - "returns": "dict", - "line": 1116, - "doc": "Promote a clerk-ready intake item into the canonical agenda lifecycle.", - "decorator": "app.post('/agenda-intake/{item_id}/promote', status_code=201)", - "errors": [ - "HTTPException(status_code=404, detail={'message': 'Agenda intake item not found.', 'fix': 'Submit the agenda item into intake, then complete clerk review before promotion.'})", - "HTTPException(status_code=409, detail={'message': 'Agenda intake item is not ready for agenda promotion.', 'current_readiness_status': intake_item.readiness_status, 'fix': 'Mark the item ready in the clerk review queue, then promote it to agenda work.'})", - "HTTPException(status_code=404, detail={'message': 'Agenda intake item disappeared during promotion.', 'fix': 'Reload the intake queue and retry promotion from the current record.'})", - "HTTPException(status_code=500, detail={'message': 'Agenda item promotion could not complete its lifecycle transitions.', 'fix': 'Retry promotion after confirming the agenda lifecycle service is available.'})" - ] - }, - { - "method": "POST", - "path": "/meetings/{meeting_id}/staff-reports", - "router": "app", - "prefix_resolved": true, - "name": "create_staff_report", - "signature": "meeting_id: str, payload: StaffReportCreate", - "returns": "dict[str, object]", - "line": 1193, - "doc": "Normalize a staff report into the clerk-visible agenda intake trail.", - "decorator": "app.post('/meetings/{meeting_id}/staff-reports', status_code=201)", - "errors": [] - }, - { - "method": "GET", - "path": "/meetings/{meeting_id}/staff-reports", - "router": "app", - "prefix_resolved": true, - "name": "list_staff_reports", - "signature": "meeting_id: str", - "returns": "dict[str, object]", - "line": 1222, - "doc": "List staff report records linked to a meeting.", - "decorator": "app.get('/meetings/{meeting_id}/staff-reports')", - "errors": [] - }, - { - "method": "POST", - "path": "/meeting-bodies", - "router": "app", - "prefix_resolved": true, - "name": "create_meeting_body", - "signature": "payload: MeetingBodyCreate", - "returns": "dict[str, str | bool]", - "line": 1246, - "doc": "Create a municipal meeting body for staff calendar workflows.", - "decorator": "app.post('/meeting-bodies', status_code=201)", - "errors": [] - }, - { - "method": "GET", - "path": "/meeting-bodies", - "router": "app", - "prefix_resolved": true, - "name": "list_meeting_bodies", - "signature": "active_only: bool=False", - "returns": "dict[str, int | list[dict[str, str | bool]]]", - "line": 1257, - "doc": "List municipal meeting bodies for staff setup and scheduling clients.", - "decorator": "app.get('/meeting-bodies')", - "errors": [] - }, - { - "method": "GET", - "path": "/meeting-bodies/{body_id}", - "router": "app", - "prefix_resolved": true, - "name": "get_meeting_body", - "signature": "body_id: str", - "returns": "dict[str, str | bool]", - "line": 1268, - "doc": "Return one municipal meeting body.", - "decorator": "app.get('/meeting-bodies/{body_id}')", - "errors": [ - "HTTPException(status_code=404, detail='Meeting body not found.')" - ] + "declared_path": "/", + "function": "root", + "line": 786 + }, + { + "method": "GET", + "declared_path": "/townlight_code", + "function": "public_lookup_home", + "line": 834 + }, + { + "method": "GET", + "declared_path": "/townlight_code/app", + "function": "townlight_code_frontend_app", + "line": 845 + }, + { + "method": "GET", + "declared_path": "/townlight_code/app/", + "function": "townlight_code_frontend_app", + "line": 845 + }, + { + "method": "GET", + "declared_path": "/townlight_code/search", + "function": "public_lookup_search", + "line": 858 + }, + { + "method": "GET", + "declared_path": "/townlight_code/answer", + "function": "public_lookup_answer", + "line": 878 + }, + { + "method": "GET", + "declared_path": "/townlight_code/sections/{section_ref}", + "function": "public_section_detail", + "line": 901 + }, + { + "method": "GET", + "declared_path": "/townlight_code/sections/{section_ref}/export", + "function": "public_section_export", + "line": 937 + }, + { + "method": "GET", + "declared_path": "/staff/sources", + "function": "staff_source_workspace", + "line": 953 + }, + { + "method": "GET", + "declared_path": "/staff/code", + "function": "staff_code_workspace", + "line": 970 + }, + { + "method": "GET", + "declared_path": "/staff/sync", + "function": "staff_sync_workspace", + "line": 983 + }, + { + "method": "GET", + "declared_path": "/staff/imports", + "function": "staff_import_ledger", + "line": 1000 + }, + { + "method": "GET", + "declared_path": "/health", + "function": "health", + "line": 1013 + }, + { + "method": "GET", + "declared_path": "/api/v1/townlight_code/staff/operational-state", + "function": "get_staff_operational_state", + "line": 1024 + }, + { + "method": "GET", + "declared_path": "/api/v1/townlight_code/sources/catalog", + "function": "source_registry_catalog", + "line": 1036 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_code/sources", + "function": "create_source", + "line": 1050 + }, + { + "method": "GET", + "declared_path": "/api/v1/townlight_code/sources", + "function": "list_public_sources", + "line": 1068 + }, + { + "method": "GET", + "declared_path": "/api/v1/townlight_code/sources/{source_id}", + "function": "get_public_source", + "line": 1079 + }, + { + "method": "GET", + "declared_path": "/api/v1/townlight_code/staff/sources", + "function": "list_staff_sources", + "line": 1097 + }, + { + "method": "GET", + "declared_path": "/api/v1/townlight_code/staff/sources/{source_id}", + "function": "get_staff_source", + "line": 1112 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_code/sources/{source_id}/transitions", + "function": "transition_source", + "line": 1127 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_code/titles", + "function": "create_title", + "line": 1148 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_code/chapters", + "function": "create_chapter", + "line": 1163 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_code/sections", + "function": "create_section", + "line": 1178 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_code/sections/{section_id}/versions", + "function": "create_section_version", + "line": 1193 + }, + { + "method": "GET", + "declared_path": "/api/v1/townlight_code/sections/lookup", + "function": "lookup_section", + "line": 1244 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_code/sections/resolve", + "function": "resolve_section", + "line": 1255 + }, + { + "method": "GET", + "declared_path": "/api/v1/townlight_code/sections/{section_id}/history", + "function": "section_history", + "line": 1354 }, { - "method": "PATCH", - "path": "/meeting-bodies/{body_id}", - "router": "app", - "prefix_resolved": true, - "name": "update_meeting_body", - "signature": "body_id: str, payload: MeetingBodyUpdate", - "returns": "dict[str, str | bool]", - "line": 1278, - "doc": "Update a municipal meeting body without losing its record identity.", - "decorator": "app.patch('/meeting-bodies/{body_id}')", - "errors": [ - "HTTPException(status_code=404, detail='Meeting body not found.')" - ] + "method": "GET", + "declared_path": "/api/v1/townlight_code/sections/{section_id}/permalink", + "function": "section_permalink", + "line": 1363 }, { - "method": "DELETE", - "path": "/meeting-bodies/{body_id}", - "router": "app", - "prefix_resolved": true, - "name": "deactivate_meeting_body", - "signature": "body_id: str", - "returns": "dict[str, str | bool]", - "line": 1296, - "doc": "Deactivate a meeting body instead of hard-deleting legal history.", - "decorator": "app.delete('/meeting-bodies/{body_id}')", - "errors": [ - "HTTPException(status_code=404, detail='Meeting body not found.')" - ] - }, - { - "method": "POST", - "path": "/meetings", - "router": "app", - "prefix_resolved": true, - "name": "create_meeting", - "signature": "payload: MeetingCreate", - "returns": "dict[str, str]", - "line": 1306, - "doc": "Create a scheduled meeting for lifecycle enforcement.", - "decorator": "app.post('/meetings', status_code=201)", - "errors": [] - }, - { - "method": "GET", - "path": "/meetings", - "router": "app", - "prefix_resolved": true, - "name": "list_meetings", - "signature": "", - "returns": "dict[str, int | list[dict[str, str | None]]]", - "line": 1322, - "doc": "List meetings for staff calendar and dashboard clients.", - "decorator": "app.get('/meetings')", - "errors": [] - }, - { - "method": "GET", - "path": "/meetings/{meeting_id}", - "router": "app", - "prefix_resolved": true, - "name": "get_meeting", - "signature": "meeting_id: str", - "returns": "dict[str, str]", - "line": 1329, - "doc": "Return the current meeting state.", - "decorator": "app.get('/meetings/{meeting_id}')", - "errors": [ - "HTTPException(status_code=404, detail='Meeting not found.')" - ] + "method": "GET", + "declared_path": "/api/v1/townlight_code/search", + "function": "search_sections", + "line": 1372 }, { - "method": "PATCH", - "path": "/meetings/{meeting_id}", - "router": "app", - "prefix_resolved": true, - "name": "update_meeting_schedule", - "signature": "meeting_id: str, payload: MeetingUpdate", - "returns": "dict[str, str]", - "line": 1338, - "doc": "Edit staff scheduling fields before the public meeting is locked.", - "decorator": "app.patch('/meetings/{meeting_id}')", - "errors": [ - "HTTPException(status_code=422, detail={'message': 'Meeting update did not include any schedule fields.', 'fix': 'Send at least one of title, meeting_type, scheduled_start, meeting_body_id, or location.'})", - "HTTPException(status_code=404, detail='Meeting not found.')", - "HTTPException(status_code=409, detail={'message': exc.message, 'fix': exc.fix})" - ] - }, - { - "method": "POST", - "path": "/meetings/{meeting_id}/transitions", - "router": "app", - "prefix_resolved": true, - "name": "transition_meeting", - "signature": "meeting_id: str, payload: MeetingTransitionRequest", - "returns": "dict[str, str]", - "line": 1391, - "doc": "Apply a canonical meeting lifecycle transition.", - "decorator": "app.post('/meetings/{meeting_id}/transitions')", - "errors": [ - "HTTPException(status_code=404, detail='Meeting not found.')", - "HTTPException(status_code=result.http_status, detail={'message': result.message, 'fix': result.fix, 'current_status': meeting.status, 'requested_status': payload.to_status})" - ] - }, - { - "method": "GET", - "path": "/meetings/{meeting_id}/audit", - "router": "app", - "prefix_resolved": true, - "name": "get_meeting_audit", - "signature": "meeting_id: str", - "returns": "dict[str, list[dict[str, object]]]", - "line": 1424, - "doc": "Return lifecycle audit entries for a meeting.", - "decorator": "app.get('/meetings/{meeting_id}/audit')", - "errors": [ - "HTTPException(status_code=404, detail='Meeting not found.')" - ] - }, - { - "method": "POST", - "path": "/meetings/{meeting_id}/packet-snapshots", - "router": "app", - "prefix_resolved": true, - "name": "create_packet_snapshot", - "signature": "meeting_id: str, payload: PacketSnapshotCreate", - "returns": "dict", - "line": 1433, - "doc": "Create an immutable packet snapshot version for a meeting.", - "decorator": "app.post('/meetings/{meeting_id}/packet-snapshots', status_code=201)", - "errors": [ - "HTTPException(status_code=404, detail='Meeting not found.')" - ] - }, - { - "method": "GET", - "path": "/meetings/{meeting_id}/packet-snapshots", - "router": "app", - "prefix_resolved": true, - "name": "list_packet_snapshots", - "signature": "meeting_id: str", - "returns": "dict[str, list[dict]]", - "line": 1449, - "doc": "Return packet snapshot versions for a meeting.", - "decorator": "app.get('/meetings/{meeting_id}/packet-snapshots')", - "errors": [ - "HTTPException(status_code=404, detail='Meeting not found.')" - ] - }, - { - "method": "POST", - "path": "/meetings/{meeting_id}/packet-assemblies", - "router": "app", - "prefix_resolved": true, - "name": "create_packet_assembly_record", - "signature": "meeting_id: str, payload: PacketAssemblyCreate", - "returns": "dict", - "line": 1463, - "doc": "Create a persisted packet assembly record tied to a packet snapshot.", - "decorator": "app.post('/meetings/{meeting_id}/packet-assemblies', status_code=201)", - "errors": [ - "HTTPException(status_code=404, detail='Meeting not found.')" - ] - }, - { - "method": "GET", - "path": "/meetings/{meeting_id}/packet-assemblies", - "router": "app", - "prefix_resolved": true, - "name": "list_packet_assembly_records", - "signature": "meeting_id: str", - "returns": "dict[str, list[dict]]", - "line": 1489, - "doc": "List persisted packet assembly records for a meeting.", - "decorator": "app.get('/meetings/{meeting_id}/packet-assemblies')", - "errors": [ - "HTTPException(status_code=404, detail='Meeting not found.')" - ] - }, - { - "method": "POST", - "path": "/packet-assemblies/{record_id}/finalize", - "router": "app", - "prefix_resolved": true, - "name": "finalize_packet_assembly_record", - "signature": "record_id: str, payload: PacketAssemblyFinalizeRequest", - "returns": "dict", - "line": 1503, - "doc": "Finalize a persisted packet assembly record.", - "decorator": "app.post('/packet-assemblies/{record_id}/finalize')", - "errors": [ - "HTTPException(status_code=404, detail={'message': 'Packet assembly record not found.', 'fix': 'Create the packet assembly record before finalizing it.'})" - ] - }, - { - "method": "POST", - "path": "/meetings/{meeting_id}/export-bundle", - "router": "app", - "prefix_resolved": true, - "name": "create_packet_export_bundle", - "signature": "meeting_id: str, payload: PacketExportCreate", - "returns": "dict", - "line": 1524, - "doc": "Create a records-ready packet export bundle with manifest, checksums, and audit.", - "decorator": "app.post('/meetings/{meeting_id}/export-bundle', status_code=201)", - "errors": [ - "HTTPException(status_code=404, detail='Meeting not found.')", - "HTTPException(status_code=error.http_status, detail=error.public_dict())" - ] - }, - { - "method": "POST", - "path": "/meetings/{meeting_id}/notices/check", - "router": "app", - "prefix_resolved": true, - "name": "check_notice_compliance", - "signature": "meeting_id: str, payload: NoticeComplianceRequest", - "returns": "dict", - "line": 1559, - "doc": "Check public notice compliance without posting.", - "decorator": "app.post('/meetings/{meeting_id}/notices/check')", - "errors": [ - "HTTPException(status_code=result.http_status, detail={'message': 'Notice is not ready for public posting. Review the warnings and fix each item.', 'warnings': result.warnings})" - ] - }, - { - "method": "POST", - "path": "/meetings/{meeting_id}/notice-checklists", - "router": "app", - "prefix_resolved": true, - "name": "create_notice_checklist_record", - "signature": "meeting_id: str, payload: NoticeChecklistCreate", - "returns": "dict", - "line": 1577, - "doc": "Persist a notice compliance checklist record for staff review.", - "decorator": "app.post('/meetings/{meeting_id}/notice-checklists', status_code=201)", - "errors": [] - }, - { - "method": "GET", - "path": "/meetings/{meeting_id}/notice-checklists", - "router": "app", - "prefix_resolved": true, - "name": "list_notice_checklist_records", - "signature": "meeting_id: str", - "returns": "dict[str, list[dict]]", - "line": 1599, - "doc": "List persisted notice checklist records for a meeting.", - "decorator": "app.get('/meetings/{meeting_id}/notice-checklists')", - "errors": [ - "HTTPException(status_code=404, detail='Meeting not found.')" - ] - }, - { - "method": "POST", - "path": "/notice-checklists/{record_id}/posting-proof", - "router": "app", - "prefix_resolved": true, - "name": "attach_notice_posting_proof", - "signature": "record_id: str, payload: NoticePostingProofCreate", - "returns": "dict", - "line": 1613, - "doc": "Attach posting proof metadata to a persisted notice checklist record.", - "decorator": "app.post('/notice-checklists/{record_id}/posting-proof')", - "errors": [ - "HTTPException(status_code=404, detail={'message': 'Notice checklist record not found.', 'fix': 'Create the notice checklist record before attaching posting proof.'})" - ] - }, - { - "method": "POST", - "path": "/meetings/{meeting_id}/notices/post", - "router": "app", - "prefix_resolved": true, - "name": "post_notice", - "signature": "meeting_id: str, payload: NoticeComplianceRequest", - "returns": "dict", - "line": 1635, - "doc": "Post a public notice after deadline and human-approval checks pass.", - "decorator": "app.post('/meetings/{meeting_id}/notices/post', status_code=201)", - "errors": [ - "HTTPException(status_code=result.http_status, detail={'message': 'Notice cannot be posted publicly. Review the warnings and fix each item.', 'warnings': result.warnings})" - ] - }, - { - "method": "POST", - "path": "/meetings/{meeting_id}/motions", - "router": "app", - "prefix_resolved": true, - "name": "capture_motion", - "signature": "meeting_id: str, payload: MotionCreate", - "returns": "dict", - "line": 1653, - "doc": "Capture an immutable motion for a meeting.", - "decorator": "app.post('/meetings/{meeting_id}/motions', status_code=201)", - "errors": [ - "HTTPException(status_code=404, detail='Meeting not found.')" - ] - }, - { - "method": "GET", - "path": "/meetings/{meeting_id}/motions", - "router": "app", - "prefix_resolved": true, - "name": "list_motions", - "signature": "meeting_id: str", - "returns": "dict[str, list[dict]]", - "line": 1668, - "doc": "List captured motions and correction records for a meeting.", - "decorator": "app.get('/meetings/{meeting_id}/motions')", - "errors": [ - "HTTPException(status_code=404, detail='Meeting not found.')" - ] + "method": "GET", + "declared_path": "/api/v1/townlight_code/popular-questions", + "function": "list_popular_questions", + "line": 1381 }, { - "method": "PUT", - "path": "/motions/{motion_id}", - "router": "app", - "prefix_resolved": true, - "name": "reject_motion_mutation", - "signature": "motion_id: str", - "returns": "None", - "line": 1683, - "doc": "Reject edits to captured motions; corrections must be append-only.", - "decorator": "app.put('/motions/{motion_id}')", - "errors": [ - "HTTPException(status_code=409, detail={'message': 'Captured motions are immutable.', 'fix': 'Use POST /motions/{motion_id}/corrections to add a correction record that references the original motion.'})", - "HTTPException(status_code=404, detail='Motion not found.')" - ] + "method": "POST", + "declared_path": "/api/v1/townlight_code/staff/popular-questions", + "function": "create_popular_question", + "line": 1403 }, { - "method": "PATCH", - "path": "/motions/{motion_id}", - "router": "app", - "prefix_resolved": true, - "name": "reject_motion_mutation", - "signature": "motion_id: str", - "returns": "None", - "line": 1683, - "doc": "Reject edits to captured motions; corrections must be append-only.", - "decorator": "app.patch('/motions/{motion_id}')", - "errors": [ - "HTTPException(status_code=409, detail={'message': 'Captured motions are immutable.', 'fix': 'Use POST /motions/{motion_id}/corrections to add a correction record that references the original motion.'})", - "HTTPException(status_code=404, detail='Motion not found.')" - ] - }, - { - "method": "POST", - "path": "/motions/{motion_id}/corrections", - "router": "app", - "prefix_resolved": true, - "name": "correct_motion", - "signature": "motion_id: str, payload: MotionCorrectionCreate", - "returns": "dict", - "line": 1697, - "doc": "Create an append-only correction record for a captured motion.", - "decorator": "app.post('/motions/{motion_id}/corrections', status_code=201)", - "errors": [ - "HTTPException(status_code=404, detail='Motion not found.')" - ] - }, - { - "method": "POST", - "path": "/motions/{motion_id}/votes", - "router": "app", - "prefix_resolved": true, - "name": "capture_vote", - "signature": "motion_id: str, payload: VoteCreate", - "returns": "dict", - "line": 1711, - "doc": "Capture an immutable vote for a motion.", - "decorator": "app.post('/motions/{motion_id}/votes', status_code=201)", - "errors": [ - "HTTPException(status_code=404, detail='Motion not found.')" - ] - }, - { - "method": "GET", - "path": "/motions/{motion_id}/votes", - "router": "app", - "prefix_resolved": true, - "name": "list_votes", - "signature": "motion_id: str", - "returns": "dict[str, list[dict]]", - "line": 1728, - "doc": "List captured votes and correction records for a motion.", - "decorator": "app.get('/motions/{motion_id}/votes')", - "errors": [ - "HTTPException(status_code=404, detail='Motion not found.')" - ] + "method": "GET", + "declared_path": "/api/v1/townlight_code/sections/{section_number}/related", + "function": "related_materials", + "line": 1453 }, { - "method": "PUT", - "path": "/votes/{vote_id}", - "router": "app", - "prefix_resolved": true, - "name": "reject_vote_mutation", - "signature": "vote_id: str", - "returns": "None", - "line": 1743, - "doc": "Reject edits to captured votes; corrections must be append-only.", - "decorator": "app.put('/votes/{vote_id}')", - "errors": [ - "HTTPException(status_code=409, detail={'message': 'Captured votes are immutable.', 'fix': 'Use POST /votes/{vote_id}/corrections to add a correction record that references the original vote.'})", - "HTTPException(status_code=404, detail='Vote not found.')" - ] + "method": "GET", + "declared_path": "/api/v1/townlight_code/citations/build", + "function": "build_citation", + "line": 1466 }, { - "method": "PATCH", - "path": "/votes/{vote_id}", - "router": "app", - "prefix_resolved": true, - "name": "reject_vote_mutation", - "signature": "vote_id: str", - "returns": "None", - "line": 1743, - "doc": "Reject edits to captured votes; corrections must be append-only.", - "decorator": "app.patch('/votes/{vote_id}')", - "errors": [ - "HTTPException(status_code=409, detail={'message': 'Captured votes are immutable.', 'fix': 'Use POST /votes/{vote_id}/corrections to add a correction record that references the original vote.'})", - "HTTPException(status_code=404, detail='Vote not found.')" - ] - }, - { - "method": "POST", - "path": "/votes/{vote_id}/corrections", - "router": "app", - "prefix_resolved": true, - "name": "correct_vote", - "signature": "vote_id: str, payload: VoteCorrectionCreate", - "returns": "dict", - "line": 1757, - "doc": "Create an append-only correction record for a captured vote.", - "decorator": "app.post('/votes/{vote_id}/corrections', status_code=201)", - "errors": [ - "HTTPException(status_code=404, detail='Vote not found.')" - ] - }, - { - "method": "POST", - "path": "/meetings/{meeting_id}/action-items", - "router": "app", - "prefix_resolved": true, - "name": "create_action_item", - "signature": "meeting_id: str, payload: ActionItemCreate", - "returns": "dict", - "line": 1771, - "doc": "Create an action item linked to a meeting outcome.", - "decorator": "app.post('/meetings/{meeting_id}/action-items', status_code=201)", - "errors": [ - "HTTPException(status_code=404, detail='Meeting not found.')", - "HTTPException(status_code=422, detail={'message': 'Action items must reference a captured meeting outcome.', 'fix': 'Capture the related motion first, then send its id as source_motion_id.'})", - "HTTPException(status_code=404, detail='Source motion not found.')", - "HTTPException(status_code=422, detail={'message': 'Action item source motion belongs to a different meeting.', 'fix': 'Use a motion captured for this meeting as source_motion_id.'})" - ] - }, - { - "method": "GET", - "path": "/meetings/{meeting_id}/action-items", - "router": "app", - "prefix_resolved": true, - "name": "list_action_items", - "signature": "meeting_id: str", - "returns": "dict[str, list[dict]]", - "line": 1809, - "doc": "List action items linked to a meeting.", - "decorator": "app.get('/meetings/{meeting_id}/action-items')", - "errors": [ - "HTTPException(status_code=404, detail='Meeting not found.')" - ] - }, - { - "method": "POST", - "path": "/meetings/{meeting_id}/ordinance-resolution-handoff", - "router": "app", - "prefix_resolved": true, - "name": "create_ordinance_resolution_handoff", - "signature": "meeting_id: str, payload: OrdinanceResolutionHandoffCreate", - "returns": "dict[str, object]", - "line": 2063, - "doc": "Create a code-drafting handoff from adopted meeting action.", - "decorator": "app.post('/meetings/{meeting_id}/ordinance-resolution-handoff', status_code=201)", - "errors": [ - "HTTPException(status_code=404, detail='Source motion not found.')", - "HTTPException(status_code=422, detail={'message': 'Ordinance or resolution source motion belongs to a different meeting.', 'fix': 'Use a motion captured for this meeting, then retry the handoff.'})" - ] - }, - { - "method": "GET", - "path": "/meetings/{meeting_id}/ordinance-resolution-handoff", - "router": "app", - "prefix_resolved": true, - "name": "list_ordinance_resolution_handoffs", - "signature": "meeting_id: str", - "returns": "dict[str, object]", - "line": 2112, - "doc": "List ordinance and resolution handoffs for a meeting.", - "decorator": "app.get('/meetings/{meeting_id}/ordinance-resolution-handoff')", - "errors": [] - }, - { - "method": "POST", - "path": "/meetings/{meeting_id}/ordinance-resolution-handoff/retry", - "router": "app", - "prefix_resolved": true, - "name": "retry_ordinance_resolution_handoff", - "signature": "meeting_id: str, payload: OrdinanceResolutionHandoffRetry | None=None", - "returns": "dict[str, object]", - "line": 2125, - "doc": "Retry TownlightCode emission for failed or unconfigured ordinance handoffs.", - "decorator": "app.post('/meetings/{meeting_id}/ordinance-resolution-handoff/retry')", - "errors": [ - "HTTPException(status_code=404, detail='Handoff not found.')" - ] - }, - { - "method": "POST", - "path": "/meetings/{meeting_id}/minutes/drafts", - "router": "app", - "prefix_resolved": true, - "name": "create_minutes_draft", - "signature": "meeting_id: str, payload: MinutesDraftCreate", - "returns": "dict", - "line": 2159, - "doc": "Create a cited minutes draft from staff-provided sentence text.", - "decorator": "app.post('/meetings/{meeting_id}/minutes/drafts', status_code=201)", - "errors": [ - "HTTPException(status_code=404, detail='Meeting not found.')", - "HTTPException(status_code=422, detail={'message': result.message, 'fix': result.fix})" - ] - }, - { - "method": "POST", - "path": "/meetings/{meeting_id}/minutes/ai-assist", - "router": "app", - "prefix_resolved": true, - "name": "create_minutes_ai_assist", - "signature": "meeting_id: str, payload: MinutesAiAssistCreate", - "returns": "dict", - "line": 2197, - "doc": "Generate an optional Ollama-assisted cited minutes draft.", - "decorator": "app.post('/meetings/{meeting_id}/minutes/ai-assist', status_code=201)", - "errors": [ - "HTTPException(status_code=404, detail='Meeting not found.')", - "HTTPException(status_code=422, detail={'message': result.message, 'fix': result.fix})", - "HTTPException(status_code=503, detail=_minutes_ai_unavailable_detail(str(exc)))" - ] - }, - { - "method": "GET", - "path": "/meetings/{meeting_id}/minutes/drafts", - "router": "app", - "prefix_resolved": true, - "name": "list_minutes_drafts", - "signature": "meeting_id: str", - "returns": "dict[str, list[dict]]", - "line": 2243, - "doc": "List citation-gated minutes drafts for a meeting.", - "decorator": "app.get('/meetings/{meeting_id}/minutes/drafts')", - "errors": [ - "HTTPException(status_code=404, detail='Meeting not found.')" - ] - }, - { - "method": "POST", - "path": "/minutes/{minute_id}/post", - "router": "app", - "prefix_resolved": true, - "name": "reject_automatic_minutes_posting", - "signature": "minute_id: str", - "returns": "None", - "line": 2257, - "doc": "Reject automatic public posting of AI-drafted minutes.", - "decorator": "app.post('/minutes/{minute_id}/post')", - "errors": [ - "HTTPException(status_code=409, detail={'message': 'AI-drafted minutes cannot be posted automatically.', 'fix': 'Review, cite-check, and adopt minutes through a human approval workflow before public posting.'})", - "HTTPException(status_code=404, detail='Minutes draft not found.')" - ] - }, - { - "method": "POST", - "path": "/meetings/{meeting_id}/transcripts", - "router": "app", - "prefix_resolved": true, - "name": "create_transcript_record", - "signature": "meeting_id: str, payload: TranscriptCreate", - "returns": "dict[str, object]", - "line": 2271, - "doc": "Capture transcript material for clerk review before public release.", - "decorator": "app.post('/meetings/{meeting_id}/transcripts', status_code=201)", - "errors": [] - }, - { - "method": "GET", - "path": "/meetings/{meeting_id}/transcripts", - "router": "app", - "prefix_resolved": true, - "name": "list_transcript_records", - "signature": "meeting_id: str", - "returns": "dict[str, object]", - "line": 2295, - "doc": "List transcript records queued for a meeting.", - "decorator": "app.get('/meetings/{meeting_id}/transcripts')", - "errors": [] - }, - { - "method": "POST", - "path": "/meetings/{meeting_id}/public-record", - "router": "app", - "prefix_resolved": true, - "name": "publish_public_record", - "signature": "meeting_id: str, payload: PublicMeetingRecordCreate", - "returns": "dict", - "line": 2309, - "doc": "Create a public or restricted archive record for a meeting.", - "decorator": "app.post('/meetings/{meeting_id}/public-record', status_code=201)", - "errors": [ - "HTTPException(status_code=404, detail='Meeting not found.')", - "HTTPException(status_code=404, detail={'message': 'Meeting not found in the public archive database.', 'fix': 'Point TOWNLIGHT_MEETINGS_PUBLIC_ARCHIVE_DB_URL at the same database as TOWNLIGHT_MEETINGS_MEETING_DB_URL so published records reference real meetings.'})" - ] - }, - { - "method": "POST", - "path": "/imports/{connector_name}/meetings", - "router": "app", - "prefix_resolved": true, - "name": "import_connector_meeting", - "signature": "connector_name: str, payload: dict", - "returns": "dict", - "line": 2347, - "doc": "Import a local connector export payload without outbound network calls.", - "decorator": "app.post('/imports/{connector_name}/meetings', status_code=201)", - "errors": [ - "HTTPException(status_code=status_code, detail=error.public_dict())" - ] - }, - { - "method": "POST", - "path": "/vendor-live-sync/sources", - "router": "app", - "prefix_resolved": true, - "name": "create_vendor_live_sync_source", - "signature": "payload: VendorSyncSourceCreate", - "returns": "dict", - "line": 2365, - "doc": "Create a durable vendor live-sync source record without contacting the vendor.", - "decorator": "app.post('/vendor-live-sync/sources', status_code=201)", - "errors": [ - "HTTPException(status_code=422, detail=error.public_dict())" - ] - }, - { - "method": "GET", - "path": "/vendor-live-sync/sources", - "router": "app", - "prefix_resolved": true, - "name": "list_vendor_live_sync_sources", - "signature": "", - "returns": "dict[str, object]", - "line": 2386, - "doc": "List persisted vendor live-sync source health without contacting vendors.", - "decorator": "app.get('/vendor-live-sync/sources')", - "errors": [] - }, - { - "method": "POST", - "path": "/vendor-live-sync/sources/{source_id}/cursor-reset", - "router": "app", - "prefix_resolved": true, - "name": "reset_vendor_live_sync_cursor", - "signature": "source_id: str, payload: VendorSyncCursorReset", - "returns": "dict[str, object]", - "line": 2398, - "doc": "Clear or move a vendor delta cursor without contacting the vendor network.", - "decorator": "app.post('/vendor-live-sync/sources/{source_id}/cursor-reset')", - "errors": [ - "HTTPException(status_code=404, detail={'message': 'Vendor live-sync source not found.', 'fix': 'Create the source with POST /vendor-live-sync/sources before resetting its cursor.'})" - ] - }, - { - "method": "POST", - "path": "/vendor-live-sync/sources/{source_id}/run-log", - "router": "app", - "prefix_resolved": true, - "name": "record_vendor_live_sync_run", - "signature": "source_id: str, payload: VendorSyncRunRecordCreate", - "returns": "dict", - "line": 2431, - "doc": "Record one vendor sync run outcome without starting a vendor pull.", - "decorator": "app.post('/vendor-live-sync/sources/{source_id}/run-log', status_code=201)", - "errors": [ - "HTTPException(status_code=404, detail={'message': 'Vendor live-sync source not found.', 'fix': 'Create the source with POST /vendor-live-sync/sources before recording a run outcome.'})" - ] - }, - { - "method": "GET", - "path": "/vendor-live-sync/sources/{source_id}/run-log", - "router": "app", - "prefix_resolved": true, - "name": "list_vendor_live_sync_runs", - "signature": "source_id: str", - "returns": "dict[str, object]", - "line": 2463, - "doc": "Return persisted run history for one vendor source without contacting vendors.", - "decorator": "app.get('/vendor-live-sync/sources/{source_id}/run-log')", - "errors": [ - "HTTPException(status_code=404, detail={'message': 'Vendor live-sync source not found.', 'fix': 'Create the source with POST /vendor-live-sync/sources before viewing run history.'})" - ] - }, - { - "method": "GET", - "path": "/public/meetings", - "router": "app", - "prefix_resolved": true, - "name": "public_meetings", - "signature": "", - "returns": "dict[str, int | list[dict]]", - "line": 2484, - "doc": "Return public meeting calendar records only.", - "decorator": "app.get('/public/meetings')", - "errors": [] - }, - { - "method": "GET", - "path": "/public/meetings/{record_id}", - "router": "app", - "prefix_resolved": true, - "name": "public_meeting_detail", - "signature": "record_id: str", - "returns": "dict", - "line": 2494, - "doc": "Return one public meeting record without revealing restricted records.", - "decorator": "app.get('/public/meetings/{record_id}')", - "errors": [ - "HTTPException(status_code=404, detail='Public meeting record not found.')" - ] - }, - { - "method": "GET", - "path": "/public/meetings/{record_id}/{document_kind}.txt", - "router": "app", - "prefix_resolved": true, - "name": "public_meeting_download", - "signature": "record_id: str, document_kind: str", - "returns": "Response", - "line": 2503, - "doc": "Download one public-safe agenda, packet, or adopted-minutes text file.", - "decorator": "app.get('/public/meetings/{record_id}/{document_kind}.txt')", - "errors": [ - "HTTPException(status_code=404, detail='Public meeting record not found.')", - "HTTPException(status_code=404, detail={'message': 'Public meeting document not found.', 'fix': 'Use agenda.txt, packet.txt, or minutes.txt from the public meeting detail response.'})" - ] - }, - { - "method": "POST", - "path": "/public/meetings/{record_id}/comments", - "router": "app", - "prefix_resolved": true, - "name": "submit_public_comment", - "signature": "record_id: str, payload: PublicCommentCreate", - "returns": "dict", - "line": 2530, - "doc": "Accept a resident comment only for public records with comment intake enabled.", - "decorator": "app.post('/public/meetings/{record_id}/comments', status_code=201)", - "errors": [ - "HTTPException(status_code=404, detail='Public meeting record not found.')", - "HTTPException(status_code=409, detail={'message': 'Public comment intake is closed for this meeting record.', 'fix': 'Contact the clerk for the official comment method or check the posted agenda for comment instructions.'})" - ] - }, - { - "method": "GET", - "path": "/public/meetings/{record_id}/comments", - "router": "app", - "prefix_resolved": true, - "name": "list_public_comments", - "signature": "record_id: str", - "returns": "dict[str, int | list[dict]]", - "line": 2557, - "doc": "List resident comments collected for a public record.", - "decorator": "app.get('/public/meetings/{record_id}/comments')", - "errors": [ - "HTTPException(status_code=404, detail='Public meeting record not found.')" - ] - }, - { - "method": "GET", - "path": "/public-comments/review-queue", - "router": "app", - "prefix_resolved": true, - "name": "list_public_comment_review_queue", - "signature": "", - "returns": "dict[str, object]", - "line": 2567, - "doc": "List resident comments awaiting staff review across public records.", - "decorator": "app.get('/public-comments/review-queue')", - "errors": [] - }, - { - "method": "GET", - "path": "/public/archive/search", - "router": "app", - "prefix_resolved": true, - "name": "public_archive_search", - "signature": "q: str, credentials: HTTPAuthorizationCredentials | None=Depends(_archive_search_bearer)", - "returns": "dict[str, int | list[dict]]", - "line": 2580, - "doc": "Search public archives with permission-aware closed-session filtering.", - "decorator": "app.get('/public/archive/search')", - "errors": [] - } - ], - "models": [ + "method": "GET", + "declared_path": "/api/v1/townlight_code/sections/{section_ref}/export", + "function": "export_section", + "line": 1472 + }, { - "name": "AgendaItemCreate", - "bases": [ - "BaseModel" - ], - "fields": [ - { - "name": "title", - "type": "str", - "default": "Field(min_length=1)" - }, - { - "name": "department_name", - "type": "str", - "default": "Field(min_length=1)" - } - ], - "line": 238, - "doc": "" + "method": "POST", + "declared_path": "/api/v1/townlight_code/questions/answer", + "function": "answer_question", + "line": 1478 }, { - "name": "AgendaItemTransitionRequest", - "bases": [ - "BaseModel" - ], - "fields": [ - { - "name": "to_status", - "type": "str", - "default": "Field(min_length=1)" - }, - { - "name": "actor", - "type": "str", - "default": "Field(min_length=1)" - } - ], - "line": 243, - "doc": "" + "method": "POST", + "declared_path": "/api/v1/townlight_code/staff/sections/{section_id}/notes", + "function": "create_interpretation_note", + "line": 1494 }, { - "name": "AgendaIntakeCreate", - "bases": [ - "BaseModel" - ], - "fields": [ - { - "name": "title", - "type": "str", - "default": "Field(min_length=1)" - }, - { - "name": "department_name", - "type": "str", - "default": "Field(min_length=1)" - }, - { - "name": "submitted_by", - "type": "str", - "default": "Field(min_length=1)" - }, - { - "name": "summary", - "type": "str", - "default": "Field(min_length=1)" - }, - { - "name": "source_references", - "type": "list[dict]", - "default": "Field(min_length=1)" - } - ], - "line": 248, - "doc": "" + "method": "GET", + "declared_path": "/api/v1/townlight_code/staff/sections/{section_id}/notes", + "function": "list_interpretation_notes", + "line": 1517 }, { - "name": "AgendaIntakeReviewRequest", - "bases": [ - "BaseModel" - ], - "fields": [ - { - "name": "reviewer", - "type": "str", - "default": "Field(min_length=1)" - }, - { - "name": "ready", - "type": "bool", - "default": "" - }, - { - "name": "notes", - "type": "str", - "default": "Field(min_length=1)" - } - ], - "line": 256, - "doc": "" + "method": "GET", + "declared_path": "/api/v1/townlight_code/staff/audit-events", + "function": "list_staff_audit_events", + "line": 1532 }, { - "name": "AgendaIntakePromoteRequest", - "bases": [ - "BaseModel" - ], - "fields": [ - { - "name": "reviewer", - "type": "str", - "default": "Field(min_length=1)" - }, - { - "name": "notes", - "type": "str", - "default": "Field(default='Promoted to agenda lifecycle.', min_length=1)" - } - ], - "line": 262, - "doc": "" + "method": "POST", + "declared_path": "/api/v1/townlight_code/staff/imports/local-bundle", + "function": "create_local_import_job", + "line": 1548 }, { - "name": "StaffReportCreate", + "method": "POST", + "declared_path": "/api/v1/townlight_code/staff/imports/shared-pdf", + "function": "create_shared_pdf_import_job", + "line": 1560 + }, + { + "method": "GET", + "declared_path": "/api/v1/townlight_code/staff/imports", + "function": "list_import_jobs", + "line": 1594 + }, + { + "method": "GET", + "declared_path": "/api/v1/townlight_code/staff/imports/{job_id}", + "function": "get_import_job", + "line": 1604 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_code/staff/imports/{job_id}/retry", + "function": "retry_import_job", + "line": 1619 + }, + { + "method": "GET", + "declared_path": "/api/v1/townlight_code/staff/imports/{job_id}/provenance", + "function": "get_import_provenance", + "line": 1635 + }, + { + "method": "GET", + "declared_path": "/api/v1/townlight_code/staff/imports/{job_id}/tree", + "function": "get_imported_tree", + "line": 1650 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_code/staff/sync/codifier-sources", + "function": "configure_codifier_sync_source", + "line": 1673 + }, + { + "method": "GET", + "declared_path": "/api/v1/townlight_code/staff/sync/codifier-sources", + "function": "list_codifier_sync_sources", + "line": 1694 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_code/staff/sync/codifier-sources/{source_id}/run", + "function": "run_codifier_sync_source", + "line": 1709 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_code/staff/townlight_meetings/ordinance-events", + "function": "create_townlight_meetings_ordinance_event", + "line": 1730 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_code/staff/townlight_meetings/ordinance-events/{event_id}/resolve", + "function": "resolve_townlight_meetings_ordinance_event", + "line": 1756 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_code/staff/sections/{section_id}/summaries", + "function": "create_plain_language_summary", + "line": 1806 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_code/staff/summaries/{summary_id}/approve", + "function": "approve_plain_language_summary", + "line": 1841 + }, + { + "method": "GET", + "declared_path": "/api/v1/townlight_code/sections/{section_id}/summaries", + "function": "list_public_plain_language_summaries", + "line": 1866 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_code/staff/questions/answer", + "function": "answer_staff_question", + "line": 1895 + } + ], + "models": [ + { + "name": "SourceCreate", "bases": [ "BaseModel" ], "fields": [ { - "name": "title", - "type": "str", - "default": "Field(min_length=1)" - }, - { - "name": "department_name", - "type": "str", - "default": "Field(min_length=1)" + "name": "source_id", + "type": "str | None", + "line": 291 }, { - "name": "author", + "name": "name", "type": "str", - "default": "Field(min_length=1)" + "line": 292 }, { - "name": "summary", + "name": "publisher", "type": "str", - "default": "Field(min_length=1)" - }, - { - "name": "source_references", - "type": "list[dict]", - "default": "Field(min_length=1)" - }, - { - "name": "agenda_item_id", - "type": "str | None", - "default": "Field(default=None, min_length=1)" + "line": 293 }, { - "name": "legal_reviewer", - "type": "str | None", - "default": "Field(default=None, min_length=1)" - } - ], - "line": 267, - "doc": "" - }, - { - "name": "MeetingCreate", - "bases": [ - "BaseModel" - ], - "fields": [ - { - "name": "title", + "name": "source_type", "type": "str", - "default": "Field(min_length=1)" + "line": 294 }, { - "name": "meeting_type", + "name": "source_category", "type": "str", - "default": "Field(min_length=1)" - }, - { - "name": "scheduled_start", - "type": "str | None", - "default": "None" + "line": 295 }, { - "name": "meeting_body_id", + "name": "source_url", "type": "str | None", - "default": "Field(default=None, min_length=1)" + "line": 296 }, { - "name": "location", - "type": "str | None", - "default": "Field(default=None, min_length=1)" - } - ], - "line": 277, - "doc": "" - }, - { - "name": "MeetingUpdate", - "bases": [ - "BaseModel" - ], - "fields": [ - { - "name": "title", + "name": "file_reference", "type": "str | None", - "default": "Field(default=None, min_length=1)" + "line": 297 }, { - "name": "meeting_type", - "type": "str | None", - "default": "Field(default=None, min_length=1)" + "name": "retrieved_at", + "type": "datetime | None", + "line": 298 }, { - "name": "scheduled_start", + "name": "retrieval_method", "type": "str | None", - "default": "Field(default=None, min_length=1)" + "line": 299 }, { - "name": "meeting_body_id", + "name": "checksum", "type": "str | None", - "default": "Field(default=None, min_length=1)" + "line": 300 }, { - "name": "location", + "name": "source_owner", "type": "str | None", - "default": "Field(default=None, min_length=1)" + "line": 301 }, { - "name": "actor", - "type": "str", - "default": "Field(default='clerk@example.gov', min_length=1)" - } - ], - "line": 285, - "doc": "" - }, - { - "name": "MeetingBodyCreate", - "bases": [ - "BaseModel" - ], - "fields": [ - { - "name": "name", - "type": "str", - "default": "Field(min_length=1)" - }, - { - "name": "body_type", - "type": "str", - "default": "Field(min_length=1)" - }, - { - "name": "is_active", + "name": "is_official", "type": "bool", - "default": "True" - } - ], - "line": 294, - "doc": "" - }, - { - "name": "MeetingBodyUpdate", - "bases": [ - "BaseModel" - ], - "fields": [ + "line": 302 + }, { - "name": "name", + "name": "official_status_note", "type": "str | None", - "default": "Field(default=None, min_length=1)" + "line": 303 }, { - "name": "body_type", - "type": "str | None", - "default": "Field(default=None, min_length=1)" + "name": "status", + "type": "str", + "line": 304 }, { - "name": "is_active", - "type": "bool | None", - "default": "None" + "name": "staff_notes", + "type": "str | None", + "line": 305 } ], - "line": 300, - "doc": "" + "line": 286 }, { - "name": "MeetingTransitionRequest", + "name": "SourceTransitionRequest", "bases": [ "BaseModel" ], @@ -21481,8087 +20547,7637 @@ { "name": "to_status", "type": "str", - "default": "Field(min_length=1)" + "line": 313 }, { "name": "actor", "type": "str", - "default": "Field(min_length=1)" + "line": 314 }, { - "name": "statutory_basis", - "type": "str | None", - "default": "Field(default=None, min_length=1)" + "name": "reason", + "type": "str", + "line": 315 } ], - "line": 306, - "doc": "" + "line": 308 }, { - "name": "PacketSnapshotCreate", + "name": "TitleCreate", "bases": [ "BaseModel" ], "fields": [ { - "name": "agenda_item_ids", - "type": "list[str]", - "default": "Field(min_length=1)" + "name": "title_id", + "type": "str | None", + "line": 323 }, { - "name": "actor", + "name": "title_number", "type": "str", - "default": "Field(min_length=1)" + "line": 324 + }, + { + "name": "title_name", + "type": "str", + "line": 325 + }, + { + "name": "sort_order", + "type": "int", + "line": 326 } ], - "line": 312, - "doc": "" + "line": 318 }, { - "name": "PacketAssemblyCreate", + "name": "ChapterCreate", "bases": [ "BaseModel" ], "fields": [ { - "name": "title", - "type": "str", - "default": "Field(min_length=1)" + "name": "chapter_id", + "type": "str | None", + "line": 334 }, { - "name": "agenda_item_ids", - "type": "list[str]", - "default": "Field(min_length=1)" + "name": "title_id", + "type": "str", + "line": 335 }, { - "name": "actor", + "name": "chapter_number", "type": "str", - "default": "Field(min_length=1)" + "line": 336 }, { - "name": "source_references", - "type": "list[dict]", - "default": "Field(min_length=1)" + "name": "chapter_name", + "type": "str", + "line": 337 }, { - "name": "citations", - "type": "list[dict]", - "default": "Field(min_length=1)" + "name": "sort_order", + "type": "int", + "line": 338 } ], - "line": 317, - "doc": "" + "line": 329 }, { - "name": "PacketAssemblyFinalizeRequest", + "name": "SectionCreate", "bases": [ "BaseModel" ], "fields": [ { - "name": "actor", + "name": "section_id", + "type": "str | None", + "line": 346 + }, + { + "name": "chapter_id", + "type": "str", + "line": 347 + }, + { + "name": "section_number", "type": "str", - "default": "Field(min_length=1)" + "line": 348 + }, + { + "name": "section_heading", + "type": "str", + "line": 349 + }, + { + "name": "parent_section_id", + "type": "str | None", + "line": 350 + }, + { + "name": "sort_order", + "type": "int", + "line": 351 + }, + { + "name": "administrative_regulation_refs", + "type": "list[str]", + "line": 352 + }, + { + "name": "resolution_refs", + "type": "list[str]", + "line": 353 + }, + { + "name": "policy_refs", + "type": "list[str]", + "line": 354 + }, + { + "name": "approved_summary_refs", + "type": "list[str]", + "line": 355 } ], - "line": 325, - "doc": "" + "line": 341 }, { - "name": "PacketSourceCreate", + "name": "SectionVersionCreate", "bases": [ "BaseModel" ], "fields": [ + { + "name": "version_id", + "type": "str | None", + "line": 363 + }, + { + "name": "section_id", + "type": "str", + "line": 364 + }, { "name": "source_id", "type": "str", - "default": "Field(min_length=1)" + "line": 365 }, { - "name": "title", + "name": "version_label", "type": "str", - "default": "Field(min_length=1)" + "line": 366 }, { - "name": "kind", + "name": "body", "type": "str", - "default": "Field(default='document', min_length=1)" + "line": 367 }, { - "name": "source_system", - "type": "str | None", - "default": "Field(default=None, min_length=1)" + "name": "effective_start", + "type": "date", + "line": 368 }, { - "name": "source_path", + "name": "effective_end", + "type": "date | None", + "line": 369 + }, + { + "name": "status", + "type": "str", + "line": 370 + }, + { + "name": "is_current", + "type": "bool", + "line": 371 + }, + { + "name": "adoption_event_id", "type": "str | None", - "default": "Field(default=None, min_length=1)" + "line": 372 }, { - "name": "checksum", + "name": "amendment_event_id", "type": "str | None", - "default": "Field(default=None, min_length=1)" + "line": 373 }, { - "name": "sensitivity_label", + "name": "amendment_summary", "type": "str | None", - "default": "Field(default=None, min_length=1)" + "line": 374 }, { - "name": "citation_label", + "name": "prior_version_id", "type": "str | None", - "default": "Field(default=None, min_length=1)" + "line": 375 } ], - "line": 329, - "doc": "" + "line": 358 }, { - "name": "PacketExportCreate", + "name": "QuestionAnswerRequest", "bases": [ "BaseModel" ], "fields": [ { - "name": "bundle_name", - "type": "str", - "default": "Field(min_length=1)" - }, - { - "name": "actor", + "name": "question", "type": "str", - "default": "Field(min_length=1)" + "line": 383 }, { - "name": "sources", - "type": "list[PacketSourceCreate]", - "default": "Field(min_length=1)" + "name": "section_number", + "type": "str | None", + "line": 384 }, { - "name": "public_bundle", - "type": "bool", - "default": "True" + "name": "as_of", + "type": "date | None", + "line": 385 } ], - "line": 340, - "doc": "" + "line": 378 }, { - "name": "NoticeComplianceRequest", + "name": "SectionResolveRequest", "bases": [ "BaseModel" ], "fields": [ { - "name": "notice_type", + "name": "consumer_module", "type": "str", - "default": "Field(min_length=1)" - }, - { - "name": "posted_at", - "type": "datetime", - "default": "" + "line": 393 }, { - "name": "minimum_notice_hours", - "type": "int", - "default": "Field(gt=0)" + "name": "section_number", + "type": "str | None", + "line": 394 }, { - "name": "statutory_basis", + "name": "query", "type": "str | None", - "default": "Field(default=None, min_length=1)" + "line": 395 }, { - "name": "approved_by", - "type": "str | None", - "default": "Field(default=None, min_length=1)" + "name": "as_of", + "type": "date | None", + "line": 396 } ], - "line": 347, - "doc": "" + "line": 388 }, { - "name": "NoticeChecklistCreate", + "name": "PopularQuestionCreate", "bases": [ - "NoticeComplianceRequest" + "BaseModel" ], "fields": [ { - "name": "actor", + "name": "question_id", + "type": "str | None", + "line": 404 + }, + { + "name": "question_text", + "type": "str", + "line": 405 + }, + { + "name": "section_number", + "type": "str", + "line": 406 + }, + { + "name": "answer_excerpt", + "type": "str", + "line": 407 + }, + { + "name": "audience", + "type": "str", + "line": 408 + }, + { + "name": "status", "type": "str", - "default": "Field(min_length=1)" + "line": 409 + }, + { + "name": "is_popular", + "type": "bool", + "line": 410 } ], - "line": 355, - "doc": "" + "line": 399 }, { - "name": "NoticePostingProofCreate", + "name": "InterpretationNoteCreate", "bases": [ "BaseModel" ], "fields": [ { - "name": "actor", + "name": "note_id", + "type": "str | None", + "line": 418 + }, + { + "name": "note_text", "type": "str", - "default": "Field(min_length=1)" + "line": 419 }, { - "name": "posting_proof", - "type": "dict", - "default": "Field(min_length=1)" + "name": "status", + "type": "str", + "line": 420 } ], - "line": 359, - "doc": "" + "line": 413 }, { - "name": "MotionCreate", + "name": "PlainLanguageSummaryCreate", "bases": [ "BaseModel" ], "fields": [ { - "name": "text", + "name": "summary_id", + "type": "str | None", + "line": 428 + }, + { + "name": "section_version_id", "type": "str", - "default": "Field(min_length=1)" + "line": 429 }, { - "name": "actor", + "name": "summary_text", "type": "str", - "default": "Field(min_length=1)" + "line": 430 }, { - "name": "agenda_item_id", - "type": "str | None", - "default": "Field(default=None, min_length=1)" + "name": "language_code", + "type": "str", + "line": 431 }, { - "name": "seconded_by", - "type": "str | None", - "default": "Field(default=None, min_length=1)" + "name": "status", + "type": "str", + "line": 432 } ], - "line": 364, - "doc": "" + "line": 423 }, { - "name": "MotionCorrectionCreate", + "name": "TownlightMeetingsOrdinanceEventCreate", "bases": [ "BaseModel" ], "fields": [ { - "name": "text", + "name": "event_id", + "type": "str | None", + "line": 440 + }, + { + "name": "external_event_id", + "type": "str", + "line": 441 + }, + { + "name": "townlight_meetings_meeting_id", + "type": "str", + "line": 442 + }, + { + "name": "townlight_meetings_agenda_item_id", "type": "str", - "default": "Field(min_length=1)" + "line": 443 + }, + { + "name": "ordinance_number", + "type": "str", + "line": 444 + }, + { + "name": "title", + "type": "str", + "line": 445 + }, + { + "name": "status", + "type": "str", + "line": 446 + }, + { + "name": "affected_sections", + "type": "list[str]", + "line": 447 }, { - "name": "actor", + "name": "source_document_url", "type": "str", - "default": "Field(min_length=1)" + "line": 448 }, { - "name": "reason", + "name": "source_document_hash", "type": "str", - "default": "Field(min_length=1)" - } - ], - "line": 371, - "doc": "" - }, - { - "name": "VoteCreate", - "bases": [ - "BaseModel" - ], - "fields": [ + "line": 449 + }, { - "name": "voter_name", + "name": "ordinance_text", "type": "str", - "default": "Field(min_length=1)" + "line": 450 }, { - "name": "vote", - "type": "str", - "default": "Field(min_length=1)" + "name": "adopted_at", + "type": "datetime | None", + "line": 451 }, { - "name": "actor", - "type": "str", - "default": "Field(min_length=1)" + "name": "failure_reason", + "type": "str | None", + "line": 452 } ], - "line": 377, - "doc": "" + "line": 435 }, { - "name": "VoteCorrectionCreate", + "name": "TownlightMeetingsOrdinanceEventResolve", "bases": [ "BaseModel" ], "fields": [ { - "name": "vote", - "type": "str", - "default": "Field(min_length=1)" - }, - { - "name": "actor", - "type": "str", - "default": "Field(min_length=1)" - }, - { - "name": "reason", + "name": "section_version_id", "type": "str", - "default": "Field(min_length=1)" + "line": 460 } ], - "line": 383, - "doc": "" + "line": 455 }, { - "name": "ActionItemCreate", + "name": "ImportBundleCreate", "bases": [ "BaseModel" ], "fields": [ { - "name": "description", - "type": "str", - "default": "Field(min_length=1)" + "name": "job_id", + "type": "str | None", + "line": 468 }, { - "name": "actor", + "name": "connector_type", "type": "str", - "default": "Field(min_length=1)" + "line": 469 }, { - "name": "assigned_to", - "type": "str | None", - "default": "Field(default=None, min_length=1)" + "name": "source", + "type": "SourceCreate", + "line": 470 }, { - "name": "source_motion_id", - "type": "str | None", - "default": "Field(default=None, min_length=1)" - } - ], - "line": 389, - "doc": "" - }, - { - "name": "SourceMaterialCreate", - "bases": [ - "BaseModel" - ], - "fields": [ + "name": "sources", + "type": "list[SourceCreate]", + "line": 471 + }, { - "name": "source_id", - "type": "str", - "default": "Field(min_length=1)" + "name": "titles", + "type": "list[TitleCreate]", + "line": 472 }, { - "name": "label", - "type": "str", - "default": "Field(min_length=1)" + "name": "chapters", + "type": "list[ChapterCreate]", + "line": 473 }, { - "name": "text", - "type": "str", - "default": "Field(min_length=1)" + "name": "sections", + "type": "list[SectionCreate]", + "line": 474 + }, + { + "name": "versions", + "type": "list[SectionVersionCreate]", + "line": 475 + }, + { + "name": "provenance", + "type": "dict[str, Any]", + "line": 476 } ], - "line": 396, - "doc": "" + "line": 463 }, { - "name": "MinutesSentenceCreate", + "name": "SharedPdfImportCreate", "bases": [ "BaseModel" ], "fields": [ { - "name": "text", + "name": "pdf_path", "type": "str", - "default": "Field(min_length=1)" + "line": 484 }, { - "name": "citations", - "type": "list[str]", - "default": "Field(default_factory=list)" + "name": "force_reingest", + "type": "bool", + "line": 485 } ], - "line": 402, - "doc": "" + "line": 479 }, { - "name": "MinutesDraftCreate", + "name": "CodifierSyncConfigureRequest", "bases": [ "BaseModel" ], "fields": [ { - "name": "model", - "type": "str", - "default": "Field(min_length=1)" - }, - { - "name": "prompt_version", + "name": "source_id", "type": "str", - "default": "Field(min_length=1)" + "line": 493 }, { - "name": "human_approver", + "name": "sync_schedule", "type": "str", - "default": "Field(min_length=1)" - }, - { - "name": "source_materials", - "type": "list[SourceMaterialCreate]", - "default": "Field(min_length=1)" + "line": 494 }, { - "name": "sentences", - "type": "list[MinutesSentenceCreate]", - "default": "Field(min_length=1)" + "name": "allowlisted_hosts", + "type": "list[str]", + "line": 495 } ], - "line": 407, - "doc": "" + "line": 488 }, { - "name": "MinutesAiAssistCreate", + "name": "CodifierSyncRunRequest", "bases": [ "BaseModel" ], "fields": [ { - "name": "model", - "type": "str", - "default": "Field(min_length=1)" - }, - { - "name": "prompt_version", - "type": "str", - "default": "Field(min_length=1)" - }, - { - "name": "human_approver", - "type": "str", - "default": "Field(min_length=1)" - }, - { - "name": "source_materials", - "type": "list[SourceMaterialCreate]", - "default": "Field(min_length=1)" + "name": "payload", + "type": "ImportBundleCreate", + "line": 503 }, { - "name": "instruction", - "type": "str", - "default": "Field(default='Draft concise meeting minutes from the cited source material.', min_length=1)" + "name": "changed_since", + "type": "datetime | None", + "line": 504 } ], - "line": 415, - "doc": "" + "line": 498 + } + ], + "configuration": [ + { + "environment": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", + "line": 1988 + }, + { + "environment": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", + "line": 1999 + }, + { + "environment": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", + "line": 2010 + }, + { + "environment": "TOWNLIGHT_CODE_DEMO_ACTOR", + "line": 2062 + }, + { + "environment": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", + "line": 173 + }, + { + "environment": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", + "line": 201 + }, + { + "environment": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", + "line": 224 + }, + { + "environment": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", + "line": 252 + }, + { + "environment": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", + "line": 1567 }, { - "name": "TranscriptCreate", - "bases": [ - "BaseModel" - ], + "environment": "DATABASE_URL", + "line": 1567 + }, + { + "environment": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", + "line": 2020 + }, + { + "environment": "TOWNLIGHT_CODE_DEMO_SEED", + "line": 2056 + } + ] + }, + { + "source": "townlight_code/migrations/__init__.py", + "sha256": "df7969bd664b7d37c15448defbfc1facdeabac4576ebe265dbeb6e4a20bf17b8", + "bytes": 48, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_code/migrations/alembic.ini", + "sha256": "bd5b1e30a38e20eeef817cd43e76fe592f9c13874624b2421a83d52a78e02440", + "bytes": 761, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_code/migrations/env.py", + "sha256": "a6be395a9afcff83bf1b2334cf1f3744409e12c15f226027249df1a0f713366c", + "bytes": 2408, + "routes": [], + "models": [], + "configuration": [ + { + "environment": "DATABASE_URL", + "line": 24 + } + ] + }, + { + "source": "townlight_code/migrations/guards.py", + "sha256": "db594a5a1532e7edc1b68d7c056e5b105e4be028e034ffecc3ba62f8e088124f", + "bytes": 618, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_code/migrations/versions/__init__.py", + "sha256": "c86c118637e0149a6a9613dc4d6b106a0777add135b92a628ca3a481bceaad1e", + "bytes": 47, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_code/migrations/versions/townlight_code_0001_schema.py", + "sha256": "fbaae32609abcfe3b8ac6fe4135f98007fd30c0ed87343acdae133d0de3d17fa", + "bytes": 7349, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_code/migrations/versions/townlight_code_0002_source_registry_records.py", + "sha256": "3f4ea306bed500f106e2fb3e3c72a699a9fb4834d0467e4670ae54bfcd806749", + "bytes": 1710, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_code/migrations/versions/townlight_code_0003_popular_question_records.py", + "sha256": "d63be371906b6dbf380391f32892b0c52d9099de8de426a50be6cec0597eca40", + "bytes": 1766, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_code/migrations/versions/townlight_code_0004_section_lifecycle_records.py", + "sha256": "7930b4b319f4328d518c9500b35cb065aea8fe6b0c15eae9fdaf2844f125c0f0", + "bytes": 3664, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_code/migrations/versions/townlight_code_0005_staff_summary_records.py", + "sha256": "cfa383851d01d6a8c9a19175c36ab1754af06d8ef9151029d7f7b8a1905dab9d", + "bytes": 3264, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_code/migrations/versions/townlight_code_0006_ordinance_handoff_records.py", + "sha256": "82d7888ed0048e5e4b2c79ec4eab96ba223527bc1c5bf264525292fce658ef20", + "bytes": 2283, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_code/migrations/versions/townlight_code_0007_import_job_records.py", + "sha256": "0aadb2d3d74e0f8c166e140fa9ded8b549af7bfc00354ac57bf7645e5e5142d1", + "bytes": 1429, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_code/migrations/versions/townlight_code_0008_codifier_sync.py", + "sha256": "c0bcc3e99b24e7e4ce2f4a24c8ee2e556b5d7fa77ba55c3627b42b6b7efc368f", + "bytes": 3028, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_code/migrations/versions/townlight_code_0009_operational_state.py", + "sha256": "fd06ecb49b1f75ab7dbddfc2b29cf3a4730f259c4c2d08a35ef42fcc7d65ef5b", + "bytes": 1708, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_code/migrations/versions/townlight_code_0010_handoff_resolution.py", + "sha256": "154c2f55ce0b8a5b5d6a301e3ba476f52d0cd6f9757a2821912b4d1c26f5cabf", + "bytes": 1404, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_code/migrations/versions/townlight_code_0011_semantic_search.py", + "sha256": "dbf61708c6b5ae68dcc085b528b56fb37be906936d225dcce5f12d359ee2a80c", + "bytes": 1696, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_code/migrations/versions/townlight_code_0012_drop_local_search.py", + "sha256": "2665db8af43b4ada8a889cf2745f1e2cd59d69a32e29070650019b035119e290", + "bytes": 641, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_code/mock_city_environment.py", + "sha256": "13ccb031171bc7bfb0dfea4e66dcf3617559be54eaa4c93c9883bef6050ba5c2", + "bytes": 14208, + "routes": [], + "models": [ + { + "name": "MockCityCodifierContract", + "bases": [], "fields": [ { - "name": "actor", + "name": "connector", "type": "str", - "default": "Field(min_length=1)" + "line": 34 }, { - "name": "source_label", + "name": "publisher", "type": "str", - "default": "Field(min_length=1)" + "line": 35 }, { - "name": "transcript_text", + "name": "source_type", "type": "str", - "default": "Field(min_length=1)" - }, - { - "name": "public_release_requested", - "type": "bool", - "default": "False" + "line": 36 }, { - "name": "closed_session", - "type": "bool", - "default": "False" - } - ], - "line": 426, - "doc": "" - }, - { - "name": "OrdinanceResolutionHandoffCreate", - "bases": [ - "BaseModel" - ], - "fields": [ - { - "name": "item_type", + "name": "interface_status", "type": "str", - "default": "Field(pattern='^(ordinance|resolution)$')" + "line": 37 }, { - "name": "title", + "name": "source_url", "type": "str", - "default": "Field(min_length=1)" + "line": 38 }, { - "name": "actor", + "name": "retrieval_method", "type": "str", - "default": "Field(min_length=1)" + "line": 39 }, { - "name": "legal_reviewer", + "name": "auth_method", "type": "str", - "default": "Field(min_length=1)" + "line": 40 }, { - "name": "text", + "name": "delta_query_param", "type": "str", - "default": "Field(min_length=1)" - }, - { - "name": "source_motion_id", - "type": "str | None", - "default": "Field(default=None, min_length=1)" - }, - { - "name": "ordinance_number", - "type": "str | None", - "default": "Field(default=None, min_length=1)" - }, - { - "name": "resolution_number", - "type": "str | None", - "default": "Field(default=None, min_length=1)" - }, - { - "name": "source_references", - "type": "list[dict]", - "default": "Field(default_factory=list)" - }, - { - "name": "affected_sections", - "type": "list[str]", - "default": "Field(default_factory=list)" + "line": 41 }, { - "name": "source_document_url", - "type": "str | None", - "default": "Field(default=None, min_length=1)" + "name": "sample_file", + "type": "str", + "line": 42 }, { - "name": "source_document_hash", - "type": "str | None", - "default": "Field(default=None, min_length=1)" - } - ], - "line": 434, - "doc": "" - }, - { - "name": "OrdinanceResolutionHandoffRetry", - "bases": [ - "BaseModel" - ], - "fields": [ - { - "name": "handoff_id", - "type": "str | None", - "default": "Field(default=None, min_length=1)" + "name": "source_owner", + "type": "str", + "line": 43 } ], - "line": 449, - "doc": "" + "line": 31 }, { - "name": "PublicMeetingRecordCreate", - "bases": [ - "BaseModel" - ], + "name": "MockCityCodeCheck", + "bases": [], "fields": [ { - "name": "title", - "type": "str", - "default": "Field(min_length=1)" - }, - { - "name": "visibility", + "name": "connector", "type": "str", - "default": "Field(min_length=1)" + "line": 69 }, { - "name": "posted_agenda", - "type": "str", - "default": "Field(min_length=1)" + "name": "ok", + "type": "bool", + "line": 70 }, { - "name": "posted_packet", + "name": "message", "type": "str", - "default": "Field(min_length=1)" + "line": 71 }, { - "name": "approved_minutes", + "name": "fix", "type": "str", - "default": "Field(min_length=1)" - }, - { - "name": "public_comment_enabled", - "type": "bool", - "default": "False" + "line": 72 }, { - "name": "plain_language_summary", + "name": "source_id", "type": "str | None", - "default": "Field(default=None, min_length=1)" + "line": 73 }, { - "name": "minutes_adopted_at", + "name": "import_job_id", "type": "str | None", - "default": "Field(default=None, min_length=1)" + "line": 74 }, { - "name": "minutes_signed_by", + "name": "delta_request_url", "type": "str | None", - "default": "Field(default=None, min_length=1)" + "line": 75 }, { - "name": "closed_session_notes", - "type": "str | None", - "default": "Field(default=None, min_length=1)" + "name": "checked_sections", + "type": "tuple[str, ...]", + "line": 76 } ], - "line": 453, - "doc": "" - }, + "line": 66 + } + ], + "configuration": [] + }, + { + "source": "townlight_code/models.py", + "sha256": "4e3ae05293b927f6b1ce149abf707af12abb5a4181ddfcc77b85f37e5b5da03f", + "bytes": 7837, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_code/operational_readiness.py", + "sha256": "359353d77cf6742700c48f8533149390a9a84daf2a068f71259fb0445d0e4510", + "bytes": 7124, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_code/operational_state.py", + "sha256": "cdb7bd2baa6731dafafbf91f054f28cb763fbfd0a65f80905da44e4da66c6c94", + "bytes": 11156, + "routes": [], + "models": [ { - "name": "PublicCommentCreate", - "bases": [ - "BaseModel" - ], + "name": "OperationalStateRecord", + "bases": [], "fields": [ { - "name": "commenter_name", + "name": "record_id", "type": "str", - "default": "Field(min_length=1, max_length=255)" + "line": 23 }, { - "name": "comment", - "type": "str", - "default": "Field(min_length=1)" - } - ], - "line": 466, - "doc": "" - }, - { - "name": "VendorSyncSourceCreate", - "bases": [ - "BaseModel" - ], - "fields": [ - { - "name": "connector", + "name": "lane", "type": "str", - "default": "Field(min_length=1)" + "line": 24 }, { - "name": "source_name", + "name": "record_type", "type": "str", - "default": "Field(min_length=1)" + "line": 25 }, { - "name": "source_url", + "name": "subject_id", "type": "str", - "default": "Field(min_length=1)" + "line": 26 }, { - "name": "auth_method", + "name": "status", "type": "str", - "default": "Field(min_length=1)" - } - ], - "line": 471, - "doc": "" - }, - { - "name": "VendorSyncRunRecordCreate", - "bases": [ - "BaseModel" - ], - "fields": [ - { - "name": "records_discovered", - "type": "int", - "default": "Field(ge=0)" - }, - { - "name": "records_succeeded", - "type": "int", - "default": "Field(ge=0)" + "line": 27 }, { - "name": "records_failed", - "type": "int", - "default": "Field(ge=0)" + "name": "actor", + "type": "str", + "line": 28 }, { - "name": "retries_attempted", + "name": "attempt_count", "type": "int", - "default": "Field(default=0, ge=0)" - }, - { - "name": "error_summary", - "type": "str | None", - "default": "Field(default=None, min_length=1)" - } - ], - "line": 478, - "doc": "" - }, - { - "name": "VendorSyncCursorReset", - "bases": [ - "BaseModel" - ], - "fields": [ - { - "name": "cursor_at", - "type": "datetime | None", - "default": "None" + "line": 29 }, { - "name": "reason", - "type": "str", - "default": "Field(min_length=8, max_length=500)" - } - ], - "line": 486, - "doc": "" - } - ], - "configuration": [ - { - "variable": "TOWNLIGHT_MEETINGS_EXPORT_ROOT", - "default": "'exports'", - "line": 3457 - }, - { - "variable": "TOWNLIGHT_MEETINGS_AGENDA_INTAKE_DB_URL", - "default": "", - "line": 3463 - }, - { - "variable": "TOWNLIGHT_MEETINGS_AGENDA_ITEM_DB_URL", - "default": "", - "line": 3472 - }, - { - "variable": "TOWNLIGHT_MEETINGS_PACKET_ASSEMBLY_DB_URL", - "default": "", - "line": 3483 - }, - { - "variable": "TOWNLIGHT_MEETINGS_NOTICE_CHECKLIST_DB_URL", - "default": "", - "line": 3492 - }, - { - "variable": "TOWNLIGHT_MEETINGS_MEETING_BODY_DB_URL", - "default": "", - "line": 3501 - }, - { - "variable": "TOWNLIGHT_MEETINGS_MEETING_DB_URL", - "default": "", - "line": 3510 - }, - { - "variable": "TOWNLIGHT_MEETINGS_VENDOR_SYNC_DB_URL", - "default": "", - "line": 3521 - }, - { - "variable": "TOWNLIGHT_MEETINGS_MOTION_VOTE_DB_URL", - "default": "", - "line": 3530 - }, - { - "variable": "TOWNLIGHT_MEETINGS_MINUTES_DB_URL", - "default": "", - "line": 3541 - }, - { - "variable": "TOWNLIGHT_MEETINGS_PUBLIC_ARCHIVE_DB_URL", - "default": "", - "line": 3552 - }, - { - "variable": "TOWNLIGHT_MEETINGS_PUBLIC_ARCHIVE_DB_URL", - "default": "", - "line": 3563 - } - ] - }, - { - "source": "installed-owned-source/townlight_meetings/meeting_body.py", - "sha256": "21085a87b167afb85ddd1e20f561695f580f1e20e8259bc8586e29f5f40cc079", - "routes": [], - "models": [ - { - "name": "MeetingBodyRecord", - "bases": [], - "fields": [ + "name": "next_attempt_at", + "type": "datetime | None", + "line": 30 + }, { - "name": "id", - "type": "UUID", - "default": "" + "name": "cursor_key", + "type": "str | None", + "line": 31 }, { - "name": "name", - "type": "str", - "default": "" + "name": "cursor_value", + "type": "str | None", + "line": 32 }, { - "name": "body_type", - "type": "str", - "default": "" + "name": "replay_of", + "type": "str | None", + "line": 33 }, { - "name": "is_active", - "type": "bool", - "default": "" + "name": "payload_hash", + "type": "str | None", + "line": 34 + }, + { + "name": "details", + "type": "dict[str, Any]", + "line": 35 + }, + { + "name": "failure", + "type": "dict[str, Any] | None", + "line": 36 }, { "name": "created_at", "type": "datetime", - "default": "" + "line": 37 }, { "name": "updated_at", "type": "datetime", - "default": "" + "line": 38 } ], - "line": 29, - "doc": "One municipal body that can own public meetings." + "line": 20 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_meetings/meeting_lifecycle.py", - "sha256": "3eb5fdb3d1a259a6841280fca6ce1c1c56317ff8f79de39022e8b5e35fd9115e", + "source": "townlight_code/ordinance_handoff.py", + "sha256": "3b6c0315d2398e4a967d5c5cbfda07759949495eee24157ed4995a61ca41fe75", + "bytes": 21987, "routes": [], "models": [ { - "name": "TransitionResult", + "name": "OrdinanceEvent", "bases": [], "fields": [ { - "name": "allowed", - "type": "bool", - "default": "" + "name": "event_id", + "type": "str", + "line": 40 }, { - "name": "http_status", - "type": "int", - "default": "" + "name": "external_event_id", + "type": "str", + "line": 41 }, { - "name": "message", + "name": "townlight_meetings_meeting_id", "type": "str", - "default": "" + "line": 42 }, { - "name": "fix", + "name": "townlight_meetings_agenda_item_id", "type": "str", - "default": "" + "line": 43 }, { - "name": "audit_entry", - "type": "dict[str, object]", - "default": "" - } - ], - "line": 74, - "doc": "" - }, - { - "name": "MeetingRecord", - "bases": [], - "fields": [ - { - "name": "id", + "name": "ordinance_number", "type": "str", - "default": "" + "line": 44 }, { "name": "title", "type": "str", - "default": "" + "line": 45 }, { - "name": "meeting_type", + "name": "status", "type": "str", - "default": "" + "line": 46 }, { - "name": "scheduled_start", + "name": "affected_sections", + "type": "list[str]", + "line": 47 + }, + { + "name": "source_document_url", + "type": "str", + "line": 48 + }, + { + "name": "source_document_hash", + "type": "str", + "line": 49 + }, + { + "name": "ordinance_text", + "type": "str", + "line": 50 + }, + { + "name": "adopted_at", "type": "datetime | None", - "default": "None" + "line": 51 }, { - "name": "meeting_body_id", + "name": "failure_reason", "type": "str | None", - "default": "None" + "line": 52 }, { - "name": "location", + "name": "resolved_section_version_id", "type": "str | None", - "default": "None" + "line": 53 }, { - "name": "status", + "name": "resolved_by", + "type": "str | None", + "line": 54 + }, + { + "name": "resolved_at", + "type": "datetime | None", + "line": 55 + }, + { + "name": "created_by", "type": "str", - "default": "'SCHEDULED'" + "line": 56 }, { - "name": "audit_entries", - "type": "list[dict[str, object]]", - "default": "field(default_factory=list)" + "name": "created_at", + "type": "datetime", + "line": 57 } ], - "line": 83, - "doc": "" - } - ], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_meetings/migrations/__init__.py", - "sha256": "dd0a9b788de59eae83bec1152f0508532d3921e8bec7f175ba85f7caa5acc64f", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_meetings/migrations/env.py", - "sha256": "9b3b3726c41218c534b726516d30de7dce83cc3d8b2f5d02f561ae3460807d5f", - "routes": [], - "models": [], - "configuration": [ - { - "variable": "DATABASE_URL", - "default": "", - "line": 24 - } - ] - }, - { - "source": "installed-owned-source/townlight_meetings/migrations/guards.py", - "sha256": "5dfcd955681e2467f4ae52ebfe04cf3b5892c9aa68adeae3cb5a999c15ceb69e", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_meetings/migrations/versions/__init__.py", - "sha256": "e08e35c06b073f92af22b7b5bb564ea2b9caaf2295b68e9c6c5ec175605dcc96", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0001_schema.py", - "sha256": "21441c137f2570d037447bb832d9a8223dcba7ee16e4e7cd7a974d81f1824028", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0002_agenda_intake_queue.py", - "sha256": "e23ff5cf9360ab9657e183970c1e36d67111ebf57d5ab1025f9c820eb81f51b3", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0003_packet_assembly_records.py", - "sha256": "28b2b1adc000bbbfd1d537df7abfed94c1a3120f9755542718c05478e96968cc", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0004_notice_checklist_records.py", - "sha256": "a9759ee9a869cbae969e7f371800a296c53f2787ff6654dcb347c18117ce5fcf", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0005_meeting_records.py", - "sha256": "48d3c089a65d4733c164215ec9a18c153b20226f11d9cf06db0ec19d578ec4ea", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0006_agenda_item_lifecycle_records.py", - "sha256": "b030e37ee25d963ada7b51f907c28dbdd77949f2d9882dedf27ea5dc2cfdf32a", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0007_meeting_schedule_fields.py", - "sha256": "e19e655c7fdbf347a85c22be379b2a537e8075a53748facd55f0856bf93ab598", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0008_agenda_intake_promotion.py", - "sha256": "56d0019f2c413c731a09c8dae9150c4d2cd4ccf7b3911786d6e833b9d965dcc0", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0009_vendor_sync_persistence.py", - "sha256": "83df336d1ba176f5e5ef4c01485b013dd5686e5cbb1c8ca935dd5bb1336b641d", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0010_vendor_sync_cursor.py", - "sha256": "860c440f1696e8094d466c8b634b330416a7e0c0616a660820a1463542f6931b", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0011_data_model_completion.py", - "sha256": "ee830e52b4fd24d37f234ad928b4beda378ef5267a35542739477a46e7b6a93e", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0012_action_item_actor.py", - "sha256": "d7a9b4c893b3387ff7557015213cdc6dda893881998071e74b82cf15be2a986c", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0013_minutes_model_posted.py", - "sha256": "908d75f2a666d4a2837823ff48b94cdc0394227d91b48c46deb6efcc9a69e962", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0014_public_meeting_records.py", - "sha256": "f92409988f5893fcc0da7dcaa5fa083e20b7c42056681c54e9ae8152b6bf1331", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0015_capture_seq.py", - "sha256": "092e93ad53ec9ee047bf4d0d634933f5d735c2b3fa46a1de1e13f1dc11408ff1", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0016_archive_indexes.py", - "sha256": "3d91062951e78685411983f45ea206ab436b6fadb20627a79624880def896742", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0017_meeting_authority.py", - "sha256": "73c6266df0dd33b74223133a2a00d045112a1996ffc38025d3aa8ba7831f1082", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0018_agenda_authority.py", - "sha256": "7dc3993bf51db8239270fd53a651b98ebbff0dbfce56ccbb73414ac9bbac2464", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0019_minutes_decisions.py", - "sha256": "5f088e0026bef9f492cac6a4c4a6c16ee81409d6447b1ab1ee19c037cd56d9cc", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0020_delivery_history.py", - "sha256": "92a6779b59cb3228b3bbd963a9c4cef921163cbd07473381f015dbf474ba4005", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0021_sources_archive.py", - "sha256": "3220a0e7992d865b5a1f5a9bb71cb85722336f276fc974c13939d81fbfc1b29c", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_meetings/minutes.py", - "sha256": "d4d890d0c9faaa3fdd51643a156e5f6a29274f436eba858db63746ad0ebb1ea3", - "routes": [], - "models": [ + "line": 39 + }, { - "name": "MinutesProvenance", + "name": "HandoffAuditEvent", "bases": [], "fields": [ { - "name": "model", + "name": "event_id", "type": "str", - "default": "" + "line": 70 }, { - "name": "prompt_version", + "name": "event_type", "type": "str", - "default": "" + "line": 71 }, { - "name": "data_sources", - "type": "tuple[str, ...]", - "default": "" + "name": "actor", + "type": "str", + "line": 72 }, { - "name": "human_approver", + "name": "target_id", "type": "str", - "default": "" + "line": 73 + }, + { + "name": "created_at", + "type": "datetime", + "line": 74 } ], - "line": 26, - "doc": "" - }, + "line": 69 + } + ], + "configuration": [] + }, + { + "source": "townlight_code/plain_language.py", + "sha256": "c333624bd8677938ed7817055a4f96d46169c147425a05b2972ea696862ee45e", + "bytes": 14321, + "routes": [], + "models": [ { - "name": "MinutesDraft", + "name": "PlainLanguageSummary", "bases": [], "fields": [ { - "name": "id", + "name": "summary_id", "type": "str", - "default": "" + "line": 32 }, { - "name": "meeting_id", + "name": "section_id", "type": "str", - "default": "" + "line": 33 }, { - "name": "status", + "name": "section_version_id", "type": "str", - "default": "" + "line": 34 }, { - "name": "sentences", - "type": "tuple[MinutesSentence, ...]", - "default": "" + "name": "summary_text", + "type": "str", + "line": 35 }, { - "name": "source_materials", - "type": "tuple[SourceMaterial, ...]", - "default": "" + "name": "status", + "type": "str", + "line": 36 }, { - "name": "provenance", - "type": "MinutesProvenance", - "default": "" + "name": "language_code", + "type": "str", + "line": 37 }, { - "name": "adopted", - "type": "bool", - "default": "False" + "name": "created_by", + "type": "str", + "line": 38 }, { - "name": "posted", - "type": "bool", - "default": "False" + "name": "approved_by", + "type": "str | None", + "line": 39 }, { - "name": "signed_by", - "type": "str | None", - "default": "None" + "name": "approved_at", + "type": "datetime | None", + "line": 40 }, { - "name": "decision_history", - "type": "tuple[dict, ...]", - "default": "()" + "name": "created_at", + "type": "datetime", + "line": 41 } ], - "line": 42, - "doc": "" + "line": 31 }, { - "name": "MinutesValidationError", + "name": "SummaryAuditEvent", "bases": [], "fields": [ { - "name": "message", + "name": "event_id", "type": "str", - "default": "" + "line": 50 }, { - "name": "fix", + "name": "event_type", + "type": "str", + "line": 51 + }, + { + "name": "actor", + "type": "str", + "line": 52 + }, + { + "name": "section_id", + "type": "str", + "line": 53 + }, + { + "name": "target_id", "type": "str", - "default": "" + "line": 54 + }, + { + "name": "created_at", + "type": "datetime", + "line": 55 } ], - "line": 71, - "doc": "" + "line": 49 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_meetings/mock_city_environment.py", - "sha256": "6df0969766b42257f372e2babf23675b50aead141a1c91e3e9b95237074f084f", + "source": "townlight_code/public_discovery.py", + "sha256": "656e72f672dc2839d58cc4a26252169ba712265533f60ef7b35e11fc6f6c4a94", + "bytes": 10332, "routes": [], "models": [ { - "name": "MockCityHostileFixture", + "name": "PopularQuestion", "bases": [], "fields": [ { - "name": "area", - "type": "HostileArea", - "default": "" + "name": "question_id", + "type": "str", + "line": 35 }, { - "name": "scenario", + "name": "question_text", "type": "str", - "default": "" + "line": 36 }, { - "name": "target", + "name": "section_id", "type": "str", - "default": "" + "line": 37 }, { - "name": "trigger", + "name": "section_number", "type": "str", - "default": "" + "line": 38 }, { - "name": "expected_behavior", + "name": "section_heading", "type": "str", - "default": "" + "line": 39 }, { - "name": "fix", + "name": "answer_excerpt", "type": "str", - "default": "" + "line": 40 }, { - "name": "sample", + "name": "citation_payload", "type": "dict[str, Any]", - "default": "" - } - ], - "line": 47, - "doc": "Secret-free adversarial fixture for the mock-city hostile-mode toggle." - }, - { - "name": "MockCityHostileCheck", - "bases": [], - "fields": [ - { - "name": "area", - "type": "HostileArea", - "default": "" + "line": 41 }, { - "name": "scenario", + "name": "audience", "type": "str", - "default": "" + "line": 42 }, { - "name": "target", + "name": "status", "type": "str", - "default": "" + "line": 43 }, { - "name": "ok", + "name": "is_popular", "type": "bool", - "default": "" + "line": 44 }, { - "name": "message", - "type": "str", - "default": "" + "name": "approved_by", + "type": "str | None", + "line": 45 }, { - "name": "fix", - "type": "str", - "default": "" + "name": "approved_at", + "type": "datetime | None", + "line": 46 + }, + { + "name": "created_at", + "type": "datetime", + "line": 47 } ], - "line": 71, - "doc": "Conformance result for a hostile-mode mock-city fixture." + "line": 34 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_meetings/models.py", - "sha256": "ffc262c2381523ee111259d53bc402938781de926624ca2c791f2ca23bb8072c", + "source": "townlight_code/public_exports.py", + "sha256": "9a8a8a7f9db81da204be0d48a0aa9c50df56363d2d3ff37388460b81a447d372", + "bytes": 6800, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_code/public_lookup.py", + "sha256": "15d1d309c6034daade696531c73d5d5d3fbcf48cf459097646b2892422dc38c9", + "bytes": 23186, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_meetings/motion_vote.py", - "sha256": "8bc167f9e1ab291f7ee8a616f54786bf4baa686849deac1db33884d5a6d5eaef", + "source": "townlight_code/qa_harness.py", + "sha256": "db2f1e72367a5c7bd64bff9540bc7c65c6447624e06afc52479da2fc49fde34a", + "bytes": 5986, "routes": [], "models": [ { - "name": "MotionRecord", + "name": "QuestionRequestContext", "bases": [], "fields": [ { - "name": "id", + "name": "question", "type": "str", - "default": "" + "line": 40 }, { - "name": "meeting_id", + "name": "section_number", + "type": "str | None", + "line": 41 + }, + { + "name": "as_of", + "type": "date | None", + "line": 42 + } + ], + "line": 37 + } + ], + "configuration": [] + }, + { + "source": "townlight_code/real_municipal_fixtures.py", + "sha256": "e8e7814607ede1b28e0df15341aa44cbc7dad32a07122e4a08205f7db9dacc46", + "bytes": 10397, + "routes": [], + "models": [ + { + "name": "PortlandSectionFixture", + "bases": [], + "fields": [ + { + "name": "section_id", "type": "str", - "default": "" + "line": 23 }, { - "name": "text", + "name": "section_number", "type": "str", - "default": "" + "line": 24 }, { - "name": "actor", + "name": "heading", "type": "str", - "default": "" + "line": 25 }, { - "name": "agenda_item_id", - "type": "str | None", - "default": "None" + "name": "source_id", + "type": "str", + "line": 26 }, { - "name": "seconded_by", - "type": "str | None", - "default": "None" + "name": "source_url", + "type": "str", + "line": 27 }, { - "name": "correction_of_id", - "type": "str | None", - "default": "None" + "name": "file_reference", + "type": "str", + "line": 28 }, { - "name": "correction_reason", - "type": "str | None", - "default": "None" + "name": "body", + "type": "str", + "line": 29 }, { - "name": "captured", - "type": "bool", - "default": "True" + "name": "effective_start", + "type": "str", + "line": 30 + }, + { + "name": "adoption_event_id", + "type": "str | None", + "line": 31 } ], - "line": 17, - "doc": "" - }, + "line": 22 + } + ], + "configuration": [] + }, + { + "source": "townlight_code/section_lifecycle.py", + "sha256": "51fd91c02b020575641fcfbc1e2529aaedaad796559742b1aad956a3d7fd1b11", + "bytes": 42407, + "routes": [], + "models": [ { - "name": "VoteRecord", + "name": "CodeTitle", "bases": [], "fields": [ { - "name": "id", + "name": "title_id", "type": "str", - "default": "" + "line": 43 }, { - "name": "motion_id", + "name": "title_number", "type": "str", - "default": "" + "line": 44 }, { - "name": "voter_name", + "name": "title_name", "type": "str", - "default": "" + "line": 45 }, { - "name": "vote", + "name": "sort_order", + "type": "int", + "line": 46 + }, + { + "name": "created_at", + "type": "datetime", + "line": 47 + } + ], + "line": 42 + }, + { + "name": "CodeChapter", + "bases": [], + "fields": [ + { + "name": "chapter_id", "type": "str", - "default": "" + "line": 52 }, { - "name": "actor", + "name": "title_id", "type": "str", - "default": "" + "line": 53 }, { - "name": "correction_of_id", - "type": "str | None", - "default": "None" + "name": "chapter_number", + "type": "str", + "line": 54 }, { - "name": "correction_reason", - "type": "str | None", - "default": "None" + "name": "chapter_name", + "type": "str", + "line": 55 }, { - "name": "captured", - "type": "bool", - "default": "True" + "name": "sort_order", + "type": "int", + "line": 56 + }, + { + "name": "created_at", + "type": "datetime", + "line": 57 } ], - "line": 43, - "doc": "" + "line": 51 }, { - "name": "ActionItemRecord", + "name": "CodeSection", "bases": [], "fields": [ { - "name": "id", + "name": "section_id", "type": "str", - "default": "" + "line": 62 }, { - "name": "meeting_id", + "name": "chapter_id", "type": "str", - "default": "" + "line": 63 }, { - "name": "description", + "name": "section_number", "type": "str", - "default": "" + "line": 64 }, { - "name": "actor", + "name": "section_heading", "type": "str", - "default": "" + "line": 65 }, { - "name": "assigned_to", + "name": "parent_section_id", "type": "str | None", - "default": "None" + "line": 66 }, { - "name": "source_motion_id", - "type": "str | None", - "default": "None" + "name": "sort_order", + "type": "int", + "line": 67 }, { - "name": "status", - "type": "str", - "default": "'OPEN'" + "name": "administrative_regulation_refs", + "type": "list[str]", + "line": 68 + }, + { + "name": "resolution_refs", + "type": "list[str]", + "line": 69 + }, + { + "name": "policy_refs", + "type": "list[str]", + "line": 70 + }, + { + "name": "approved_summary_refs", + "type": "list[str]", + "line": 71 + }, + { + "name": "created_at", + "type": "datetime", + "line": 72 } ], - "line": 67, - "doc": "" + "line": 61 }, { - "name": "MeetingOutcomeSummary", + "name": "SectionVersion", "bases": [], "fields": [ { - "name": "meeting_id", + "name": "version_id", + "type": "str", + "line": 77 + }, + { + "name": "section_id", "type": "str", - "default": "" + "line": 78 }, { - "name": "motion_id", + "name": "source_id", "type": "str", - "default": "" + "line": 79 }, { - "name": "text", + "name": "version_label", "type": "str", - "default": "" + "line": 80 }, { - "name": "actor", + "name": "body", "type": "str", - "default": "" + "line": 81 + }, + { + "name": "effective_start", + "type": "date", + "line": 82 + }, + { + "name": "effective_end", + "type": "date | None", + "line": 83 }, { "name": "status", "type": "str", - "default": "" + "line": 84 }, { - "name": "vote_count", - "type": "int", - "default": "" + "name": "is_current", + "type": "bool", + "line": 85 }, { - "name": "action_item_count", - "type": "int", - "default": "" + "name": "adoption_event_id", + "type": "str | None", + "line": 86 + }, + { + "name": "amendment_event_id", + "type": "str | None", + "line": 87 + }, + { + "name": "amendment_summary", + "type": "str | None", + "line": 88 + }, + { + "name": "prior_version_id", + "type": "str | None", + "line": 89 + }, + { + "name": "created_at", + "type": "datetime", + "line": 90 } ], - "line": 89, - "doc": "" + "line": 76 } ], - "configuration": [] + "configuration": [ + { + "environment": "TOWNLIGHT_CODE_SEMANTIC_SCORE_FLOOR", + "line": 929 + } + ] }, { - "source": "installed-owned-source/townlight_meetings/notice_checklist.py", - "sha256": "093031a3501ad47e35075e5350f20a3cf5ad8f7d29aa9298ea654edcbd253f71", + "source": "townlight_code/semantic_search.py", + "sha256": "21c05a1238ee9b84e68289c4b7f91e631e4c0a66d30de537b589bce1029fa9f7", + "bytes": 3889, "routes": [], "models": [ { - "name": "NoticeChecklistRecord", + "name": "SemanticDocument", "bases": [], "fields": [ { "name": "id", "type": "str", - "default": "" + "line": 25 }, { - "name": "meeting_id", + "name": "version_id", "type": "str", - "default": "" + "line": 26 }, { - "name": "notice_type", + "name": "text", "type": "str", - "default": "" - }, + "line": 27 + } + ], + "line": 24 + }, + { + "name": "EmbeddingConfig", + "bases": [], + "fields": [ { - "name": "status", + "name": "mode", "type": "str", - "default": "" + "line": 32 }, { - "name": "compliant", - "type": "bool", - "default": "" - }, - { - "name": "http_status", - "type": "int", - "default": "" - }, - { - "name": "warnings", - "type": "list[dict]", - "default": "" - }, - { - "name": "deadline_at", - "type": "datetime", - "default": "" - }, - { - "name": "posted_at", - "type": "datetime", - "default": "" - }, - { - "name": "minimum_notice_hours", - "type": "int", - "default": "" - }, - { - "name": "statutory_basis", - "type": "str | None", - "default": "" - }, - { - "name": "approved_by", - "type": "str | None", - "default": "" - }, - { - "name": "posting_proof", - "type": "dict | None", - "default": "" + "name": "base_url", + "type": "str", + "line": 33 }, { - "name": "last_audit_hash", + "name": "model", "type": "str", - "default": "" + "line": 34 }, { - "name": "created_at", - "type": "datetime", - "default": "" - }, + "name": "timeout_seconds", + "type": "float", + "line": 35 + } + ], + "line": 31 + } + ], + "configuration": [ + { + "environment": "TOWNLIGHT_CODE_OLLAMA_EMBEDDING_MODEL", + "line": 49 + }, + { + "environment": "TOWNLIGHT_CODE_OLLAMA_EMBEDDING_URL", + "line": 45 + }, + { + "environment": "TOWNLIGHT_CODE_OLLAMA_URL", + "line": 46 + }, + { + "environment": "OLLAMA_BASE_URL", + "line": 47 + }, + { + "environment": "TOWNLIGHT_CODE_OLLAMA_EMBEDDING_TIMEOUT_SECONDS", + "line": 50 + }, + { + "environment": "TOWNLIGHT_CODE_EMBEDDING_MODE", + "line": 40 + } + ] + }, + { + "source": "townlight_code/shared_ingestion.py", + "sha256": "1d16228fdafa8c533a52e528fa9e99e71c9a009099d99e8e6291baa72b14eb5e", + "bytes": 28230, + "routes": [], + "models": [ + { + "name": "SharedIngestionImport", + "bases": [], + "fields": [ { - "name": "updated_at", - "type": "datetime", - "default": "" + "name": "payload", + "type": "dict[str, Any]", + "line": 68 }, { - "name": "audit_entries", - "type": "list[dict]", - "default": "" + "name": "proof", + "type": "dict[str, Any]", + "line": 69 } ], - "line": 50, - "doc": "Persisted notice compliance check and optional posting proof." + "line": 65 } ], - "configuration": [] + "configuration": [ + { + "environment": "DATABASE_URL", + "line": 172 + }, + { + "environment": "TOWNLIGHT_CODE_SHARED_INGEST_CHUNK_SIZE", + "line": 88 + }, + { + "environment": "TOWNLIGHT_CODE_SHARED_INGEST_CHUNK_OVERLAP", + "line": 89 + }, + { + "environment": "TOWNLIGHT_CODE_SHARED_INGEST_ALLOWED_DIRS", + "line": 252 + }, + { + "environment": "TOWNLIGHT_CODE_SHARED_INGEST_ALLOWED_DIR", + "line": 252 + } + ] }, { - "source": "installed-owned-source/townlight_meetings/oidc_auth.py", - "sha256": "3c9ae9b5d1f664d4372048c6e708cc77589cceb071d3e15cab8b90cf76926120", + "source": "townlight_code/source_registry.py", + "sha256": "4a9b4df376bb2a8456676f95de554ee7508b58892fda9e0342c27186a4740a76", + "bytes": 20364, "routes": [], "models": [ { - "name": "OidcStaffAuthConfig", + "name": "CodeSource", "bases": [], "fields": [ { - "name": "provider", + "name": "source_id", "type": "str", - "default": "" + "line": 77 }, { - "name": "issuer", + "name": "name", "type": "str", - "default": "" + "line": 78 }, { - "name": "audience", + "name": "publisher", "type": "str", - "default": "" + "line": 79 }, { - "name": "jwks_url", - "type": "str | None", - "default": "" + "name": "source_type", + "type": "str", + "line": 80 }, { - "name": "jwks_json", + "name": "source_category", + "type": "str", + "line": 81 + }, + { + "name": "source_url", "type": "str | None", - "default": "" + "line": 82 }, { - "name": "role_claims", - "type": "tuple[str, ...]", - "default": "" + "name": "file_reference", + "type": "str | None", + "line": 83 }, { - "name": "algorithms", - "type": "tuple[str, ...]", - "default": "" + "name": "retrieved_at", + "type": "datetime | None", + "line": 84 }, { - "name": "authorization_url", + "name": "retrieval_method", "type": "str | None", - "default": "" + "line": 85 }, { - "name": "token_url", + "name": "checksum", "type": "str | None", - "default": "" + "line": 86 }, { - "name": "client_id", + "name": "source_owner", "type": "str | None", - "default": "" + "line": 87 }, { - "name": "client_secret", - "type": "str | None", - "default": "" + "name": "is_official", + "type": "bool", + "line": 88 }, { - "name": "redirect_uri", + "name": "official_status_note", "type": "str | None", - "default": "" + "line": 89 }, { - "name": "session_cookie_secret", + "name": "status", + "type": "str", + "line": 90 + }, + { + "name": "staff_notes", "type": "str | None", - "default": "" + "line": 91 + }, + { + "name": "created_at", + "type": "datetime", + "line": 92 + }, + { + "name": "updated_at", + "type": "datetime", + "line": 93 } ], - "line": 21, - "doc": "" + "line": 74 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_meetings/packet_assembly.py", - "sha256": "5edc8d3316a5eb4965b8bcbd94468fb70ef5050ed75811facccc560cec6a4791", + "source": "townlight_code/staff_code.py", + "sha256": "5e182127807244627eee862325e0d8f8bf971487727fd7c82d3a7a96cf35a4de", + "bytes": 11716, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_code/staff_imports.py", + "sha256": "25d0008a594aa2292eea2f3a02a5b8e0d0cc46ff5ba5b3cfbda02c99ee308823", + "bytes": 12231, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_code/staff_sources.py", + "sha256": "2e726e0776a086d4395657fa6d76e3254322faf9329b015c023dafeb3146041e", + "bytes": 10334, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_code/staff_sync.py", + "sha256": "8b8eabf1485a67e877348050645be5d7751d4a0567f3ca3fe404334f230e0b3e", + "bytes": 12704, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_code/staff_workbench.py", + "sha256": "542b379f07c9a0ab41f5b002b7eb78b5a193d8c75d011b11bbf683b66b08e60d", + "bytes": 9134, "routes": [], "models": [ { - "name": "PacketAssemblyRecord", + "name": "InterpretationNote", "bases": [], "fields": [ { - "name": "id", - "type": "str", - "default": "" - }, - { - "name": "meeting_id", - "type": "str", - "default": "" - }, - { - "name": "packet_snapshot_id", - "type": "str", - "default": "" - }, - { - "name": "packet_version", - "type": "int", - "default": "" - }, - { - "name": "title", + "name": "note_id", "type": "str", - "default": "" + "line": 32 }, { - "name": "status", + "name": "section_id", "type": "str", - "default": "" + "line": 33 }, { - "name": "actor", + "name": "note_text", "type": "str", - "default": "" - }, - { - "name": "agenda_item_ids", - "type": "list[str]", - "default": "" + "line": 34 }, { - "name": "source_references", - "type": "list[dict]", - "default": "" + "name": "status", + "type": "str", + "line": 35 }, { - "name": "citations", - "type": "list[dict]", - "default": "" + "name": "visibility", + "type": "str", + "line": 36 }, { - "name": "finalized_by", - "type": "str | None", - "default": "" + "name": "created_by", + "type": "str", + "line": 37 }, { - "name": "finalized_at", - "type": "datetime | None", - "default": "" - }, + "name": "created_at", + "type": "datetime", + "line": 38 + } + ], + "line": 31 + }, + { + "name": "AuditEvent", + "bases": [], + "fields": [ { - "name": "last_audit_hash", + "name": "event_id", "type": "str", - "default": "" + "line": 43 }, { - "name": "created_at", - "type": "datetime", - "default": "" + "name": "event_type", + "type": "str", + "line": 44 }, { - "name": "updated_at", - "type": "datetime", - "default": "" + "name": "actor", + "type": "str", + "line": 45 }, { - "name": "snapshot_content", - "type": "list[dict]", - "default": "" + "name": "section_id", + "type": "str | None", + "line": 46 }, { - "name": "delivery_history", - "type": "list[dict]", - "default": "" + "name": "target_id", + "type": "str | None", + "line": 47 }, { - "name": "audit_entries", - "type": "list[dict]", - "default": "" + "name": "created_at", + "type": "datetime", + "line": 48 } ], - "line": 51, - "doc": "One persisted packet assembly draft or finalized packet record." + "line": 42 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_meetings/packet_notice.py", - "sha256": "826b46e12dc114c10b25838bd68bc2d668dc5bdfa2e74bfafc841b6fddff3ffc", + "source": "townlight_code/suite_session_auth.py", + "sha256": "91ee6d997570b8c1e27f3aa2507b1ec005cf2a1bd3e51536fe622d3c03e5a12c", + "bytes": 9854, "routes": [], "models": [ { - "name": "PacketSource", + "name": "SuiteSessionPrincipal", "bases": [], "fields": [ { - "name": "source_id", + "name": "subject", "type": "str", - "default": "" + "line": 35 }, { - "name": "title", - "type": "str", - "default": "" + "name": "roles", + "type": "frozenset[str]", + "line": 36 }, { - "name": "kind", + "name": "session_id", "type": "str", - "default": "'document'" - }, - { - "name": "source_system", - "type": "str | None", - "default": "None" - }, + "line": 37 + } + ], + "line": 32 + } + ], + "configuration": [] + } + ] + }, + "zoning": { + "repository": "townlight/zone", + "repository_head": "4d2a77a653e42a17aaea8d83d0b196ba83413c57", + "working_tree_modified": true, + "principal_import": "townlight_zoning", + "source": [ + { + "source": "townlight_zoning/__init__.py", + "sha256": "c92eb3c3aa9d0fd13b8904cbdc0d75828d3eb4a0cbeaba1165140254ce0889a7", + "bytes": 58, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_zoning/cited_questions.py", + "sha256": "a243c3887ee4358698008f4753a4877d17c4179ef7f59672ef06429013ea2537", + "bytes": 12311, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_zoning/cited_rules.py", + "sha256": "ed8c7210d9f0fd320713f32e9c06a9ea03c94252ddcced19d4c60edf98c549ff", + "bytes": 8521, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_zoning/connected_sources.py", + "sha256": "8bf1acad90f7f66e637a45727fc751a5d74f2c98f893c43f91a41914f8735883", + "bytes": 11235, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_zoning/discretionary.py", + "sha256": "cd7afa08af24988604e6e3daa7c2db3f6d9103b64d64cc55716725f9ef50afd6", + "bytes": 10195, + "routes": [], + "models": [ + { + "name": "Unavailable", + "bases": [], + "fields": [ { - "name": "source_path", - "type": "str | None", - "default": "None" + "name": "reason", + "type": "str", + "line": 48 }, { - "name": "checksum", - "type": "str | None", - "default": "None" + "name": "fix", + "type": "str", + "line": 49 }, { - "name": "sensitivity_label", - "type": "str | None", - "default": "None" + "name": "review_required", + "type": "bool", + "line": 50 }, { - "name": "citation_label", - "type": "str | None", - "default": "None" + "name": "disclaimer", + "type": "str", + "line": 51 } ], - "line": 58, - "doc": "Source material included in an exported packet bundle." + "line": 45 }, { - "name": "PacketSnapshot", + "name": "NonconformityFlag", "bases": [], "fields": [ { - "name": "id", + "name": "observed", "type": "str", - "default": "" + "line": 58 }, { - "name": "meeting_id", + "name": "standard", "type": "str", - "default": "" + "line": 59 }, { - "name": "version", - "type": "int", - "default": "" + "name": "citation", + "type": "str", + "line": 60 }, { - "name": "agenda_item_ids", - "type": "tuple[str, ...]", - "default": "" + "name": "basis", + "type": "str", + "line": 61 }, { - "name": "actor", - "type": "str", - "default": "" + "name": "review_required", + "type": "bool", + "line": 62 }, { - "name": "created_at", - "type": "datetime", - "default": "field(default_factory=lambda: datetime.now(UTC))" + "name": "determination_made", + "type": "bool", + "line": 63 + }, + { + "name": "disclaimer", + "type": "str", + "line": 64 } ], - "line": 92, - "doc": "" + "line": 55 }, { - "name": "PacketExportResult", + "name": "ProcessExplanation", "bases": [], "fields": [ { - "name": "meeting_id", + "name": "process", "type": "str", - "default": "" + "line": 69 }, { - "name": "bundle_path", + "name": "label", "type": "str", - "default": "" + "line": 70 }, { - "name": "manifest_path", + "name": "what", "type": "str", - "default": "" + "line": 71 }, { - "name": "checksums_path", + "name": "standard_citation", "type": "str", - "default": "" + "line": 72 }, { - "name": "townlight_core_version", - "type": "str", - "default": "" + "name": "needs", + "type": "list", + "line": 73 }, { - "name": "packet_version", - "type": "int", - "default": "" + "name": "review", + "type": "list", + "line": 74 }, { - "name": "audit_hash", + "name": "source_citation", + "type": "dict", + "line": 75 + }, + { + "name": "standards", + "type": "list", + "line": 76 + }, + { + "name": "flags", + "type": "list", + "line": 77 + }, + { + "name": "review_required", + "type": "bool", + "line": 78 + }, + { + "name": "determination_made", + "type": "bool", + "line": 79 + }, + { + "name": "disclaimer", "type": "str", - "default": "" + "line": 80 }, { - "name": "generated_files", - "type": "tuple[str, ...]", - "default": "" + "name": "as_of", + "type": "str | None", + "line": 81 } ], - "line": 112, - "doc": "Result of creating a records-ready packet export bundle." - }, + "line": 68 + } + ], + "configuration": [] + }, + { + "source": "townlight_zoning/geo_import.py", + "sha256": "8926ce327572fe40e18e513c04928920a5d14306df6b003fd3e0a466914a5a26", + "bytes": 13686, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_zoning/geo_spatial.py", + "sha256": "dfe4c88a940a20825c5c493babacb0cb0a96a70cb31a831c3ff1ecb4b77ebc13", + "bytes": 5469, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_zoning/geo_validate.py", + "sha256": "65b4a2b84722be8c25decfaeb80c6177ff30588259379927e853f7727d767178", + "bytes": 6419, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_zoning/integration_mocks.py", + "sha256": "a31da986c6165cf5528bf2065ac856d25fdf3576c11e6fed4cf4656dca683bed", + "bytes": 14445, + "routes": [], + "models": [ { - "name": "NoticeComplianceResult", + "name": "IntegrationError", "bases": [], "fields": [ { - "name": "meeting_id", + "name": "provider", "type": "str", - "default": "" + "line": 28 }, { - "name": "notice_type", + "name": "message", "type": "str", - "default": "" - }, - { - "name": "scheduled_start", - "type": "datetime", - "default": "" - }, - { - "name": "posted_at", - "type": "datetime", - "default": "" + "line": 29 }, { - "name": "minimum_notice_hours", - "type": "int", - "default": "" + "name": "fix", + "type": "str", + "line": 30 }, { - "name": "deadline_at", - "type": "datetime", - "default": "" - }, + "name": "code", + "type": "str", + "line": 31 + } + ], + "line": 27 + }, + { + "name": "IntegrationResult", + "bases": [], + "fields": [ { - "name": "statutory_basis", - "type": "str | None", - "default": "" + "name": "provider", + "type": "str", + "line": 36 }, { - "name": "approved_by", - "type": "str | None", - "default": "" + "name": "records", + "type": "tuple[dict[str, Any], ...]", + "line": 37 }, { - "name": "compliant", - "type": "bool", - "default": "" + "name": "source", + "type": "str", + "line": 38 }, { - "name": "http_status", - "type": "int", - "default": "" + "name": "warnings", + "type": "tuple[str, ...]", + "line": 39 }, { - "name": "warnings", - "type": "list[dict[str, str]]", - "default": "" + "name": "stale", + "type": "bool", + "line": 40 } ], - "line": 343, - "doc": "" + "line": 35 }, { - "name": "PostedNotice", + "name": "LocalIntegrationAdapter", "bases": [], "fields": [ { - "name": "id", + "name": "provider", "type": "str", - "default": "" + "line": 44 }, { - "name": "result", - "type": "NoticeComplianceResult", - "default": "" + "name": "dependency", + "type": "str | None", + "line": 45 } ], - "line": 372, - "doc": "" + "line": 43 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_meetings/prompt_evals.py", - "sha256": "0c47c06b36500ae63a0ad9dda52edd4baadd8688010714701b6228d6ccca21bd", - "routes": [], + "source": "townlight_zoning/main.py", + "sha256": "90e869902f36672be17516e85aca88a348e37d2942243deb415cb5f6018f7183", + "bytes": 27978, + "routes": [ + { + "method": "GET", + "declared_path": "/", + "function": "root", + "line": 74 + }, + { + "method": "GET", + "declared_path": "/health", + "function": "health", + "line": 92 + }, + { + "method": "GET", + "declared_path": "/townlight_zoning", + "function": "public_townlight_zoning_page", + "line": 104 + }, + { + "method": "GET", + "declared_path": "/townlight_zoning/staff", + "function": "staff_townlight_zoning_page", + "line": 111 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_zoning/parcels/lookup", + "function": "parcel_lookup", + "line": 220 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_zoning/rules/use", + "function": "use_rule_lookup", + "line": 246 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_zoning/rules/dimensional", + "function": "dimensional_rule_lookup", + "line": 261 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_zoning/standards/process-explanation", + "function": "discretionary_explanation", + "line": 283 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_zoning/questions/answer", + "function": "zone_question_answer", + "line": 353 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_zoning/planner-review/classify", + "function": "planner_review_classify", + "line": 378 + }, + { + "method": "GET", + "declared_path": "/api/v1/townlight_zoning/staff/precedents/{precedent_id}", + "function": "staff_precedent", + "line": 384 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_zoning/staff/questions/answer", + "function": "staff_question_answer", + "line": 402 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_zoning/staff/ambiguity-reviews", + "function": "create_ambiguity_review", + "line": 415 + }, + { + "method": "GET", + "declared_path": "/api/v1/townlight_zoning/staff/ambiguity-reviews", + "function": "list_ambiguity_reviews", + "line": 429 + }, + { + "method": "PATCH", + "declared_path": "/api/v1/townlight_zoning/staff/ambiguity-reviews/{item_id}", + "function": "update_ambiguity_review", + "line": 443 + }, + { + "method": "GET", + "declared_path": "/api/v1/townlight_zoning/staff/questions/analytics", + "function": "staff_question_analytics", + "line": 472 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_zoning/staff/reports/outline", + "function": "staff_report_outline", + "line": 496 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_zoning/staff/flagged-answers", + "function": "create_flagged_answer_review", + "line": 520 + }, + { + "method": "PATCH", + "declared_path": "/api/v1/townlight_zoning/staff/flagged-answers/{review_id}/improve", + "function": "improve_flagged_answer_review", + "line": 536 + } + ], "models": [ { - "name": "PromptEvalResult", + "name": "StaffPrincipal", "bases": [], "fields": [ { - "name": "prompt_reference", - "type": "str", - "default": "" - }, - { - "name": "provider", + "name": "subject", "type": "str", - "default": "" - }, - { - "name": "offline", - "type": "bool", - "default": "" - }, - { - "name": "passed", - "type": "bool", - "default": "" + "line": 69 }, { - "name": "message", - "type": "str", - "default": "" + "name": "roles", + "type": "tuple[str, ...]", + "line": 70 } ], - "line": 17, - "doc": "" - } - ], - "configuration": [ - { - "variable": "TOWNLIGHT_CORE_LLM_PROVIDER", - "default": "''", - "line": 128 + "line": 68 }, { - "variable": "TOWNLIGHT_MEETINGS_EVAL_OFFLINE", - "default": "", - "line": 129 - } - ] - }, - { - "source": "installed-owned-source/townlight_meetings/prompt_library.py", - "sha256": "433e349bb9c768d37359bae0a68c89715337da8f363ddaec5a62f37bddd563d9", - "routes": [], - "models": [ - { - "name": "PromptEvaluation", - "bases": [], + "name": "ParcelLookupRequest", + "bases": [ + "BaseModel" + ], "fields": [ { - "name": "name", - "type": "str", - "default": "" + "name": "parcel_number", + "type": "str | None", + "line": 118 }, { - "name": "required_phrases", - "type": "tuple[str, ...]", - "default": "" + "name": "address", + "type": "str | None", + "line": 119 } ], - "line": 34, - "doc": "" + "line": 117 }, { - "name": "PromptDefinition", - "bases": [], + "name": "UseRuleLookupRequest", + "bases": [ + "BaseModel" + ], "fields": [ { - "name": "id", + "name": "zone_code", "type": "str", - "default": "" + "line": 123 }, { - "name": "version", + "name": "use", "type": "str", - "default": "" - }, + "line": 124 + } + ], + "line": 122 + }, + { + "name": "DimensionalRuleLookupRequest", + "bases": [ + "BaseModel" + ], + "fields": [ { - "name": "provider", + "name": "zone_code", "type": "str", - "default": "" + "line": 128 }, { - "name": "purpose", + "name": "rule_type", "type": "str", - "default": "" - }, - { - "name": "required_variables", - "type": "tuple[str, ...]", - "default": "" - }, + "line": 129 + } + ], + "line": 127 + }, + { + "name": "ZoneQuestionRequest", + "bases": [ + "BaseModel" + ], + "fields": [ { - "name": "system_prompt", + "name": "zone_code", "type": "str", - "default": "" + "line": 133 }, { - "name": "template", + "name": "question", "type": "str", - "default": "" - }, - { - "name": "evaluations", - "type": "tuple[PromptEvaluation, ...]", - "default": "" - }, - { - "name": "public_facing", - "type": "bool", - "default": "False" - }, - { - "name": "approval_required", - "type": "str | None", - "default": "None" + "line": 134 } ], - "line": 40, - "doc": "" - } - ], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_meetings/public_archive.py", - "sha256": "389d714ee91ef1c4b0cbf49d960894bba49787232a29537ddaebcb9eecbe06b9", - "routes": [], - "models": [ + "line": 132 + }, { - "name": "PublicMeetingRecord", - "bases": [], + "name": "PlannerReviewRequest", + "bases": [ + "BaseModel" + ], "fields": [ { - "name": "id", + "name": "question", "type": "str", - "default": "" - }, + "line": 138 + } + ], + "line": 137 + }, + { + "name": "StaffQuestionAnswerRequest", + "bases": [ + "BaseModel" + ], + "fields": [ { - "name": "meeting_id", + "name": "zone_code", "type": "str", - "default": "" + "line": 142 }, { - "name": "title", + "name": "question", "type": "str", - "default": "" - }, + "line": 143 + } + ], + "line": 141 + }, + { + "name": "AmbiguityReviewCreateRequest", + "bases": [ + "BaseModel" + ], + "fields": [ { - "name": "visibility", + "name": "zone_code", "type": "str", - "default": "" + "line": 147 }, { - "name": "posted_agenda", + "name": "question", "type": "str", - "default": "" + "line": 148 }, { - "name": "posted_packet", + "name": "reason", "type": "str", - "default": "" - }, + "line": 149 + } + ], + "line": 146 + }, + { + "name": "AmbiguityReviewUpdateRequest", + "bases": [ + "BaseModel" + ], + "fields": [ { - "name": "approved_minutes", + "name": "status", "type": "str", - "default": "" + "line": 153 }, { - "name": "public_comment_enabled", - "type": "bool", - "default": "False" + "name": "assigned_to", + "type": "str | None", + "line": 154 }, { - "name": "plain_language_summary", - "type": "str | None", - "default": "None" + "name": "resolution", + "type": "str | None", + "line": 155 + } + ], + "line": 152 + }, + { + "name": "StaffReportOutlineRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "title", + "type": "str", + "line": 159 }, { - "name": "agenda_download_url", - "type": "str | None", - "default": "None" + "name": "question_ids", + "type": "list[str]", + "line": 160 }, { - "name": "packet_download_url", - "type": "str | None", - "default": "None" - }, + "name": "queue_item_ids", + "type": "list[str]", + "line": 161 + } + ], + "line": 158 + }, + { + "name": "FlaggedAnswerCreateRequest", + "bases": [ + "BaseModel" + ], + "fields": [ { - "name": "minutes_download_url", - "type": "str | None", - "default": "None" + "name": "zone_code", + "type": "str", + "line": 165 }, { - "name": "minutes_adopted_at", - "type": "str | None", - "default": "None" + "name": "question", + "type": "str", + "line": 166 }, { - "name": "minutes_signed_by", - "type": "str | None", - "default": "None" + "name": "original_answer", + "type": "str", + "line": 167 }, { - "name": "closed_session_notes", - "type": "str | None", - "default": "None" + "name": "flag_reason", + "type": "str", + "line": 168 }, { - "name": "audit_entries", - "type": "list[dict]", - "default": "field(default_factory=list)" + "name": "citations", + "type": "list[str]", + "line": 169 } ], - "line": 27, - "doc": "" + "line": 164 }, { - "name": "PublicCommentRecord", - "bases": [], + "name": "FlaggedAnswerImproveRequest", + "bases": [ + "BaseModel" + ], "fields": [ { - "name": "id", + "name": "improved_answer", "type": "str", - "default": "" + "line": 173 }, { - "name": "public_record_id", + "name": "improvement_notes", "type": "str", - "default": "" - }, + "line": 174 + } + ], + "line": 172 + }, + { + "name": "DiscretionaryExplanationRequest", + "bases": [ + "BaseModel" + ], + "fields": [ { - "name": "commenter_name", + "name": "process_section", "type": "str", - "default": "" + "line": 275 }, { - "name": "comment", + "name": "question", "type": "str", - "default": "" + "line": 276 }, { - "name": "submitted_at", + "name": "zone_code", "type": "str", - "default": "" + "line": 277 }, { - "name": "status", - "type": "str", - "default": "'RECEIVED'" + "name": "rule_types", + "type": "list[str]", + "line": 278 + }, + { + "name": "observed", + "type": "dict[str, str]", + "line": 279 } ], - "line": 69, - "doc": "" + "line": 274 } ], + "configuration": [ + { + "environment": "TOWNLIGHT_ZONING_PARCEL_RULE_DB_URL", + "line": 559 + } + ] + }, + { + "source": "townlight_zoning/migrations/__init__.py", + "sha256": "5b0db2ee33fc0c4091e615e58fc97420e861a39c50b7a37a090ba8e117c9869e", + "bytes": 43, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_zoning/migrations/alembic.ini", + "sha256": "d5dee873fc4cceb1d53bfae71f8fbed319dd4c1b93934e35cbb271d3b97c9c08", + "bytes": 580, + "routes": [], + "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_meetings/public_ui.py", - "sha256": "4359447b52c4499727fa1d62f385e778154a4243af716cd2fb828e30af6f5db0", + "source": "townlight_zoning/migrations/env.py", + "sha256": "5d437b18f5267667c260fe384f6617648d57d940e2d3a91de05b79aa87598e21", + "bytes": 2206, + "routes": [], + "models": [], + "configuration": [ + { + "environment": "DATABASE_URL", + "line": 22 + } + ] + }, + { + "source": "townlight_zoning/migrations/guards.py", + "sha256": "6dff39d29a7936155d1bd5e3ff9b84e09548beeff7a031cdf1172a6855128398", + "bytes": 543, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_meetings/records_sources.py", - "sha256": "843b4808e4a335ab05a7801a33a3a5750dc49ce84d7e71961841e91e7532598f", + "source": "townlight_zoning/migrations/versions/__init__.py", + "sha256": "6529bd8ce272c2c512ceda3ababea3a9d17dc04e8842f3a7f991657e1c7a8d72", + "bytes": 44, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_meetings/staff_ui.py", - "sha256": "158329afdeafeb52619ae70bb78cdc731a1cc65f21b31494e3cafd2884b5bdb3", + "source": "townlight_zoning/migrations/versions/townlight_zoning_0001_schema.py", + "sha256": "c0a1010064afac0904ec92314f0c03c6820a360e75f36df523962226008fd2bf", + "bytes": 5813, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_meetings/suite_session_compat.py", - "sha256": "6b7cfc7719b722eb7da68fa137c3996d64f237d313ef925ba340f6c39d74474e", + "source": "townlight_zoning/migrations/versions/townlight_zoning_0002_parcel_rule_lookup_records.py", + "sha256": "1a69bdf0eee9bd044ca970eb5ea23eb72abb778dbf313c9c53cb00ca57f374ab", + "bytes": 2733, "routes": [], - "models": [ - { - "name": "SuiteSessionPrincipal", - "bases": [], - "fields": [ - { - "name": "subject", - "type": "str", - "default": "" - }, - { - "name": "roles", - "type": "frozenset[str]", - "default": "" - }, - { - "name": "session_id", - "type": "str", - "default": "" - } - ], - "line": 28, - "doc": "Validated TownlightCore suite session principal." - } - ], + "models": [], + "configuration": [] + }, + { + "source": "townlight_zoning/migrations/versions/townlight_zoning_0003_question_ledger.py", + "sha256": "5161cc3504e7be2f7b59c893d7d94f2fc42ab141b501b01c745c86833d9cc943", + "bytes": 1372, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_zoning/migrations/versions/townlight_zoning_0004_staff_workflows.py", + "sha256": "a6101844d74baca978f82703ceedcaa817452cb2bcabe20cb6863fdd8d8714ef", + "bytes": 3447, + "routes": [], + "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_meetings/transcripts.py", - "sha256": "33d5b6f97ce58b6f645e0c236a53a855c358d01db06ee048ec9c90100474bc98", + "source": "townlight_zoning/migrations/versions/townlight_zoning_0005_geo_import.py", + "sha256": "e0a14dadd86311b9af7e66c34c33d94ea9b3a2489c59c3b188b870e77ba48c6f", + "bytes": 3920, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_meetings/vendor_delta.py", - "sha256": "cebd1ffb95726fd5beb874fbfd9726555681e6c35be7957b97dda26a69898cd3", + "source": "townlight_zoning/migrations/versions/townlight_zoning_0006_cited_questions.py", + "sha256": "5195cf011c8c384b5c0a3b7cf7abc1b3414f59dc8e92a37c5248c6f8dfada527", + "bytes": 2398, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_meetings/vendor_live_sync.py", - "sha256": "0a5048436302ad12e21d822952705ae754ed0ca7a76a7ea9080b292cc2489ab5", + "source": "townlight_zoning/models.py", + "sha256": "bdbc7553151a8bd14d24bd9f50a929087a08fa9ce8a17cd8398cd665753aee93", + "bytes": 6251, "routes": [], "models": [ { - "name": "LiveSyncCheck", + "name": "TimestampMixin", "bases": [], "fields": [ { - "name": "status", - "type": "Literal['PASS', 'FAIL']", - "default": "" + "name": "created_at", + "type": "Mapped[object]", + "line": 13 + }, + { + "name": "updated_at", + "type": "Mapped[object]", + "line": 16 + } + ], + "line": 12 + }, + { + "name": "IdMixin", + "bases": [], + "fields": [ + { + "name": "id", + "type": "Mapped[uuid.UUID]", + "line": 22 + } + ], + "line": 21 + }, + { + "name": "Zone", + "bases": [ + "IdMixin", + "TimestampMixin", + "Base" + ], + "fields": [ + { + "name": "__table_args__", + "type": "ClassVar[dict]", + "line": 29 + }, + { + "name": "code", + "type": "Mapped[str]", + "line": 31 }, { "name": "name", - "type": "str", - "default": "" + "type": "Mapped[str]", + "line": 32 }, { - "name": "message", - "type": "str", - "default": "" + "name": "description", + "type": "Mapped[str | None]", + "line": 33 }, { - "name": "fix", - "type": "str", - "default": "" + "name": "jurisdiction", + "type": "Mapped[str]", + "line": 34 + }, + { + "name": "source_section_ref", + "type": "Mapped[str | None]", + "line": 35 + }, + { + "name": "is_active", + "type": "Mapped[bool]", + "line": 36 } ], - "line": 49, - "doc": "" + "line": 27 }, { - "name": "VendorLiveSyncConfig", - "bases": [], + "name": "Overlay", + "bases": [ + "IdMixin", + "TimestampMixin", + "Base" + ], "fields": [ { - "name": "connector", - "type": "str", - "default": "" + "name": "__table_args__", + "type": "ClassVar[dict]", + "line": 41 }, { - "name": "source_url", - "type": "str", - "default": "" + "name": "code", + "type": "Mapped[str]", + "line": 43 }, { - "name": "auth_method", - "type": "AuthMethod", - "default": "" + "name": "name", + "type": "Mapped[str]", + "line": 44 + }, + { + "name": "description", + "type": "Mapped[str | None]", + "line": 45 + }, + { + "name": "source_section_ref", + "type": "Mapped[str | None]", + "line": 46 + }, + { + "name": "is_active", + "type": "Mapped[bool]", + "line": 47 } ], - "line": 57, - "doc": "" - } - ], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_meetings/vendor_network_sync.py", - "sha256": "cf3a9c14de83f76b8deb87aabfaeb43e93bca98f26a65183f1dd4001a3df91e1", - "routes": [], - "models": [ + "line": 39 + }, { - "name": "VendorNetworkSyncAttempt", - "bases": [], + "name": "Parcel", + "bases": [ + "IdMixin", + "TimestampMixin", + "Base" + ], "fields": [ { - "name": "ok", - "type": "bool", - "default": "" + "name": "__table_args__", + "type": "ClassVar[dict]", + "line": 52 }, { - "name": "message", - "type": "str", - "default": "" + "name": "parcel_number", + "type": "Mapped[str]", + "line": 54 + }, + { + "name": "address", + "type": "Mapped[str]", + "line": 55 + }, + { + "name": "zone_id", + "type": "Mapped[uuid.UUID]", + "line": 56 }, { - "name": "fix", - "type": "str", - "default": "" + "name": "overlay_payload", + "type": "Mapped[dict]", + "line": 57 }, { - "name": "external_meeting_id", - "type": "str | None", - "default": "None" + "name": "geometry_ref", + "type": "Mapped[str | None]", + "line": 58 }, { - "name": "error_class", - "type": "str | None", - "default": "None" + "name": "source_payload", + "type": "Mapped[dict]", + "line": 59 } ], - "line": 31, - "doc": "" + "line": 50 }, { - "name": "VendorNetworkSyncReport", - "bases": [], + "name": "UseCategory", + "bases": [ + "IdMixin", + "TimestampMixin", + "Base" + ], "fields": [ { - "name": "source_id", - "type": "str", - "default": "" + "name": "__table_args__", + "type": "ClassVar[dict]", + "line": 64 }, { - "name": "connector", - "type": "str", - "default": "" + "name": "code", + "type": "Mapped[str]", + "line": 66 }, { - "name": "network_calls", - "type": "bool", - "default": "" + "name": "label", + "type": "Mapped[str]", + "line": 67 }, { - "name": "records_discovered", - "type": "int", - "default": "" + "name": "description", + "type": "Mapped[str | None]", + "line": 68 + } + ], + "line": 62 + }, + { + "name": "UseRule", + "bases": [ + "IdMixin", + "TimestampMixin", + "Base" + ], + "fields": [ + { + "name": "__table_args__", + "type": "ClassVar[dict]", + "line": 73 }, { - "name": "records_succeeded", - "type": "int", - "default": "" + "name": "zone_id", + "type": "Mapped[uuid.UUID]", + "line": 75 }, { - "name": "records_failed", - "type": "int", - "default": "" + "name": "use_category_id", + "type": "Mapped[uuid.UUID]", + "line": 76 }, { - "name": "run_status", - "type": "str | None", - "default": "" + "name": "status", + "type": "Mapped[str]", + "line": 79 }, { - "name": "source_health_status", - "type": "str | None", - "default": "" + "name": "review_path", + "type": "Mapped[str | None]", + "line": 80 }, { - "name": "delta_request_url", - "type": "str | None", - "default": "" + "name": "source_section_ref", + "type": "Mapped[str | None]", + "line": 81 }, { - "name": "cursor_param", - "type": "str | None", - "default": "" + "name": "conditions", + "type": "Mapped[dict]", + "line": 82 + } + ], + "line": 71 + }, + { + "name": "DimensionalRule", + "bases": [ + "IdMixin", + "TimestampMixin", + "Base" + ], + "fields": [ + { + "name": "__table_args__", + "type": "ClassVar[dict]", + "line": 87 }, { - "name": "cursor_value", - "type": "str | None", - "default": "" + "name": "zone_id", + "type": "Mapped[uuid.UUID]", + "line": 89 }, { - "name": "cursor_advanced_at", - "type": "str | None", - "default": "" + "name": "rule_type", + "type": "Mapped[str]", + "line": 90 }, { - "name": "message", - "type": "str", - "default": "" + "name": "value_text", + "type": "Mapped[str]", + "line": 91 }, { - "name": "fix", - "type": "str", - "default": "" + "name": "source_section_ref", + "type": "Mapped[str | None]", + "line": 92 }, { - "name": "attempts", - "type": "list[VendorNetworkSyncAttempt]", - "default": "" + "name": "applies_to", + "type": "Mapped[str | None]", + "line": 93 } ], - "line": 40, - "doc": "" - } - ], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_meetings/vendor_sync_persistence.py", - "sha256": "f719849f9cd2e1c667bc61f501dc281bf0efe26646e230b0b5b786afcb082d9b", - "routes": [], - "models": [ + "line": 85 + }, { - "name": "VendorSyncSourceRecord", - "bases": [], + "name": "Citation", + "bases": [ + "IdMixin", + "TimestampMixin", + "Base" + ], "fields": [ { - "name": "id", - "type": "str", - "default": "" + "name": "__table_args__", + "type": "ClassVar[dict]", + "line": 98 }, { - "name": "connector", - "type": "str", - "default": "" + "name": "source_section_ref", + "type": "Mapped[str]", + "line": 100 }, { - "name": "source_name", - "type": "str", - "default": "" + "name": "citation_text", + "type": "Mapped[str]", + "line": 101 }, { - "name": "source_url", - "type": "str", - "default": "" + "name": "url", + "type": "Mapped[str | None]", + "line": 102 }, { - "name": "auth_method", - "type": "str", - "default": "" - }, + "name": "retrieved_at", + "type": "Mapped[object | None]", + "line": 103 + } + ], + "line": 96 + }, + { + "name": "Precedent", + "bases": [ + "IdMixin", + "TimestampMixin", + "Base" + ], + "fields": [ { - "name": "consecutive_failure_count", - "type": "int", - "default": "" + "name": "__table_args__", + "type": "ClassVar[dict]", + "line": 108 }, { - "name": "active_failure_count", - "type": "int", - "default": "" + "name": "title", + "type": "Mapped[str]", + "line": 110 }, { - "name": "sync_paused", - "type": "bool", - "default": "" + "name": "body", + "type": "Mapped[str]", + "line": 111 }, { - "name": "sync_paused_at", - "type": "datetime | None", - "default": "" + "name": "visibility", + "type": "Mapped[str]", + "line": 112 }, { - "name": "sync_paused_reason", - "type": "str | None", - "default": "" + "name": "source_ref", + "type": "Mapped[str | None]", + "line": 113 }, { - "name": "last_sync_status", - "type": "str | None", - "default": "" + "name": "tags", + "type": "Mapped[dict]", + "line": 114 + } + ], + "line": 106 + }, + { + "name": "InterpretationNote", + "bases": [ + "IdMixin", + "TimestampMixin", + "Base" + ], + "fields": [ + { + "name": "__table_args__", + "type": "ClassVar[dict]", + "line": 119 }, { - "name": "last_error_at", - "type": "datetime | None", - "default": "" + "name": "zone_id", + "type": "Mapped[uuid.UUID | None]", + "line": 121 }, { - "name": "last_success_cursor_at", - "type": "datetime | None", - "default": "" + "name": "note_text", + "type": "Mapped[str]", + "line": 122 }, { - "name": "created_at", - "type": "datetime", - "default": "" + "name": "visibility", + "type": "Mapped[str]", + "line": 123 }, { - "name": "updated_at", - "type": "datetime", - "default": "" + "name": "status", + "type": "Mapped[str]", + "line": 124 } ], - "line": 81, - "doc": "" + "line": 117 }, { - "name": "VendorSyncRunRecord", - "bases": [], + "name": "ZoneQuestion", + "bases": [ + "IdMixin", + "TimestampMixin", + "Base" + ], "fields": [ { - "name": "id", - "type": "str", - "default": "" - }, - { - "name": "source_id", - "type": "str", - "default": "" - }, - { - "name": "status", - "type": "str", - "default": "" - }, - { - "name": "records_discovered", - "type": "int", - "default": "" + "name": "__table_args__", + "type": "ClassVar[dict]", + "line": 129 }, { - "name": "records_succeeded", - "type": "int", - "default": "" + "name": "question_text", + "type": "Mapped[str]", + "line": 131 }, { - "name": "records_failed", - "type": "int", - "default": "" + "name": "audience", + "type": "Mapped[str]", + "line": 132 }, { - "name": "retries_attempted", - "type": "int", - "default": "" + "name": "status", + "type": "Mapped[str]", + "line": 133 }, { - "name": "error_summary", - "type": "str | None", - "default": "" + "name": "answer_text", + "type": "Mapped[str | None]", + "line": 134 }, { - "name": "started_at", - "type": "datetime", - "default": "" + "name": "citation_payload", + "type": "Mapped[dict]", + "line": 135 }, { - "name": "finished_at", - "type": "datetime", - "default": "" + "name": "escalation_reason", + "type": "Mapped[str | None]", + "line": 136 } ], - "line": 140, - "doc": "" + "line": 127 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_meetings/worker.py", - "sha256": "6e0aa475591252a06401a613e85d402c8981bdaaf23b460f30b442efbdd43a9b", + "source": "townlight_zoning/parcel_lookup.py", + "sha256": "45703bbce2f91f8c6f2b86b3571314d6bafeaf58ba6965b6a7e9c7e3b01b925f", + "bytes": 6367, "routes": [], - "models": [], - "configuration": [ - { - "variable": "TOWNLIGHT_MEETINGS_REDIS_URL", - "default": "'redis://redis:6379/0'", - "line": 46 - } - ] - } - ], - "bridge": [ - { - "source": "installed-owned-source/townlight_runtime/meetings_bridge.py", - "sha256": "37ea43e633b55e9428e928143e5da0d41a7a5906673b8cc54b40fa4d1748fa52", - "routes": [ - { - "method": "POST", - "path": "/desktop/v1/meetings/meetings/{meeting_id}/stages", - "router": "router", - "prefix_resolved": true, - "name": "record_meeting_stage", - "signature": "meeting_id: UUID, data: MeetingStageInput, actor_id: str=Depends(actor)", - "returns": "", - "line": 106, - "doc": "", - "decorator": "router.post('/meetings/{meeting_id}/stages')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/meetings/meetings", - "router": "router", - "prefix_resolved": true, - "name": "create_meeting", - "signature": "data: MeetingInput, actor_id: str=Depends(actor)", - "returns": "", - "line": 128, - "doc": "", - "decorator": "router.post('/meetings', status_code=201)", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/meetings/meetings/{meeting_id}", - "router": "router", - "prefix_resolved": true, - "name": "get_meeting", - "signature": "meeting_id: UUID, actor_id: str=Depends(actor)", - "returns": "", - "line": 136, - "doc": "", - "decorator": "router.get('/meetings/{meeting_id}')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/meetings/agenda-items", - "router": "router", - "prefix_resolved": true, - "name": "create_agenda_item", - "signature": "data: AgendaInput, actor_id: str=Depends(actor)", - "returns": "", - "line": 141, - "doc": "", - "decorator": "router.post('/agenda-items', status_code=201)", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/meetings/agenda-items/{item_id}", - "router": "router", - "prefix_resolved": true, - "name": "get_agenda_item", - "signature": "item_id: UUID, actor_id: str=Depends(actor)", - "returns": "", - "line": 148, - "doc": "", - "decorator": "router.get('/agenda-items/{item_id}')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/meetings/agenda-items/{item_id}/reviews", - "router": "router", - "prefix_resolved": true, - "name": "record_agenda_review", - "signature": "item_id: UUID, data: AgendaReviewInput, actor_id: str=Depends(actor)", - "returns": "", - "line": 164, - "doc": "", - "decorator": "router.post('/agenda-items/{item_id}/reviews')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/meetings/agenda-items/{item_id}/meeting", - "router": "router", - "prefix_resolved": true, - "name": "assign_agenda", - "signature": "item_id: UUID, data: AgendaAssignment, actor_id: str=Depends(actor)", - "returns": "", - "line": 170, - "doc": "", - "decorator": "router.post('/agenda-items/{item_id}/meeting')", - "errors": [ - "HTTPException(409, str(error))" - ] - }, - { - "method": "GET", - "path": "/desktop/v1/meetings/notices/{notice_id}/template", - "router": "router", - "prefix_resolved": true, - "name": "notice_template", - "signature": "notice_id: UUID, actor_id: str=Depends(actor)", - "returns": "", - "line": 249, - "doc": "", - "decorator": "router.get('/notices/{notice_id}/template')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/meetings/notices/{notice_id}/document", - "router": "router", - "prefix_resolved": true, - "name": "notice_document", - "signature": "notice_id: UUID, data: NoticeDocumentInput, actor_id: str=Depends(actor)", - "returns": "", - "line": 264, - "doc": "", - "decorator": "router.post('/notices/{notice_id}/document')", - "errors": [ - "HTTPException(404, 'Notice not found.')", - "HTTPException(422, 'Notice delivery not confirmed; existing documents were retained.')", - "HTTPException(503, 'Notice history write not confirmed; read saved work before retrying.')" - ] - }, - { - "method": "POST", - "path": "/desktop/v1/meetings/meetings/{meeting_id}/notice-checks", - "router": "router", - "prefix_resolved": true, - "name": "check_notice", - "signature": "meeting_id: UUID, data: NoticeInput, actor_id: str=Depends(actor)", - "returns": "", - "line": 278, - "doc": "", - "decorator": "router.post('/meetings/{meeting_id}/notice-checks', status_code=201)", - "errors": [ - "HTTPException(422, 'A scheduled start is needed to calculate a notice deadline.')" - ] - }, - { - "method": "POST", - "path": "/desktop/v1/meetings/notices/{notice_id}/proof", - "router": "router", - "prefix_resolved": true, - "name": "record_notice_proof", - "signature": "notice_id: UUID, data: NoticeProofInput, actor_id: str=Depends(actor)", - "returns": "", - "line": 295, - "doc": "", - "decorator": "router.post('/notices/{notice_id}/proof')", - "errors": [ - "HTTPException(422, str(error))" - ] - }, - { - "method": "POST", - "path": "/desktop/v1/meetings/meetings/{meeting_id}/transcripts", - "router": "router", - "prefix_resolved": true, - "name": "capture_transcript", - "signature": "meeting_id: UUID, data: TranscriptInput, actor_id: str=Depends(actor)", - "returns": "", - "line": 332, - "doc": "", - "decorator": "router.post('/meetings/{meeting_id}/transcripts', status_code=201)", - "errors": [ - "HTTPException(422, str(error))" - ] - }, - { - "method": "POST", - "path": "/desktop/v1/meetings/meetings/{meeting_id}/action-items", - "router": "router", - "prefix_resolved": true, - "name": "capture_action_item", - "signature": "meeting_id: UUID, data: ActionItemInput, actor_id: str=Depends(actor)", - "returns": "", - "line": 344, - "doc": "", - "decorator": "router.post('/meetings/{meeting_id}/action-items', status_code=201)", - "errors": [ - "HTTPException(422, 'Motion belongs to another meeting.')" - ] - }, - { - "method": "POST", - "path": "/desktop/v1/meetings/meetings/{meeting_id}/archive", - "router": "router", - "prefix_resolved": true, - "name": "archive_meeting", - "signature": "meeting_id: UUID, data: ArchiveInput, actor_id: str=Depends(actor)", - "returns": "", - "line": 356, - "doc": "", - "decorator": "router.post('/meetings/{meeting_id}/archive', status_code=201)", - "errors": [ - "HTTPException(422, 'Packet belongs to another meeting.')", - "HTTPException(422, 'Minutes belong to another meeting.')" - ] - }, - { - "method": "GET", - "path": "/public/meetings", - "router": "public_router", - "prefix_resolved": true, - "name": "public_archive_index", - "signature": "q: str=''", - "returns": "", - "line": 399, - "doc": "", - "decorator": "public_router.get('', response_class=HTMLResponse, dependencies=[Depends(public_active)])", - "errors": [] - }, - { - "method": "GET", - "path": "/public/meetings/{record_id}", - "router": "public_router", - "prefix_resolved": true, - "name": "public_archive_detail", - "signature": "record_id: UUID", - "returns": "", - "line": 407, - "doc": "", - "decorator": "public_router.get('/{record_id}', response_class=HTMLResponse, dependencies=[Depends(public_active)])", - "errors": [] - }, - { - "method": "GET", - "path": "/public/meetings/{record_id}/{kind}.txt", - "router": "public_router", - "prefix_resolved": true, - "name": "public_archive_download", - "signature": "record_id: UUID, kind: Literal['agenda', 'packet', 'minutes']", - "returns": "", - "line": 417, - "doc": "", - "decorator": "public_router.get('/{record_id}/{kind}.txt', dependencies=[Depends(public_active)])", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/meetings/meetings/{meeting_id}/packet-snapshots", - "router": "router", - "prefix_resolved": true, - "name": "capture_packet", - "signature": "meeting_id: UUID, data: PacketInput, actor_id: str=Depends(actor)", - "returns": "", - "line": 441, - "doc": "", - "decorator": "router.post('/meetings/{meeting_id}/packet-snapshots', status_code=201)", - "errors": [ - "HTTPException(422, str(error))" - ] - }, - { - "method": "POST", - "path": "/desktop/v1/meetings/packets/{packet_id}/deliver", - "router": "router", - "prefix_resolved": true, - "name": "export_packet", - "signature": "packet_id: UUID, actor_id: str=Depends(actor)", - "returns": "", - "line": 462, - "doc": "", - "decorator": "router.post('/packets/{packet_id}/deliver')", - "errors": [ - "HTTPException(404, 'Packet not found.')", - "HTTPException(422, str(error))", - "HTTPException(503, 'Packet delivery not confirmed. Inspect saved work before retrying.')" - ] - }, - { - "method": "POST", - "path": "/desktop/v1/meetings/minutes/{draft_id}/decisions", - "router": "router", - "prefix_resolved": true, - "name": "decide_minutes", - "signature": "draft_id: UUID, data: MinutesDecision, actor_id: str=Depends(actor)", - "returns": "", - "line": 475, - "doc": "", - "decorator": "router.post('/minutes/{draft_id}/decisions')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/meetings/meetings/{meeting_id}/motions", - "router": "router", - "prefix_resolved": true, - "name": "capture_motion", - "signature": "meeting_id: UUID, data: MotionInput, actor_id: str=Depends(actor)", - "returns": "", - "line": 498, - "doc": "", - "decorator": "router.post('/meetings/{meeting_id}/motions', status_code=201)", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/meetings/motions/{motion_id}/corrections", - "router": "router", - "prefix_resolved": true, - "name": "correct_motion", - "signature": "motion_id: UUID, data: MotionCorrection, actor_id: str=Depends(actor)", - "returns": "", - "line": 505, - "doc": "", - "decorator": "router.post('/motions/{motion_id}/corrections', status_code=201)", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/meetings/motions/{motion_id}/votes", - "router": "router", - "prefix_resolved": true, - "name": "capture_vote", - "signature": "motion_id: UUID, data: VoteInput, actor_id: str=Depends(actor)", - "returns": "", - "line": 511, - "doc": "", - "decorator": "router.post('/motions/{motion_id}/votes', status_code=201)", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/meetings/votes/{vote_id}/corrections", - "router": "router", - "prefix_resolved": true, - "name": "correct_vote", - "signature": "vote_id: UUID, data: VoteCorrection, actor_id: str=Depends(actor)", - "returns": "", - "line": 517, - "doc": "", - "decorator": "router.post('/votes/{vote_id}/corrections', status_code=201)", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/meetings/meetings/{meeting_id}/minutes/drafts", - "router": "router", - "prefix_resolved": true, - "name": "create_minutes", - "signature": "meeting_id: UUID, data: DraftInput, actor_id: str=Depends(actor)", - "returns": "", - "line": 523, - "doc": "", - "decorator": "router.post('/meetings/{meeting_id}/minutes/drafts', status_code=201)", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/meetings/meetings/{meeting_id}/proceedings", - "router": "router", - "prefix_resolved": true, - "name": "proceedings", - "signature": "meeting_id: UUID, actor_id: str=Depends(actor)", - "returns": "", - "line": 532, - "doc": "", - "decorator": "router.get('/meetings/{meeting_id}/proceedings')", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/meetings/station/catalog", - "router": "router", - "prefix_resolved": true, - "name": "station_catalog", - "signature": "actor_id: str=Depends(actor)", - "returns": "", - "line": 552, - "doc": "Authorized name-based operator selection from canonical Meetings data.", - "decorator": "router.get('/station/catalog')", - "errors": [] - } - ], "models": [ { - "name": "MeetingInput", - "bases": [ - "BaseModel" - ], + "name": "ParcelLookupResult", + "bases": [], "fields": [ { - "name": "title", + "name": "parcel_number", "type": "str", - "default": "Field(min_length=1, max_length=255)" + "line": 13 }, { - "name": "scheduled_start", - "type": "AwareDatetime", - "default": "" + "name": "address", + "type": "str", + "line": 14 }, { - "name": "location", + "name": "zone_code", "type": "str", - "default": "Field(min_length=1, max_length=255)" + "line": 15 }, { - "name": "meeting_type", - "type": "Literal['regular', 'special', 'emergency', 'closed_session', 'executive']", - "default": "'regular'" - } - ], - "line": 83, - "doc": "" - }, - { - "name": "AgendaInput", - "bases": [ - "BaseModel" - ], - "fields": [ - { - "name": "title", + "name": "zone_name", "type": "str", - "default": "Field(min_length=1, max_length=500)" + "line": 16 }, { - "name": "department_name", - "type": "str", - "default": "Field(min_length=1, max_length=255)" - } - ], - "line": 91, - "doc": "" - }, - { - "name": "MeetingStageInput", - "bases": [ - "BaseModel" - ], - "fields": [ + "name": "overlays", + "type": "tuple[str, ...]", + "line": 17 + }, { - "name": "to_status", - "type": "Literal['SCHEDULED', 'NOTICED', 'PACKET_POSTED', 'IN_PROGRESS', 'RECESSED', 'ADJOURNED', 'TRANSCRIPT_READY', 'MINUTES_DRAFTED', 'MINUTES_POSTED', 'MINUTES_ADOPTED', 'MINUTES_SIGNED', 'ARCHIVED', 'CANCELLED']", - "default": "" + "name": "constraints", + "type": "tuple[str, ...]", + "line": 18 }, { - "name": "statutory_basis", - "type": "str | None", - "default": "None" - } - ], - "line": 97, - "doc": "" - }, - { - "name": "AgendaReviewInput", - "bases": [ - "BaseModel" - ], - "fields": [ + "name": "source", + "type": "str", + "line": 19 + }, { - "name": "to_status", - "type": "Literal['DRAFTED', 'SUBMITTED', 'DEPT_APPROVED', 'LEGAL_REVIEWED', 'CLERK_ACCEPTED', 'ON_AGENDA', 'IN_PACKET', 'POSTED', 'HEARD', 'DISPOSED', 'ARCHIVED']", - "default": "" + "name": "disclaimer", + "type": "str", + "line": 20 } ], - "line": 152, - "doc": "" + "line": 12 }, { - "name": "AgendaAssignment", - "bases": [ - "BaseModel" - ], + "name": "ParcelLookupError", + "bases": [], "fields": [ { - "name": "meeting_id", - "type": "UUID", - "default": "" + "name": "message", + "type": "str", + "line": 25 + }, + { + "name": "fix", + "type": "str", + "line": 26 } ], - "line": 158, - "doc": "" - }, + "line": 24 + } + ], + "configuration": [] + }, + { + "source": "townlight_zoning/public_ui.py", + "sha256": "494537866bf7b7198eef0cefa59d83c8ad6608ccc44b1c521a4b1a58a041a58c", + "bytes": 12835, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_zoning/qa.py", + "sha256": "adad43278cb57b3c83032117d46df2b48b919354cb92083162389993cfb29f85", + "bytes": 4699, + "routes": [], + "models": [ { - "name": "MotionInput", - "bases": [ - "BaseModel" - ], + "name": "ZoneAnswer", + "bases": [], "fields": [ { - "name": "text", + "name": "answer", "type": "str", - "default": "Field(min_length=1)" + "line": 17 }, { - "name": "seconded_by", - "type": "str | None", - "default": "Field(default=None, min_length=1)" - } - ], - "line": 178, - "doc": "" - }, - { - "name": "MotionCorrection", - "bases": [ - "BaseModel" - ], - "fields": [ + "name": "citations", + "type": "tuple[str, ...]", + "line": 18 + }, { - "name": "text", + "name": "status", "type": "str", - "default": "Field(min_length=1)" + "line": 19 }, { "name": "reason", "type": "str", - "default": "Field(min_length=1)" - } - ], - "line": 184, - "doc": "" - }, - { - "name": "VoteInput", - "bases": [ - "BaseModel" - ], - "fields": [ + "line": 20 + }, { - "name": "voter_name", + "name": "confidence", "type": "str", - "default": "Field(min_length=1)" + "line": 21 }, { - "name": "vote", + "name": "next_step", + "type": "str", + "line": 22 + }, + { + "name": "disclaimer", "type": "str", - "default": "Field(min_length=1)" + "line": 23 } ], - "line": 190, - "doc": "" - }, + "line": 16 + } + ], + "configuration": [] + }, + { + "source": "townlight_zoning/question_ledger.py", + "sha256": "7895c6ba5ec3eb4fba1666cf42ba131a389570c308237b01a91473b937c761b6", + "bytes": 4945, + "routes": [], + "models": [ { - "name": "VoteCorrection", - "bases": [ - "BaseModel" - ], + "name": "ZoneQuestionLedgerRecord", + "bases": [], "fields": [ { - "name": "vote", + "name": "id", "type": "str", - "default": "Field(min_length=1)" + "line": 33 }, { - "name": "reason", + "name": "zone_code", "type": "str", - "default": "Field(min_length=1)" - } - ], - "line": 196, - "doc": "" - }, - { - "name": "SourceInput", - "bases": [ - "BaseModel" - ], - "fields": [ + "line": 34 + }, { - "name": "source_id", + "name": "question_text", "type": "str", - "default": "Field(min_length=1)" + "line": 35 }, { - "name": "label", + "name": "audience", "type": "str", - "default": "Field(min_length=1)" + "line": 36 }, { - "name": "text", + "name": "status", "type": "str", - "default": "Field(min_length=1)" - } - ], - "line": 202, - "doc": "" - }, - { - "name": "SentenceInput", - "bases": [ - "BaseModel" - ], - "fields": [ + "line": 37 + }, { - "name": "text", + "name": "answer_text", + "type": "str | None", + "line": 38 + }, + { + "name": "citation_payload", + "type": "tuple[str, ...]", + "line": 39 + }, + { + "name": "disclaimer", "type": "str", - "default": "Field(min_length=1)" + "line": 40 }, { - "name": "citations", - "type": "list[str]", - "default": "Field(default_factory=list)" - } - ], - "line": 209, - "doc": "" - }, - { - "name": "DraftInput", - "bases": [ - "BaseModel" - ], - "fields": [ + "name": "escalation_reason", + "type": "str | None", + "line": 41 + }, { - "name": "source_materials", - "type": "list[SourceInput]", - "default": "Field(default_factory=list)" + "name": "created_at", + "type": "datetime", + "line": 42 }, { - "name": "sentences", - "type": "list[SentenceInput]", - "default": "Field(min_length=1)" + "name": "updated_at", + "type": "datetime", + "line": 43 } ], - "line": 215, - "doc": "" - }, + "line": 32 + } + ], + "configuration": [] + }, + { + "source": "townlight_zoning/rule_lookup.py", + "sha256": "b69c6e8a89cf2586b05984ccb6079164c75fa460c053fca546c3e771ea8c75f5", + "bytes": 9642, + "routes": [], + "models": [ { - "name": "MinutesDecision", - "bases": [ - "BaseModel" - ], + "name": "UseRuleResult", + "bases": [], "fields": [ { - "name": "action", - "type": "Literal['post', 'adopt', 'sign']", - "default": "" + "name": "zone_code", + "type": "str", + "line": 15 + }, + { + "name": "use", + "type": "str", + "line": 16 + }, + { + "name": "status", + "type": "str", + "line": 17 + }, + { + "name": "review_path", + "type": "str", + "line": 18 + }, + { + "name": "citation", + "type": "str", + "line": 19 }, { - "name": "note", + "name": "disclaimer", "type": "str", - "default": "''" + "line": 20 } ], - "line": 221, - "doc": "" + "line": 14 }, { - "name": "NoticeInput", - "bases": [ - "BaseModel" - ], + "name": "DimensionalRuleResult", + "bases": [], "fields": [ { - "name": "notice_type", - "type": "Literal['regular', 'special', 'emergency', 'closed_session', 'executive']", - "default": "" + "name": "zone_code", + "type": "str", + "line": 25 }, { - "name": "posted_at", - "type": "AwareDatetime", - "default": "" + "name": "rule_type", + "type": "str", + "line": 26 }, { - "name": "minimum_notice_hours", - "type": "int", - "default": "Field(ge=0)" + "name": "value", + "type": "str", + "line": 27 }, { - "name": "statutory_basis", - "type": "str | None", - "default": "None" + "name": "citation", + "type": "str", + "line": 28 }, { - "name": "approved_by", - "type": "str | None", - "default": "None" + "name": "disclaimer", + "type": "str", + "line": 29 } ], - "line": 227, - "doc": "" + "line": 24 }, { - "name": "NoticeProofInput", - "bases": [ - "BaseModel" - ], + "name": "RuleLookupError", + "bases": [], "fields": [ { - "name": "location", + "name": "message", "type": "str", - "default": "Field(min_length=1)" + "line": 34 }, { - "name": "note", + "name": "fix", "type": "str", - "default": "''" - }, - { - "name": "document_delivery_id", - "type": "str | None", - "default": "None" + "line": 35 } ], - "line": 236, - "doc": "" - }, + "line": 33 + } + ], + "configuration": [] + }, + { + "source": "townlight_zoning/staff_context.py", + "sha256": "50784c2b595741098e2de9d9ad90a7957607ae09839afe6167af13e38037c91c", + "bytes": 1368, + "routes": [], + "models": [ { - "name": "NoticeDocumentInput", - "bases": [ - "BaseModel" - ], + "name": "EscalationResult", + "bases": [], "fields": [ { - "name": "text", + "name": "status", "type": "str", - "default": "Field(min_length=1)" - } - ], - "line": 243, - "doc": "" - }, - { - "name": "PacketInput", - "bases": [ - "BaseModel" - ], - "fields": [ + "line": 10 + }, { - "name": "agenda_item_ids", - "type": "list[UUID]", - "default": "" + "name": "reason", + "type": "str", + "line": 11 }, { - "name": "source_files", - "type": "list['ManagedSource']", - "default": "Field(default_factory=list)" + "name": "next_step", + "type": "str", + "line": 12 } ], - "line": 303, - "doc": "" + "line": 9 }, { - "name": "TranscriptInput", - "bases": [ - "BaseModel" - ], + "name": "StaffPrecedent", + "bases": [], "fields": [ { - "name": "source_label", + "name": "title", "type": "str", - "default": "Field(min_length=1)" + "line": 17 }, { - "name": "transcript_text", + "name": "summary", "type": "str", - "default": "Field(min_length=1)" + "line": 18 }, { - "name": "correction_of_id", - "type": "UUID | None", - "default": "None" + "name": "visibility", + "type": "str", + "line": 19 } ], - "line": 309, - "doc": "" - }, + "line": 16 + } + ], + "configuration": [] + }, + { + "source": "townlight_zoning/staff_ui.py", + "sha256": "0b9f26845887662a88e643224360e3c89b11d0fbe88dcca0e865c57fecb623ee", + "bytes": 8358, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_zoning/staff_workflows.py", + "sha256": "620797c1132212795b703d5a452553be1d0b4f2ae73082e9b26c52615a95b498", + "bytes": 24606, + "routes": [], + "models": [ { - "name": "ActionItemInput", - "bases": [ - "BaseModel" - ], + "name": "CodeCrossReference", + "bases": [], "fields": [ { - "name": "description", + "name": "citation", "type": "str", - "default": "Field(min_length=1)" + "line": 81 }, { - "name": "assigned_to", - "type": "str | None", - "default": "None" + "name": "source", + "type": "str", + "line": 82 }, { - "name": "source_motion_id", - "type": "UUID | None", - "default": "None" + "name": "relevance", + "type": "str", + "line": 83 } ], - "line": 316, - "doc": "" + "line": 80 }, { - "name": "ArchiveInput", - "bases": [ - "BaseModel" - ], + "name": "StaffQuestionRecord", + "bases": [], "fields": [ { - "name": "visibility", - "type": "Literal['public', 'closed_session']", - "default": "" + "name": "id", + "type": "str", + "line": 88 }, { - "name": "packet_id", - "type": "UUID | None", - "default": "None" + "name": "zone_code", + "type": "str", + "line": 89 }, { - "name": "minutes_id", - "type": "UUID | None", - "default": "None" + "name": "question_text", + "type": "str", + "line": 90 }, { - "name": "plain_language_summary", + "name": "status", + "type": "str", + "line": 91 + }, + { + "name": "answer_text", + "type": "str", + "line": 92 + }, + { + "name": "citations", + "type": "tuple[str, ...]", + "line": 93 + }, + { + "name": "code_cross_references", + "type": "tuple[CodeCrossReference, ...]", + "line": 94 + }, + { + "name": "created_by", + "type": "str", + "line": 95 + }, + { + "name": "created_at", + "type": "datetime", + "line": 96 + }, + { + "name": "visibility", + "type": "str", + "line": 97 + }, + { + "name": "disclaimer", "type": "str", - "default": "''" + "line": 98 } ], - "line": 323, - "doc": "" + "line": 87 }, { - "name": "ManagedSource", - "bases": [ - "BaseModel" - ], + "name": "AmbiguityReviewItem", + "bases": [], "fields": [ { - "name": "original_path", + "name": "id", "type": "str", - "default": "" + "line": 103 }, { - "name": "stored_path", + "name": "zone_code", "type": "str", - "default": "" + "line": 104 }, { - "name": "file_name", + "name": "question_text", "type": "str", - "default": "" + "line": 105 }, { - "name": "sha256", + "name": "reason", "type": "str", - "default": "Field(pattern='^[0-9a-f]{64}$')" + "line": 106 }, { - "name": "size_bytes", - "type": "int", - "default": "Field(ge=0)" + "name": "status", + "type": "str", + "line": 107 + }, + { + "name": "assigned_to", + "type": "str | None", + "line": 108 + }, + { + "name": "resolution", + "type": "str | None", + "line": 109 + }, + { + "name": "source_question_id", + "type": "str | None", + "line": 110 + }, + { + "name": "created_by", + "type": "str", + "line": 111 + }, + { + "name": "created_at", + "type": "datetime", + "line": 112 + }, + { + "name": "updated_at", + "type": "datetime", + "line": 113 + }, + { + "name": "visibility", + "type": "str", + "line": 114 } ], - "line": 424, - "doc": "" - } - ], - "configuration": [ - { - "variable": "DATABASE_URL", - "default": "''", - "line": 38 + "line": 102 }, { - "variable": "TOWNLIGHT_PROFILE_ROOT", - "default": "", - "line": 434 - } - ] - } - ] - }, - "code": { - "package": "townlight_code", - "source": [ - { - "source": "installed-owned-source/townlight_code/__init__.py", - "sha256": "22abb4eaa2a94737461591a5b6f494bf7c4ad481b476fc3cf020fa090c97bcd8", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_code/ai_answer.py", - "sha256": "0d82f0c105e1b8102e0b640b97de85f95f79695cc6903008d56245ed79e6568d", - "routes": [], - "models": [ - { - "name": "LocalLLMConfig", + "name": "HighVolumeQuestion", "bases": [], "fields": [ { - "name": "provider", + "name": "zone_code", "type": "str", - "default": "" + "line": 119 + }, + { + "name": "question_text", + "type": "str", + "line": 120 + }, + { + "name": "count", + "type": "int", + "line": 121 }, { - "name": "base_url", - "type": "str", - "default": "" + "name": "statuses", + "type": "tuple[str, ...]", + "line": 122 }, { - "name": "model", + "name": "latest_question_id", "type": "str", - "default": "" - }, - { - "name": "timeout_seconds", - "type": "float", - "default": "" + "line": 123 } ], - "line": 18, - "doc": "" - } - ], - "configuration": [ - { - "variable": "TOWNLIGHT_CODE_OLLAMA_URL", - "default": "''", - "line": 28 - }, - { - "variable": "TOWNLIGHT_CODE_OLLAMA_TIMEOUT_SECONDS", - "default": "'20'", - "line": 35 - }, - { - "variable": "TOWNLIGHT_CODE_AI_MODE", - "default": "''", - "line": 27 + "line": 118 }, { - "variable": "TOWNLIGHT_CODE_OLLAMA_MODEL", - "default": "'gemma4:e4b'", - "line": 34 - } - ] - }, - { - "source": "installed-owned-source/townlight_code/citation_contract.py", - "sha256": "58e2cc3b8e05987a801a94c174ad34a8a7af18f684d367b08f097ab420ff3e37", - "routes": [], - "models": [ - { - "name": "CitationRefusal", + "name": "StaffQuestionAnalytics", "bases": [], "fields": [ { - "name": "reason", - "type": "str", - "default": "" + "name": "total_questions", + "type": "int", + "line": 128 }, { - "name": "fix", - "type": "str", - "default": "" + "name": "by_status", + "type": "dict[str, int]", + "line": 129 }, { - "name": "refusal_type", + "name": "high_volume_questions", + "type": "tuple[HighVolumeQuestion, ...]", + "line": 130 + }, + { + "name": "generated_at", + "type": "datetime", + "line": 131 + }, + { + "name": "visibility", "type": "str", - "default": "" + "line": 132 } ], - "line": 10, - "doc": "Structured refusal object for unsafe citation requests." - } - ], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_code/codifier_sync.py", - "sha256": "9c8b9635a2534eaccd3f80cc0b2a9b5c4751830a9d99796bb125e773778bd57f", - "routes": [], - "models": [ + "line": 127 + }, { - "name": "CodifierDeltaPlan", + "name": "StaffReportOutline", "bases": [], "fields": [ { - "name": "connector", + "name": "id", "type": "str", - "default": "" + "line": 137 }, { - "name": "request_url", + "name": "title", "type": "str", - "default": "" + "line": 138 }, { - "name": "delta_enabled", - "type": "bool", - "default": "" + "name": "sections", + "type": "tuple[dict[str, object], ...]", + "line": 139 }, { - "name": "cursor_param", - "type": "str | None", - "default": "" + "name": "source_question_ids", + "type": "tuple[str, ...]", + "line": 140 }, { - "name": "cursor_value", - "type": "str | None", - "default": "" + "name": "source_queue_item_ids", + "type": "tuple[str, ...]", + "line": 141 }, { - "name": "message", + "name": "created_by", "type": "str", - "default": "" + "line": 142 }, { - "name": "fix", + "name": "created_at", + "type": "datetime", + "line": 143 + }, + { + "name": "visibility", + "type": "str", + "line": 144 + }, + { + "name": "disclaimer", "type": "str", - "default": "" + "line": 145 } ], - "line": 56, - "doc": "Operator-visible planned codifier request." + "line": 136 }, { - "name": "CodifierSyncSource", + "name": "FlaggedAnswerReview", "bases": [], "fields": [ { - "name": "source_id", + "name": "id", "type": "str", - "default": "" + "line": 150 }, { - "name": "connector", + "name": "zone_code", "type": "str", - "default": "" + "line": 151 }, { - "name": "source_name", + "name": "question_text", "type": "str", - "default": "" + "line": 152 }, { - "name": "source_url", + "name": "original_answer", "type": "str", - "default": "" + "line": 153 }, { - "name": "sync_schedule", + "name": "flag_reason", "type": "str", - "default": "" + "line": 154 }, { - "name": "allowlisted_hosts", + "name": "citations", "type": "tuple[str, ...]", - "default": "()" + "line": 155 }, { - "name": "last_successful_sync_at", - "type": "datetime | None", - "default": "None" + "name": "status", + "type": "str", + "line": 156 }, { - "name": "last_attempted_sync_at", - "type": "datetime | None", - "default": "None" + "name": "improved_answer", + "type": "str | None", + "line": 157 }, { - "name": "last_import_job_id", + "name": "improvement_notes", "type": "str | None", - "default": "None" + "line": 158 }, { - "name": "next_sync_at_recorded", - "type": "datetime | None", - "default": "None" + "name": "reviewed_by", + "type": "str | None", + "line": 159 }, { - "name": "host_validation", - "type": "dict[str, Any]", - "default": "field(default_factory=dict)" + "name": "created_by", + "type": "str", + "line": 160 }, { - "name": "delta_plan_history", - "type": "list[dict[str, Any]]", - "default": "field(default_factory=list)" + "name": "created_at", + "type": "datetime", + "line": 161 }, { - "name": "state", - "type": "SyncCircuitState", - "default": "field(default_factory=lambda: SyncCircuitState(connector='codifier'))" + "name": "updated_at", + "type": "datetime", + "line": 162 + }, + { + "name": "visibility", + "type": "str", + "line": 163 } ], - "line": 80, - "doc": "Configured codifier sync source backed by a registered TownlightCode source." - }, + "line": 149 + } + ], + "configuration": [] + } + ] + }, + "planning": { + "repository": "townlight/plan", + "repository_head": "8dc9e455a5f4bb916b66d65da820914cfab42af1", + "working_tree_modified": true, + "principal_import": "townlight_planning", + "source": [ + { + "source": "townlight_planning/__init__.py", + "sha256": "e435f903a2e808bb3d38271366e0a2bad2d7333e20d4cb69839f5a4891fe8af6", + "bytes": 65, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_planning/connections.py", + "sha256": "649c8474e787fca1e30a11f153d2f776283204b5dc8053b7e88fbc325cdcf944", + "bytes": 2293, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_planning/consistency.py", + "sha256": "6bfcecb82ae9ebdceb7760c10eb9ae00b5d6895474cb4dc636b8bc0e448e4aaf", + "bytes": 1759, + "routes": [], + "models": [ { - "name": "CodifierSyncRun", + "name": "ConsistencyCheck", "bases": [], "fields": [ { - "name": "source", - "type": "CodifierSyncSource", - "default": "" + "name": "policy_id", + "type": "str", + "line": 12 }, { - "name": "job_payload", - "type": "dict[str, Any]", - "default": "" + "name": "status", + "type": "str", + "line": 13 }, { - "name": "delta_plan", - "type": "CodifierDeltaPlan", - "default": "" + "name": "factors", + "type": "tuple[str, ...]", + "line": 14 + }, + { + "name": "staff_next_step", + "type": "str", + "line": 15 + }, + { + "name": "disclaimer", + "type": "str", + "line": 16 } ], - "line": 103, - "doc": "Result of one local codifier sync run." + "line": 11 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_code/import_connectors.py", - "sha256": "bf4013448af2bd851642baefdbd1abcd212dd7b5b3c0e91d5811414c85e792f0", + "source": "townlight_planning/integration_mocks.py", + "sha256": "f70c0cc39c08cd7e5044c67e39e735fea4857313a6f8eae9f8d1cf838523215f", + "bytes": 5350, "routes": [], "models": [ { - "name": "ImportJob", + "name": "IntegrationError", "bases": [], "fields": [ { - "name": "job_id", + "name": "provider", "type": "str", - "default": "" + "line": 19 }, { - "name": "connector_type", + "name": "message", "type": "str", - "default": "" + "line": 20 }, { - "name": "actor", + "name": "fix", "type": "str", - "default": "" + "line": 21 }, { - "name": "status", + "name": "code", "type": "str", - "default": "'pending'" - }, - { - "name": "retry_of", - "type": "str | None", - "default": "None" - }, - { - "name": "counts", - "type": "dict[str, int]", - "default": "field(default_factory=dict)" - }, - { - "name": "provenance", - "type": "dict[str, Any]", - "default": "field(default_factory=dict)" - }, + "line": 22 + } + ], + "line": 18 + }, + { + "name": "IntegrationResult", + "bases": [], + "fields": [ { - "name": "failure", - "type": "dict[str, str] | None", - "default": "None" + "name": "provider", + "type": "str", + "line": 27 }, { - "name": "source_id", - "type": "str | None", - "default": "None" + "name": "records", + "type": "tuple[dict[str, Any], ...]", + "line": 28 }, { - "name": "created_at", - "type": "datetime", - "default": "field(default_factory=lambda: datetime.now(UTC))" + "name": "source", + "type": "str", + "line": 29 }, { - "name": "completed_at", - "type": "datetime | None", - "default": "None" + "name": "warnings", + "type": "tuple[str, ...]", + "line": 30 } ], - "line": 54, - "doc": "Auditable local import job record." + "line": 26 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_code/main.py", - "sha256": "930e05298b82f10ec0338040770d8af83aa56a9d43016908931ab8f796e63f48", + "source": "townlight_planning/main.py", + "sha256": "f1132f0cd9b3b169a835565f146a8575b918687ff95650ba87ac917daa462c6d", + "bytes": 25178, "routes": [ { "method": "GET", - "path": "/", - "router": "app", - "prefix_resolved": true, - "name": "root", - "signature": "", - "returns": "dict[str, str]", - "line": 786, - "doc": "Describe the current shipped runtime boundary.", - "decorator": "app.get('/')", - "errors": [] - }, - { - "method": "GET", - "path": "/townlight_code", - "router": "app", - "prefix_resolved": true, - "name": "public_lookup_home", - "signature": "", - "returns": "str", - "line": 834, - "doc": "Render the resident-facing public code lookup home page.", - "decorator": "app.get('/townlight_code', response_class=HTMLResponse)", - "errors": [] - }, - { - "method": "GET", - "path": "/townlight_code/app", - "router": "app", - "prefix_resolved": true, - "name": "townlight_code_frontend_app", - "signature": "", - "returns": "Response", - "line": 845, - "doc": "Serve the React/Vite TownlightCode frontend when built.", - "decorator": "app.get('/townlight_code/app')", - "errors": [] - }, - { - "method": "GET", - "path": "/townlight_code/app/", - "router": "app", - "prefix_resolved": true, - "name": "townlight_code_frontend_app", - "signature": "", - "returns": "Response", - "line": 845, - "doc": "Serve the React/Vite TownlightCode frontend when built.", - "decorator": "app.get('/townlight_code/app/')", - "errors": [] - }, - { - "method": "GET", - "path": "/townlight_code/search", - "router": "app", - "prefix_resolved": true, - "name": "public_lookup_search", - "signature": "q: str=''", - "returns": "str", - "line": 858, - "doc": "Render public search results, empty states, or refusal states.", - "decorator": "app.get('/townlight_code/search', response_class=HTMLResponse)", - "errors": [] - }, - { - "method": "GET", - "path": "/townlight_code/answer", - "router": "app", - "prefix_resolved": true, - "name": "public_lookup_answer", - "signature": "q: str='', section_number: str | None=None, as_of: date | None=None", - "returns": "str", - "line": 878, - "doc": "Render a resident-facing cited answer for one adopted section.", - "decorator": "app.get('/townlight_code/answer', response_class=HTMLResponse)", - "errors": [] - }, - { - "method": "GET", - "path": "/townlight_code/sections/{section_ref}", - "router": "app", - "prefix_resolved": true, - "name": "public_section_detail", - "signature": "section_ref: str, as_of: date | None=None", - "returns": "str", - "line": 901, - "doc": "Render a public section detail page with citation and warning context.", - "decorator": "app.get('/townlight_code/sections/{section_ref}', response_class=HTMLResponse)", - "errors": [] - }, - { - "method": "GET", - "path": "/townlight_code/sections/{section_ref}/export", - "router": "app", - "prefix_resolved": true, - "name": "public_section_export", - "signature": "section_ref: str, as_of: date | None=None", - "returns": "str", - "line": 937, - "doc": "Render an accessible records-ready export page for a section.", - "decorator": "app.get('/townlight_code/sections/{section_ref}/export', response_class=HTMLResponse)", - "errors": [] - }, - { - "method": "GET", - "path": "/staff/sources", - "router": "app", - "prefix_resolved": true, - "name": "staff_source_workspace", - "signature": "x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", - "returns": "HTMLResponse", - "line": 953, - "doc": "Render the staff source registry workspace.", - "decorator": "app.get('/staff/sources', response_class=HTMLResponse)", - "errors": [] - }, - { - "method": "GET", - "path": "/staff/code", - "router": "app", - "prefix_resolved": true, - "name": "staff_code_workspace", - "signature": "x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", - "returns": "HTMLResponse", - "line": 970, - "doc": "Render the staff code lifecycle workspace.", - "decorator": "app.get('/staff/code', response_class=HTMLResponse)", - "errors": [] - }, - { - "method": "GET", - "path": "/staff/sync", - "router": "app", - "prefix_resolved": true, - "name": "staff_sync_workspace", - "signature": "x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", - "returns": "HTMLResponse", - "line": 983, - "doc": "Render the staff codifier sync health workspace.", - "decorator": "app.get('/staff/sync', response_class=HTMLResponse)", - "errors": [] - }, - { - "method": "GET", - "path": "/staff/imports", - "router": "app", - "prefix_resolved": true, - "name": "staff_import_ledger", - "signature": "x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", - "returns": "HTMLResponse", - "line": 1000, - "doc": "Render the staff import job and provenance ledger.", - "decorator": "app.get('/staff/imports', response_class=HTMLResponse)", - "errors": [] - }, - { - "method": "GET", - "path": "/health", - "router": "app", - "prefix_resolved": true, - "name": "health", - "signature": "", - "returns": "dict[str, str]", - "line": 1013, - "doc": "Provide a simple operational health check for IT staff.", - "decorator": "app.get('/health')", - "errors": [] - }, - { - "method": "GET", - "path": "/api/v1/townlight_code/staff/operational-state", - "router": "app", - "prefix_resolved": true, - "name": "get_staff_operational_state", - "signature": "x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", - "returns": "dict[str, Any]", - "line": 1024, - "doc": "Return current operational readiness state for staff operators.", - "decorator": "app.get('/api/v1/townlight_code/staff/operational-state')", - "errors": [] - }, - { - "method": "GET", - "path": "/api/v1/townlight_code/sources/catalog", - "router": "app", - "prefix_resolved": true, - "name": "source_registry_catalog", - "signature": "", - "returns": "dict[str, Any]", - "line": 1036, - "doc": "Expose allowed source registry vocabulary for staff integration clients.", - "decorator": "app.get('/api/v1/townlight_code/sources/catalog')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_code/sources", - "router": "app", - "prefix_resolved": true, - "name": "create_source", - "signature": "request: SourceCreate, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", - "returns": "dict[str, Any]", - "line": 1050, - "doc": "Register a municipal code source without importing its contents yet.", - "decorator": "app.post('/api/v1/townlight_code/sources', status_code=201)", - "errors": [] - }, - { - "method": "GET", - "path": "/api/v1/townlight_code/sources", - "router": "app", - "prefix_resolved": true, - "name": "list_public_sources", - "signature": "", - "returns": "dict[str, Any]", - "line": 1068, - "doc": "List public-visible sources without exposing staff-only notes.", - "decorator": "app.get('/api/v1/townlight_code/sources')", - "errors": [] - }, - { - "method": "GET", - "path": "/api/v1/townlight_code/sources/{source_id}", - "router": "app", - "prefix_resolved": true, - "name": "get_public_source", - "signature": "source_id: str", - "returns": "dict[str, Any]", - "line": 1079, - "doc": "Read a public source record without leaking staff-only notes.", - "decorator": "app.get('/api/v1/townlight_code/sources/{source_id}')", - "errors": [ - "HTTPException(status_code=404, detail={'message': f\"Source '{source_id}' is not public-visible.\", 'fix': 'Use the staff source endpoint if you are authorized to view it.'})" - ] - }, - { - "method": "GET", - "path": "/api/v1/townlight_code/staff/sources", - "router": "app", - "prefix_resolved": true, - "name": "list_staff_sources", - "signature": "x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", - "returns": "dict[str, Any]", - "line": 1097, - "doc": "List all registered sources for staff workflows.", - "decorator": "app.get('/api/v1/townlight_code/staff/sources')", - "errors": [] - }, - { - "method": "GET", - "path": "/api/v1/townlight_code/staff/sources/{source_id}", - "router": "app", - "prefix_resolved": true, - "name": "get_staff_source", - "signature": "source_id: str, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", - "returns": "dict[str, Any]", - "line": 1112, - "doc": "Read a staff source record including staff-only notes.", - "decorator": "app.get('/api/v1/townlight_code/staff/sources/{source_id}')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_code/sources/{source_id}/transitions", - "router": "app", - "prefix_resolved": true, - "name": "transition_source", - "signature": "source_id: str, request: SourceTransitionRequest, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", - "returns": "dict[str, Any]", - "line": 1127, - "doc": "Transition a source through the official registry lifecycle.", - "decorator": "app.post('/api/v1/townlight_code/sources/{source_id}/transitions')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_code/titles", - "router": "app", - "prefix_resolved": true, - "name": "create_title", - "signature": "request: TitleCreate, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", - "returns": "dict[str, Any]", - "line": 1148, - "doc": "Create a municipal code title container.", - "decorator": "app.post('/api/v1/townlight_code/titles', status_code=201)", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_code/chapters", - "router": "app", - "prefix_resolved": true, - "name": "create_chapter", - "signature": "request: ChapterCreate, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", - "returns": "dict[str, Any]", - "line": 1163, - "doc": "Create a municipal code chapter under a title.", - "decorator": "app.post('/api/v1/townlight_code/chapters', status_code=201)", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_code/sections", - "router": "app", - "prefix_resolved": true, - "name": "create_section", - "signature": "request: SectionCreate, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", - "returns": "dict[str, Any]", - "line": 1178, - "doc": "Create a code section or subsection without generating answers.", - "decorator": "app.post('/api/v1/townlight_code/sections', status_code=201)", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_code/sections/{section_id}/versions", - "router": "app", - "prefix_resolved": true, - "name": "create_section_version", - "signature": "section_id: str, request: SectionVersionCreate, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", - "returns": "dict[str, Any]", - "line": 1193, - "doc": "Create an immutable section version for adopted, pending, or retired text.", - "decorator": "app.post('/api/v1/townlight_code/sections/{section_id}/versions', status_code=201)", - "errors": [ - "HTTPException(status_code=422, detail={'message': 'Path section_id must match request body section_id.', 'fix': 'Use the same section_id in the URL and JSON body.'})", - "HTTPException(status_code=409, detail={'message': f\"Source '{source.source_id}' is {source.status} and cannot back section text.\", 'fix': 'Use an active source or refresh the source registry record first.'})", - "HTTPException(status_code=409, detail={'message': 'Adopted section versions require an active public-visible source.', 'fix': 'Activate an official source in the registry before marking text as adopted law.'})", - "HTTPException(status_code=404, detail={'message': f\"Source '{data['source_id']}' was not found for this section version.\", 'fix': 'Register the source before adding section text from it.'})" - ] - }, - { - "method": "GET", - "path": "/api/v1/townlight_code/sections/lookup", - "router": "app", - "prefix_resolved": true, - "name": "lookup_section", - "signature": "section_number: str, as_of: date | None=None", - "returns": "dict[str, Any]", - "line": 1244, - "doc": "Lookup adopted section text by current flag or effective date.", - "decorator": "app.get('/api/v1/townlight_code/sections/lookup')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_code/sections/resolve", - "router": "app", - "prefix_resolved": true, - "name": "resolve_section", - "signature": "request: SectionResolveRequest", - "returns": "dict[str, Any]", - "line": 1255, - "doc": "Resolve adopted code context for downstream Townlight module clients.", - "decorator": "app.post('/api/v1/townlight_code/sections/resolve')", - "errors": [] - }, - { - "method": "GET", - "path": "/api/v1/townlight_code/sections/{section_id}/history", - "router": "app", - "prefix_resolved": true, - "name": "section_history", - "signature": "section_id: str", - "returns": "dict[str, Any]", - "line": 1354, - "doc": "Return immutable amendment/version history for a section.", - "decorator": "app.get('/api/v1/townlight_code/sections/{section_id}/history')", - "errors": [] - }, - { - "method": "GET", - "path": "/api/v1/townlight_code/sections/{section_id}/permalink", - "router": "app", - "prefix_resolved": true, - "name": "section_permalink", - "signature": "section_id: str", - "returns": "dict[str, Any]", - "line": 1363, - "doc": "Return the stable public-facing permalink for a section.", - "decorator": "app.get('/api/v1/townlight_code/sections/{section_id}/permalink')", - "errors": [] - }, - { - "method": "GET", - "path": "/api/v1/townlight_code/search", - "router": "app", - "prefix_resolved": true, - "name": "search_sections", - "signature": "q: str", - "returns": "dict[str, Any]", - "line": 1372, - "doc": "Search public-visible code sections and related public materials.", - "decorator": "app.get('/api/v1/townlight_code/search')", - "errors": [] - }, - { - "method": "GET", - "path": "/api/v1/townlight_code/popular-questions", - "router": "app", - "prefix_resolved": true, - "name": "list_popular_questions", - "signature": "", - "returns": "dict[str, Any]", - "line": 1381, - "doc": "List staff-approved public popular questions as navigation aids.", - "decorator": "app.get('/api/v1/townlight_code/popular-questions')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_code/staff/popular-questions", - "router": "app", - "prefix_resolved": true, - "name": "create_popular_question", - "signature": "request: PopularQuestionCreate, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", - "returns": "dict[str, Any]", - "line": 1403, - "doc": "Create a staff-approved public popular question tied to cited adopted code.", - "decorator": "app.post('/api/v1/townlight_code/staff/popular-questions', status_code=201)", - "errors": [ - "HTTPException(status_code=422, detail={'message': 'Popular questions cannot ask TownlightCode for a legal determination.', 'fix': \"Rewrite the question as a navigation prompt, such as 'Where do I read the backyard chicken permit rule?'\"})", - "HTTPException(status_code=409, detail={'message': citation_payload.get('reason', 'Citation could not be built.'), 'fix': citation_payload.get('fix', 'Attach the question to cited adopted code.')})" - ] - }, - { - "method": "GET", - "path": "/api/v1/townlight_code/sections/{section_number}/related", - "router": "app", - "prefix_resolved": true, - "name": "related_materials", - "signature": "section_number: str", - "returns": "dict[str, Any]", - "line": 1453, - "doc": "List explicit public related materials for one adopted section.", - "decorator": "app.get('/api/v1/townlight_code/sections/{section_number}/related')", - "errors": [] - }, - { - "method": "GET", - "path": "/api/v1/townlight_code/citations/build", - "router": "app", - "prefix_resolved": true, - "name": "build_citation", - "signature": "section_number: str, as_of: date | None=None", - "returns": "dict[str, Any]", - "line": 1466, - "doc": "Build a deterministic citation object or a structured refusal.", - "decorator": "app.get('/api/v1/townlight_code/citations/build')", - "errors": [] - }, - { - "method": "GET", - "path": "/api/v1/townlight_code/sections/{section_ref}/export", - "router": "app", - "prefix_resolved": true, - "name": "export_section", - "signature": "section_ref: str, as_of: date | None=None", - "returns": "dict[str, Any]", - "line": 1472, - "doc": "Return a records-ready section export with citation and source provenance.", - "decorator": "app.get('/api/v1/townlight_code/sections/{section_ref}/export')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_code/questions/answer", - "router": "app", - "prefix_resolved": true, - "name": "answer_question", - "signature": "request: QuestionAnswerRequest", - "returns": "dict[str, Any]", - "line": 1478, - "doc": "Answer code questions only when an adopted section citation grounds them.", - "decorator": "app.post('/api/v1/townlight_code/questions/answer')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_code/staff/sections/{section_id}/notes", - "router": "app", - "prefix_resolved": true, - "name": "create_interpretation_note", - "signature": "section_id: str, request: InterpretationNoteCreate, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", - "returns": "dict[str, Any]", - "line": 1494, - "doc": "Create a staff-only interpretation note without exposing it publicly.", - "decorator": "app.post('/api/v1/townlight_code/staff/sections/{section_id}/notes', status_code=201)", - "errors": [] - }, - { - "method": "GET", - "path": "/api/v1/townlight_code/staff/sections/{section_id}/notes", - "router": "app", - "prefix_resolved": true, - "name": "list_interpretation_notes", - "signature": "section_id: str, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", - "returns": "dict[str, Any]", - "line": 1517, - "doc": "List staff-only interpretation notes for authorized staff clients.", - "decorator": "app.get('/api/v1/townlight_code/staff/sections/{section_id}/notes')", - "errors": [] - }, - { - "method": "GET", - "path": "/api/v1/townlight_code/staff/audit-events", - "router": "app", - "prefix_resolved": true, - "name": "list_staff_audit_events", - "signature": "x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", - "returns": "dict[str, Any]", - "line": 1532, - "doc": "List staff workbench audit events for authorized staff clients.", - "decorator": "app.get('/api/v1/townlight_code/staff/audit-events')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_code/staff/imports/local-bundle", - "router": "app", - "prefix_resolved": true, - "name": "create_local_import_job", - "signature": "request: ImportBundleCreate, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", - "returns": "dict[str, Any]", - "line": 1548, - "doc": "Import a local codifier/file-drop fixture without outbound network calls.", - "decorator": "app.post('/api/v1/townlight_code/staff/imports/local-bundle', status_code=201)", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_code/staff/imports/shared-pdf", - "router": "app", - "prefix_resolved": true, - "name": "create_shared_pdf_import_job", - "signature": "request: SharedPdfImportCreate, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", - "returns": "dict[str, Any]", - "line": 1560, - "doc": "Ingest a municipal code PDF through TownlightCore, then structure it for TownlightCode.", - "decorator": "app.post('/api/v1/townlight_code/staff/imports/shared-pdf', status_code=201)", - "errors": [ - "HTTPException(status_code=409, detail={'message': 'Shared PDF ingestion requires a durable PostgreSQL runtime.', 'fix': 'Set TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL or DATABASE_URL to the TownlightCode PostgreSQL DSN.'})" - ] - }, - { - "method": "GET", - "path": "/api/v1/townlight_code/staff/imports", - "router": "app", - "prefix_resolved": true, - "name": "list_import_jobs", - "signature": "x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", - "returns": "dict[str, Any]", - "line": 1594, - "doc": "List local import jobs and their visible success/failure states.", - "decorator": "app.get('/api/v1/townlight_code/staff/imports')", - "errors": [] - }, - { - "method": "GET", - "path": "/api/v1/townlight_code/staff/imports/{job_id}", - "router": "app", - "prefix_resolved": true, - "name": "get_import_job", - "signature": "job_id: str, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", - "returns": "dict[str, Any]", - "line": 1604, - "doc": "Read a local import job, including actionable failure details.", - "decorator": "app.get('/api/v1/townlight_code/staff/imports/{job_id}')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_code/staff/imports/{job_id}/retry", - "router": "app", - "prefix_resolved": true, - "name": "retry_import_job", - "signature": "job_id: str, request: ImportBundleCreate, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", - "returns": "dict[str, Any]", - "line": 1619, - "doc": "Retry a failed import job with a corrected local bundle.", - "decorator": "app.post('/api/v1/townlight_code/staff/imports/{job_id}/retry', status_code=201)", - "errors": [] - }, - { - "method": "GET", - "path": "/api/v1/townlight_code/staff/imports/{job_id}/provenance", - "router": "app", - "prefix_resolved": true, - "name": "get_import_provenance", - "signature": "job_id: str, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", - "returns": "dict[str, Any]", - "line": 1635, - "doc": "Return a provenance report for a local import job.", - "decorator": "app.get('/api/v1/townlight_code/staff/imports/{job_id}/provenance')", - "errors": [] - }, - { - "method": "GET", - "path": "/api/v1/townlight_code/staff/imports/{job_id}/tree", - "router": "app", - "prefix_resolved": true, - "name": "get_imported_tree", - "signature": "job_id: str, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", - "returns": "dict[str, Any]", - "line": 1650, - "doc": "Show imported title/chapter/section/version tree for staff verification.", - "decorator": "app.get('/api/v1/townlight_code/staff/imports/{job_id}/tree')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_code/staff/sync/codifier-sources", - "router": "app", - "prefix_resolved": true, - "name": "configure_codifier_sync_source", - "signature": "request: CodifierSyncConfigureRequest, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", - "returns": "dict[str, Any]", - "line": 1673, - "doc": "Enable staff-controlled codifier sync readiness for an official source.", - "decorator": "app.post('/api/v1/townlight_code/staff/sync/codifier-sources', status_code=201)", - "errors": [] - }, - { - "method": "GET", - "path": "/api/v1/townlight_code/staff/sync/codifier-sources", - "router": "app", - "prefix_resolved": true, - "name": "list_codifier_sync_sources", - "signature": "x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", - "returns": "dict[str, Any]", - "line": 1694, - "doc": "List codifier sync readiness and circuit health for staff.", - "decorator": "app.get('/api/v1/townlight_code/staff/sync/codifier-sources')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_code/staff/sync/codifier-sources/{source_id}/run", - "router": "app", - "prefix_resolved": true, - "name": "run_codifier_sync_source", - "signature": "source_id: str, request: CodifierSyncRunRequest, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", - "returns": "dict[str, Any]", - "line": 1709, - "doc": "Run one staff-controlled codifier sync using an already fetched local payload.", - "decorator": "app.post('/api/v1/townlight_code/staff/sync/codifier-sources/{source_id}/run', status_code=201)", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_code/staff/townlight_meetings/ordinance-events", - "router": "app", - "prefix_resolved": true, - "name": "create_townlight_meetings_ordinance_event", - "signature": "request: TownlightMeetingsOrdinanceEventCreate, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None), x_townlight_code_intake_auth: str | None=Header(default=None, alias=TOWNLIGHT_CODE_INTAKE_AUTH_HEADER), authorization: str | None=Header(default=None)", - "returns": "dict[str, Any]", - "line": 1730, - "doc": "Receive TownlightMeetings ordinance/adoption events without codifying them.", - "decorator": "app.post('/api/v1/townlight_code/staff/townlight_meetings/ordinance-events', status_code=201)", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_code/staff/townlight_meetings/ordinance-events/{event_id}/resolve", - "router": "app", - "prefix_resolved": true, - "name": "resolve_townlight_meetings_ordinance_event", - "signature": "event_id: str, request: TownlightMeetingsOrdinanceEventResolve, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None), x_townlight_code_intake_auth: str | None=Header(default=None, alias=TOWNLIGHT_CODE_INTAKE_AUTH_HEADER), authorization: str | None=Header(default=None)", - "returns": "dict[str, Any]", - "line": 1756, - "doc": "Mark a TownlightMeetings handoff codified after staff creates the adopted code version.", - "decorator": "app.post('/api/v1/townlight_code/staff/townlight_meetings/ordinance-events/{event_id}/resolve')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_code/staff/sections/{section_id}/summaries", - "router": "app", - "prefix_resolved": true, - "name": "create_plain_language_summary", - "signature": "section_id: str, request: PlainLanguageSummaryCreate, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", - "returns": "dict[str, Any]", - "line": 1806, - "doc": "Create a staff-drafted plain-language summary tied to adopted code text.", - "decorator": "app.post('/api/v1/townlight_code/staff/sections/{section_id}/summaries', status_code=201)", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_code/staff/summaries/{summary_id}/approve", - "router": "app", - "prefix_resolved": true, - "name": "approve_plain_language_summary", - "signature": "summary_id: str, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", - "returns": "dict[str, Any]", - "line": 1841, - "doc": "Approve a plain-language summary for public display after staff review.", - "decorator": "app.post('/api/v1/townlight_code/staff/summaries/{summary_id}/approve')", - "errors": [] - }, - { - "method": "GET", - "path": "/api/v1/townlight_code/sections/{section_id}/summaries", - "router": "app", - "prefix_resolved": true, - "name": "list_public_plain_language_summaries", - "signature": "section_id: str", - "returns": "dict[str, Any]", - "line": 1866, - "doc": "List public approved summaries while keeping authoritative code visible.", - "decorator": "app.get('/api/v1/townlight_code/sections/{section_id}/summaries')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_code/staff/questions/answer", - "router": "app", - "prefix_resolved": true, - "name": "answer_staff_question", - "signature": "request: QuestionAnswerRequest, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", - "returns": "dict[str, Any]", - "line": 1895, - "doc": "Answer staff questions with staff-only notes kept out of public responses.", - "decorator": "app.post('/api/v1/townlight_code/staff/questions/answer')", - "errors": [] + "declared_path": "/", + "function": "root", + "line": 130 + }, + { + "method": "GET", + "declared_path": "/health", + "function": "health", + "line": 148 + }, + { + "method": "GET", + "declared_path": "/townlight_planning", + "function": "public_townlight_planning_page", + "line": 194 + }, + { + "method": "GET", + "declared_path": "/api/v1/townlight_planning/public/plan-explore", + "function": "public_plan_explore", + "line": 221 + }, + { + "method": "GET", + "declared_path": "/api/v1/townlight_planning/public/policy/{revision_id}/{policy_id}", + "function": "public_policy_citation", + "line": 238 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_planning/policies/lookup", + "function": "policy_lookup", + "line": 257 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_planning/policies/ingest", + "function": "ingest_policy", + "line": 271 + }, + { + "method": "GET", + "declared_path": "/api/v1/townlight_planning/plans/navigator", + "function": "plans_navigator", + "line": 284 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_planning/questions/answer", + "function": "plan_question_answer", + "line": 293 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_planning/plans/synthesis", + "function": "plan_synthesis", + "line": 307 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_planning/context/townlight_meetings", + "function": "townlight_meetings_context", + "line": 315 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_planning/integrations/mock", + "function": "integration_mock", + "line": 329 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_planning/context/zoning", + "function": "zoning_policy_context", + "line": 350 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_planning/consistency/check", + "function": "consistency_check", + "line": 379 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_planning/staff-analysis/draft", + "function": "staff_analysis", + "line": 393 + }, + { + "method": "GET", + "declared_path": "/api/v1/townlight_planning/staff-analysis/{analysis_id}", + "function": "get_staff_analysis", + "line": 420 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_planning/export", + "function": "policy_export", + "line": 452 } ], "models": [ { - "name": "SourceCreate", + "name": "PolicyLookupRequest", "bases": [ "BaseModel" ], "fields": [ { - "name": "source_id", - "type": "str | None", - "default": "None" - }, - { - "name": "name", - "type": "str", - "default": "Field(min_length=1)" - }, - { - "name": "publisher", + "name": "topic", "type": "str", - "default": "Field(min_length=1)" + "line": 66 }, { - "name": "source_type", + "name": "plan_type", "type": "str", - "default": "Field(min_length=1)" - }, + "line": 67 + } + ], + "line": 65 + }, + { + "name": "ZoningPolicyContextRequest", + "bases": [ + "BaseModel" + ], + "fields": [ { - "name": "source_category", + "name": "topic", "type": "str", - "default": "Field(min_length=1)" - }, - { - "name": "source_url", - "type": "str | None", - "default": "None" + "line": 71 }, { - "name": "file_reference", + "name": "zone_code", "type": "str | None", - "default": "None" - }, - { - "name": "retrieved_at", - "type": "datetime | None", - "default": "None" + "line": 72 }, { - "name": "retrieval_method", + "name": "use", "type": "str | None", - "default": "None" + "line": 73 }, { - "name": "checksum", + "name": "parcel_number", "type": "str | None", - "default": "None" + "line": 74 }, { - "name": "source_owner", + "name": "address", "type": "str | None", - "default": "None" + "line": 75 }, { - "name": "is_official", - "type": "bool", - "default": "True" + "name": "plan_type", + "type": "str", + "line": 76 }, { - "name": "official_status_note", + "name": "townlight_zoning_context_id", "type": "str | None", - "default": "None" - }, + "line": 77 + } + ], + "line": 70 + }, + { + "name": "ConsistencyRequest", + "bases": [ + "BaseModel" + ], + "fields": [ { - "name": "status", + "name": "proposal", "type": "str", - "default": "'draft'" + "line": 81 }, { - "name": "staff_notes", - "type": "str | None", - "default": "None" + "name": "policy_id", + "type": "str", + "line": 82 } ], - "line": 286, - "doc": "Request body for registering an official or explicitly labeled source." + "line": 80 }, { - "name": "SourceTransitionRequest", + "name": "StaffAnalysisRequest", "bases": [ "BaseModel" ], "fields": [ { - "name": "to_status", + "name": "project_name", "type": "str", - "default": "" + "line": 86 }, { - "name": "actor", + "name": "proposal", "type": "str", - "default": "Field(min_length=1)" + "line": 87 }, { - "name": "reason", + "name": "policy_id", "type": "str", - "default": "Field(min_length=1)" + "line": 88 } ], - "line": 308, - "doc": "Request body for source-state changes." + "line": 85 }, { - "name": "TitleCreate", + "name": "PolicyExportRequest", "bases": [ "BaseModel" ], "fields": [ { - "name": "title_id", - "type": "str | None", - "default": "None" + "name": "title", + "type": "str", + "line": 92 }, { - "name": "title_number", + "name": "policy_id", "type": "str", - "default": "Field(min_length=1)" + "line": 93 }, { - "name": "title_name", + "name": "format", "type": "str", - "default": "Field(min_length=1)" + "line": 94 }, { - "name": "sort_order", - "type": "int", - "default": "0" + "name": "snapshot_id", + "type": "str | None", + "line": 95 } ], - "line": 318, - "doc": "Request body for creating a code title." + "line": 91 }, { - "name": "ChapterCreate", + "name": "PolicyIngestRequest", "bases": [ "BaseModel" ], "fields": [ { - "name": "chapter_id", - "type": "str | None", - "default": "None" + "name": "topic_key", + "type": "str", + "line": 99 }, { - "name": "title_id", + "name": "policy_id", "type": "str", - "default": "Field(min_length=1)" + "line": 100 }, { - "name": "chapter_number", + "name": "plan_type", "type": "str", - "default": "Field(min_length=1)" + "line": 101 }, { - "name": "chapter_name", + "name": "title", "type": "str", - "default": "Field(min_length=1)" + "line": 102 }, { - "name": "sort_order", - "type": "int", - "default": "0" + "name": "citation", + "type": "str", + "line": 103 + }, + { + "name": "excerpt", + "type": "str", + "line": 104 + }, + { + "name": "relevance", + "type": "str", + "line": 105 + }, + { + "name": "adoption_status", + "type": "str", + "line": 106 + }, + { + "name": "source_document", + "type": "str", + "line": 107 } ], - "line": 329, - "doc": "Request body for creating a code chapter." + "line": 98 }, { - "name": "SectionCreate", + "name": "PlanQuestionRequest", "bases": [ "BaseModel" ], "fields": [ { - "name": "section_id", - "type": "str | None", - "default": "None" + "name": "question", + "type": "str", + "line": 111 }, { - "name": "chapter_id", + "name": "plan_type", "type": "str", - "default": "Field(min_length=1)" - }, + "line": 112 + } + ], + "line": 110 + }, + { + "name": "PlanSynthesisRequest", + "bases": [ + "BaseModel" + ], + "fields": [ { - "name": "section_number", + "name": "topic", + "type": "str", + "line": 116 + } + ], + "line": 115 + }, + { + "name": "TownlightMeetingsContextRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "agenda_item", "type": "str", - "default": "Field(min_length=1)" + "line": 120 }, { - "name": "section_heading", + "name": "topic", + "type": "str", + "line": 121 + } + ], + "line": 119 + }, + { + "name": "IntegrationMockRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "provider", "type": "str", - "default": "Field(min_length=1)" + "line": 125 }, { - "name": "parent_section_id", - "type": "str | None", - "default": "None" + "name": "payload", + "type": "dict[str, object]", + "line": 126 + } + ], + "line": 124 + } + ], + "configuration": [ + { + "environment": "TOWNLIGHT_PLANNING_POLICY_DB_URL", + "line": 470 + }, + { + "environment": "TOWNLIGHT_PLANNING_DEMO_MODE", + "line": 497 + } + ] + }, + { + "source": "townlight_planning/migrations/__init__.py", + "sha256": "d633520d0fcec8ca93f8f5dc22e206cc65ea5c646a8a61e89eb6614d51008986", + "bytes": 2183, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_planning/migrations/__main__.py", + "sha256": "dc61223a3923f9e2b085e0dab9e033dcf799f99b08f4c808638824e0d303d13b", + "bytes": 647, + "routes": [], + "models": [], + "configuration": [ + { + "environment": "TOWNLIGHT_PLANNING_POLICY_DB_URL", + "line": 7 + } + ] + }, + { + "source": "townlight_planning/migrations/env.py", + "sha256": "c1dcc827b65af850e94f41ac02aec0528ad0abaf5b0d6a22e5773df2ceadaafc", + "bytes": 442, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_planning/migrations/versions/townlight_planning_0001_sources.py", + "sha256": "0552047ca4ca0eee1eaf5878f3f8f759e188da8d371a377efc93df9867ac2601", + "bytes": 1608, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_planning/migrations/versions/townlight_planning_0002_workflows.py", + "sha256": "eba85cad351b499cd7456e68305309d92cb4c3087e355417df5259458d9c3f4f", + "bytes": 1093, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_planning/migrations/versions/townlight_planning_0003_municipal.py", + "sha256": "c66314f036cb2c96263eafece836760e1fb0c31b96578238c5c900cdd5477417", + "bytes": 1200, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_planning/migrations/versions/townlight_planning_0004_neighborhoods.py", + "sha256": "5db83c05d550ab4f9f0a414c6f139fa454bdc03ae1c7963e55290ecbc8fd644a", + "bytes": 853, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_planning/municipal.py", + "sha256": "97e153119e296d9529f3c6b4e51d40be446fb3fed12a41c301b0fc3aa70b4e10", + "bytes": 12736, + "routes": [], + "models": [ + { + "name": "Measurement", + "bases": [ + "BundleModel" + ], + "fields": [ + { + "name": "recorded_on", + "type": "date", + "line": 42 }, { - "name": "sort_order", - "type": "int", - "default": "0" + "name": "value", + "type": "Decimal", + "line": 43 }, { - "name": "administrative_regulation_refs", - "type": "list[str]", - "default": "Field(default_factory=list)" + "name": "evidence", + "type": "str", + "line": 44 + } + ], + "line": 41 + }, + { + "name": "Milestone", + "bases": [ + "BundleModel" + ], + "fields": [ + { + "name": "title", + "type": "str", + "line": 54 }, { - "name": "resolution_refs", - "type": "list[str]", - "default": "Field(default_factory=list)" + "name": "due_on", + "type": "date", + "line": 55 }, { - "name": "policy_refs", - "type": "list[str]", - "default": "Field(default_factory=list)" + "name": "completed_on", + "type": "date | None", + "line": 56 }, { - "name": "approved_summary_refs", - "type": "list[str]", - "default": "Field(default_factory=list)" + "name": "evidence", + "type": "str", + "line": 57 } ], - "line": 341, - "doc": "Request body for creating a code section or subsection." + "line": 53 }, { - "name": "SectionVersionCreate", + "name": "InitiativeInput", "bases": [ - "BaseModel" + "BundleModel" ], "fields": [ { - "name": "version_id", + "name": "expected_revision", "type": "str | None", - "default": "None" - }, - { - "name": "section_id", - "type": "str", - "default": "Field(min_length=1)" + "line": 67 }, { - "name": "source_id", + "name": "title", "type": "str", - "default": "Field(min_length=1)" + "line": 68 }, { - "name": "version_label", - "type": "str", - "default": "Field(min_length=1)" + "name": "policy", + "type": "PolicySelection", + "line": 69 }, { - "name": "body", + "name": "responsible_staff", "type": "str", - "default": "Field(min_length=1)" + "line": 70 }, { - "name": "effective_start", - "type": "date", - "default": "" - }, - { - "name": "effective_end", - "type": "date | None", - "default": "None" + "name": "target", + "type": "Decimal", + "line": 71 }, { - "name": "status", + "name": "unit", "type": "str", - "default": "'draft'" + "line": 72 }, { - "name": "is_current", - "type": "bool", - "default": "False" + "name": "due_on", + "type": "date", + "line": 73 }, { - "name": "adoption_event_id", - "type": "str | None", - "default": "None" + "name": "status", + "type": "Literal['planned', 'active', 'completed', 'cancelled']", + "line": 74 }, { - "name": "amendment_event_id", - "type": "str | None", - "default": "None" + "name": "milestones", + "type": "list[Milestone]", + "line": 75 }, { - "name": "amendment_summary", - "type": "str | None", - "default": "None" + "name": "measurements", + "type": "list[Measurement]", + "line": 76 }, { - "name": "prior_version_id", - "type": "str | None", - "default": "None" + "name": "note", + "type": "str", + "line": 77 } ], - "line": 358, - "doc": "Request body for adding an immutable section version." + "line": 66 }, { - "name": "QuestionAnswerRequest", + "name": "AmendmentInput", "bases": [ - "BaseModel" + "BundleModel" ], "fields": [ { - "name": "question", + "name": "expected_revision", + "type": "str | None", + "line": 91 + }, + { + "name": "title", "type": "str", - "default": "Field(min_length=1)" + "line": 92 }, { - "name": "section_number", - "type": "str | None", - "default": "None" + "name": "policy", + "type": "PolicySelection", + "line": 93 }, { - "name": "as_of", - "type": "date | None", - "default": "None" - } - ], - "line": 378, - "doc": "Request body for citation-grounded code Q&A." - }, - { - "name": "SectionResolveRequest", - "bases": [ - "BaseModel" - ], - "fields": [ + "name": "proposal", + "type": "str", + "line": 94 + }, { - "name": "consumer_module", + "name": "responsible_staff", "type": "str", - "default": "Field(min_length=1)" + "line": 95 }, { - "name": "section_number", - "type": "str | None", - "default": "None" + "name": "status", + "type": "Literal['draft', 'review', 'adopted', 'withdrawn']", + "line": 96 }, { - "name": "query", + "name": "review_note", + "type": "str", + "line": 97 + }, + { + "name": "adoption_revision", "type": "str | None", - "default": "None" + "line": 98 }, { - "name": "as_of", - "type": "date | None", - "default": "None" + "name": "note", + "type": "str", + "line": 99 } ], - "line": 388, - "doc": "Request body for downstream module section-resolution clients." + "line": 90 + } + ], + "configuration": [] + }, + { + "source": "townlight_planning/municipal_api.py", + "sha256": "8b6b99a44b2a2b186f1e2c6c0c09a4815c8aa7184f60993aab6e45ffbc2fa5bd", + "bytes": 2323, + "routes": [ + { + "method": "POST", + "declared_path": "/initiatives", + "function": "create_initiative", + "line": 17 }, { - "name": "PopularQuestionCreate", - "bases": [ - "BaseModel" - ], + "method": "POST", + "declared_path": "/initiatives/{item_id}/revisions", + "function": "update_initiative", + "line": 22 + }, + { + "method": "POST", + "declared_path": "/amendments", + "function": "create_amendment", + "line": 29 + }, + { + "method": "POST", + "declared_path": "/amendments/{item_id}/revisions", + "function": "update_amendment", + "line": 34 + }, + { + "method": "GET", + "declared_path": "/municipal-work/{item_id}/history", + "function": "history", + "line": 41 + }, + { + "method": "GET", + "declared_path": "/progress/targets", + "function": "progress", + "line": 49 + }, + { + "method": "GET", + "declared_path": "/amendments/history", + "function": "amendments", + "line": 60 + } + ], + "models": [], + "configuration": [] + }, + { + "source": "townlight_planning/persistence.py", + "sha256": "3a19584080cbb99c2a3bccd9673fe57d0abf20ecae8ad541cabccb42bccc9465", + "bytes": 10309, + "routes": [], + "models": [ + { + "name": "StoredStaffAnalysis", + "bases": [], "fields": [ { - "name": "question_id", - "type": "str | None", - "default": "None" + "name": "analysis_id", + "type": "str", + "line": 52 }, { - "name": "question_text", + "name": "project_name", "type": "str", - "default": "Field(min_length=1)" + "line": 53 }, { - "name": "section_number", + "name": "proposal", "type": "str", - "default": "Field(min_length=1)" + "line": 54 }, { - "name": "answer_excerpt", + "name": "policy_id", "type": "str", - "default": "Field(min_length=1)" + "line": 55 }, { - "name": "audience", + "name": "heading", "type": "str", - "default": "'public'" + "line": 56 }, { - "name": "status", - "type": "str", - "default": "'approved'" + "name": "bullets", + "type": "tuple[str, ...]", + "line": 57 }, { - "name": "is_popular", - "type": "bool", - "default": "True" - } - ], - "line": 399, - "doc": "Request body for a staff-approved public popular-question navigation aid." - }, - { - "name": "InterpretationNoteCreate", - "bases": [ - "BaseModel" - ], - "fields": [ + "name": "citations", + "type": "tuple[str, ...]", + "line": 58 + }, { - "name": "note_id", - "type": "str | None", - "default": "None" + "name": "review_required", + "type": "bool", + "line": 59 }, { - "name": "note_text", + "name": "disclaimer", "type": "str", - "default": "Field(min_length=1)" + "line": 60 }, { - "name": "status", - "type": "str", - "default": "'draft'" + "name": "created_at", + "type": "datetime", + "line": 61 } ], - "line": 413, - "doc": "Request body for staff-only interpretation notes." - }, + "line": 51 + } + ], + "configuration": [] + }, + { + "source": "townlight_planning/plan_workflows.py", + "sha256": "d303125e8b39b632081b320ca96869c729c3941fd29d1e34d8daae3e35038414", + "bytes": 7954, + "routes": [], + "models": [ { - "name": "PlainLanguageSummaryCreate", - "bases": [ - "BaseModel" - ], + "name": "PlanPolicyIngestRecord", + "bases": [], "fields": [ { - "name": "summary_id", - "type": "str | None", - "default": "None" - }, - { - "name": "section_version_id", + "name": "topic_key", "type": "str", - "default": "Field(min_length=1)" + "line": 15 }, { - "name": "summary_text", - "type": "str", - "default": "Field(min_length=1)" + "name": "policy", + "type": "PlanPolicy", + "line": 16 }, { - "name": "language_code", - "type": "str", - "default": "'en'" + "name": "adoption_status", + "type": "PlanStatus", + "line": 17 }, { - "name": "status", + "name": "source_document", "type": "str", - "default": "'draft'" + "line": 18 } ], - "line": 423, - "doc": "Request body for staff-drafted plain-language summaries." + "line": 14 }, { - "name": "TownlightMeetingsOrdinanceEventCreate", - "bases": [ - "BaseModel" - ], - "fields": [ - { - "name": "event_id", - "type": "str | None", - "default": "None" - }, - { - "name": "external_event_id", - "type": "str", - "default": "Field(min_length=1)" - }, - { - "name": "townlight_meetings_meeting_id", - "type": "str", - "default": "Field(min_length=1)" - }, - { - "name": "townlight_meetings_agenda_item_id", - "type": "str", - "default": "Field(min_length=1)" - }, - { - "name": "ordinance_number", - "type": "str", - "default": "Field(min_length=1)" - }, - { - "name": "title", - "type": "str", - "default": "Field(min_length=1)" - }, + "name": "PlanQuestionAnswer", + "bases": [], + "fields": [ { "name": "status", "type": "str", - "default": "'pending'" - }, - { - "name": "affected_sections", - "type": "list[str]", - "default": "Field(default_factory=list)" + "line": 23 }, { - "name": "source_document_url", + "name": "answer", "type": "str", - "default": "Field(min_length=1)" + "line": 24 }, { - "name": "source_document_hash", - "type": "str", - "default": "Field(min_length=1)" + "name": "citations", + "type": "tuple[str, ...]", + "line": 25 }, { - "name": "ordinance_text", - "type": "str", - "default": "''" + "name": "source_policy_ids", + "type": "tuple[str, ...]", + "line": 26 }, { - "name": "adopted_at", - "type": "datetime | None", - "default": "None" + "name": "review_required", + "type": "bool", + "line": 27 }, { - "name": "failure_reason", - "type": "str | None", - "default": "None" - } - ], - "line": 435, - "doc": "Request body for TownlightMeetings ordinance/adoption handoff intake." - }, - { - "name": "TownlightMeetingsOrdinanceEventResolve", - "bases": [ - "BaseModel" - ], - "fields": [ - { - "name": "section_version_id", + "name": "disclaimer", "type": "str", - "default": "Field(min_length=1)" + "line": 28 } ], - "line": 455, - "doc": "Request body for resolving a handoff after staff codifies the amendment." + "line": 22 }, { - "name": "ImportBundleCreate", - "bases": [ - "BaseModel" - ], + "name": "PlanAmendment", + "bases": [], "fields": [ { - "name": "job_id", - "type": "str | None", - "default": "None" - }, - { - "name": "connector_type", + "name": "amendment_id", "type": "str", - "default": "Field(min_length=1)" - }, - { - "name": "source", - "type": "SourceCreate", - "default": "" + "line": 33 }, { - "name": "sources", - "type": "list[SourceCreate]", - "default": "Field(default_factory=list)" + "name": "plan_type", + "type": "str", + "line": 34 }, { - "name": "titles", - "type": "list[TitleCreate]", - "default": "Field(default_factory=list)" + "name": "title", + "type": "str", + "line": 35 }, { - "name": "chapters", - "type": "list[ChapterCreate]", - "default": "Field(default_factory=list)" + "name": "adoption_status", + "type": "PlanStatus", + "line": 36 }, { - "name": "sections", - "type": "list[SectionCreate]", - "default": "Field(default_factory=list)" + "name": "adopted_date", + "type": "str | None", + "line": 37 }, { - "name": "versions", - "type": "list[SectionVersionCreate]", - "default": "Field(default_factory=list)" + "name": "citation", + "type": "str", + "line": 38 }, { - "name": "provenance", - "type": "dict[str, Any]", - "default": "Field(default_factory=dict)" + "name": "summary", + "type": "str", + "line": 39 } ], - "line": 463, - "doc": "Request body for local fixture/file-drop import jobs." + "line": 32 }, { - "name": "SharedPdfImportCreate", - "bases": [ - "BaseModel" - ], + "name": "ProgressTarget", + "bases": [], "fields": [ { - "name": "pdf_path", + "name": "target_id", "type": "str", - "default": "Field(min_length=1)" + "line": 44 }, { - "name": "force_reingest", - "type": "bool", - "default": "False" - } - ], - "line": 479, - "doc": "Request body for TownlightCore shared PDF ingestion into TownlightCode." - }, - { - "name": "CodifierSyncConfigureRequest", - "bases": [ - "BaseModel" - ], - "fields": [ + "name": "policy_id", + "type": "str", + "line": 45 + }, { - "name": "source_id", + "name": "metric", "type": "str", - "default": "Field(min_length=1)" + "line": 46 }, { - "name": "sync_schedule", + "name": "status", "type": "str", - "default": "Field(min_length=1)" + "line": 47 }, { - "name": "allowlisted_hosts", - "type": "list[str]", - "default": "Field(default_factory=list)" - } - ], - "line": 488, - "doc": "Request body for enabling staff-controlled codifier sync readiness." - }, - { - "name": "CodifierSyncRunRequest", - "bases": [ - "BaseModel" - ], - "fields": [ + "name": "evidence", + "type": "str", + "line": 48 + }, { - "name": "payload", - "type": "ImportBundleCreate", - "default": "" + "name": "citation", + "type": "str", + "line": 49 }, { - "name": "changed_since", - "type": "datetime | None", - "default": "None" + "name": "updated_at", + "type": "datetime", + "line": 50 } ], - "line": 498, - "doc": "Request body for a local codifier sync run." + "line": 43 } ], - "configuration": [ - { - "variable": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", - "default": "", - "line": 1988 - }, - { - "variable": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", - "default": "", - "line": 1999 - }, - { - "variable": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", - "default": "", - "line": 2010 - }, - { - "variable": "TOWNLIGHT_CODE_DEMO_ACTOR", - "default": "'demo-seed@portland.example.gov'", - "line": 2062 - }, - { - "variable": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", - "default": "", - "line": 173 - }, - { - "variable": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", - "default": "", - "line": 201 - }, - { - "variable": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", - "default": "", - "line": 224 - }, - { - "variable": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", - "default": "", - "line": 252 - }, - { - "variable": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", - "default": "", - "line": 1567 - }, - { - "variable": "DATABASE_URL", - "default": "", - "line": 1567 - }, - { - "variable": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", - "default": "", - "line": 2020 - }, - { - "variable": "TOWNLIGHT_CODE_DEMO_SEED", - "default": "''", - "line": 2056 - } - ] - }, - { - "source": "installed-owned-source/townlight_code/migrations/__init__.py", - "sha256": "4c8b91a2b40fe7951bf11bd74070344c9967b0feb5170a68d490305dc8333b8e", - "routes": [], - "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_code/migrations/env.py", - "sha256": "5526b8ac01c1bc652c77861bb77209503668127d5c9a8d810dda351dff7a158e", + "source": "townlight_planning/policy_lookup.py", + "sha256": "eef53ba621332d75f069f00ddcac34c19bca42d469a697fd22555eb3d11c68b2", + "bytes": 3155, "routes": [], - "models": [], - "configuration": [ + "models": [ { - "variable": "DATABASE_URL", - "default": "", - "line": 24 - } - ] - }, - { - "source": "installed-owned-source/townlight_code/migrations/guards.py", - "sha256": "110cca437db7e2507374b9e0d9d32739dbdbaf57c664ac89d8a4c56472c05d7f", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_code/migrations/versions/__init__.py", - "sha256": "74446fe86c7d899c1e4942b131ef47880cbb716011970d702ac78799902cc7ac", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_code/migrations/versions/townlight_code_0001_schema.py", - "sha256": "3361408fb75b2330c3dffa4c343bffa39ec96cb41b25d7c3e980f3efea69a950", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_code/migrations/versions/townlight_code_0002_source_registry_records.py", - "sha256": "a237d274d614a260242b2eee1661845fa96476445a8496c1fc2e8ff773fcc85c", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_code/migrations/versions/townlight_code_0003_popular_question_records.py", - "sha256": "d973ad1e13a5b84cc4bcc19d9977d9532d09388451c3872549180fa02ecfe609", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_code/migrations/versions/townlight_code_0004_section_lifecycle_records.py", - "sha256": "e11d0b3c4d08f32c00e513bbf336bf9f3ee2459c929aca0fed7c2158b688299f", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_code/migrations/versions/townlight_code_0005_staff_summary_records.py", - "sha256": "04d9a42402dbf503f9988dc07c4fe264390470d798d8e2d51983a1d7b8a5e601", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_code/migrations/versions/townlight_code_0006_ordinance_handoff_records.py", - "sha256": "bd2c85f222a0d4946298bdb580a36af174be378fbb3bdf62641457b87d5499fa", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_code/migrations/versions/townlight_code_0007_import_job_records.py", - "sha256": "d965ccf019d4059fe56ffd234955f45193d51d52a38b20fa1ba66e809493cb67", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_code/migrations/versions/townlight_code_0008_codifier_sync.py", - "sha256": "10b417a95e25d79ea3cc48fb3feedec0eea878f9580eba0b3c9e0b9413886366", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_code/migrations/versions/townlight_code_0009_operational_state.py", - "sha256": "5ff5a28d099a69b55c121fbf6ff9336cb8dee51e385966900510aba5df9a7540", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_code/migrations/versions/townlight_code_0010_handoff_resolution.py", - "sha256": "ed20579ff39863de49bd01a97a47b77d84b380f54f0aba7473c1aad360b11b4a", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_code/migrations/versions/townlight_code_0011_semantic_search.py", - "sha256": "4bf32028058db6ff90c19e2cf891886fef6d4e958ed7e72165e9a224ebd1b19d", - "routes": [], - "models": [], + "name": "PlanPolicy", + "bases": [], + "fields": [ + { + "name": "policy_id", + "type": "str", + "line": 17 + }, + { + "name": "plan_type", + "type": "str", + "line": 18 + }, + { + "name": "title", + "type": "str", + "line": 19 + }, + { + "name": "citation", + "type": "str", + "line": 20 + }, + { + "name": "excerpt", + "type": "str", + "line": 21 + }, + { + "name": "relevance", + "type": "str", + "line": 22 + }, + { + "name": "disclaimer", + "type": "str", + "line": 23 + } + ], + "line": 16 + } + ], "configuration": [] }, { - "source": "installed-owned-source/townlight_code/migrations/versions/townlight_code_0012_drop_local_search.py", - "sha256": "6ac60feecb72efbe78a788066ac58d790f6e6c460f4a71eea6ecf6cf30a6570d", + "source": "townlight_planning/policy_service.py", + "sha256": "27fa2483c62a98d4bb4b80a8b88598e7366c9a8ad421701e594e0f71d7f1ddc4", + "bytes": 5990, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_code/mock_city_environment.py", - "sha256": "91c1e1089e2956417fd520725847950c544166f0a93f2a0a63b7c1a9859c1189", + "source": "townlight_planning/public_explore.py", + "sha256": "2ff3160485f6a947db8e6cf38f56b7e0259c0f5492b714aed40dafd974351dd3", + "bytes": 7151, "routes": [], "models": [ { - "name": "MockCityCodifierContract", + "name": "Exploration", "bases": [], "fields": [ { - "name": "connector", + "name": "query", "type": "str", - "default": "" + "line": 37 }, { - "name": "publisher", + "name": "plan_type", "type": "str", - "default": "" + "line": 38 }, { - "name": "source_type", + "name": "goal", "type": "str", - "default": "" + "line": 39 }, { - "name": "interface_status", + "name": "topic", "type": "str", - "default": "" + "line": 40 }, { - "name": "source_url", + "name": "neighborhood", "type": "str", - "default": "" + "line": 41 }, { - "name": "retrieval_method", - "type": "str", - "default": "" + "name": "plans", + "type": "list", + "line": 42 }, { - "name": "auth_method", - "type": "str", - "default": "" + "name": "total", + "type": "int", + "line": 43 }, { - "name": "delta_query_param", - "type": "str", - "default": "" + "name": "review_required", + "type": "bool", + "line": 44 }, { - "name": "sample_file", + "name": "disclaimer", "type": "str", - "default": "" + "line": 45 }, { - "name": "source_owner", - "type": "str", - "default": "'City Clerk'" + "name": "empty_reason", + "type": "str | None", + "line": 46 + }, + { + "name": "facets", + "type": "dict", + "line": 49 } ], - "line": 31, - "doc": "A public, secret-free contract for one municipal-code source interface." - }, + "line": 34 + } + ], + "configuration": [] + }, + { + "source": "townlight_planning/public_explore_ui.py", + "sha256": "609356af82f905829d271060c9150ddb4f5576b201ae7d91a9a6027252406869", + "bytes": 9868, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_planning/public_ui.py", + "sha256": "8551ce36f854a4a7fc4573a20b73dbb0b6f01d7b60b7267d8c73b5f21f246ccc", + "bytes": 6946, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_planning/records_export.py", + "sha256": "f846832525f23c4183db12742de37c3ce68fe4c57219762e2a5ac81947965d1c", + "bytes": 1294, + "routes": [], + "models": [ { - "name": "MockCityCodeCheck", + "name": "PolicyExport", "bases": [], "fields": [ { - "name": "connector", + "name": "title", "type": "str", - "default": "" + "line": 12 }, { - "name": "ok", - "type": "bool", - "default": "" - }, - { - "name": "message", + "name": "policy_id", "type": "str", - "default": "" + "line": 13 }, { - "name": "fix", + "name": "format", "type": "str", - "default": "" + "line": 14 }, { - "name": "source_id", - "type": "str | None", - "default": "None" - }, - { - "name": "import_job_id", - "type": "str | None", - "default": "None" - }, - { - "name": "delta_request_url", - "type": "str | None", - "default": "None" + "name": "checklist", + "type": "tuple[str, ...]", + "line": 15 }, { - "name": "checked_sections", - "type": "tuple[str, ...]", - "default": "()" + "name": "retention_note", + "type": "str", + "line": 16 } ], - "line": 66, - "doc": "Result for one mock-city codifier contract check." + "line": 11 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_code/models.py", - "sha256": "15f328be4b05481401d8ccd296110136ef98e98634fe59af1c2aa729340e8e4f", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_code/operational_readiness.py", - "sha256": "002130b66583a7645218e271d515ca6b9295f7a8fe19ee9e85e6e52adacc07a9", - "routes": [], - "models": [], - "configuration": [] + "source": "townlight_planning/source_api.py", + "sha256": "42ff7e02374c4624112c104bcb8a246b62f3fbc68110b008e5a1fbfa66295207", + "bytes": 3468, + "routes": [ + { + "method": "POST", + "declared_path": "/source-imports", + "function": "import_sources", + "line": 51 + }, + { + "method": "GET", + "declared_path": "/source-plans/{plan_id}/history", + "function": "source_history", + "line": 63 + }, + { + "method": "GET", + "declared_path": "/source-revisions/{revision_id}", + "function": "source_revision", + "line": 68 + }, + { + "method": "GET", + "declared_path": "/source-revisions/{revision_id}/documents/{document_id}", + "function": "source_document", + "line": 76 + } + ], + "models": [ + { + "name": "ImportRequest", + "bases": [ + "BundleModel" + ], + "fields": [ + { + "name": "bundle", + "type": "PlanBundle", + "line": 46 + }, + { + "name": "expected_previous_revision", + "type": "str | None", + "line": 47 + } + ], + "line": 45 + } + ], + "configuration": [ + { + "environment": "TOWNLIGHT_PLANNING_POLICY_DB_URL", + "line": 31 + } + ] }, { - "source": "installed-owned-source/townlight_code/operational_state.py", - "sha256": "6d73c3201fc449de9bf6678d129184533323960f82ccb0a5c0f6dcb147421b0f", + "source": "townlight_planning/source_bundle.py", + "sha256": "f6547516067e27697dfcd6ba80de6e2ca03d1473370209aa354a5bf95b7db98a", + "bytes": 6466, "routes": [], "models": [ { - "name": "OperationalStateRecord", - "bases": [], + "name": "SourceDocument", + "bases": [ + "BundleModel" + ], "fields": [ { - "name": "record_id", + "name": "document_id", "type": "str", - "default": "" + "line": 19 }, { - "name": "lane", + "name": "filename", "type": "str", - "default": "" + "line": 20 }, { - "name": "record_type", - "type": "str", - "default": "" + "name": "media_type", + "type": "Literal['text/plain', 'text/markdown', 'application/pdf', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document']", + "line": 21 }, { - "name": "subject_id", + "name": "sha256", "type": "str", - "default": "" + "line": 25 }, { - "name": "status", + "name": "content_base64", + "type": "str", + "line": 26 + } + ], + "line": 18 + }, + { + "name": "SourcePolicy", + "bases": [ + "BundleModel" + ], + "fields": [ + { + "name": "policy_id", "type": "str", - "default": "" + "line": 63 }, { - "name": "actor", + "name": "document_id", "type": "str", - "default": "'system'" + "line": 64 }, { - "name": "attempt_count", - "type": "int", - "default": "0" + "name": "goal", + "type": "str", + "line": 65 }, { - "name": "next_attempt_at", - "type": "datetime | None", - "default": "None" + "name": "objective", + "type": "str", + "line": 66 }, { - "name": "cursor_key", - "type": "str | None", - "default": "None" + "name": "topic_key", + "type": "str", + "line": 67 }, { - "name": "cursor_value", - "type": "str | None", - "default": "None" + "name": "neighborhoods", + "type": "list[str]", + "line": 68 }, { - "name": "replay_of", - "type": "str | None", - "default": "None" + "name": "title", + "type": "str", + "line": 69 }, { - "name": "payload_hash", - "type": "str | None", - "default": "None" + "name": "citation", + "type": "str", + "line": 70 }, { - "name": "details", - "type": "dict[str, Any]", - "default": "field(default_factory=dict)" + "name": "anchor", + "type": "str", + "line": 71 }, { - "name": "failure", - "type": "dict[str, Any] | None", - "default": "None" + "name": "excerpt", + "type": "str", + "line": 72 }, { - "name": "created_at", - "type": "datetime", - "default": "field(default_factory=lambda: datetime.now(UTC))" + "name": "relevance", + "type": "str", + "line": 73 }, { - "name": "updated_at", - "type": "datetime", - "default": "field(default_factory=lambda: datetime.now(UTC))" + "name": "staff_verified", + "type": "Literal[True]", + "line": 74 } ], - "line": 20, - "doc": "One operator-visible operational state record." - } - ], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_code/ordinance_handoff.py", - "sha256": "5e98eefc3e510efaf0d5973927aa3506f8b652d319320f745a831bef0cb5897b", - "routes": [], - "models": [ + "line": 62 + }, { - "name": "OrdinanceEvent", - "bases": [], + "name": "AdoptionEvidence", + "bases": [ + "BundleModel" + ], "fields": [ { - "name": "event_id", - "type": "str", - "default": "" + "name": "kind", + "type": "Literal['manual-record', 'meeting-reference', 'source-document']", + "line": 78 }, { - "name": "external_event_id", + "name": "reference", "type": "str", - "default": "" + "line": 79 }, { - "name": "townlight_meetings_meeting_id", - "type": "str", - "default": "" + "name": "document_id", + "type": "str | None", + "line": 80 }, { - "name": "townlight_meetings_agenda_item_id", + "name": "note", "type": "str", - "default": "" + "line": 81 + } + ], + "line": 77 + }, + { + "name": "PlanBundle", + "bases": [ + "BundleModel" + ], + "fields": [ + { + "name": "schema_version", + "type": "Literal[1]", + "line": 85 }, { - "name": "ordinance_number", + "name": "plan_id", "type": "str", - "default": "" + "line": 86 }, { "name": "title", "type": "str", - "default": "" + "line": 87 }, { - "name": "status", + "name": "jurisdiction", "type": "str", - "default": "" + "line": 88 }, { - "name": "affected_sections", - "type": "list[str]", - "default": "" + "name": "plan_type", + "type": "PlanType", + "line": 89 }, { - "name": "source_document_url", - "type": "str", - "default": "" + "name": "status", + "type": "Literal['pending', 'adopted', 'superseded']", + "line": 90 }, { - "name": "source_document_hash", - "type": "str", - "default": "" + "name": "visibility", + "type": "Literal['staff', 'public']", + "line": 91 }, { - "name": "ordinance_text", - "type": "str", - "default": "''" + "name": "dataset_kind", + "type": "Literal['municipal', 'demo']", + "line": 92 }, { - "name": "adopted_at", - "type": "datetime | None", - "default": "None" + "name": "source_date", + "type": "date", + "line": 93 }, { - "name": "failure_reason", - "type": "str | None", - "default": "None" + "name": "adopted_on", + "type": "date | None", + "line": 94 }, { - "name": "resolved_section_version_id", - "type": "str | None", - "default": "None" + "name": "effective_on", + "type": "date | None", + "line": 95 }, { - "name": "resolved_by", - "type": "str | None", - "default": "None" + "name": "change_note", + "type": "str", + "line": 96 }, { - "name": "resolved_at", - "type": "datetime | None", - "default": "None" + "name": "reviewer_label", + "type": "str", + "line": 97 }, { - "name": "created_by", - "type": "str", - "default": "'unknown'" + "name": "documents", + "type": "list[SourceDocument]", + "line": 98 }, { - "name": "created_at", - "type": "datetime", - "default": "field(default_factory=lambda: datetime.now(UTC))" + "name": "policies", + "type": "list[SourcePolicy]", + "line": 99 + }, + { + "name": "adoption_evidence", + "type": "list[AdoptionEvidence]", + "line": 100 } ], - "line": 39, - "doc": "" - }, + "line": 84 + } + ], + "configuration": [] + }, + { + "source": "townlight_planning/source_schema.py", + "sha256": "24e5350df4f9e1439327a8e72097dc50b7e4a35b1fe8f87d9db0ab4d92114b52", + "bytes": 4535, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_planning/source_store.py", + "sha256": "7d04677e0c94acd7831d5bfad930c7e8d1583fb1ed9ca6e654da9df4fded76bb", + "bytes": 14109, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_planning/staff_analysis.py", + "sha256": "2cb81dca0930e2289daa9fa8550b7ee8518d114efc4c3be89ea8b954eb3cec1d", + "bytes": 1369, + "routes": [], + "models": [ { - "name": "HandoffAuditEvent", + "name": "StaffAnalysisDraft", "bases": [], "fields": [ { - "name": "event_id", + "name": "project_name", "type": "str", - "default": "" + "line": 13 }, { - "name": "event_type", + "name": "heading", "type": "str", - "default": "" + "line": 14 }, { - "name": "actor", - "type": "str", - "default": "" + "name": "bullets", + "type": "tuple[str, ...]", + "line": 15 }, { - "name": "target_id", - "type": "str", - "default": "" + "name": "citations", + "type": "tuple[str, ...]", + "line": 16 }, { - "name": "created_at", - "type": "datetime", - "default": "field(default_factory=lambda: datetime.now(UTC))" + "name": "review_required", + "type": "bool", + "line": 17 + }, + { + "name": "disclaimer", + "type": "str", + "line": 18 } ], - "line": 69, - "doc": "" + "line": 12 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_code/plain_language.py", - "sha256": "074b7aae42a3c4ee7ae5e64726a5fbbe151039cb51467f89f47b977e93e9b2bd", - "routes": [], + "source": "townlight_planning/workflow_api.py", + "sha256": "4aaf78976e900770cb6d1d1e7bdb8fdf489646a541ad460b8261786751a265e3", + "bytes": 5797, + "routes": [ + { + "method": "POST", + "declared_path": "/analyses", + "function": "create_analysis", + "line": 45 + }, + { + "method": "POST", + "declared_path": "/analyses/{analysis_id}/revisions", + "function": "revise_analysis", + "line": 52 + }, + { + "method": "GET", + "declared_path": "/analyses/{analysis_id}", + "function": "read_analysis", + "line": 59 + }, + { + "method": "GET", + "declared_path": "/analyses/{analysis_id}/history", + "function": "analysis_history", + "line": 67 + }, + { + "method": "POST", + "declared_path": "/analyses/{analysis_id}/snapshots", + "function": "create_snapshot", + "line": 77 + }, + { + "method": "GET", + "declared_path": "/snapshots/{snapshot_id}", + "function": "read_snapshot", + "line": 82 + }, + { + "method": "GET", + "declared_path": "/snapshots/{snapshot_id}/export", + "function": "export_snapshot", + "line": 90 + }, + { + "method": "POST", + "declared_path": "/snapshots/{snapshot_id}/access-advice", + "function": "access_advice", + "line": 98 + }, + { + "method": "POST", + "declared_path": "/policies/search", + "function": "search_policies", + "line": 108 + }, + { + "method": "POST", + "declared_path": "/connections/search", + "function": "search_connections", + "line": 118 + }, + { + "method": "GET", + "declared_path": "/policy-sources/{revision_id}/documents/{document_id}", + "function": "public_original", + "line": 123 + } + ], "models": [ { - "name": "PlainLanguageSummary", - "bases": [], + "name": "SnapshotInput", + "bases": [ + "BundleModel" + ], "fields": [ { - "name": "summary_id", + "name": "expected_revision", "type": "str", - "default": "" + "line": 72 }, { - "name": "section_id", - "type": "str", - "default": "" - }, + "name": "visibility", + "type": "Literal['staff_only', 'public']", + "line": 73 + } + ], + "line": 71 + }, + { + "name": "SearchInput", + "bases": [ + "BundleModel" + ], + "fields": [ { - "name": "section_version_id", + "name": "query", "type": "str", - "default": "" + "line": 103 }, { - "name": "summary_text", - "type": "str", - "default": "" - }, + "name": "plan_type", + "type": "str | None", + "line": 104 + } + ], + "line": 102 + }, + { + "name": "ConnectionSearch", + "bases": [ + "BundleModel" + ], + "fields": [ { - "name": "status", - "type": "str", - "default": "" + "name": "provider", + "type": "Literal['meetings', 'zoning']", + "line": 113 }, { - "name": "language_code", + "name": "query", "type": "str", - "default": "'en'" - }, + "line": 114 + } + ], + "line": 112 + } + ], + "configuration": [] + }, + { + "source": "townlight_planning/workflow_models.py", + "sha256": "26e6d23b365d440c827351d639fbe825ca28f0d76c98da5f64e34a464d856ffe", + "bytes": 2748, + "routes": [], + "models": [ + { + "name": "PolicySelection", + "bases": [ + "BundleModel" + ], + "fields": [ { - "name": "created_by", + "name": "plan_id", "type": "str", - "default": "'unknown'" - }, - { - "name": "approved_by", - "type": "str | None", - "default": "None" + "line": 8 }, { - "name": "approved_at", - "type": "datetime | None", - "default": "None" + "name": "revision_id", + "type": "str", + "line": 9 }, { - "name": "created_at", - "type": "datetime", - "default": "field(default_factory=lambda: datetime.now(UTC))" + "name": "policy_id", + "type": "str", + "line": 10 } ], - "line": 31, - "doc": "" + "line": 7 }, { - "name": "SummaryAuditEvent", - "bases": [], + "name": "LinkedSource", + "bases": [ + "BundleModel" + ], "fields": [ { - "name": "event_id", - "type": "str", - "default": "" + "name": "provider", + "type": "Literal['meetings', 'zoning']", + "line": 14 }, { - "name": "event_type", + "name": "source_id", "type": "str", - "default": "" + "line": 15 }, { - "name": "actor", + "name": "expected_sha256", "type": "str", - "default": "" + "line": 16 }, { - "name": "section_id", - "type": "str", - "default": "" + "name": "relation", + "type": "Literal['adoption-evidence', 'hearing', 'context', 'precedent']", + "line": 17 + } + ], + "line": 13 + }, + { + "name": "Consideration", + "bases": [ + "BundleModel" + ], + "fields": [ + { + "name": "policy", + "type": "PolicySelection", + "line": 21 }, { - "name": "target_id", - "type": "str", - "default": "" + "name": "stance", + "type": "Literal['supporting', 'conflicting', 'uncertain']", + "line": 22 }, { - "name": "created_at", - "type": "datetime", - "default": "field(default_factory=lambda: datetime.now(UTC))" + "name": "note", + "type": "str", + "line": 23 } ], - "line": 49, - "doc": "" - } - ], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_code/public_discovery.py", - "sha256": "f87497befbd3f75db94c4db0f36fb04fc1a34af8eba73a425ff49edb8dfc20ae", - "routes": [], - "models": [ + "line": 20 + }, { - "name": "PopularQuestion", - "bases": [], + "name": "AnalysisInput", + "bases": [ + "BundleModel" + ], "fields": [ { - "name": "question_id", + "name": "expected_previous_revision", + "type": "str | None", + "line": 27 + }, + { + "name": "project_name", "type": "str", - "default": "" + "line": 28 }, { - "name": "question_text", + "name": "proposal", "type": "str", - "default": "" + "line": 29 }, { - "name": "section_id", - "type": "str", - "default": "" + "name": "selected_policies", + "type": "list[PolicySelection]", + "line": 30 }, { - "name": "section_number", - "type": "str", - "default": "" + "name": "considerations", + "type": "list[Consideration]", + "line": 31 }, { - "name": "section_heading", + "name": "analysis_text", "type": "str", - "default": "" + "line": 32 }, { - "name": "answer_excerpt", + "name": "public_summary", "type": "str", - "default": "" + "line": 33 }, { - "name": "citation_payload", - "type": "dict[str, Any]", - "default": "" + "name": "staff_notes", + "type": "str", + "line": 34 }, { "name": "audience", - "type": "str", - "default": "'public'" + "type": "Literal['staff', 'public']", + "line": 35 }, { - "name": "status", - "type": "str", - "default": "'draft'" + "name": "review_state", + "type": "Literal['draft', 'reviewed']", + "line": 36 }, { - "name": "is_popular", - "type": "bool", - "default": "True" + "name": "reviewer_label", + "type": "str", + "line": 37 }, { - "name": "approved_by", - "type": "str | None", - "default": "None" + "name": "reviewed_on", + "type": "date | None", + "line": 38 }, { - "name": "approved_at", - "type": "datetime | None", - "default": "None" + "name": "review_notes", + "type": "str", + "line": 39 }, { - "name": "created_at", - "type": "datetime", - "default": "field(default_factory=lambda: datetime.now(UTC))" + "name": "linked_sources", + "type": "list[LinkedSource]", + "line": 40 } ], - "line": 34, - "doc": "" + "line": 26 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_code/public_exports.py", - "sha256": "2d413d312f8baf1e790bb4205ad93ac25928f1afefa3aca1898d91092085bcc4", + "source": "townlight_planning/workflow_schema.py", + "sha256": "4976be5b782694c5b5ab126bc47d3fff1cd96fdec4b04a6fa9b01871e23ef98b", + "bytes": 2272, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_code/public_lookup.py", - "sha256": "a3c62b6aaa3de1ef98ac824fd5806e61bd444ae61241e2a19f0f7dff3a3cca79", + "source": "townlight_planning/workflow_store.py", + "sha256": "abf17394c1d03528208f26343afece0dd928e96920e9ecc7c46885d0f1543aef", + "bytes": 17298, + "routes": [], + "models": [], + "configuration": [] + } + ] + }, + "permitting": { + "repository": "townlight/permit", + "repository_head": "7d3f0cf0aff294c2a2372ae393d340f4e4ce1bc8", + "working_tree_modified": true, + "principal_import": "townlight_permitting", + "source": [ + { + "source": "townlight_permitting/__init__.py", + "sha256": "bedf11d628d9eb33c3d6724f11c532296889b719a6b5fe71c23b4eec6c7e55d8", + "bytes": 68, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_code/qa_harness.py", - "sha256": "bc040cb0c4ff124f13a63e10fbcb26d478a06da5364e7fa18d177b40af269797", + "source": "townlight_permitting/connections.py", + "sha256": "4159a4eb4a407bebbefeb49bb760788cff3ac51a45c34af094d3be4b5a746798", + "bytes": 1995, "routes": [], - "models": [ - { - "name": "QuestionRequestContext", - "bases": [], - "fields": [ - { - "name": "question", - "type": "str", - "default": "" - }, - { - "name": "section_number", - "type": "str | None", - "default": "None" - }, - { - "name": "as_of", - "type": "date | None", - "default": "None" - } - ], - "line": 37, - "doc": "Normalized input for deterministic question answering." - } - ], + "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_code/real_municipal_fixtures.py", - "sha256": "a88b400d5b5bb8d6a74ec8a29d793c3e51ab94226e0f0b8abbde7030f667280a", + "source": "townlight_permitting/intake_review.py", + "sha256": "50aff3cf1b85c1789bf989edeaba444e124e42c49449c845fe0cd66053d9738c", + "bytes": 1626, "routes": [], "models": [ { - "name": "PortlandSectionFixture", + "name": "IntakeReadiness", "bases": [], "fields": [ { - "name": "section_id", - "type": "str", - "default": "" - }, - { - "name": "section_number", - "type": "str", - "default": "" - }, - { - "name": "heading", - "type": "str", - "default": "" - }, - { - "name": "source_id", + "name": "project_type", "type": "str", - "default": "" + "line": 12 }, { - "name": "source_url", + "name": "status", "type": "str", - "default": "" + "line": 13 }, { - "name": "file_reference", - "type": "str", - "default": "" + "name": "missing_or_unclear", + "type": "tuple[str, ...]", + "line": 14 }, { - "name": "body", + "name": "next_step", "type": "str", - "default": "" + "line": 15 }, { - "name": "effective_start", + "name": "disclaimer", "type": "str", - "default": "" - }, - { - "name": "adoption_event_id", - "type": "str | None", - "default": "None" + "line": 16 } ], - "line": 22, - "doc": "" + "line": 11 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_code/section_lifecycle.py", - "sha256": "34096b4ca4fa8f65628d33761609044f29a03bf0d89a5da09085440e56d149f2", + "source": "townlight_permitting/integration_mocks.py", + "sha256": "dbdd49fba6836940936e5112076582a43d94bcff8c9c87faa2f80a49e4e5736c", + "bytes": 2023, "routes": [], "models": [ { - "name": "CodeTitle", + "name": "IntegrationMockResult", "bases": [], "fields": [ { - "name": "title_id", + "name": "scenario", "type": "str", - "default": "" + "line": 11 }, { - "name": "title_number", + "name": "status", "type": "str", - "default": "" + "line": 12 }, { - "name": "title_name", - "type": "str", - "default": "" + "name": "review_required", + "type": "bool", + "line": 13 }, { - "name": "sort_order", - "type": "int", - "default": "0" + "name": "findings", + "type": "tuple[str, ...]", + "line": 14 }, { - "name": "created_at", - "type": "datetime", - "default": "field(default_factory=lambda: datetime.now(UTC))" + "name": "boundary", + "type": "str", + "line": 15 } ], - "line": 42, - "doc": "" + "line": 10 + } + ], + "configuration": [] + }, + { + "source": "townlight_permitting/main.py", + "sha256": "6c554e6d74ff5be743db71541d4b05f0c7118f65cb442ec0b784eaa131f99cd7", + "bytes": 24021, + "routes": [ + { + "method": "GET", + "declared_path": "/", + "function": "root", + "line": 104 }, { - "name": "CodeChapter", - "bases": [], + "method": "GET", + "declared_path": "/health", + "function": "health", + "line": 124 + }, + { + "method": "GET", + "declared_path": "/townlight_permitting", + "function": "public_townlight_permitting_page", + "line": 163 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_permitting/requirements/lookup", + "function": "requirement_lookup", + "line": 170 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_permitting/intake/review", + "function": "intake_review", + "line": 179 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_permitting/pathway/explain", + "function": "pathway_explain", + "line": 305 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_permitting/pathway/explain-assisted", + "function": "pathway_explain_assisted", + "line": 319 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_permitting/context/development-review", + "function": "development_review_context", + "line": 339 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_permitting/integrations/mock/development-review", + "function": "integration_mock_development_review", + "line": 372 + }, + { + "method": "GET", + "declared_path": "/api/v1/townlight_permitting/intake/{intake_id}", + "function": "get_intake_review", + "line": 384 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_permitting/submittal/outline", + "function": "submittal_outline", + "line": 411 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_permitting/export", + "function": "permit_export", + "line": 421 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_permitting/staff/reviews", + "function": "create_staff_review", + "line": 431 + }, + { + "method": "GET", + "declared_path": "/api/v1/townlight_permitting/staff/reviews", + "function": "list_staff_reviews", + "line": 449 + }, + { + "method": "PATCH", + "declared_path": "/api/v1/townlight_permitting/staff/reviews/{review_id}", + "function": "update_staff_review", + "line": 466 + }, + { + "method": "GET", + "declared_path": "/api/v1/townlight_permitting/staff/reviews/summary", + "function": "staff_review_summary", + "line": 498 + } + ], + "models": [ + { + "name": "RequirementLookupRequest", + "bases": [ + "BaseModel" + ], "fields": [ { - "name": "chapter_id", + "name": "project_type", "type": "str", - "default": "" + "line": 46 }, { - "name": "title_id", + "name": "location_context", "type": "str", - "default": "" - }, + "line": 47 + } + ], + "line": 45 + }, + { + "name": "IntakeReviewRequest", + "bases": [ + "BaseModel" + ], + "fields": [ { - "name": "chapter_number", + "name": "proposal", "type": "str", - "default": "" + "line": 51 }, { - "name": "chapter_name", + "name": "project_type", "type": "str", - "default": "" - }, - { - "name": "sort_order", - "type": "int", - "default": "0" - }, - { - "name": "created_at", - "type": "datetime", - "default": "field(default_factory=lambda: datetime.now(UTC))" + "line": 52 } ], - "line": 51, - "doc": "" + "line": 50 }, { - "name": "CodeSection", - "bases": [], + "name": "DevelopmentReviewContextRequest", + "bases": [ + "BaseModel" + ], "fields": [ { - "name": "section_id", - "type": "str", - "default": "" - }, - { - "name": "chapter_id", + "name": "project_type", "type": "str", - "default": "" + "line": 58 }, { - "name": "section_number", + "name": "proposal", "type": "str", - "default": "" + "line": 59 }, { - "name": "section_heading", + "name": "location_context", "type": "str", - "default": "" + "line": 60 }, { - "name": "parent_section_id", + "name": "zoning_context_id", "type": "str | None", - "default": "None" - }, - { - "name": "sort_order", - "type": "int", - "default": "0" - }, - { - "name": "administrative_regulation_refs", - "type": "list[str]", - "default": "field(default_factory=list)" - }, - { - "name": "resolution_refs", - "type": "list[str]", - "default": "field(default_factory=list)" + "line": 61 }, { - "name": "policy_refs", - "type": "list[str]", - "default": "field(default_factory=list)" + "name": "code_context_id", + "type": "str | None", + "line": 62 + } + ], + "line": 55 + }, + { + "name": "SubmittalOutlineRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "project_name", + "type": "str", + "line": 66 }, { - "name": "approved_summary_refs", - "type": "list[str]", - "default": "field(default_factory=list)" + "name": "proposal", + "type": "str", + "line": 67 }, { - "name": "created_at", - "type": "datetime", - "default": "field(default_factory=lambda: datetime.now(UTC))" + "name": "project_type", + "type": "str", + "line": 68 } ], - "line": 61, - "doc": "" + "line": 65 }, { - "name": "SectionVersion", - "bases": [], + "name": "PermitExportRequest", + "bases": [ + "BaseModel" + ], "fields": [ { - "name": "version_id", + "name": "title", "type": "str", - "default": "" + "line": 72 }, { - "name": "section_id", + "name": "project_type", "type": "str", - "default": "" + "line": 73 }, { - "name": "source_id", + "name": "format", "type": "str", - "default": "" - }, + "line": 74 + } + ], + "line": 71 + }, + { + "name": "StaffReviewCreateRequest", + "bases": [ + "BaseModel" + ], + "fields": [ { - "name": "version_label", + "name": "proposal", "type": "str", - "default": "" + "line": 78 }, { - "name": "body", + "name": "project_type", "type": "str", - "default": "" + "line": 79 }, { - "name": "effective_start", - "type": "date", - "default": "" + "name": "reason", + "type": "str", + "line": 80 }, { - "name": "effective_end", - "type": "date | None", - "default": "None" - }, + "name": "intake_id", + "type": "str | None", + "line": 81 + } + ], + "line": 77 + }, + { + "name": "StaffReviewUpdateRequest", + "bases": [ + "BaseModel" + ], + "fields": [ { "name": "status", "type": "str", - "default": "'draft'" - }, - { - "name": "is_current", - "type": "bool", - "default": "False" + "line": 85 }, { - "name": "adoption_event_id", + "name": "assigned_to", "type": "str | None", - "default": "None" + "line": 86 }, { - "name": "amendment_event_id", + "name": "resolution", "type": "str | None", - "default": "None" + "line": 87 + } + ], + "line": 84 + }, + { + "name": "PathwayRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "project_type", + "type": "str", + "line": 91 }, { - "name": "amendment_summary", - "type": "str | None", - "default": "None" + "name": "proposal", + "type": "str", + "line": 92 }, { - "name": "prior_version_id", - "type": "str | None", - "default": "None" + "name": "location_context", + "type": "str", + "line": 93 }, { - "name": "created_at", - "type": "datetime", - "default": "field(default_factory=lambda: datetime.now(UTC))" + "name": "use_model_assistance", + "type": "bool", + "line": 94 + } + ], + "line": 90 + }, + { + "name": "IntegrationMockRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "scenario", + "type": "str", + "line": 100 } ], - "line": 76, - "doc": "" + "line": 97 } ], "configuration": [ { - "variable": "TOWNLIGHT_CODE_SEMANTIC_SCORE_FLOOR", - "default": "", - "line": 929 + "environment": "TOWNLIGHT_PERMITTING_INTAKE_DB_URL", + "line": 508 + }, + { + "environment": "TOWNLIGHT_PERMITTING_LLM_MODEL", + "line": 233 + }, + { + "environment": "TOWNLIGHT_PERMITTING_LLM_PROVIDER", + "line": 218 } ] }, { - "source": "installed-owned-source/townlight_code/semantic_search.py", - "sha256": "85de9cb0b861a7551a701bd4082ec3343728831c8bf20e45d90719db60f8b78c", + "source": "townlight_permitting/migrations/__init__.py", + "sha256": "ef1b983ce930e61e3f65c585e38d76dc54005d07ad81dcc67bd0bffc842b66af", + "bytes": 1872, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_permitting/migrations/env.py", + "sha256": "b802c986b358b031ff58863a84322c332fcef243d7376fa60e44bcc9563bff88", + "bytes": 439, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_permitting/migrations/versions/townlight_permitting_0001_connected.py", + "sha256": "8ca41fd995d6c4b4ed938d6aa5b13467df6db04224344544a0ad38d40d420765", + "bytes": 1343, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_permitting/pathway.py", + "sha256": "52b79c81f8cf016145a074f877171896a99268b31917314e221b2ca395698e75", + "bytes": 14992, "routes": [], "models": [ { - "name": "SemanticDocument", + "name": "AssistantProvider", + "bases": [ + "Protocol" + ], + "fields": [ + { + "name": "name", + "type": "str", + "line": 77 + } + ], + "line": 74 + }, + { + "name": "PathwayStage", "bases": [], "fields": [ { - "name": "id", + "name": "key", "type": "str", - "default": "" + "line": 99 }, { - "name": "version_id", + "name": "label", "type": "str", - "default": "" + "line": 100 }, { - "name": "text", + "name": "source_id", + "type": "str", + "line": 101 + }, + { + "name": "typical_time", "type": "str", - "default": "" + "line": 102 } ], - "line": 24, - "doc": "" + "line": 91 }, { - "name": "EmbeddingConfig", + "name": "Pathway", "bases": [], "fields": [ { - "name": "mode", + "name": "project_type", "type": "str", - "default": "" + "line": 107 }, { - "name": "base_url", + "name": "title", "type": "str", - "default": "" + "line": 108 }, { - "name": "model", + "name": "stages", + "type": "tuple[PathwayStage, ...]", + "line": 109 + }, + { + "name": "attachments_citation", "type": "str", - "default": "" + "line": 110 }, { - "name": "timeout_seconds", - "type": "float", - "default": "" + "name": "attachments", + "type": "tuple[str, ...]", + "line": 111 + }, + { + "name": "note", + "type": "str", + "line": 112 } ], - "line": 31, - "doc": "" - } - ], - "configuration": [ - { - "variable": "TOWNLIGHT_CODE_OLLAMA_EMBEDDING_MODEL", - "default": "DEFAULT_EMBEDDING_MODEL", - "line": 49 - }, - { - "variable": "TOWNLIGHT_CODE_OLLAMA_EMBEDDING_URL", - "default": "", - "line": 45 - }, - { - "variable": "TOWNLIGHT_CODE_OLLAMA_URL", - "default": "", - "line": 46 - }, - { - "variable": "OLLAMA_BASE_URL", - "default": "", - "line": 47 + "line": 106 }, { - "variable": "TOWNLIGHT_CODE_OLLAMA_EMBEDDING_TIMEOUT_SECONDS", - "default": "'30'", - "line": 50 - }, - { - "variable": "TOWNLIGHT_CODE_EMBEDDING_MODE", - "default": "''", - "line": 40 - } - ] - }, - { - "source": "installed-owned-source/townlight_code/shared_ingestion.py", - "sha256": "caf8ec1c4d1da5a485ec96d0ae04e800e29f02fe1a71809cbebe0718c574f987", - "routes": [], - "models": [ - { - "name": "SharedIngestionImport", + "name": "PathwayExplanation", "bases": [], "fields": [ { - "name": "payload", - "type": "dict[str, Any]", - "default": "" + "name": "project_type", + "type": "str", + "line": 135 }, { - "name": "proof", - "type": "dict[str, Any]", - "default": "" - } - ], - "line": 65, - "doc": "A TownlightCore-ingested document plus a TownlightCode local-bundle payload." - } - ], - "configuration": [ - { - "variable": "DATABASE_URL", - "default": "", - "line": 172 - }, - { - "variable": "TOWNLIGHT_CODE_SHARED_INGEST_CHUNK_SIZE", - "default": "'500'", - "line": 88 - }, - { - "variable": "TOWNLIGHT_CODE_SHARED_INGEST_CHUNK_OVERLAP", - "default": "'50'", - "line": 89 - }, - { - "variable": "TOWNLIGHT_CODE_SHARED_INGEST_ALLOWED_DIRS", - "default": "", - "line": 252 - }, - { - "variable": "TOWNLIGHT_CODE_SHARED_INGEST_ALLOWED_DIR", - "default": "", - "line": 252 + "name": "title", + "type": "str", + "line": 136 + }, + { + "name": "likely_permits", + "type": "list[dict[str, str]]", + "line": 137 + }, + { + "name": "attachments", + "type": "list[dict[str, str]]", + "line": 138 + }, + { + "name": "timeline", + "type": "list[dict[str, str]]", + "line": 139 + }, + { + "name": "unavailable", + "type": "list[dict[str, str]]", + "line": 140 + }, + { + "name": "fee", + "type": "dict[str, object]", + "line": 141 + }, + { + "name": "resident_explanation", + "type": "str", + "line": 142 + }, + { + "name": "assistance", + "type": "dict[str, object]", + "line": 143 + }, + { + "name": "review_required", + "type": "bool", + "line": 144 + }, + { + "name": "determination_made", + "type": "bool", + "line": 145 + }, + { + "name": "citations", + "type": "list[str]", + "line": 146 + }, + { + "name": "boundary", + "type": "str", + "line": 147 + }, + { + "name": "disclaimer", + "type": "str", + "line": 148 + } + ], + "line": 132 } - ] + ], + "configuration": [] }, { - "source": "installed-owned-source/townlight_code/source_registry.py", - "sha256": "292e2286802f36458a7468b749f81ff82277cc5f404fbf7b0ac7dd88f5d79651", + "source": "townlight_permitting/persistence.py", + "sha256": "71b13022235e2f7a248c0638f3f2909e292b3519812dbbf33ac75bf7d78bf315", + "bytes": 14453, "routes": [], "models": [ { - "name": "CodeSource", + "name": "StoredIntakeReview", "bases": [], "fields": [ { - "name": "source_id", + "name": "intake_id", "type": "str", - "default": "" + "line": 73 }, { - "name": "name", + "name": "project_type", "type": "str", - "default": "" + "line": 74 }, { - "name": "publisher", + "name": "proposal", "type": "str", - "default": "" + "line": 75 }, { - "name": "source_type", + "name": "status", "type": "str", - "default": "" + "line": 76 }, { - "name": "source_category", - "type": "str", - "default": "" + "name": "missing_or_unclear", + "type": "tuple[str, ...]", + "line": 77 }, { - "name": "source_url", - "type": "str | None", - "default": "None" + "name": "next_step", + "type": "str", + "line": 78 }, { - "name": "file_reference", - "type": "str | None", - "default": "None" + "name": "disclaimer", + "type": "str", + "line": 79 }, { - "name": "retrieved_at", - "type": "datetime | None", - "default": "None" - }, + "name": "created_at", + "type": "datetime", + "line": 80 + } + ], + "line": 72 + }, + { + "name": "StaffReviewQueueItem", + "bases": [], + "fields": [ { - "name": "retrieval_method", - "type": "str | None", - "default": "None" + "name": "review_id", + "type": "str", + "line": 85 }, { - "name": "checksum", + "name": "intake_id", "type": "str | None", - "default": "None" + "line": 86 }, { - "name": "source_owner", - "type": "str | None", - "default": "None" + "name": "project_type", + "type": "str", + "line": 87 }, { - "name": "is_official", - "type": "bool", - "default": "True" + "name": "proposal", + "type": "str", + "line": 88 }, { - "name": "official_status_note", - "type": "str | None", - "default": "None" + "name": "status", + "type": "str", + "line": 89 }, { - "name": "status", + "name": "reason", "type": "str", - "default": "'draft'" + "line": 90 }, { - "name": "staff_notes", + "name": "assigned_to", + "type": "str | None", + "line": 91 + }, + { + "name": "resolution", "type": "str | None", - "default": "None" + "line": 92 + }, + { + "name": "created_by", + "type": "str", + "line": 93 }, { "name": "created_at", "type": "datetime", - "default": "field(default_factory=lambda: datetime.now(UTC))" + "line": 94 }, { "name": "updated_at", "type": "datetime", - "default": "field(default_factory=lambda: datetime.now(UTC))" + "line": 95 + }, + { + "name": "visibility", + "type": "str", + "line": 96 + } + ], + "line": 84 + }, + { + "name": "StaffReviewSummary", + "bases": [], + "fields": [ + { + "name": "total_items", + "type": "int", + "line": 101 + }, + { + "name": "by_status", + "type": "dict[str, int]", + "line": 102 + }, + { + "name": "open_items", + "type": "int", + "line": 103 + }, + { + "name": "generated_at", + "type": "datetime", + "line": 104 + }, + { + "name": "visibility", + "type": "str", + "line": 105 } ], - "line": 74, - "doc": "Runtime representation of an official or explicitly non-official source." + "line": 100 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_code/staff_code.py", - "sha256": "90b3d8ac3c6eb0c65831b47d8f6fa63ce3ac3d2350442c0913e15f7a768e317d", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_code/staff_imports.py", - "sha256": "f5ccf4e1d8d24bd23b62f922013f0f8eb2a8b633737b0a1134002ea0ea51e8df", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_code/staff_sources.py", - "sha256": "b7d00f3e051f131fde7142426b911e4484076987e4711685d18cf85dcee15412", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_code/staff_sync.py", - "sha256": "92361f57357bd12e22dff589a6f2353de3602947ed739b8738d8479e2462791d", + "source": "townlight_permitting/public_ui.py", + "sha256": "e0e1e6056acb09ce92cde228bcf91711ce57b9b93b374acff51d462227c9f3c8", + "bytes": 11183, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_code/staff_workbench.py", - "sha256": "13893408816cb0794c266c78d78e30e8182171b92830e757353001afea4f79fd", + "source": "townlight_permitting/records_export.py", + "sha256": "990c764b82130895bea153363e48e65a812a06d8589a8e5376f3709b4d84aecd", + "bytes": 1335, "routes": [], "models": [ { - "name": "InterpretationNote", + "name": "PermitExport", "bases": [], "fields": [ { - "name": "note_id", - "type": "str", - "default": "" - }, - { - "name": "section_id", + "name": "title", "type": "str", - "default": "" + "line": 12 }, { - "name": "note_text", + "name": "project_type", "type": "str", - "default": "" + "line": 13 }, { - "name": "status", + "name": "format", "type": "str", - "default": "" + "line": 14 }, { - "name": "visibility", - "type": "str", - "default": "'staff_only'" + "name": "checklist", + "type": "tuple[str, ...]", + "line": 15 }, { - "name": "created_by", + "name": "retention_note", "type": "str", - "default": "'unknown'" - }, - { - "name": "created_at", - "type": "datetime", - "default": "field(default_factory=lambda: datetime.now(UTC))" + "line": 16 } ], - "line": 31, - "doc": "" - }, + "line": 11 + } + ], + "configuration": [] + }, + { + "source": "townlight_permitting/requirement_lookup.py", + "sha256": "f9a1fbd111096e7d4c00cc6cb7f25b9cf91af522f26c743f86234a0ecffe783c", + "bytes": 2998, + "routes": [], + "models": [ { - "name": "AuditEvent", + "name": "PermitRequirement", "bases": [], "fields": [ { - "name": "event_id", + "name": "requirement_id", "type": "str", - "default": "" + "line": 17 }, { - "name": "event_type", + "name": "project_type", "type": "str", - "default": "" + "line": 18 }, { - "name": "actor", + "name": "title", "type": "str", - "default": "" + "line": 19 }, { - "name": "section_id", - "type": "str | None", - "default": "None" + "name": "citation", + "type": "str", + "line": 20 }, { - "name": "target_id", - "type": "str | None", - "default": "None" + "name": "required_materials", + "type": "tuple[str, ...]", + "line": 21 }, { - "name": "created_at", - "type": "datetime", - "default": "field(default_factory=lambda: datetime.now(UTC))" + "name": "staff_note", + "type": "str", + "line": 22 + }, + { + "name": "disclaimer", + "type": "str", + "line": 23 } ], - "line": 42, - "doc": "" + "line": 16 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_code/suite_session_auth.py", - "sha256": "b30a449b95838c04098d33373f3b6b030539b7a8ea2a998210333b314f9f4582", + "source": "townlight_permitting/sources.py", + "sha256": "b49dd295c25b33f48a9756c86d6063137e35d76fdc8c4ff0f29ed8e22c4207df", + "bytes": 4372, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_permitting/submittal_outline.py", + "sha256": "14f980ef5a70f3bc712f582a1c27b1b596e8d35e86f28b2aeb110460e4859eff", + "bytes": 1365, "routes": [], "models": [ { - "name": "SuiteSessionPrincipal", + "name": "SubmittalOutline", "bases": [], "fields": [ { - "name": "subject", + "name": "project_name", "type": "str", - "default": "" + "line": 13 }, { - "name": "roles", - "type": "frozenset[str]", - "default": "" + "name": "heading", + "type": "str", + "line": 14 }, { - "name": "session_id", + "name": "required_materials", + "type": "tuple[str, ...]", + "line": 15 + }, + { + "name": "applicant_message", + "type": "str", + "line": 16 + }, + { + "name": "review_required", + "type": "bool", + "line": 17 + }, + { + "name": "disclaimer", "type": "str", - "default": "" + "line": 18 } ], - "line": 32, - "doc": "Validated TownlightCore suite-session identity." - } - ], - "configuration": [] - } - ], - "bridge": [ - { - "source": "installed-owned-source/townlight_runtime/code_bridge.py", - "sha256": "901f1473aa6f4db4b089925a2fec17e963cef7a27c6bf885099a362df1fe15e9", - "routes": [ - { - "method": "POST", - "path": "/desktop/v1/code/imports", - "router": "router", - "prefix_resolved": true, - "name": "imports", - "signature": "data: code.ImportBundleCreate, actor_id: str=Depends(actor)", - "returns": "", - "line": 46, - "doc": "", - "decorator": "router.post('/imports')", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/code/sources", - "router": "router", - "prefix_resolved": true, - "name": "sources", - "signature": "actor_id: str=Depends(actor)", - "returns": "", - "line": 55, - "doc": "", - "decorator": "router.get('/sources')", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/code/workspace", - "router": "router", - "prefix_resolved": true, - "name": "workspace", - "signature": "actor_id: str=Depends(actor)", - "returns": "", - "line": 60, - "doc": "", - "decorator": "router.get('/workspace')", - "errors": [ - "HTTPException(503, 'Townlight Code persistence unavailable.')" - ] - }, - { - "method": "GET", - "path": "/desktop/v1/code/lookup", - "router": "router", - "prefix_resolved": true, - "name": "lookup", - "signature": "section_number: str, as_of: date | None=None, actor_id: str=Depends(actor)", - "returns": "", - "line": 68, - "doc": "", - "decorator": "router.get('/lookup')", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/code/sections/{section_id}/history", - "router": "router", - "prefix_resolved": true, - "name": "section_history", - "signature": "section_id: str, actor_id: str=Depends(actor)", - "returns": "", - "line": 77, - "doc": "", - "decorator": "router.get('/sections/{section_id}/history')", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/code/citation", - "router": "router", - "prefix_resolved": true, - "name": "citation", - "signature": "section_number: str, as_of: date | None=None, actor_id: str=Depends(actor)", - "returns": "", - "line": 82, - "doc": "", - "decorator": "router.get('/citation')", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/code/search", - "router": "router", - "prefix_resolved": true, - "name": "search", - "signature": "q: str, actor_id: str=Depends(actor)", - "returns": "", - "line": 89, - "doc": "", - "decorator": "router.get('/search')", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/code/imports", - "router": "router", - "prefix_resolved": true, - "name": "list_imports", - "signature": "actor_id: str=Depends(actor)", - "returns": "", - "line": 100, - "doc": "", - "decorator": "router.get('/imports')", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/code/imports/{job_id}/tree", - "router": "router", - "prefix_resolved": true, - "name": "import_tree", - "signature": "job_id: str, actor_id: str=Depends(actor)", - "returns": "", - "line": 105, - "doc": "", - "decorator": "router.get('/imports/{job_id}/tree')", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/code/imports/{job_id}/provenance", - "router": "router", - "prefix_resolved": true, - "name": "import_provenance", - "signature": "job_id: str, actor_id: str=Depends(actor)", - "returns": "", - "line": 110, - "doc": "", - "decorator": "router.get('/imports/{job_id}/provenance')", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/code/export", - "router": "router", - "prefix_resolved": true, - "name": "export_section", - "signature": "section_ref: str, as_of: date | None=None, actor_id: str=Depends(actor)", - "returns": "", - "line": 115, - "doc": "", - "decorator": "router.get('/export')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/code/questions", - "router": "router", - "prefix_resolved": true, - "name": "questions", - "signature": "data: code.QuestionAnswerRequest, actor_id: str=Depends(actor)", - "returns": "", - "line": 120, - "doc": "", - "decorator": "router.post('/questions')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/code/sections/{section_id}/notes", - "router": "router", - "prefix_resolved": true, - "name": "create_note", - "signature": "section_id: str, data: code.InterpretationNoteCreate, actor_id: str=Depends(actor)", - "returns": "", - "line": 125, - "doc": "", - "decorator": "router.post('/sections/{section_id}/notes')", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/code/sections/{section_id}/notes", - "router": "router", - "prefix_resolved": true, - "name": "list_notes", - "signature": "section_id: str, actor_id: str=Depends(actor)", - "returns": "", - "line": 130, - "doc": "", - "decorator": "router.get('/sections/{section_id}/notes')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/code/sections/{section_id}/summaries", - "router": "router", - "prefix_resolved": true, - "name": "create_summary", - "signature": "section_id: str, data: code.PlainLanguageSummaryCreate, actor_id: str=Depends(actor)", - "returns": "", - "line": 135, - "doc": "", - "decorator": "router.post('/sections/{section_id}/summaries')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/code/summaries/{summary_id}/approve", - "router": "router", - "prefix_resolved": true, - "name": "approve_summary", - "signature": "summary_id: str, actor_id: str=Depends(actor)", - "returns": "", - "line": 140, - "doc": "", - "decorator": "router.post('/summaries/{summary_id}/approve')", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/code/sections/{section_id}/summaries", - "router": "router", - "prefix_resolved": true, - "name": "list_summaries", - "signature": "section_id: str, actor_id: str=Depends(actor)", - "returns": "", - "line": 145, - "doc": "", - "decorator": "router.get('/sections/{section_id}/summaries')", - "errors": [] - } - ], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_runtime/code_public.py", - "sha256": "0fe956329a96e54e138b669d4ab4f69ab0d6f489b647a115cfd126cfa58742a5", - "routes": [ - { - "method": "GET", - "path": "/townlight_code", - "router": "router", - "prefix_resolved": true, - "name": "home", - "signature": "", - "returns": "", - "line": 66, - "doc": "", - "decorator": "router.get('', response_class=HTMLResponse)", - "errors": [] - }, - { - "method": "GET", - "path": "/townlight_code/search", - "router": "router", - "prefix_resolved": true, - "name": "search", - "signature": "q: str=''", - "returns": "", - "line": 71, - "doc": "", - "decorator": "router.get('/search', response_class=HTMLResponse)", - "errors": [] - }, - { - "method": "GET", - "path": "/townlight_code/answer", - "router": "router", - "prefix_resolved": true, - "name": "answer", - "signature": "q: str='', section_number: str | None=None, as_of: date | None=None", - "returns": "", - "line": 80, - "doc": "", - "decorator": "router.get('/answer', response_class=HTMLResponse)", - "errors": [] - }, - { - "method": "GET", - "path": "/townlight_code/sections/{section_ref}", - "router": "router", - "prefix_resolved": true, - "name": "detail", - "signature": "section_ref: str, as_of: date | None=None", - "returns": "HTMLResponse", - "line": 91, - "doc": "", - "decorator": "router.get('/sections/{section_ref}', response_class=HTMLResponse)", - "errors": [ - "HTTPException(503, 'Service unavailable')" - ] - }, - { - "method": "GET", - "path": "/townlight_code/sections/{section_ref}/export", - "router": "router", - "prefix_resolved": true, - "name": "export", - "signature": "section_ref: str, as_of: date | None=None", - "returns": "HTMLResponse", - "line": 109, - "doc": "", - "decorator": "router.get('/sections/{section_ref}/export', response_class=HTMLResponse)", - "errors": [ - "HTTPException(503, 'Service unavailable')" - ] + "line": 12 } ], - "models": [], "configuration": [] }, - { - "source": "installed-owned-source/townlight_runtime/code_meetings_bridge.py", - "sha256": "831045dc48508e866472a9ff6d9d837e8eed0a46c91c8f93b41eec526650c7c5", - "routes": [ - { - "method": "GET", - "path": "/desktop/v1/code/connections", - "router": "code_router", - "prefix_resolved": true, - "name": "list_connections", - "signature": "actor=Depends(code_actor)", - "returns": "", - "line": 87, - "doc": "", - "decorator": "code_router.get('/connections')", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/code/connections/{connection_id}", - "router": "code_router", - "prefix_resolved": true, - "name": "get_connection", - "signature": "connection_id: Key, actor=Depends(code_actor)", - "returns": "", - "line": 92, - "doc": "", - "decorator": "code_router.get('/connections/{connection_id}')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/code/connections", - "router": "code_router", - "prefix_resolved": true, - "name": "create_connection", - "signature": "payload: Proposal, actor=Depends(code_actor)", - "returns": "", - "line": 97, - "doc": "", - "decorator": "code_router.post('/connections')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/code/connections/{connection_id}/closeout", - "router": "code_router", - "prefix_resolved": true, - "name": "closeout_connection", - "signature": "connection_id: Key, payload: Closeout, actor=Depends(code_actor)", - "returns": "", - "line": 104, - "doc": "", - "decorator": "code_router.post('/connections/{connection_id}/closeout')", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/meetings/code-connections", - "router": "meetings_router", - "prefix_resolved": true, - "name": "list_code_connections", - "signature": "actor=Depends(meeting_actor)", - "returns": "", - "line": 111, - "doc": "", - "decorator": "meetings_router.get('/code-connections')", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/meetings/code-connections/{connection_id}", - "router": "meetings_router", - "prefix_resolved": true, - "name": "get_code_connection", - "signature": "connection_id: Key, actor=Depends(meeting_actor)", - "returns": "", - "line": 116, - "doc": "", - "decorator": "meetings_router.get('/code-connections/{connection_id}')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/meetings/code-connections/{connection_id}/decisions", - "router": "meetings_router", - "prefix_resolved": true, - "name": "record_decision", - "signature": "connection_id: Key, payload: Decision, actor=Depends(meeting_actor)", - "returns": "", - "line": 121, - "doc": "", - "decorator": "meetings_router.post('/code-connections/{connection_id}/decisions')", - "errors": [] - } - ], + { + "source": "townlight_permitting/workflow_models.py", + "sha256": "3d09f3ae137c5c48091e22a60a3e732ea3ec299236778d377df55807bb8bbfdd", + "bytes": 4405, + "routes": [], "models": [ { - "name": "Proposal", + "name": "Material", "bases": [ - "_Strict" + "Model" ], "fields": [ { - "name": "id", - "type": "Key", - "default": "" + "name": "material_id", + "type": "str", + "line": 21 }, { - "name": "version_id", + "name": "description", "type": "str", - "default": "Field(min_length=1, max_length=255)" + "line": 22 }, { - "name": "meeting_id", - "type": "UUID", - "default": "" - }, + "name": "citation", + "type": "str", + "line": 23 + } + ], + "line": 20 + }, + { + "name": "PathwayStep", + "bases": [ + "Model" + ], + "fields": [ { - "name": "title", + "name": "step", "type": "str", - "default": "Field(min_length=1, max_length=500)" + "line": 27 }, { - "name": "ordinance_number", + "name": "citation", "type": "str", - "default": "Field(min_length=1, max_length=120)" + "line": 28 }, { - "name": "proposed_text", + "name": "typical_time", "type": "str", - "default": "Field(min_length=1, max_length=1000000)" + "line": 29 + } + ], + "line": 26 + }, + { + "name": "SourceLink", + "bases": [ + "Model" + ], + "fields": [ + { + "name": "provider", + "type": "Literal['code', 'zoning']", + "line": 33 }, { - "name": "supersedes_id", - "type": "Key | None", - "default": "None" + "name": "source_id", + "type": "str", + "line": 34 }, { - "name": "reconciliation_note", - "type": "str | None", - "default": "None" + "name": "expected_sha256", + "type": "str", + "line": 35 } ], - "line": 26, - "doc": "" + "line": 32 }, { - "name": "Decision", + "name": "RequirementBundle", "bases": [ - "_Strict" + "Model" ], "fields": [ { - "name": "id", - "type": "Key", - "default": "" + "name": "requirement_id", + "type": "str", + "line": 39 }, { - "name": "outcome", - "type": "Literal['adopted', 'not_adopted', 'deferred', 'withdrawn']", - "default": "" + "name": "title", + "type": "str", + "line": 40 }, { - "name": "decided_at", - "type": "AwareDatetime | None", - "default": "None" + "name": "jurisdiction", + "type": "str", + "line": 41 }, { - "name": "decision_text", + "name": "project_type", "type": "str", - "default": "Field(min_length=1, max_length=1000000)" + "line": 42 }, { - "name": "supporting_references", - "type": "list[str]", - "default": "Field(default_factory=list)" + "name": "source_reference", + "type": "str", + "line": 43 }, { - "name": "supersedes_decision_id", - "type": "Key | None", - "default": "None" + "name": "source_date", + "type": "date", + "line": 44 }, { - "name": "reconciliation_note", - "type": "str | None", - "default": "None" + "name": "effective_on", + "type": "date", + "line": 45 + }, + { + "name": "dataset_kind", + "type": "Literal['municipal', 'fictional']", + "line": 46 + }, + { + "name": "filename", + "type": "str", + "line": 47 + }, + { + "name": "content_base64", + "type": "str", + "line": 48 + }, + { + "name": "sha256", + "type": "str", + "line": 49 + }, + { + "name": "materials", + "type": "list[Material]", + "line": 50 + }, + { + "name": "pathway", + "type": "list[PathwayStep]", + "line": 51 + }, + { + "name": "fee_link", + "type": "SourceLink | None", + "line": 52 + }, + { + "name": "staff_note", + "type": "str", + "line": 53 + }, + { + "name": "change_note", + "type": "str", + "line": 54 } ], - "line": 37, - "doc": "" + "line": 38 }, { - "name": "Closeout", + "name": "MaterialReview", "bases": [ - "_Strict" + "Model" ], "fields": [ { - "name": "decision_id", - "type": "Key", - "default": "" + "name": "material_id", + "type": "str", + "line": 71 }, { - "name": "version_id", + "name": "status", + "type": "Literal['not_reviewed', 'provided', 'missing', 'unclear']", + "line": 72 + }, + { + "name": "note", "type": "str", - "default": "Field(min_length=1, max_length=255)" + "line": 73 + } + ], + "line": 70 + }, + { + "name": "IntakeInput", + "bases": [ + "Model" + ], + "fields": [ + { + "name": "expected_revision", + "type": "UUID | None", + "line": 77 }, { - "name": "source_id", + "name": "project_name", "type": "str", - "default": "Field(min_length=1, max_length=255)" + "line": 78 }, { - "name": "version_label", + "name": "project_description", "type": "str", - "default": "Field(min_length=1, max_length=255)" + "line": 79 }, { - "name": "body", + "name": "location", "type": "str", - "default": "Field(min_length=1, max_length=1000000)" + "line": 80 }, { - "name": "effective_start", - "type": "date", - "default": "" + "name": "applicant_contact", + "type": "str", + "line": 81 }, { - "name": "effective_end", - "type": "date | None", - "default": "None" + "name": "requirement_revision", + "type": "UUID", + "line": 82 }, { - "name": "is_current", - "type": "bool", - "default": "" + "name": "materials", + "type": "list[MaterialReview]", + "line": 83 }, { - "name": "reconciliation_note", - "type": "str | None", - "default": "None" + "name": "linked_sources", + "type": "list[SourceLink]", + "line": 84 + }, + { + "name": "staff_notes", + "type": "str", + "line": 85 + }, + { + "name": "assigned_to", + "type": "str", + "line": 86 + }, + { + "name": "review_state", + "type": "Literal['draft', 'follow_up', 'reviewed']", + "line": 87 + }, + { + "name": "review_notes", + "type": "str", + "line": 88 + }, + { + "name": "public_summary", + "type": "str", + "line": 89 } ], - "line": 47, - "doc": "" + "line": 76 } ], "configuration": [] - } - ] - }, - "zoning": { - "package": "townlight_zoning", - "source": [ + }, { - "source": "installed-owned-source/townlight_zoning/__init__.py", - "sha256": "528eaa60c6814c1cf2b3ceb5a510c059380c37670f48928c27a02d765a2d4d15", + "source": "townlight_permitting/workflow_schema.py", + "sha256": "6797fd13cbe6ba85884fc522c05e56aefe0fea3796d5a269d5be8824da3809c5", + "bytes": 2263, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_zoning/cited_questions.py", - "sha256": "7a154dd540eae464090b4c12e6e0c1ca263670525df6a7328d317b0dd1e79a43", + "source": "townlight_permitting/workflow_store.py", + "sha256": "451c6ee455cf85d1b5a18a1e54ac02653b52a1d2e479adbe9213f086104ddd94", + "bytes": 15521, "routes": [], "models": [], "configuration": [] - }, + } + ] + }, + "inspections": { + "repository": "townlight/inspect", + "repository_head": "e058106d36b9164b702acac878fb00c3e533e4a6", + "working_tree_modified": true, + "principal_import": "townlight_inspections", + "source": [ { - "source": "installed-owned-source/townlight_zoning/cited_rules.py", - "sha256": "4fb421ff3cd9e27be7689de75711bba8d1cd3ede304547868c204cf7a0daa43a", + "source": "townlight_inspections/__init__.py", + "sha256": "f1a274959add447eba3a43e59f72d62e4abbe6189a62c723c7ce2d127baa2096", + "bytes": 69, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_zoning/connected_sources.py", - "sha256": "68ad55c71b897eca689a6d028f4aee115dc5ca4b5ef005613385f9588387715b", + "source": "townlight_inspections/_whistle_driver.py", + "sha256": "90ce9276c7d1de4d3259a2c00ff581e5d55d28dd8da913ed7b8bd2d7c89a5264", + "bytes": 1419, + "routes": [], + "models": [], + "configuration": [ + { + "environment": "TEXTFLOWKIT_MODELS_DIR", + "line": 19 + }, + { + "environment": "TEXTFLOWKIT_OFFLINE", + "line": 20 + } + ] + }, + { + "source": "townlight_inspections/adapters.py", + "sha256": "6ac1d1b2d1a57c63c1c03af1e23bfa9540136bb1b8b2fba9eda3f27e42ecfd9e", + "bytes": 5419, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_zoning/discretionary.py", - "sha256": "919a5a573109fc76840290b4656e8fc63be91cdd10a6b3ff21fd106b52218ca5", + "source": "townlight_inspections/case_lookup.py", + "sha256": "b68030ecdf6a7f83ed35aec636afcb70c5ce247a40ed7d60a3283655bfdb3214", + "bytes": 1538, "routes": [], "models": [ { - "name": "Unavailable", + "name": "RepeatCaseResult", "bases": [], "fields": [ { - "name": "reason", + "name": "property_reference", "type": "str", - "default": "" + "line": 16 }, { - "name": "fix", + "name": "violation_type", "type": "str", - "default": "" + "line": 17 }, { - "name": "review_required", - "type": "bool", - "default": "True" + "name": "repeat_case_count", + "type": "int", + "line": 18 }, { - "name": "disclaimer", - "type": "str", - "default": "DISCLAIMER" - } - ], - "line": 45, - "doc": "An explicit refusal: the sources do not support an answer." - }, - { - "name": "NonconformityFlag", - "bases": [], - "fields": [ + "name": "related_case_ids", + "type": "tuple[str, ...]", + "line": 19 + }, { - "name": "observed", + "name": "staff_note", "type": "str", - "default": "" + "line": 20 }, { - "name": "standard", + "name": "disclaimer", "type": "str", - "default": "" - }, + "line": 21 + } + ], + "line": 15 + } + ], + "configuration": [] + }, + { + "source": "townlight_inspections/connections.py", + "sha256": "a32e5723ed2b93b0e72a6659ac0db8f614db1be7cc5cb4881a40b9abdff85e60", + "bytes": 1969, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_inspections/integration_mocks.py", + "sha256": "a22c28a8d47e6357b3c4b526b1d4690e8b98cc9d9115c93c74656734a58901ce", + "bytes": 2337, + "routes": [], + "models": [ + { + "name": "IntegrationMockResult", + "bases": [], + "fields": [ { - "name": "citation", + "name": "scenario", "type": "str", - "default": "" + "line": 11 }, { - "name": "basis", + "name": "status", "type": "str", - "default": "" + "line": 12 }, { "name": "review_required", "type": "bool", - "default": "True" + "line": 13 }, { - "name": "determination_made", - "type": "bool", - "default": "False" + "name": "findings", + "type": "tuple[str, ...]", + "line": 14 }, { - "name": "disclaimer", + "name": "boundary", "type": "str", - "default": "DISCLAIMER" + "line": 15 } ], - "line": 55, - "doc": "A REVIEW flag raised from existing parcel/rule data. Never a finding." + "line": 10 + } + ], + "configuration": [] + }, + { + "source": "townlight_inspections/main.py", + "sha256": "d6f4908f4898ef87372b61527536fa73542630d4c96b5fad5cdf9e626698db65", + "bytes": 19966, + "routes": [ + { + "method": "GET", + "declared_path": "/", + "function": "root", + "line": 130 }, { - "name": "ProcessExplanation", - "bases": [], + "method": "GET", + "declared_path": "/health", + "function": "health", + "line": 150 + }, + { + "method": "GET", + "declared_path": "/townlight_inspections", + "function": "public_townlight_inspections_page", + "line": 162 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_inspections/cases/repeat-lookup", + "function": "repeat_case_lookup", + "line": 169 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_inspections/reports/draft", + "function": "inspection_report_draft", + "line": 178 + }, + { + "method": "GET", + "declared_path": "/api/v1/townlight_inspections/reports/{report_id}", + "function": "get_inspection_report", + "line": 215 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_inspections/evidence/retain", + "function": "retain_evidence_route", + "line": 291 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_inspections/media/analyse", + "function": "media_analyse", + "line": 307 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_inspections/notices/draft", + "function": "notice_draft", + "line": 325 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_inspections/context/inspection-review", + "function": "inspection_review_context", + "line": 336 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_inspections/integrations/mock/inspection-context", + "function": "integration_mock_inspection_context", + "line": 365 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_inspections/export", + "function": "inspection_export", + "line": 377 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_inspections/staff/reviews", + "function": "create_staff_review", + "line": 387 + }, + { + "method": "GET", + "declared_path": "/api/v1/townlight_inspections/staff/reviews", + "function": "list_staff_reviews", + "line": 403 + }, + { + "method": "PATCH", + "declared_path": "/api/v1/townlight_inspections/staff/reviews/{review_id}", + "function": "update_staff_review", + "line": 418 + }, + { + "method": "GET", + "declared_path": "/api/v1/townlight_inspections/staff/reviews/summary", + "function": "staff_review_summary", + "line": 448 + } + ], + "models": [ + { + "name": "RepeatCaseLookupRequest", + "bases": [ + "BaseModel" + ], "fields": [ { - "name": "process", + "name": "property_reference", "type": "str", - "default": "" + "line": 51 }, { - "name": "label", + "name": "violation_type", "type": "str", - "default": "" - }, + "line": 52 + } + ], + "line": 50 + }, + { + "name": "ReportDraftRequest", + "bases": [ + "BaseModel" + ], + "fields": [ { - "name": "what", + "name": "inspection_id", "type": "str", - "default": "" + "line": 56 }, { - "name": "standard_citation", + "name": "property_reference", "type": "str", - "default": "" - }, - { - "name": "needs", - "type": "list", - "default": "" + "line": 57 }, { - "name": "review", - "type": "list", - "default": "" + "name": "inspector_notes", + "type": "str", + "line": 58 }, { - "name": "source_citation", - "type": "dict", - "default": "field(default_factory=dict)" + "name": "photo_observations", + "type": "list[str]", + "line": 59 }, { - "name": "standards", - "type": "list", - "default": "field(default_factory=list)" + "name": "voice_notes", + "type": "str", + "line": 60 }, { - "name": "flags", - "type": "list", - "default": "field(default_factory=list)" - }, + "name": "analysis", + "type": "AnalysisRecord | None", + "line": 61 + } + ], + "line": 55 + }, + { + "name": "NoticeDraftRequest", + "bases": [ + "BaseModel" + ], + "fields": [ { - "name": "review_required", - "type": "bool", - "default": "True" + "name": "case_id", + "type": "str", + "line": 65 }, { - "name": "determination_made", - "type": "bool", - "default": "False" + "name": "property_reference", + "type": "str", + "line": 66 }, { - "name": "disclaimer", + "name": "violation_type", "type": "str", - "default": "DISCLAIMER" + "line": 67 }, { - "name": "as_of", - "type": "str | None", - "default": "None" + "name": "observations", + "type": "list[str]", + "line": 68 } ], - "line": 68, - "doc": "" - } - ], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_zoning/geo_import.py", - "sha256": "e49824301593f8c06dd6bc64832542721d7b1763d745deb7ba531f7b894cc4a0", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_zoning/geo_spatial.py", - "sha256": "dfe4c88a940a20825c5c493babacb0cb0a96a70cb31a831c3ff1ecb4b77ebc13", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_zoning/geo_validate.py", - "sha256": "65b4a2b84722be8c25decfaeb80c6177ff30588259379927e853f7727d767178", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_zoning/integration_mocks.py", - "sha256": "ed14fba1a58020377ebee28c20ef042f5b50126ca2351efb73e46d7a2d80982c", - "routes": [], - "models": [ + "line": 64 + }, { - "name": "IntegrationError", - "bases": [], + "name": "InspectionExportRequest", + "bases": [ + "BaseModel" + ], "fields": [ { - "name": "provider", - "type": "str", - "default": "" - }, - { - "name": "message", + "name": "title", "type": "str", - "default": "" + "line": 72 }, { - "name": "fix", + "name": "case_id", "type": "str", - "default": "" + "line": 73 }, { - "name": "code", + "name": "format", "type": "str", - "default": "" + "line": 74 } ], - "line": 27, - "doc": "" + "line": 71 }, { - "name": "IntegrationResult", - "bases": [], + "name": "InspectionContextRequest", + "bases": [ + "BaseModel" + ], "fields": [ { - "name": "provider", + "name": "inspection_id", "type": "str", - "default": "" + "line": 78 }, { - "name": "records", - "type": "tuple[dict[str, Any], ...]", - "default": "" + "name": "property_reference", + "type": "str", + "line": 79 }, { - "name": "source", + "name": "violation_type", "type": "str", - "default": "" + "line": 80 }, { - "name": "warnings", - "type": "tuple[str, ...]", - "default": "()" + "name": "code_context_id", + "type": "str", + "line": 81 }, { - "name": "stale", - "type": "bool", - "default": "False" + "name": "case_context_id", + "type": "str", + "line": 82 + }, + { + "name": "source_date_status", + "type": "str", + "line": 83 } ], - "line": 35, - "doc": "" + "line": 77 }, { - "name": "LocalIntegrationAdapter", - "bases": [], + "name": "IntegrationMockRequest", + "bases": [ + "BaseModel" + ], "fields": [ { - "name": "provider", + "name": "scenario", "type": "str", - "default": "" + "line": 87 }, { - "name": "dependency", - "type": "str | None", - "default": "None" - } - ], - "line": 43, - "doc": "" - } - ], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_zoning/main.py", - "sha256": "cdbc4bd6f20650c08ca4a81c7e9d2fc7c85e0896bbd3d1c4e982dfe178c7bb93", - "routes": [ - { - "method": "GET", - "path": "/", - "router": "app", - "prefix_resolved": true, - "name": "root", - "signature": "", - "returns": "dict[str, str]", - "line": 74, - "doc": "Return current product state without overstating unshipped behavior.", - "decorator": "app.get('/')", - "errors": [] - }, - { - "method": "GET", - "path": "/health", - "router": "app", - "prefix_resolved": true, - "name": "health", - "signature": "", - "returns": "dict[str, str]", - "line": 92, - "doc": "Return dependency/version health for deployment smoke checks.", - "decorator": "app.get('/health')", - "errors": [] - }, - { - "method": "GET", - "path": "/townlight_zoning", - "router": "app", - "prefix_resolved": true, - "name": "public_townlight_zoning_page", - "signature": "", - "returns": "str", - "line": 104, - "doc": "Return the accessible public sample UI.", - "decorator": "app.get('/townlight_zoning', response_class=HTMLResponse)", - "errors": [] - }, - { - "method": "GET", - "path": "/townlight_zoning/staff", - "router": "app", - "prefix_resolved": true, - "name": "staff_townlight_zoning_page", - "signature": "", - "returns": "str", - "line": 111, - "doc": "Return the staff workflow shell without exposing staff data in HTML.", - "decorator": "app.get('/townlight_zoning/staff', response_class=HTMLResponse)", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_zoning/parcels/lookup", - "router": "app", - "prefix_resolved": true, - "name": "parcel_lookup", - "signature": "request: ParcelLookupRequest", - "returns": "dict[str, object]", - "line": 220, - "doc": "", - "decorator": "app.post('/api/v1/townlight_zoning/parcels/lookup')", - "errors": [ - "HTTPException(status_code=422, detail={'message': 'Provide either parcel_number or address.', 'fix': \"Send parcel_number '100-200-300' or address '123 Main St', or load local parcel records into TOWNLIGHT_ZONING_PARCEL_RULE_DB_URL.\"})", - "HTTPException(status_code=404, detail={'message': result.message, 'fix': result.fix})" - ] - }, - { - "method": "POST", - "path": "/api/v1/townlight_zoning/rules/use", - "router": "app", - "prefix_resolved": true, - "name": "use_rule_lookup", - "signature": "request: UseRuleLookupRequest", - "returns": "dict[str, str]", - "line": 246, - "doc": "", - "decorator": "app.post('/api/v1/townlight_zoning/rules/use')", - "errors": [ - "HTTPException(status_code=404, detail={'message': result.message, 'fix': result.fix})" - ] - }, - { - "method": "POST", - "path": "/api/v1/townlight_zoning/rules/dimensional", - "router": "app", - "prefix_resolved": true, - "name": "dimensional_rule_lookup", - "signature": "request: DimensionalRuleLookupRequest", - "returns": "dict[str, str]", - "line": 261, - "doc": "", - "decorator": "app.post('/api/v1/townlight_zoning/rules/dimensional')", - "errors": [ - "HTTPException(status_code=404, detail={'message': result.message, 'fix': result.fix})" - ] - }, - { - "method": "POST", - "path": "/api/v1/townlight_zoning/standards/process-explanation", - "router": "app", - "prefix_resolved": true, - "name": "discretionary_explanation", - "signature": "request: DiscretionaryExplanationRequest", - "returns": "dict[str, object]", - "line": 283, - "doc": "Explain the variance/CUP process a question is about, with citations.\n\nReturns an explicit ``unavailable`` payload when the loaded rule dataset cannot\nsupport an answer; never a guessed standard, and never a determination.", - "decorator": "app.post('/api/v1/townlight_zoning/standards/process-explanation')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_zoning/questions/answer", - "router": "app", - "prefix_resolved": true, - "name": "zone_question_answer", - "signature": "request: ZoneQuestionRequest", - "returns": "dict[str, object]", - "line": 353, - "doc": "", - "decorator": "app.post('/api/v1/townlight_zoning/questions/answer')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_zoning/planner-review/classify", - "router": "app", - "prefix_resolved": true, - "name": "planner_review_classify", - "signature": "request: PlannerReviewRequest", - "returns": "dict[str, str]", - "line": 378, - "doc": "", - "decorator": "app.post('/api/v1/townlight_zoning/planner-review/classify')", - "errors": [] - }, - { - "method": "GET", - "path": "/api/v1/townlight_zoning/staff/precedents/{precedent_id}", - "router": "app", - "prefix_resolved": true, - "name": "staff_precedent", - "signature": "precedent_id: str, _principal: Annotated[StaffPrincipal, Depends(_require_staff_access)]", - "returns": "dict[str, str]", - "line": 384, - "doc": "", - "decorator": "app.get('/api/v1/townlight_zoning/staff/precedents/{precedent_id}')", - "errors": [ - "HTTPException(status_code=404, detail={'message': 'Staff precedent not found.', 'fix': \"Try precedent_id 'historic-adu'.\"})" - ] - }, - { - "method": "POST", - "path": "/api/v1/townlight_zoning/staff/questions/answer", - "router": "app", - "prefix_resolved": true, - "name": "staff_question_answer", - "signature": "request: StaffQuestionAnswerRequest, principal: Annotated[StaffPrincipal, Depends(_require_staff_access)]", - "returns": "dict[str, object]", - "line": 402, - "doc": "", - "decorator": "app.post('/api/v1/townlight_zoning/staff/questions/answer')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_zoning/staff/ambiguity-reviews", - "router": "app", - "prefix_resolved": true, - "name": "create_ambiguity_review", - "signature": "request: AmbiguityReviewCreateRequest, principal: Annotated[StaffPrincipal, Depends(_require_staff_access)]", - "returns": "dict[str, object]", - "line": 415, - "doc": "", - "decorator": "app.post('/api/v1/townlight_zoning/staff/ambiguity-reviews')", - "errors": [] - }, - { - "method": "GET", - "path": "/api/v1/townlight_zoning/staff/ambiguity-reviews", - "router": "app", - "prefix_resolved": true, - "name": "list_ambiguity_reviews", - "signature": "_principal: Annotated[StaffPrincipal, Depends(_require_staff_access)], status: str | None=None", - "returns": "dict[str, object]", - "line": 429, - "doc": "", - "decorator": "app.get('/api/v1/townlight_zoning/staff/ambiguity-reviews')", - "errors": [] - }, - { - "method": "PATCH", - "path": "/api/v1/townlight_zoning/staff/ambiguity-reviews/{item_id}", - "router": "app", - "prefix_resolved": true, - "name": "update_ambiguity_review", - "signature": "item_id: str, request: AmbiguityReviewUpdateRequest, _principal: Annotated[StaffPrincipal, Depends(_require_staff_access)]", - "returns": "dict[str, object]", - "line": 443, - "doc": "", - "decorator": "app.patch('/api/v1/townlight_zoning/staff/ambiguity-reviews/{item_id}')", - "errors": [ - "HTTPException(status_code=404, detail={'message': 'Ambiguity review item was not found.', 'fix': 'List staff ambiguity reviews and retry with an existing item id.'})", - "HTTPException(status_code=422, detail={'message': 'Ambiguity review update is invalid.', 'fix': str(exc)})" - ] - }, - { - "method": "GET", - "path": "/api/v1/townlight_zoning/staff/questions/analytics", - "router": "app", - "prefix_resolved": true, - "name": "staff_question_analytics", - "signature": "_principal: Annotated[StaffPrincipal, Depends(_require_staff_access)], high_volume_threshold: int=2", - "returns": "dict[str, object]", - "line": 472, - "doc": "", - "decorator": "app.get('/api/v1/townlight_zoning/staff/questions/analytics')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_zoning/staff/reports/outline", - "router": "app", - "prefix_resolved": true, - "name": "staff_report_outline", - "signature": "request: StaffReportOutlineRequest, principal: Annotated[StaffPrincipal, Depends(_require_staff_access)]", - "returns": "dict[str, object]", - "line": 496, - "doc": "", - "decorator": "app.post('/api/v1/townlight_zoning/staff/reports/outline')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_zoning/staff/flagged-answers", - "router": "app", - "prefix_resolved": true, - "name": "create_flagged_answer_review", - "signature": "request: FlaggedAnswerCreateRequest, principal: Annotated[StaffPrincipal, Depends(_require_staff_access)]", - "returns": "dict[str, object]", - "line": 520, - "doc": "", - "decorator": "app.post('/api/v1/townlight_zoning/staff/flagged-answers')", - "errors": [] - }, - { - "method": "PATCH", - "path": "/api/v1/townlight_zoning/staff/flagged-answers/{review_id}/improve", - "router": "app", - "prefix_resolved": true, - "name": "improve_flagged_answer_review", - "signature": "review_id: str, request: FlaggedAnswerImproveRequest, principal: Annotated[StaffPrincipal, Depends(_require_staff_access)]", - "returns": "dict[str, object]", - "line": 536, - "doc": "", - "decorator": "app.patch('/api/v1/townlight_zoning/staff/flagged-answers/{review_id}/improve')", - "errors": [ - "HTTPException(status_code=404, detail={'message': 'Flagged answer review was not found.', 'fix': 'Create or list the flagged answer review before submitting improvements.'})" - ] - } - ], - "models": [ - { - "name": "StaffPrincipal", - "bases": [], - "fields": [ + "name": "role", + "type": "str", + "line": 88 + }, { - "name": "subject", + "name": "code_context_id", "type": "str", - "default": "" + "line": 89 }, { - "name": "roles", - "type": "tuple[str, ...]", - "default": "" - } - ], - "line": 68, - "doc": "" - }, - { - "name": "ParcelLookupRequest", - "bases": [ - "BaseModel" - ], - "fields": [ + "name": "case_context_id", + "type": "str", + "line": 90 + }, { - "name": "parcel_number", - "type": "str | None", - "default": "Field(default=None)" + "name": "official_finding", + "type": "bool", + "line": 91 }, { - "name": "address", + "name": "citation_issued", + "type": "bool", + "line": 92 + }, + { + "name": "fine_amount", "type": "str | None", - "default": "Field(default=None)" - } - ], - "line": 117, - "doc": "" - }, - { - "name": "UseRuleLookupRequest", - "bases": [ - "BaseModel" - ], - "fields": [ + "line": 93 + }, { - "name": "zone_code", + "name": "photo_analysis_source", "type": "str", - "default": "" + "line": 94 }, { - "name": "use", + "name": "source_date_status", "type": "str", - "default": "" + "line": 95 } ], - "line": 122, - "doc": "" + "line": 86 }, { - "name": "DimensionalRuleLookupRequest", + "name": "EvidenceItemRequest", "bases": [ "BaseModel" ], "fields": [ { - "name": "zone_code", + "name": "filename", "type": "str", - "default": "" + "line": 99 }, { - "name": "rule_type", + "name": "media_type", "type": "str", - "default": "" - } - ], - "line": 127, - "doc": "" - }, - { - "name": "ZoneQuestionRequest", - "bases": [ - "BaseModel" - ], - "fields": [ + "line": 100 + }, { - "name": "zone_code", + "name": "description", "type": "str", - "default": "Field(min_length=1, max_length=80)" + "line": 101 }, { - "name": "question", + "name": "content_base64", + "type": "str", + "line": 102 + }, + { + "name": "sha256", "type": "str", - "default": "Field(min_length=1, max_length=1000)" + "line": 103 } ], - "line": 132, - "doc": "" + "line": 98 }, { - "name": "PlannerReviewRequest", + "name": "EvidenceRetainRequest", "bases": [ "BaseModel" ], "fields": [ { - "name": "question", - "type": "str", - "default": "" + "name": "items", + "type": "list[EvidenceItemRequest]", + "line": 107 } ], - "line": 137, - "doc": "" + "line": 106 }, { - "name": "StaffQuestionAnswerRequest", + "name": "MediaAnalysisRequest", "bases": [ "BaseModel" ], "fields": [ { - "name": "zone_code", - "type": "str", - "default": "Field(min_length=1, max_length=80)" + "name": "items", + "type": "list[EvidenceItemRequest]", + "line": 111 }, { - "name": "question", + "name": "code_links", + "type": "list[dict[str, str]]", + "line": 112 + }, + { + "name": "inspector_supplied_text", "type": "str", - "default": "Field(min_length=1, max_length=1000)" + "line": 113 } ], - "line": 141, - "doc": "" + "line": 110 }, { - "name": "AmbiguityReviewCreateRequest", + "name": "StaffReviewCreateRequest", "bases": [ "BaseModel" ], "fields": [ { - "name": "zone_code", + "name": "inspection_id", "type": "str", - "default": "Field(min_length=1, max_length=80)" + "line": 117 }, { - "name": "question", + "name": "property_reference", "type": "str", - "default": "Field(min_length=1, max_length=1000)" + "line": 118 }, { "name": "reason", "type": "str", - "default": "Field(min_length=1, max_length=1000)" + "line": 119 + }, + { + "name": "report_id", + "type": "str | None", + "line": 120 } ], - "line": 146, - "doc": "" + "line": 116 }, { - "name": "AmbiguityReviewUpdateRequest", + "name": "StaffReviewUpdateRequest", "bases": [ "BaseModel" ], @@ -29569,6108 +28185,5558 @@ { "name": "status", "type": "str", - "default": "Field(min_length=1, max_length=80)" + "line": 124 }, { "name": "assigned_to", "type": "str | None", - "default": "Field(default=None, max_length=255)" + "line": 125 }, { "name": "resolution", "type": "str | None", - "default": "Field(default=None, max_length=1000)" + "line": 126 } ], - "line": 152, - "doc": "" - }, + "line": 123 + } + ], + "configuration": [ { - "name": "StaffReportOutlineRequest", - "bases": [ - "BaseModel" - ], + "environment": "TOWNLIGHT_INSPECTIONS_CASE_DB_URL", + "line": 456 + } + ] + }, + { + "source": "townlight_inspections/media_analysis.py", + "sha256": "b976ff774c8bb158346a34cd1976dc2d6b553bdef7c0f435808c133c6d062dd1", + "bytes": 14084, + "routes": [], + "models": [ + { + "name": "RetainedEvidence", + "bases": [], "fields": [ { - "name": "title", + "name": "filename", "type": "str", - "default": "Field(min_length=1, max_length=255)" - }, - { - "name": "question_ids", - "type": "list[str]", - "default": "Field(default_factory=list)" + "line": 58 }, { - "name": "queue_item_ids", - "type": "list[str]", - "default": "Field(default_factory=list)" - } - ], - "line": 158, - "doc": "" - }, - { - "name": "FlaggedAnswerCreateRequest", - "bases": [ - "BaseModel" - ], - "fields": [ - { - "name": "zone_code", + "name": "media_type", "type": "str", - "default": "Field(min_length=1, max_length=80)" + "line": 59 }, { - "name": "question", + "name": "description", "type": "str", - "default": "Field(min_length=1, max_length=1000)" + "line": 60 }, { - "name": "original_answer", - "type": "str", - "default": "Field(min_length=1, max_length=2000)" + "name": "size_bytes", + "type": "int", + "line": 61 }, { - "name": "flag_reason", + "name": "sha256", "type": "str", - "default": "Field(min_length=1, max_length=1000)" + "line": 62 }, { - "name": "citations", - "type": "list[str]", - "default": "Field(default_factory=list)" + "name": "raw", + "type": "bytes", + "line": 63 } ], - "line": 164, - "doc": "" + "line": 55 }, { - "name": "FlaggedAnswerImproveRequest", + "name": "VisionProvider", "bases": [ - "BaseModel" + "Protocol" ], "fields": [ { - "name": "improved_answer", + "name": "name", "type": "str", - "default": "Field(min_length=1, max_length=2000)" + "line": 113 }, { - "name": "improvement_notes", - "type": "str", - "default": "Field(min_length=1, max_length=1000)" + "name": "supports_images", + "type": "bool", + "line": 114 } ], - "line": 172, - "doc": "" + "line": 110 }, { - "name": "DiscretionaryExplanationRequest", + "name": "TranscriptionProvider", "bases": [ - "BaseModel" + "Protocol" ], "fields": [ { - "name": "process_section", + "name": "name", "type": "str", - "default": "Field(default='', max_length=255)" + "line": 124 + } + ], + "line": 121 + }, + { + "name": "MediaAnalysis", + "bases": [], + "fields": [ + { + "name": "draft_observations", + "type": "list[dict[str, Any]]", + "line": 142 }, { - "name": "question", - "type": "str", - "default": "Field(min_length=1, max_length=1000)" + "name": "cited_sections", + "type": "list[dict[str, str]]", + "line": 143 }, { - "name": "zone_code", - "type": "str", - "default": "Field(default='', max_length=20)" + "name": "unavailable", + "type": "list[dict[str, str]]", + "line": 144 }, { - "name": "rule_types", - "type": "list[str]", - "default": "Field(default_factory=list, max_length=12)" + "name": "retained", + "type": "list[dict[str, Any]]", + "line": 145 }, { - "name": "observed", - "type": "dict[str, str]", - "default": "Field(default_factory=dict)" + "name": "runtime", + "type": "dict[str, Any]", + "line": 146 + }, + { + "name": "review_required", + "type": "bool", + "line": 147 + }, + { + "name": "determination_made", + "type": "bool", + "line": 148 + }, + { + "name": "boundary", + "type": "str", + "line": 149 } ], - "line": 274, - "doc": "" + "line": 139 } ], - "configuration": [ - { - "variable": "TOWNLIGHT_ZONING_PARCEL_RULE_DB_URL", - "default": "", - "line": 559 - } - ] - }, - { - "source": "installed-owned-source/townlight_zoning/migrations/__init__.py", - "sha256": "38cbccb2471a214eac40f174b618d28d0367c43a0e66d3eb5807dad737142765", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_zoning/migrations/env.py", - "sha256": "3baae8fbf8726f8811647eb75d257e310d2d9660b0150833f17220dd8fa431ba", - "routes": [], - "models": [], - "configuration": [ - { - "variable": "DATABASE_URL", - "default": "", - "line": 22 - } - ] - }, - { - "source": "installed-owned-source/townlight_zoning/migrations/guards.py", - "sha256": "9346e9812f238cfee1bdd21f5487fb5c51ee4cabeda45da9aaed6ac2db9b5f7c", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_zoning/migrations/versions/__init__.py", - "sha256": "a1087a2a3cedf40641ab02c8e97838630305726600105ad59e30727b61a2f95d", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_zoning/migrations/versions/townlight_zoning_0001_schema.py", - "sha256": "0a6985e6fda034f4e654e63f2cb47610bf2af75dd028fc8f43473604550a2a18", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_zoning/migrations/versions/townlight_zoning_0002_parcel_rule_lookup_records.py", - "sha256": "8a473e69469f9fdbca5adefcdb7e9a41d50850f1a7460381691da5a4f137314d", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_zoning/migrations/versions/townlight_zoning_0003_question_ledger.py", - "sha256": "fd654ca0d15832acb727b88ece26acce25cb45da1ff8b438152ad7c766df0abc", - "routes": [], - "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_zoning/migrations/versions/townlight_zoning_0004_staff_workflows.py", - "sha256": "3c0a145ff691077453b65413f2f08a6b7107a55f3ff21c072a8bc3788028b952", + "source": "townlight_inspections/migrations/__init__.py", + "sha256": "80c59209c59d5bc08d3c46e01a38ec9afef712d6e660c9d3842684be9c7bacf9", + "bytes": 1879, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_zoning/migrations/versions/townlight_zoning_0005_geo_import.py", - "sha256": "8d4c34c15197ddc856c712d7fb8f9005cb553a2befd38a093a2c952a321d20ce", + "source": "townlight_inspections/migrations/env.py", + "sha256": "a3a7ca12e132a15db797733d493de4b07f6596cf3e92127b12102c3b0c7ae1ec", + "bytes": 442, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_zoning/migrations/versions/townlight_zoning_0006_cited_questions.py", - "sha256": "65b8c591b5adf3f0022720a2c4e780c818f0f4b5b51db83b81cab78edb2a1f9d", + "source": "townlight_inspections/migrations/versions/townlight_inspections_0001_connected.py", + "sha256": "1f8aaf5660480513bf538ee1b4145e287f4fd29f4495ce3fdf6f0c13ee030494", + "bytes": 1350, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_zoning/models.py", - "sha256": "206d16a1b4aa343eceee7bb25bdf39411f2b57e947a98a8be45607664635aba9", + "source": "townlight_inspections/notice_draft.py", + "sha256": "30a230f05dc3b31aad29dc1389ec713af4ee89ca306a8b30ed39cf60d4db6417", + "bytes": 1831, "routes": [], "models": [ { - "name": "TimestampMixin", + "name": "NoticeDraft", "bases": [], "fields": [ { - "name": "created_at", - "type": "Mapped[object]", - "default": "mapped_column(DateTime(timezone=True), nullable=False, server_default=func.now())" + "name": "case_id", + "type": "str", + "line": 12 }, { - "name": "updated_at", - "type": "Mapped[object]", - "default": "mapped_column(DateTime(timezone=True), nullable=False, server_default=func.now())" - } - ], - "line": 12, - "doc": "" - }, - { - "name": "IdMixin", - "bases": [], - "fields": [ + "name": "property_reference", + "type": "str", + "line": 13 + }, { - "name": "id", - "type": "Mapped[uuid.UUID]", - "default": "mapped_column(UUID(as_uuid=True), primary_key=True, server_default=text('gen_random_uuid()'))" + "name": "heading", + "type": "str", + "line": 14 + }, + { + "name": "draft_body", + "type": "str", + "line": 15 + }, + { + "name": "required_staff_actions", + "type": "tuple[str, ...]", + "line": 16 + }, + { + "name": "disclaimer", + "type": "str", + "line": 17 } ], - "line": 21, - "doc": "" - }, + "line": 11 + } + ], + "configuration": [] + }, + { + "source": "townlight_inspections/persistence.py", + "sha256": "0145cd2f96215ca17f9d6bbb5f1249777e9f9e87ab23863792be4deb4b05458a", + "bytes": 14471, + "routes": [], + "models": [ { - "name": "Zone", - "bases": [ - "IdMixin", - "TimestampMixin", - "Base" - ], + "name": "StoredInspectionReport", + "bases": [], "fields": [ { - "name": "__table_args__", - "type": "ClassVar[dict]", - "default": "{'schema': 'townlight_zoning'}" + "name": "report_id", + "type": "str", + "line": 71 }, { - "name": "code", - "type": "Mapped[str]", - "default": "mapped_column(String(80), nullable=False)" + "name": "inspection_id", + "type": "str", + "line": 72 }, { - "name": "name", - "type": "Mapped[str]", - "default": "mapped_column(String(255), nullable=False)" + "name": "property_reference", + "type": "str", + "line": 73 }, { - "name": "description", - "type": "Mapped[str | None]", - "default": "mapped_column(Text)" + "name": "summary", + "type": "str", + "line": 74 }, { - "name": "jurisdiction", - "type": "Mapped[str]", - "default": "mapped_column(String(255), nullable=False)" + "name": "observation_bullets", + "type": "tuple[str, ...]", + "line": 75 }, { - "name": "source_section_ref", - "type": "Mapped[str | None]", - "default": "mapped_column(String(255))" + "name": "inspector_review_required", + "type": "bool", + "line": 76 }, { - "name": "is_active", - "type": "Mapped[bool]", - "default": "mapped_column(Boolean, nullable=False, server_default=text('true'))" + "name": "disclaimer", + "type": "str", + "line": 77 + }, + { + "name": "created_at", + "type": "datetime", + "line": 78 } ], - "line": 27, - "doc": "" + "line": 70 }, { - "name": "Overlay", - "bases": [ - "IdMixin", - "TimestampMixin", - "Base" - ], + "name": "StaffReviewQueueItem", + "bases": [], "fields": [ { - "name": "__table_args__", - "type": "ClassVar[dict]", - "default": "{'schema': 'townlight_zoning'}" + "name": "review_id", + "type": "str", + "line": 83 }, { - "name": "code", - "type": "Mapped[str]", - "default": "mapped_column(String(80), nullable=False)" + "name": "report_id", + "type": "str | None", + "line": 84 }, { - "name": "name", - "type": "Mapped[str]", - "default": "mapped_column(String(255), nullable=False)" + "name": "inspection_id", + "type": "str", + "line": 85 }, { - "name": "description", - "type": "Mapped[str | None]", - "default": "mapped_column(Text)" + "name": "property_reference", + "type": "str", + "line": 86 }, { - "name": "source_section_ref", - "type": "Mapped[str | None]", - "default": "mapped_column(String(255))" + "name": "status", + "type": "str", + "line": 87 }, { - "name": "is_active", - "type": "Mapped[bool]", - "default": "mapped_column(Boolean, nullable=False, server_default=text('true'))" + "name": "reason", + "type": "str", + "line": 88 + }, + { + "name": "assigned_to", + "type": "str | None", + "line": 89 + }, + { + "name": "resolution", + "type": "str | None", + "line": 90 + }, + { + "name": "created_by", + "type": "str", + "line": 91 + }, + { + "name": "created_at", + "type": "datetime", + "line": 92 + }, + { + "name": "updated_at", + "type": "datetime", + "line": 93 + }, + { + "name": "visibility", + "type": "str", + "line": 94 } ], - "line": 39, - "doc": "" + "line": 82 }, { - "name": "Parcel", - "bases": [ - "IdMixin", - "TimestampMixin", - "Base" - ], + "name": "StaffReviewSummary", + "bases": [], "fields": [ { - "name": "__table_args__", - "type": "ClassVar[dict]", - "default": "{'schema': 'townlight_zoning'}" + "name": "total_items", + "type": "int", + "line": 99 }, { - "name": "parcel_number", - "type": "Mapped[str]", - "default": "mapped_column(String(120), nullable=False)" + "name": "by_status", + "type": "dict[str, int]", + "line": 100 }, { - "name": "address", - "type": "Mapped[str]", - "default": "mapped_column(String(500), nullable=False)" + "name": "open_items", + "type": "int", + "line": 101 }, { - "name": "zone_id", - "type": "Mapped[uuid.UUID]", - "default": "mapped_column(ForeignKey('townlight_zoning.zones.id'), nullable=False)" + "name": "generated_at", + "type": "datetime", + "line": 102 }, { - "name": "overlay_payload", - "type": "Mapped[dict]", - "default": "mapped_column(JSONB, nullable=False, server_default=text(\"'[]'::jsonb\"))" + "name": "visibility", + "type": "str", + "line": 103 + } + ], + "line": 98 + } + ], + "configuration": [] + }, + { + "source": "townlight_inspections/public_ui.py", + "sha256": "c14bd5b3d45dc1434edeffb931cd6abb8804bff675989769c8eb89c85a46f965", + "bytes": 8120, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_inspections/records_export.py", + "sha256": "6adcb9a04cbff7d9d455f41598a0bdb1dfd736aa13f439a61f1e2ed98f8b49bb", + "bytes": 1178, + "routes": [], + "models": [ + { + "name": "InspectionExport", + "bases": [], + "fields": [ + { + "name": "title", + "type": "str", + "line": 10 }, { - "name": "geometry_ref", - "type": "Mapped[str | None]", - "default": "mapped_column(Text)" + "name": "case_id", + "type": "str", + "line": 11 }, { - "name": "source_payload", - "type": "Mapped[dict]", - "default": "mapped_column(JSONB, nullable=False, server_default=text(\"'{}'::jsonb\"))" + "name": "format", + "type": "str", + "line": 12 + }, + { + "name": "checklist", + "type": "tuple[str, ...]", + "line": 13 + }, + { + "name": "retention_note", + "type": "str", + "line": 14 } ], - "line": 50, - "doc": "" - }, + "line": 9 + } + ], + "configuration": [] + }, + { + "source": "townlight_inspections/report_draft.py", + "sha256": "9de0986afe2e0aee2e39e913af1ea6dd7b8f37c91f0b26d4294566fbc0f0a03c", + "bytes": 2420, + "routes": [], + "models": [ { - "name": "UseCategory", - "bases": [ - "IdMixin", - "TimestampMixin", - "Base" - ], + "name": "InspectionReportDraft", + "bases": [], "fields": [ { - "name": "__table_args__", - "type": "ClassVar[dict]", - "default": "{'schema': 'townlight_zoning'}" + "name": "inspection_id", + "type": "str", + "line": 12 }, { - "name": "code", - "type": "Mapped[str]", - "default": "mapped_column(String(120), nullable=False)" + "name": "property_reference", + "type": "str", + "line": 13 }, { - "name": "label", - "type": "Mapped[str]", - "default": "mapped_column(String(255), nullable=False)" + "name": "summary", + "type": "str", + "line": 14 }, { - "name": "description", - "type": "Mapped[str | None]", - "default": "mapped_column(Text)" + "name": "observation_bullets", + "type": "tuple[str, ...]", + "line": 15 + }, + { + "name": "inspector_review_required", + "type": "bool", + "line": 16 + }, + { + "name": "cited_sections", + "type": "tuple[str, ...]", + "line": 17 + }, + { + "name": "disclaimer", + "type": "str", + "line": 18 } ], - "line": 62, - "doc": "" + "line": 11 + } + ], + "configuration": [] + }, + { + "source": "townlight_inspections/transcription.py", + "sha256": "632f91d1c28aa4ed00c383cec0fd903cbaba42734b99f08fd67d4f384a263ab1", + "bytes": 6488, + "routes": [], + "models": [], + "configuration": [ + { + "environment": "TOWNLIGHT_INSPECTIONS_FFMPEG", + "line": 53 }, { - "name": "UseRule", + "environment": "TOWNLIGHT_INSPECTIONS_TEXTFLOWKIT_PYTHON", + "line": 49 + } + ] + }, + { + "source": "townlight_inspections/workflow_models.py", + "sha256": "8f2a9ee259a26d05c35efa1e63225094934256922e2477337c15ca987119d5e7", + "bytes": 7436, + "routes": [], + "models": [ + { + "name": "AnalysisObservation", "bases": [ - "IdMixin", - "TimestampMixin", - "Base" + "Model" ], "fields": [ { - "name": "__table_args__", - "type": "ClassVar[dict]", - "default": "{'schema': 'townlight_zoning'}" - }, - { - "name": "zone_id", - "type": "Mapped[uuid.UUID]", - "default": "mapped_column(ForeignKey('townlight_zoning.zones.id'), nullable=False)" + "name": "source", + "type": "str", + "line": 26 }, { - "name": "use_category_id", - "type": "Mapped[uuid.UUID]", - "default": "mapped_column(ForeignKey('townlight_zoning.use_categories.id'), nullable=False)" + "name": "filename", + "type": "str", + "line": 27 }, { - "name": "status", - "type": "Mapped[str]", - "default": "mapped_column(String(80), nullable=False)" + "name": "media_type", + "type": "str", + "line": 28 }, { - "name": "review_path", - "type": "Mapped[str | None]", - "default": "mapped_column(String(255))" + "name": "text", + "type": "str", + "line": 29 }, { - "name": "source_section_ref", - "type": "Mapped[str | None]", - "default": "mapped_column(String(255))" + "name": "adapter", + "type": "str", + "line": 30 }, { - "name": "conditions", - "type": "Mapped[dict]", - "default": "mapped_column(JSONB, nullable=False, server_default=text(\"'[]'::jsonb\"))" + "name": "citation_source_ids", + "type": "list[str]", + "line": 31 } ], - "line": 71, - "doc": "" + "line": 23 }, { - "name": "DimensionalRule", + "name": "CitedSection", "bases": [ - "IdMixin", - "TimestampMixin", - "Base" + "Model" ], "fields": [ { - "name": "__table_args__", - "type": "ClassVar[dict]", - "default": "{'schema': 'townlight_zoning'}" - }, - { - "name": "zone_id", - "type": "Mapped[uuid.UUID]", - "default": "mapped_column(ForeignKey('townlight_zoning.zones.id'), nullable=False)" - }, - { - "name": "rule_type", - "type": "Mapped[str]", - "default": "mapped_column(String(120), nullable=False)" + "name": "source_id", + "type": "str", + "line": 43 }, { - "name": "value_text", - "type": "Mapped[str]", - "default": "mapped_column(String(255), nullable=False)" + "name": "citation", + "type": "str", + "line": 44 }, { - "name": "source_section_ref", - "type": "Mapped[str | None]", - "default": "mapped_column(String(255))" + "name": "title", + "type": "str", + "line": 45 }, { - "name": "applies_to", - "type": "Mapped[str | None]", - "default": "mapped_column(String(255))" + "name": "version", + "type": "str", + "line": 46 } ], - "line": 85, - "doc": "" + "line": 40 }, { - "name": "Citation", + "name": "AnalysisRecord", "bases": [ - "IdMixin", - "TimestampMixin", - "Base" + "Model" ], "fields": [ { - "name": "__table_args__", - "type": "ClassVar[dict]", - "default": "{'schema': 'townlight_zoning'}" + "name": "observations", + "type": "list[AnalysisObservation]", + "line": 52 }, { - "name": "source_section_ref", - "type": "Mapped[str]", - "default": "mapped_column(String(255), nullable=False)" + "name": "cited_sections", + "type": "list[CitedSection]", + "line": 53 }, { - "name": "citation_text", - "type": "Mapped[str]", - "default": "mapped_column(String(500), nullable=False)" + "name": "unavailable", + "type": "list[str]", + "line": 54 }, { - "name": "url", - "type": "Mapped[str | None]", - "default": "mapped_column(Text)" + "name": "runtime", + "type": "dict", + "line": 55 }, { - "name": "retrieved_at", - "type": "Mapped[object | None]", - "default": "mapped_column(DateTime(timezone=True))" + "name": "review_required", + "type": "bool", + "line": 56 } ], - "line": 96, - "doc": "" + "line": 49 }, { - "name": "Precedent", + "name": "Evidence", "bases": [ - "IdMixin", - "TimestampMixin", - "Base" + "Model" ], "fields": [ { - "name": "__table_args__", - "type": "ClassVar[dict]", - "default": "{'schema': 'townlight_zoning'}" - }, - { - "name": "title", - "type": "Mapped[str]", - "default": "mapped_column(String(500), nullable=False)" + "name": "filename", + "type": "str", + "line": 94 }, { - "name": "body", - "type": "Mapped[str]", - "default": "mapped_column(Text, nullable=False)" + "name": "description", + "type": "str", + "line": 95 }, { - "name": "visibility", - "type": "Mapped[str]", - "default": "mapped_column(String(80), nullable=False)" + "name": "media_type", + "type": "Literal['text/plain', 'image/jpeg', 'image/png', 'image/webp', 'application/pdf', 'audio/webm', 'audio/ogg', 'audio/wav', 'audio/mpeg', 'audio/mp4']", + "line": 96 }, { - "name": "source_ref", - "type": "Mapped[str | None]", - "default": "mapped_column(String(255))" + "name": "content_base64", + "type": "str", + "line": 99 }, { - "name": "tags", - "type": "Mapped[dict]", - "default": "mapped_column(JSONB, nullable=False, server_default=text(\"'[]'::jsonb\"))" + "name": "sha256", + "type": "str", + "line": 100 } ], - "line": 106, - "doc": "" + "line": 93 }, { - "name": "InterpretationNote", + "name": "SourceLink", "bases": [ - "IdMixin", - "TimestampMixin", - "Base" + "Model" ], "fields": [ { - "name": "__table_args__", - "type": "ClassVar[dict]", - "default": "{'schema': 'townlight_zoning'}" - }, - { - "name": "zone_id", - "type": "Mapped[uuid.UUID | None]", - "default": "mapped_column(ForeignKey('townlight_zoning.zones.id'))" - }, - { - "name": "note_text", - "type": "Mapped[str]", - "default": "mapped_column(Text, nullable=False)" + "name": "provider", + "type": "Literal['code']", + "line": 114 }, { - "name": "visibility", - "type": "Mapped[str]", - "default": "mapped_column(String(80), nullable=False)" + "name": "source_id", + "type": "str", + "line": 115 }, { - "name": "status", - "type": "Mapped[str]", - "default": "mapped_column(String(80), nullable=False)" + "name": "expected_sha256", + "type": "str", + "line": 116 } ], - "line": 117, - "doc": "" + "line": 113 }, { - "name": "ZoneQuestion", + "name": "InspectionInput", "bases": [ - "IdMixin", - "TimestampMixin", - "Base" + "Model" ], "fields": [ { - "name": "__table_args__", - "type": "ClassVar[dict]", - "default": "{'schema': 'townlight_zoning'}" + "name": "expected_revision", + "type": "UUID | None", + "line": 120 }, { - "name": "question_text", - "type": "Mapped[str]", - "default": "mapped_column(Text, nullable=False)" + "name": "title", + "type": "str", + "line": 121 }, { - "name": "audience", - "type": "Mapped[str]", - "default": "mapped_column(String(80), nullable=False)" + "name": "property_reference", + "type": "str", + "line": 122 }, { - "name": "status", - "type": "Mapped[str]", - "default": "mapped_column(String(80), nullable=False)" + "name": "inspection_reference", + "type": "str", + "line": 123 }, { - "name": "answer_text", - "type": "Mapped[str | None]", - "default": "mapped_column(Text)" + "name": "dataset_kind", + "type": "Literal['municipal', 'fictional']", + "line": 124 }, { - "name": "citation_payload", - "type": "Mapped[dict]", - "default": "mapped_column(JSONB, nullable=False, server_default=text(\"'[]'::jsonb\"))" + "name": "inspector_notes", + "type": "str", + "line": 125 }, { - "name": "escalation_reason", - "type": "Mapped[str | None]", - "default": "mapped_column(String(255))" - } - ], - "line": 127, - "doc": "" - } - ], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_zoning/parcel_lookup.py", - "sha256": "3629424d9af4d5ac514f285835f9b8179c1cf6ceb22d586576603a270edb5671", - "routes": [], - "models": [ - { - "name": "ParcelLookupResult", - "bases": [], - "fields": [ + "name": "photo_observations", + "type": "list[str]", + "line": 126 + }, { - "name": "parcel_number", + "name": "voice_notes", "type": "str", - "default": "" + "line": 127 }, { - "name": "address", - "type": "str", - "default": "" + "name": "evidence", + "type": "list[Evidence]", + "line": 128 }, { - "name": "zone_code", - "type": "str", - "default": "" + "name": "linked_sources", + "type": "list[SourceLink]", + "line": 129 }, { - "name": "zone_name", + "name": "assigned_to", "type": "str", - "default": "" + "line": 130 }, { - "name": "overlays", - "type": "tuple[str, ...]", - "default": "" + "name": "staff_notes", + "type": "str", + "line": 131 }, { - "name": "constraints", - "type": "tuple[str, ...]", - "default": "" + "name": "notice_draft", + "type": "str", + "line": 132 }, { - "name": "source", - "type": "str", - "default": "" + "name": "review_state", + "type": "Literal['draft', 'follow_up', 'reviewed']", + "line": 133 }, { - "name": "disclaimer", + "name": "review_notes", "type": "str", - "default": "" - } - ], - "line": 12, - "doc": "" - }, - { - "name": "ParcelLookupError", - "bases": [], - "fields": [ + "line": 134 + }, { - "name": "message", + "name": "public_summary", "type": "str", - "default": "" + "line": 135 }, { - "name": "fix", - "type": "str", - "default": "" + "name": "analysis", + "type": "AnalysisRecord | None", + "line": 136 } ], - "line": 24, - "doc": "" + "line": 119 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_zoning/public_ui.py", - "sha256": "75d1542af38b920b5a4527da79af374ade3abf03d7a78f5d9ad2b075790681a5", + "source": "townlight_inspections/workflow_schema.py", + "sha256": "1d7b0976826350a2e34671ea569918471848639ea09a571d5b775e9646b9db2a", + "bytes": 2264, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_inspections/workflow_store.py", + "sha256": "1ebe80dee56578f11dd5aeac643a0b899325a2bc250af399600979075fa9911d", + "bytes": 17794, + "routes": [], + "models": [], + "configuration": [] + } + ] + }, + "access": { + "repository": "townlight/access", + "repository_head": "a70b56263aa0eef26d4021a5e47b5fb0a7ba7e97", + "working_tree_modified": true, + "principal_import": "townlight_access", + "source": [ + { + "source": "townlight_access/__init__.py", + "sha256": "f49d540adddb1dde0dbc6b109c82349cdd0b1af029bb06a6b41c28e799bff0f5", + "bytes": 58, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_zoning/qa.py", - "sha256": "374b232775a482a3a02ce283d047652e0c188f7f856e0046e465d663ef863315", + "source": "townlight_access/access_review.py", + "sha256": "511b887896e468aa0954e1a8763d0445d4ba4ea10f2fcf99a462dc725e98746e", + "bytes": 13859, "routes": [], "models": [ { - "name": "ZoneAnswer", + "name": "AccessibilityFinding", "bases": [], "fields": [ { - "name": "answer", + "name": "code", "type": "str", - "default": "" + "line": 16 }, { - "name": "citations", - "type": "tuple[str, ...]", - "default": "" + "name": "severity", + "type": "str", + "line": 17 }, { - "name": "status", + "name": "message", "type": "str", - "default": "" + "line": 18 }, { - "name": "reason", + "name": "fix", "type": "str", - "default": "" + "line": 19 }, { - "name": "confidence", + "name": "wcag_reference", "type": "str", - "default": "" - }, + "line": 20 + } + ], + "line": 15 + }, + { + "name": "AccessibilityReview", + "bases": [], + "fields": [ { - "name": "next_step", + "name": "status", "type": "str", - "default": "" + "line": 25 + }, + { + "name": "findings", + "type": "tuple[AccessibilityFinding, ...]", + "line": 26 }, { "name": "disclaimer", "type": "str", - "default": "DISCLAIMER" + "line": 27 + }, + { + "name": "next_steps", + "type": "tuple[str, ...]", + "line": 28 } ], - "line": 16, - "doc": "" - } - ], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_zoning/question_ledger.py", - "sha256": "0fca91aa0a7338771f760fe9032da442023c3407584d0ee0c621ce0290a65e7b", - "routes": [], - "models": [ + "line": 24 + }, { - "name": "ZoneQuestionLedgerRecord", + "name": "StoredAccessibilityReview", "bases": [], "fields": [ { - "name": "id", + "name": "review_id", "type": "str", - "default": "" + "line": 33 }, { - "name": "zone_code", + "name": "title", "type": "str", - "default": "" + "line": 34 }, { - "name": "question_text", + "name": "body", "type": "str", - "default": "" + "line": 35 }, { - "name": "audience", - "type": "str", - "default": "" + "name": "has_alt_text", + "type": "bool", + "line": 36 }, { - "name": "status", + "name": "language", "type": "str", - "default": "" + "line": 37 }, { - "name": "answer_text", - "type": "str | None", - "default": "" + "name": "status", + "type": "str", + "line": 38 }, { - "name": "citation_payload", - "type": "tuple[str, ...]", - "default": "" + "name": "findings", + "type": "tuple[AccessibilityFinding, ...]", + "line": 39 }, { "name": "disclaimer", "type": "str", - "default": "" + "line": 40 }, { - "name": "escalation_reason", + "name": "created_at", + "type": "datetime", + "line": 41 + } + ], + "line": 32 + }, + { + "name": "SchemaStatus", + "bases": [], + "fields": [ + { + "name": "schema_version", "type": "str | None", - "default": "" + "line": 91 }, { - "name": "created_at", - "type": "datetime", - "default": "" + "name": "expected_schema_version", + "type": "str", + "line": 92 }, { - "name": "updated_at", - "type": "datetime", - "default": "" + "name": "ready", + "type": "bool", + "line": 93 + }, + { + "name": "missing_tables", + "type": "tuple[str, ...]", + "line": 94 + }, + { + "name": "dialect", + "type": "str", + "line": 95 } ], - "line": 32, - "doc": "" + "line": 90 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_zoning/rule_lookup.py", - "sha256": "5c53135c7a413e0eecf663061593945c56330eae6a96808d61d69bd4e6d996a2", + "source": "townlight_access/db_admin.py", + "sha256": "c9b86df06388061de0646c9c7bc1c6964cdf075113a04fdda3b6a4103aa988c0", + "bytes": 1099, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_access/exports.py", + "sha256": "f6496dc04cae8445a25c779d1556a8026f27dd304d7b1c22325e143faedb48ab", + "bytes": 1793, "routes": [], "models": [ { - "name": "UseRuleResult", + "name": "AccessibleExport", "bases": [], "fields": [ { - "name": "zone_code", + "name": "title", "type": "str", - "default": "" + "line": 10 }, { - "name": "use", + "name": "format", "type": "str", - "default": "" + "line": 11 }, { - "name": "status", - "type": "str", - "default": "" + "name": "checklist", + "type": "tuple[str, ...]", + "line": 12 }, { - "name": "review_path", + "name": "retention_note", "type": "str", - "default": "" + "line": 13 }, { - "name": "citation", + "name": "status", "type": "str", - "default": "" + "line": 14 }, { - "name": "disclaimer", - "type": "str", - "default": "DISCLAIMER" + "name": "fix", + "type": "str | None", + "line": 15 } ], - "line": 14, - "doc": "" + "line": 9 + } + ], + "configuration": [] + }, + { + "source": "townlight_access/main.py", + "sha256": "0eb87c6acb2c97e6c43f928a457bb226a826d807a8bc3c5afc347bf88c8daf8e", + "bytes": 18671, + "routes": [ + { + "method": "GET", + "declared_path": "/", + "function": "root", + "line": 87 }, { - "name": "DimensionalRuleResult", - "bases": [], + "method": "GET", + "declared_path": "/health", + "function": "health", + "line": 103 + }, + { + "method": "GET", + "declared_path": "/ready", + "function": "ready", + "line": 142 + }, + { + "method": "GET", + "declared_path": "/api/v1/townlight_access/readiness", + "function": "readiness", + "line": 149 + }, + { + "method": "GET", + "declared_path": "/townlight_access", + "function": "public_townlight_access_page", + "line": 156 + }, + { + "method": "GET", + "declared_path": "/townlight_access/staff", + "function": "staff_townlight_access_page", + "line": 163 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_access/analyze", + "function": "analyze_accessibility", + "line": 173 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_access/review", + "function": "accessibility_review", + "line": 192 + }, + { + "method": "GET", + "declared_path": "/api/v1/townlight_access/reviews", + "function": "list_accessibility_reviews", + "line": 207 + }, + { + "method": "GET", + "declared_path": "/api/v1/townlight_access/reviews/{review_id}", + "function": "get_accessibility_review", + "line": 217 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_access/reviews/{review_id}/records-export", + "function": "export_accessibility_review_record", + "line": 231 + }, + { + "method": "GET", + "declared_path": "/api/v1/townlight_access/integration-contracts", + "function": "integration_contracts", + "line": 278 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_access/plain-language", + "function": "plain_language_rewrite", + "line": 307 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_access/language-variant", + "function": "language_variant", + "line": 313 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_access/forms", + "function": "accessible_form", + "line": 319 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_access/publishing-workflow", + "function": "publishing_workflow", + "line": 331 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_access/ada-title-ii", + "function": "ada_title_ii_review", + "line": 348 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_access/tagged-pdf", + "function": "tagged_pdf_expectations", + "line": 363 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_access/export", + "function": "accessible_export", + "line": 374 + } + ], + "models": [ + { + "name": "AccessibilityReviewRequest", + "bases": [ + "BaseModel" + ], "fields": [ { - "name": "zone_code", + "name": "title", "type": "str", - "default": "" + "line": 45 }, { - "name": "rule_type", + "name": "body", "type": "str", - "default": "" + "line": 46 }, { - "name": "value", - "type": "str", - "default": "" + "name": "has_alt_text", + "type": "bool", + "line": 47 }, { - "name": "citation", + "name": "language", "type": "str", - "default": "" - }, + "line": 48 + } + ], + "line": 44 + }, + { + "name": "PlainLanguageRequest", + "bases": [ + "BaseModel" + ], + "fields": [ { - "name": "disclaimer", + "name": "text", "type": "str", - "default": "DISCLAIMER" + "line": 52 } ], - "line": 24, - "doc": "" + "line": 51 }, { - "name": "RuleLookupError", - "bases": [], + "name": "LanguageVariantRequest", + "bases": [ + "BaseModel" + ], "fields": [ { - "name": "message", + "name": "text", "type": "str", - "default": "" + "line": 56 }, { - "name": "fix", + "name": "language", "type": "str", - "default": "" + "line": 57 } ], - "line": 33, - "doc": "" - } - ], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_zoning/staff_context.py", - "sha256": "50784c2b595741098e2de9d9ad90a7957607ae09839afe6167af13e38037c91c", - "routes": [], - "models": [ + "line": 55 + }, { - "name": "EscalationResult", - "bases": [], + "name": "AccessibleExportRequest", + "bases": [ + "BaseModel" + ], "fields": [ { - "name": "status", + "name": "title", "type": "str", - "default": "" + "line": 61 }, { - "name": "reason", + "name": "format", "type": "str", - "default": "" - }, + "line": 62 + } + ], + "line": 60 + }, + { + "name": "AccessibleFormRequest", + "bases": [ + "BaseModel" + ], + "fields": [ { - "name": "next_step", + "name": "form_name", "type": "str", - "default": "" + "line": 66 + }, + { + "name": "fields", + "type": "list[str]", + "line": 67 } ], - "line": 9, - "doc": "" + "line": 65 }, { - "name": "StaffPrecedent", - "bases": [], + "name": "PublishingWorkflowRequest", + "bases": [ + "BaseModel" + ], "fields": [ { "name": "title", "type": "str", - "default": "" + "line": 71 }, { - "name": "summary", - "type": "str", - "default": "" + "name": "has_review", + "type": "bool", + "line": 72 }, { - "name": "visibility", - "type": "str", - "default": "'staff_only'" + "name": "has_plain_language", + "type": "bool", + "line": 73 + }, + { + "name": "has_translation_review", + "type": "bool", + "line": 74 } ], - "line": 16, - "doc": "" - } - ], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_zoning/staff_ui.py", - "sha256": "69448abc334931b5f19168fdffbef81497e250dd61f1912811d4ebdb28ee0b25", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_zoning/staff_workflows.py", - "sha256": "27cf6da89c7a1472b23cbcace93adb63a0384be443b95228c882eb3bfb0ed642", - "routes": [], - "models": [ + "line": 70 + }, { - "name": "CodeCrossReference", - "bases": [], + "name": "AdaTitleIiReviewRequest", + "bases": [ + "BaseModel" + ], "fields": [ { - "name": "citation", + "name": "service_area", "type": "str", - "default": "" + "line": 78 }, { - "name": "source", - "type": "str", - "default": "" - }, + "name": "has_coordinator_review", + "type": "bool", + "line": 79 + } + ], + "line": 77 + }, + { + "name": "TaggedPdfExpectationRequest", + "bases": [ + "BaseModel" + ], + "fields": [ { - "name": "relevance", - "type": "str", - "default": "" + "name": "heading_levels", + "type": "list[int]", + "line": 83 } ], - "line": 80, - "doc": "" + "line": 82 + } + ], + "configuration": [ + { + "environment": "TOWNLIGHT_ACCESS_TRUSTED_WRITE_TOKEN", + "line": 387 + }, + { + "environment": "TOWNLIGHT_ACCESS_REVIEW_DB_URL", + "line": 427 + }, + { + "environment": "DATABASE_URL", + "line": 431 }, { - "name": "StaffQuestionRecord", + "environment": "TOWNLIGHT_ACCESS_DATA_DIR", + "line": 435 + } + ] + }, + { + "source": "townlight_access/multilingual.py", + "sha256": "49903d5b7cddc2453fe99989e519306d4ac1796e8a45713cae0651c00aae9be6", + "bytes": 1630, + "routes": [], + "models": [ + { + "name": "LanguageVariant", "bases": [], "fields": [ { - "name": "id", + "name": "source_text", "type": "str", - "default": "" + "line": 12 }, { - "name": "zone_code", + "name": "language", "type": "str", - "default": "" + "line": 13 }, { - "name": "question_text", + "name": "text", "type": "str", - "default": "" + "line": 14 }, { - "name": "status", - "type": "str", - "default": "" + "name": "review_required", + "type": "bool", + "line": 15 }, { - "name": "answer_text", + "name": "status", "type": "str", - "default": "" - }, - { - "name": "citations", - "type": "tuple[str, ...]", - "default": "" - }, - { - "name": "code_cross_references", - "type": "tuple[CodeCrossReference, ...]", - "default": "" + "line": 16 }, { - "name": "created_by", + "name": "fix", "type": "str", - "default": "" - }, - { - "name": "created_at", - "type": "datetime", - "default": "" + "line": 17 }, { - "name": "visibility", - "type": "str", - "default": "STAFF_VISIBILITY" + "name": "translation_performed", + "type": "bool", + "line": 18 }, { "name": "disclaimer", "type": "str", - "default": "DISCLAIMER" + "line": 19 } ], - "line": 87, - "doc": "" - }, + "line": 11 + } + ], + "configuration": [] + }, + { + "source": "townlight_access/plain_language.py", + "sha256": "7677832cee72ad515490486489749b41f0a209fc66a75fb76e7a7190bf69ca26", + "bytes": 1420, + "routes": [], + "models": [ { - "name": "AmbiguityReviewItem", + "name": "PlainLanguageRewrite", "bases": [], "fields": [ { - "name": "id", - "type": "str", - "default": "" - }, - { - "name": "zone_code", - "type": "str", - "default": "" - }, - { - "name": "question_text", - "type": "str", - "default": "" - }, - { - "name": "reason", + "name": "original", "type": "str", - "default": "" + "line": 12 }, { - "name": "status", + "name": "rewritten", "type": "str", - "default": "" - }, - { - "name": "assigned_to", - "type": "str | None", - "default": "" - }, - { - "name": "resolution", - "type": "str | None", - "default": "" - }, - { - "name": "source_question_id", - "type": "str | None", - "default": "" + "line": 13 }, { - "name": "created_by", + "name": "reading_level", "type": "str", - "default": "" + "line": 14 }, { - "name": "created_at", - "type": "datetime", - "default": "" + "name": "review_required", + "type": "bool", + "line": 15 }, { - "name": "updated_at", - "type": "datetime", - "default": "" + "name": "provenance", + "type": "tuple[str, ...]", + "line": 16 }, { - "name": "visibility", + "name": "disclaimer", "type": "str", - "default": "STAFF_VISIBILITY" + "line": 17 } ], - "line": 102, - "doc": "" - }, + "line": 11 + } + ], + "configuration": [] + }, + { + "source": "townlight_access/public_ui.py", + "sha256": "78168321622a780a4d373b35432668daad0d5f6a0a3f011c8e41862c9998068e", + "bytes": 20623, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_access/record_artifact.py", + "sha256": "57d8966dbdbd0764b323355fdca5ef6ff52f7ca86594f22926b2ffa96f4b8d29", + "bytes": 985, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_access/workflows.py", + "sha256": "87d7787f658c9cb43ff2bee670ad78e532d836944ba4d26bdbc15b5b9c66f860", + "bytes": 5913, + "routes": [], + "models": [ { - "name": "HighVolumeQuestion", + "name": "AccessibleFormPlan", "bases": [], "fields": [ { - "name": "zone_code", + "name": "status", "type": "str", - "default": "" + "line": 12 }, { - "name": "question_text", - "type": "str", - "default": "" + "name": "missing_fields", + "type": "tuple[str, ...]", + "line": 13 }, { - "name": "count", - "type": "int", - "default": "" + "name": "checklist", + "type": "tuple[str, ...]", + "line": 14 }, { - "name": "statuses", - "type": "tuple[str, ...]", - "default": "" + "name": "fix", + "type": "str | None", + "line": 15 }, { - "name": "latest_question_id", + "name": "disclaimer", "type": "str", - "default": "" + "line": 16 } ], - "line": 118, - "doc": "" + "line": 11 }, { - "name": "StaffQuestionAnalytics", + "name": "PublishingWorkflowPlan", "bases": [], "fields": [ { - "name": "total_questions", - "type": "int", - "default": "" + "name": "status", + "type": "str", + "line": 21 }, { - "name": "by_status", - "type": "dict[str, int]", - "default": "" + "name": "steps", + "type": "tuple[str, ...]", + "line": 22 }, { - "name": "high_volume_questions", - "type": "tuple[HighVolumeQuestion, ...]", - "default": "" + "name": "blockers", + "type": "tuple[str, ...]", + "line": 23 }, { - "name": "generated_at", - "type": "datetime", - "default": "" + "name": "fix", + "type": "str | None", + "line": 24 }, { - "name": "visibility", + "name": "disclaimer", "type": "str", - "default": "STAFF_VISIBILITY" + "line": 25 } ], - "line": 127, - "doc": "" + "line": 20 }, { - "name": "StaffReportOutline", + "name": "AdaTitleIiReviewPlan", "bases": [], "fields": [ { - "name": "id", - "type": "str", - "default": "" - }, - { - "name": "title", + "name": "status", "type": "str", - "default": "" - }, - { - "name": "sections", - "type": "tuple[dict[str, object], ...]", - "default": "" + "line": 30 }, { - "name": "source_question_ids", - "type": "tuple[str, ...]", - "default": "" - }, - { - "name": "source_queue_item_ids", + "name": "checklist", "type": "tuple[str, ...]", - "default": "" - }, - { - "name": "created_by", - "type": "str", - "default": "" + "line": 31 }, { - "name": "created_at", - "type": "datetime", - "default": "" + "name": "reviewer_required", + "type": "bool", + "line": 32 }, { - "name": "visibility", - "type": "str", - "default": "STAFF_VISIBILITY" + "name": "fix", + "type": "str | None", + "line": 33 }, { "name": "disclaimer", "type": "str", - "default": "'Draft staff outline only; verify citations before publication.'" + "line": 34 } ], - "line": 136, - "doc": "" + "line": 29 }, { - "name": "FlaggedAnswerReview", + "name": "TaggedPdfExpectationPlan", "bases": [], "fields": [ { - "name": "id", + "name": "status", "type": "str", - "default": "" + "line": 39 }, { - "name": "zone_code", - "type": "str", - "default": "" + "name": "checklist", + "type": "tuple[str, ...]", + "line": 40 }, { - "name": "question_text", - "type": "str", - "default": "" + "name": "fix", + "type": "str | None", + "line": 41 }, { - "name": "original_answer", + "name": "disclaimer", "type": "str", - "default": "" - }, + "line": 42 + } + ], + "line": 38 + } + ], + "configuration": [] + } + ] + }, + "notice": { + "repository": "townlight/notice", + "repository_head": "6c7bc4435cdd700fd4673486d3c7b3794d5def82", + "working_tree_modified": true, + "principal_import": "townlight_notice", + "source": [ + { + "source": "townlight_notice/__init__.py", + "sha256": "cdce8d39689ef3269af032210d1990198318fdbe04f6eb0a739241f347102890", + "bytes": 64, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_notice/accessibility_review.py", + "sha256": "a2f9463a4362b03ef0b2a41d00c0991a0e99346d2cf8b64c6909bf06328fb23f", + "bytes": 3448, + "routes": [], + "models": [ + { + "name": "NoticeAccessibilityReview", + "bases": [], + "fields": [ { - "name": "flag_reason", + "name": "notice_id", "type": "str", - "default": "" - }, - { - "name": "citations", - "type": "tuple[str, ...]", - "default": "" + "line": 12 }, { - "name": "status", + "name": "title", "type": "str", - "default": "" + "line": 13 }, { - "name": "improved_answer", - "type": "str | None", - "default": "" + "name": "missing_accessibility_items", + "type": "tuple[str, ...]", + "line": 14 }, { - "name": "improvement_notes", - "type": "str | None", - "default": "" + "name": "plain_language_flags", + "type": "tuple[str, ...]", + "line": 15 }, { - "name": "reviewed_by", - "type": "str | None", - "default": "" + "name": "translation_tasks", + "type": "tuple[str, ...]", + "line": 16 }, { - "name": "created_by", - "type": "str", - "default": "" + "name": "attachment_review_required", + "type": "bool", + "line": 17 }, { - "name": "created_at", - "type": "datetime", - "default": "" + "name": "staff_review_required", + "type": "bool", + "line": 18 }, { - "name": "updated_at", - "type": "datetime", - "default": "" + "name": "review_notes", + "type": "tuple[str, ...]", + "line": 19 }, { - "name": "visibility", + "name": "disclaimer", "type": "str", - "default": "STAFF_VISIBILITY" + "line": 20 } ], - "line": 149, - "doc": "" + "line": 11 } ], "configuration": [] - } - ], - "bridge": [ + }, { - "source": "installed-owned-source/townlight_runtime/zoning_bridge.py", - "sha256": "eb80d79ffc4fc736789aab4f3d3b75a4d9d01101d6414a69a29053c7d5f90505", - "routes": [ - { - "method": "POST", - "path": "/desktop/v1/zoning/imports", - "router": "router", - "prefix_resolved": true, - "name": "imports", - "signature": "payload: dict, actor_id: str=Depends(actor)", - "returns": "", - "line": 68, - "doc": "", - "decorator": "router.post('/imports')", - "errors": [ - "HTTPException(422, detail)", - "HTTPException(503, 'Zoning persistence unavailable.')" - ] - }, - { - "method": "POST", - "path": "/desktop/v1/zoning/parcels/lookup", - "router": "router", - "prefix_resolved": true, - "name": "parcel_lookup", - "signature": "body: _ParcelLookupIn, _actor: str=Depends(actor)", - "returns": "", - "line": 91, - "doc": "", - "decorator": "router.post('/parcels/lookup')", - "errors": [ - "HTTPException(503, 'Townlight Code database/schema is not ready; no determination.')", - "HTTPException(503, 'Zoning persistence unavailable.')" - ] - }, - { - "method": "GET", - "path": "/desktop/v1/zoning/questions/{question_id}/history", - "router": "router", - "prefix_resolved": true, - "name": "question_history", - "signature": "question_id: UUID, actor_id=Depends(actor), provider=Depends(meeting_provider)", - "returns": "", - "line": 209, - "doc": "", - "decorator": "router.get('/questions/{question_id}/history')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/zoning/meetings/search", - "router": "router", - "prefix_resolved": true, - "name": "search_meetings", - "signature": "p: MeetingSearch, actor_id=Depends(actor), provider=Depends(meeting_provider)", - "returns": "", - "line": 216, - "doc": "", - "decorator": "router.post('/meetings/search')", - "errors": [ - "HTTPException(status_code=503, detail='Meeting search unavailable')" - ] - }, - { - "method": "POST", - "path": "/desktop/v1/zoning/questions/{question_id}/meetings", - "router": "router", - "prefix_resolved": true, - "name": "link_meeting", - "signature": "question_id: UUID, p: MeetingLink, actor_id=Depends(actor), provider=Depends(meeting_provider)", - "returns": "", - "line": 242, - "doc": "", - "decorator": "router.post('/questions/{question_id}/meetings')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/zoning/questions/{question_id}/snapshots", - "router": "router", - "prefix_resolved": true, - "name": "create_snapshot", - "signature": "question_id: UUID, p: SourceSnapshot, actor_id=Depends(actor), provider=Depends(meeting_provider)", - "returns": "", - "line": 259, - "doc": "", - "decorator": "router.post('/questions/{question_id}/snapshots')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/zoning/rules", - "router": "router", - "prefix_resolved": true, - "name": "create_rule", - "signature": "p: Rule, actor_id=Depends(actor)", - "returns": "", - "line": 291, - "doc": "", - "decorator": "router.post('/rules')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/zoning/questions", - "router": "router", - "prefix_resolved": true, - "name": "create_question", - "signature": "p: Question, actor_id=Depends(actor)", - "returns": "", - "line": 300, - "doc": "", - "decorator": "router.post('/questions')", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/zoning/workspace", - "router": "router", - "prefix_resolved": true, - "name": "get_workspace", - "signature": "actor_id=Depends(actor)", - "returns": "", - "line": 313, - "doc": "", - "decorator": "router.get('/workspace')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/zoning/questions/{question_id}/reviews", - "router": "router", - "prefix_resolved": true, - "name": "create_review", - "signature": "question_id: UUID, p: Review, actor_id=Depends(actor)", - "returns": "", - "line": 318, - "doc": "", - "decorator": "router.post('/questions/{question_id}/reviews')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/zoning/outlines", - "router": "router", - "prefix_resolved": true, - "name": "create_outline", - "signature": "p: Outline, actor_id=Depends(actor)", - "returns": "", - "line": 325, - "doc": "", - "decorator": "router.post('/outlines')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/zoning/code-context", - "router": "router", - "prefix_resolved": true, - "name": "create_code_context", - "signature": "p: CodeContext, actor_id=Depends(actor)", - "returns": "", - "line": 332, - "doc": "", - "decorator": "router.post('/code-context')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/zoning/standards/process-explanation", - "router": "router", - "prefix_resolved": true, - "name": "standards_explanation", - "signature": "p: StandardsExplanation, actor_id=Depends(actor)", - "returns": "", - "line": 373, - "doc": "Cited variance/CUP/nonconformity process; never a determination.", - "decorator": "router.post('/standards/process-explanation')", - "errors": [ - "HTTPException(422, f\"Unknown rule type '{rule_type}'.\")" - ] - }, - { - "method": "POST", - "path": "/townlight_zoning/questions", - "router": "public_router", - "prefix_resolved": true, - "name": "public_question", - "signature": "p: Question", - "returns": "", - "line": 423, - "doc": "", - "decorator": "public_router.post('/questions', dependencies=[Depends(public_active)])", - "errors": [] - }, - { - "method": "POST", - "path": "/townlight_zoning/parcels/lookup", - "router": "public_router", - "prefix_resolved": true, - "name": "public_parcel_lookup", - "signature": "p: _ParcelLookupIn", - "returns": "", - "line": 434, - "doc": "", - "decorator": "public_router.post('/parcels/lookup', dependencies=[Depends(public_active)])", - "errors": [] - } - ], + "source": "townlight_notice/archive_packet.py", + "sha256": "05db28385a7e2854cfeb96148751f119586e888e2ce0460f3686ed651f16ae32", + "bytes": 3101, + "routes": [], "models": [ { - "name": "_ParcelLookupIn", - "bases": [ - "BaseModel" - ], + "name": "NoticeArchivePacket", + "bases": [], "fields": [ { - "name": "jurisdiction", + "name": "notice_id", "type": "str", - "default": "Field(min_length=1, max_length=255)" + "line": 12 }, { - "name": "query", + "name": "notice_type", "type": "str", - "default": "Field(min_length=1, max_length=500)" - } - ], - "line": 60, - "doc": "" - }, - { - "name": "Question", - "bases": [ - "Strict" - ], - "fields": [ + "line": 13 + }, { - "name": "jurisdiction", + "name": "source_module", + "type": "str", + "line": 14 + }, + { + "name": "source_record_id", "type": "str", - "default": "Field(min_length=1, max_length=255)" + "line": 15 }, { - "name": "query", - "type": "str", - "default": "Field(min_length=1, max_length=500)" + "name": "evidence_items", + "type": "tuple[str, ...]", + "line": 16 }, { - "name": "question", - "type": "str", - "default": "Field(min_length=1, max_length=2000)" + "name": "missing_items", + "type": "tuple[str, ...]", + "line": 17 }, { - "name": "kind", - "type": "Literal['use', 'dimension']", - "default": "" + "name": "handoff_targets", + "type": "tuple[str, ...]", + "line": 18 }, { - "name": "key", + "name": "readiness_status", "type": "str", - "default": "Field(min_length=1, max_length=255)" + "line": 19 }, { - "name": "audience", - "type": "Literal['resident', 'staff']", - "default": "'resident'" + "name": "staff_review_required", + "type": "bool", + "line": 20 + }, + { + "name": "disclaimer", + "type": "str", + "line": 21 } ], - "line": 150, - "doc": "" - }, + "line": 11 + } + ], + "configuration": [] + }, + { + "source": "townlight_notice/channel_plan.py", + "sha256": "acdce60fa24fcfbd903100e02df1d730ed9b913013a52f8287839272bf58a643", + "bytes": 1182, + "routes": [], + "models": [ { - "name": "Rule", - "bases": [ - "Strict" - ], + "name": "ChannelPlan", + "bases": [], "fields": [ { - "name": "jurisdiction", - "type": "str", - "default": "Field(min_length=1, max_length=255)" - }, - { - "name": "zone_code", + "name": "notice_type", "type": "str", - "default": "Field(..., min_length=1, max_length=80)" + "line": 12 }, { - "name": "key", - "type": "str", - "default": "Field(..., min_length=1, max_length=120)" + "name": "channels", + "type": "tuple[str, ...]", + "line": 13 }, { - "name": "section_number", - "type": "str", - "default": "Field(min_length=1, max_length=255)" + "name": "accessibility_notes", + "type": "tuple[str, ...]", + "line": 14 }, { - "name": "kind", - "type": "Literal['use', 'dimension']", - "default": "" + "name": "staff_review_required", + "type": "bool", + "line": 15 }, { - "name": "value", + "name": "disclaimer", "type": "str", - "default": "Field(..., min_length=1, max_length=255)" - }, - { - "name": "overlay_code", - "type": "str | None", - "default": "Field(default=None, max_length=255)" + "line": 16 } ], - "line": 159, - "doc": "" - }, + "line": 11 + } + ], + "configuration": [] + }, + { + "source": "townlight_notice/deadline_tracker.py", + "sha256": "7dd15044ff4cf2597be1b0eebd525ea641328388d7f79ff2ad42d7f1063b6c8d", + "bytes": 1106, + "routes": [], + "models": [ { - "name": "Review", - "bases": [ - "Strict" - ], + "name": "DeadlinePlan", + "bases": [], "fields": [ { - "name": "answer", + "name": "notice_type", "type": "str", - "default": "Field(default='', max_length=10000)" + "line": 14 }, { - "name": "notes", - "type": "str", - "default": "Field(default='', max_length=10000)" + "name": "event_date", + "type": "date", + "line": 15 }, { - "name": "queue_status", - "type": "Literal['open', 'in_review', 'resolved', 'closed']", - "default": "'resolved'" - } - ], - "line": 169, - "doc": "" - }, - { - "name": "Outline", - "bases": [ - "Strict" - ], - "fields": [ + "name": "reminders", + "type": "tuple[str, ...]", + "line": 16 + }, { - "name": "title", - "type": "str", - "default": "Field(min_length=1, max_length=255)" + "name": "staff_review_required", + "type": "bool", + "line": 17 }, { - "name": "question_ids", - "type": "list[UUID]", - "default": "Field(min_length=1, max_length=50)" + "name": "disclaimer", + "type": "str", + "line": 18 } ], - "line": 175, - "doc": "" + "line": 13 + } + ], + "configuration": [] + }, + { + "source": "townlight_notice/main.py", + "sha256": "5074a5d9d80332f672401cfa37035d13ec4e5b9707b155ea154d1a689404c920", + "bytes": 23999, + "routes": [ + { + "method": "GET", + "declared_path": "/", + "function": "root", + "line": 186 }, { - "name": "CodeContext", + "method": "GET", + "declared_path": "/health", + "function": "health", + "line": 206 + }, + { + "method": "GET", + "declared_path": "/townlight_notice", + "function": "public_townlight_notice_page", + "line": 218 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_notice/registry", + "function": "notice_registry", + "line": 225 + }, + { + "method": "GET", + "declared_path": "/api/v1/townlight_notice/registry/{record_id}", + "function": "get_notice_registry", + "line": 250 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_notice/deadlines", + "function": "deadline_plan", + "line": 272 + }, + { + "method": "GET", + "declared_path": "/api/v1/townlight_notice/deadlines/{plan_id}", + "function": "get_deadline_plan", + "line": 297 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_notice/publication-proof", + "function": "publication_proof", + "line": 319 + }, + { + "method": "GET", + "declared_path": "/api/v1/townlight_notice/publication-proof/{proof_id}", + "function": "get_publication_proof", + "line": 352 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_notice/publication-check", + "function": "publication_checklist", + "line": 376 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_notice/rule-check", + "function": "rule_check", + "line": 384 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_notice/templates", + "function": "notice_template", + "line": 404 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_notice/channels", + "function": "channel_plan", + "line": 421 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_notice/subscribers/plan", + "function": "subscriber_delivery_plan", + "line": 429 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_notice/accessibility-review", + "function": "accessibility_review", + "line": 451 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_notice/archive-packet", + "function": "archive_packet", + "line": 465 + }, + { + "method": "POST", + "declared_path": "/api/v1/townlight_notice/export", + "function": "records_export", + "line": 483 + } + ], + "models": [ + { + "name": "NoticeRegistryRequest", "bases": [ - "Strict" + "BaseModel" ], "fields": [ { - "name": "section_number", + "name": "notice_id", "type": "str", - "default": "Field(min_length=1, max_length=255)" + "line": 55 }, { - "name": "as_of", - "type": "date | None", - "default": "None" - } - ], - "line": 180, - "doc": "" - }, - { - "name": "MeetingSearch", - "bases": [ - "Strict" - ], - "fields": [ + "name": "notice_type", + "type": "str", + "line": 56 + }, { - "name": "query", + "name": "owner", "type": "str", - "default": "Field(min_length=1, max_length=500)" + "line": 57 } ], - "line": 185, - "doc": "" + "line": 54 }, { - "name": "MeetingLink", + "name": "DeadlineRequest", "bases": [ - "Strict" + "BaseModel" ], "fields": [ { - "name": "source_id", + "name": "notice_type", "type": "str", - "default": "Field(min_length=1, max_length=200)" + "line": 61 }, { - "name": "expected_sha256", - "type": "str", - "default": "Field(pattern='^[0-9a-f]{64}$')" + "name": "event_date", + "type": "date", + "line": 62 }, { - "name": "relation", - "type": "Literal['hearing', 'context', 'precedent']", - "default": "" + "name": "lead_days", + "type": "int", + "line": 63 } ], - "line": 189, - "doc": "" + "line": 60 }, { - "name": "SourceSnapshot", + "name": "PublicationRequest", "bases": [ - "Strict" + "BaseModel" ], "fields": [ { - "name": "visibility", - "type": "Literal['public', 'staff_only']", - "default": "" + "name": "notice_type", + "type": "str", + "line": 67 }, { - "name": "meeting_event_ids", - "type": "list[UUID]", - "default": "Field(default_factory=list, max_length=50)" + "name": "channel", + "type": "str", + "line": 68 } ], - "line": 195, - "doc": "" + "line": 66 }, { - "name": "StandardsExplanation", + "name": "RuleCheckRequest", "bases": [ "BaseModel" ], "fields": [ { - "name": "question", + "name": "notice_type", "type": "str", - "default": "Field(min_length=1, max_length=2000)" + "line": 72 }, { - "name": "process_section", - "type": "str", - "default": "Field(default='', max_length=255)" + "name": "event_date", + "type": "date", + "line": 77 }, { - "name": "zone_code", - "type": "str", - "default": "Field(default='', max_length=40)" + "name": "publication_dates", + "type": "list[date]", + "line": 81 }, { - "name": "rule_types", + "name": "channels", "type": "list[str]", - "default": "Field(default_factory=list, max_length=10)" - }, - { - "name": "observed", - "type": "dict[str, str]", - "default": "Field(default_factory=dict)" - } - ], - "line": 342, - "doc": "" - } - ], - "configuration": [ - { - "variable": "TOWNLIGHT_ZONING_PARCEL_RULE_DB_URL", - "default": "", - "line": 359 - } - ] - } - ] - }, - "planning": { - "package": "townlight_planning", - "source": [ - { - "source": "installed-owned-source/townlight_planning/__init__.py", - "sha256": "d6a014eba48a6bdcdaea2a444cfcaa743cd2ba33cec6d63ea5e450266ad71c82", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_planning/connections.py", - "sha256": "649c8474e787fca1e30a11f153d2f776283204b5dc8053b7e88fbc325cdcf944", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_planning/consistency.py", - "sha256": "d18ef439391d859f0d1a020356edaf91d2441333eacf36036d03d1b7ea467210", - "routes": [], - "models": [ - { - "name": "ConsistencyCheck", - "bases": [], - "fields": [ - { - "name": "policy_id", - "type": "str", - "default": "" - }, - { - "name": "status", - "type": "str", - "default": "" - }, - { - "name": "factors", - "type": "tuple[str, ...]", - "default": "" + "line": 86 }, { - "name": "staff_next_step", - "type": "str", - "default": "" + "name": "content_fields", + "type": "list[str]", + "line": 91 }, { - "name": "disclaimer", + "name": "statutory_basis", "type": "str", - "default": "DISCLAIMER" + "line": 96 } ], - "line": 11, - "doc": "" - } - ], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_planning/integration_mocks.py", - "sha256": "09c350c13fe4e14c3f385549021f57c09341c8dbe110b18e6e4739cf70ac6254", - "routes": [], - "models": [ + "line": 71 + }, { - "name": "IntegrationError", - "bases": [], + "name": "NoticeTemplateRequest", + "bases": [ + "BaseModel" + ], "fields": [ { - "name": "provider", + "name": "notice_type", "type": "str", - "default": "" + "line": 105 }, { - "name": "message", + "name": "matter_title", "type": "str", - "default": "" + "line": 110 }, { - "name": "fix", - "type": "str", - "default": "" + "name": "event_date", + "type": "date", + "line": 111 }, { - "name": "code", - "type": "str", - "default": "" - } - ], - "line": 18, - "doc": "" - }, - { - "name": "IntegrationResult", - "bases": [], - "fields": [ - { - "name": "provider", + "name": "location", "type": "str", - "default": "" + "line": 112 }, { - "name": "records", - "type": "tuple[dict[str, Any], ...]", - "default": "" + "name": "contact", + "type": "str", + "line": 113 }, { - "name": "source", + "name": "source_module", "type": "str", - "default": "" + "line": 114 }, { - "name": "warnings", - "type": "tuple[str, ...]", - "default": "()" + "name": "statutory_basis", + "type": "str", + "line": 115 } ], - "line": 26, - "doc": "" - } - ], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_planning/main.py", - "sha256": "34aaae27da4bc8f34570849cc446a134efb78c004294425ac62ef2c80abb1adf", - "routes": [ - { - "method": "GET", - "path": "/", - "router": "app", - "prefix_resolved": true, - "name": "root", - "signature": "", - "returns": "dict[str, str]", - "line": 129, - "doc": "Return current product state without overstating unshipped behavior.", - "decorator": "app.get('/')", - "errors": [] - }, - { - "method": "GET", - "path": "/health", - "router": "app", - "prefix_resolved": true, - "name": "health", - "signature": "", - "returns": "dict[str, str]", - "line": 147, - "doc": "Return dependency/version health for deployment smoke checks.", - "decorator": "app.get('/health')", - "errors": [] - }, - { - "method": "GET", - "path": "/townlight_planning", - "router": "app", - "prefix_resolved": true, - "name": "public_townlight_planning_page", - "signature": "q: str='', goal: str='', topic: str='', plan_type: str='', clear: str='', neighborhood: str=''", - "returns": "str", - "line": 193, - "doc": "Explore the adopted plan sources this deployment actually holds.\n\nPublic readers get only adopted, effective, public municipal revisions. When\nno plan database is configured the page says so instead of showing sample text.", - "decorator": "app.get('/townlight_planning', response_class=HTMLResponse)", - "errors": [] - }, - { - "method": "GET", - "path": "/api/v1/townlight_planning/public/plan-explore", - "router": "app", - "prefix_resolved": true, - "name": "public_plan_explore", - "signature": "q: str='', goal: str='', topic: str='', plan_type: str='', neighborhood: str=''", - "returns": "dict[str, object]", - "line": 220, - "doc": "The same persisted-source exploration as the page, as JSON.", - "decorator": "app.get('/api/v1/townlight_planning/public/plan-explore')", - "errors": [ - "HTTPException(503, 'No plan source database is configured for this deployment.')" - ] - }, - { - "method": "GET", - "path": "/api/v1/townlight_planning/public/policy/{revision_id}/{policy_id}", - "router": "app", - "prefix_resolved": true, - "name": "public_policy_citation", - "signature": "revision_id: str, policy_id: str", - "returns": "dict[str, object]", - "line": 237, - "doc": "One cited policy for a public reader, or a refusal.\n\nA staff-only, pending, superseded or non-effective revision is refused here by\nthe service; naming its id does not reach it.", - "decorator": "app.get('/api/v1/townlight_planning/public/policy/{revision_id}/{policy_id}')", - "errors": [ - "HTTPException(503, 'No plan source database is configured for this deployment.')", - "HTTPException(404, str(exc))" - ] - }, - { - "method": "POST", - "path": "/api/v1/townlight_planning/policies/lookup", - "router": "app", - "prefix_resolved": true, - "name": "policy_lookup", - "signature": "request: PolicyLookupRequest, is_staff=Depends(audience)", - "returns": "dict[str, object]", - "line": 256, - "doc": "", - "decorator": "app.post('/api/v1/townlight_planning/policies/lookup')", - "errors": [ - "HTTPException(404, 'No supported adopted policy found; inspect imported sources.')" - ] - }, - { - "method": "POST", - "path": "/api/v1/townlight_planning/policies/ingest", - "router": "app", - "prefix_resolved": true, - "name": "ingest_policy", - "signature": "request: PolicyIngestRequest, x_townlight_planning_role: Annotated[str | None, Header()]=None, x_townlight_planning_staff_key: Annotated[str | None, Header()]=None", - "returns": "dict[str, object]", - "line": 270, - "doc": "", - "decorator": "app.post('/api/v1/townlight_planning/policies/ingest')", - "errors": [ - "HTTPException(409, detail={'message': 'Metadata-only ingestion cannot establish plan provenance.', 'fix': 'Use POST /api/v1/townlight_planning/source-imports with a staff-verified source bundle.'})" - ] - }, - { - "method": "GET", - "path": "/api/v1/townlight_planning/plans/navigator", - "router": "app", - "prefix_resolved": true, - "name": "plans_navigator", - "signature": "plan_type: str | None=None, is_staff=Depends(audience)", - "returns": "dict[str, object]", - "line": 283, - "doc": "", - "decorator": "app.get('/api/v1/townlight_planning/plans/navigator')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_planning/questions/answer", - "router": "app", - "prefix_resolved": true, - "name": "plan_question_answer", - "signature": "request: PlanQuestionRequest, is_staff=Depends(audience)", - "returns": "dict[str, object]", - "line": 292, - "doc": "", - "decorator": "app.post('/api/v1/townlight_planning/questions/answer')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_planning/plans/synthesis", - "router": "app", - "prefix_resolved": true, - "name": "plan_synthesis", - "signature": "request: PlanSynthesisRequest, is_staff=Depends(audience)", - "returns": "dict[str, object]", - "line": 306, - "doc": "", - "decorator": "app.post('/api/v1/townlight_planning/plans/synthesis')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_planning/context/townlight_meetings", - "router": "app", - "prefix_resolved": true, - "name": "townlight_meetings_context", - "signature": "request: TownlightMeetingsContextRequest, is_staff=Depends(audience)", - "returns": "dict[str, object]", - "line": 314, - "doc": "", - "decorator": "app.post('/api/v1/townlight_planning/context/townlight_meetings')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_planning/integrations/mock", - "router": "app", - "prefix_resolved": true, - "name": "integration_mock", - "signature": "request: IntegrationMockRequest", - "returns": "dict[str, object]", - "line": 328, - "doc": "", - "decorator": "app.post('/api/v1/townlight_planning/integrations/mock')", - "errors": [ - "HTTPException(status_code=422, detail={'message': result.message, 'fix': result.fix, 'code': result.code, 'provider': result.provider})" - ] - }, - { - "method": "POST", - "path": "/api/v1/townlight_planning/context/zoning", - "router": "app", - "prefix_resolved": true, - "name": "zoning_policy_context", - "signature": "request: ZoningPolicyContextRequest, is_staff=Depends(audience)", - "returns": "dict[str, object]", - "line": 349, - "doc": "", - "decorator": "app.post('/api/v1/townlight_planning/context/zoning')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_planning/consistency/check", - "router": "app", - "prefix_resolved": true, - "name": "consistency_check", - "signature": "request: ConsistencyRequest, is_staff=Depends(audience)", - "returns": "dict[str, object]", - "line": 378, - "doc": "", - "decorator": "app.post('/api/v1/townlight_planning/consistency/check')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_planning/staff-analysis/draft", - "router": "app", - "prefix_resolved": true, - "name": "staff_analysis", - "signature": "request: StaffAnalysisRequest, x_townlight_planning_role: Annotated[str | None, Header()]=None, x_townlight_planning_staff_key: Annotated[str | None, Header()]=None", - "returns": "dict[str, object]", - "line": 392, - "doc": "", - "decorator": "app.post('/api/v1/townlight_planning/staff-analysis/draft')", - "errors": [ - "HTTPException(404, 'No supported adopted policy found.')" - ] - }, - { - "method": "GET", - "path": "/api/v1/townlight_planning/staff-analysis/{analysis_id}", - "router": "app", - "prefix_resolved": true, - "name": "get_staff_analysis", - "signature": "analysis_id: str, native_request: Request, x_townlight_planning_role: Annotated[str | None, Header()]=None, x_townlight_planning_staff_key: Annotated[str | None, Header()]=None", - "returns": "dict[str, object]", - "line": 419, - "doc": "", - "decorator": "app.get('/api/v1/townlight_planning/staff-analysis/{analysis_id}')", - "errors": [ - "HTTPException(status_code=503, detail={'message': 'Townlight Planning policy persistence is not configured.', 'fix': 'Set TOWNLIGHT_PLANNING_POLICY_DB_URL to retrieve persisted staff-analysis records.'})", - "HTTPException(status_code=404, detail={'message': 'Staff-analysis record not found.', 'fix': 'Use an analysis_id returned by POST /api/v1/townlight_planning/staff-analysis/draft.'})" - ] - }, - { - "method": "POST", - "path": "/api/v1/townlight_planning/export", - "router": "app", - "prefix_resolved": true, - "name": "policy_export", - "signature": "request: PolicyExportRequest, native_request: Request, is_staff=Depends(audience)", - "returns": "dict[str, object]", - "line": 451, - "doc": "", - "decorator": "app.post('/api/v1/townlight_planning/export')", - "errors": [ - "HTTPException(403, 'Staff authentication is required to export analysis snapshots.')", - "HTTPException(422, 'Select a reviewed immutable snapshot; a policy ID alone is not an export.')", - "HTTPException(404, 'Snapshot not found.')" - ] - } - ], - "models": [ + "line": 104 + }, { - "name": "PolicyLookupRequest", + "name": "ChannelRequest", "bases": [ "BaseModel" ], "fields": [ { - "name": "topic", + "name": "notice_type", "type": "str", - "default": "Field(min_length=1, max_length=500)" + "line": 119 }, { - "name": "plan_type", + "name": "audience", "type": "str", - "default": "Field(default='comprehensive', min_length=1, max_length=120)" + "line": 120 } ], - "line": 64, - "doc": "" + "line": 118 }, { - "name": "ZoningPolicyContextRequest", + "name": "SubscriberRequest", "bases": [ "BaseModel" ], "fields": [ { - "name": "topic", + "name": "subscriber_id", "type": "str", - "default": "Field(min_length=1, max_length=500)" - }, - { - "name": "zone_code", - "type": "str | None", - "default": "Field(default=None, max_length=80)" + "line": 124 }, { - "name": "use", - "type": "str | None", - "default": "Field(default=None, max_length=160)" + "name": "name", + "type": "str", + "line": 125 }, { - "name": "parcel_number", - "type": "str | None", - "default": "Field(default=None, max_length=120)" + "name": "email", + "type": "str", + "line": 126 }, { - "name": "address", - "type": "str | None", - "default": "Field(default=None, max_length=500)" + "name": "channels", + "type": "list[str]", + "line": 127 }, { - "name": "plan_type", + "name": "language", "type": "str", - "default": "Field(default='comprehensive', min_length=1, max_length=120)" + "line": 128 }, { - "name": "townlight_zoning_context_id", - "type": "str | None", - "default": "Field(default=None, max_length=160)" + "name": "active", + "type": "bool", + "line": 129 } ], - "line": 69, - "doc": "" + "line": 123 }, { - "name": "ConsistencyRequest", + "name": "SubscriberDeliveryRequest", "bases": [ "BaseModel" ], "fields": [ { - "name": "proposal", + "name": "notice_id", "type": "str", - "default": "Field(min_length=1, max_length=5000)" + "line": 133 }, { - "name": "policy_id", + "name": "notice_type", "type": "str", - "default": "Field(min_length=1, max_length=160)" - } - ], - "line": 79, - "doc": "" - }, - { - "name": "StaffAnalysisRequest", - "bases": [ - "BaseModel" - ], - "fields": [ + "line": 134 + }, { - "name": "project_name", + "name": "audience", "type": "str", - "default": "Field(min_length=1, max_length=500)" + "line": 135 }, { - "name": "proposal", - "type": "str", - "default": "Field(min_length=1, max_length=5000)" + "name": "subscribers", + "type": "list[SubscriberRequest]", + "line": 136 }, { - "name": "policy_id", - "type": "str", - "default": "Field(min_length=1, max_length=160)" + "name": "required_channels", + "type": "list[str]", + "line": 137 } ], - "line": 84, - "doc": "" + "line": 132 }, { - "name": "PolicyExportRequest", + "name": "AccessibilityReviewRequest", "bases": [ "BaseModel" ], "fields": [ { - "name": "title", + "name": "notice_id", "type": "str", - "default": "Field(min_length=1, max_length=500)" + "line": 141 }, { - "name": "policy_id", + "name": "title", "type": "str", - "default": "Field(min_length=1, max_length=160)" + "line": 142 }, { - "name": "format", + "name": "notice_text", "type": "str", - "default": "Field(default='markdown', min_length=1, max_length=40)" + "line": 143 }, { - "name": "snapshot_id", - "type": "str | None", - "default": "Field(default=None, min_length=36, max_length=36)" + "name": "target_languages", + "type": "list[str]", + "line": 144 + }, + { + "name": "attachments", + "type": "list[str]", + "line": 145 + }, + { + "name": "has_contact", + "type": "bool", + "line": 146 + }, + { + "name": "has_event_date", + "type": "bool", + "line": 147 + }, + { + "name": "has_plain_language_summary", + "type": "bool", + "line": 148 } ], - "line": 90, - "doc": "" + "line": 140 }, { - "name": "PolicyIngestRequest", + "name": "ArchivePacketRequest", "bases": [ "BaseModel" ], "fields": [ { - "name": "topic_key", + "name": "notice_id", "type": "str", - "default": "Field(min_length=1, max_length=160)" + "line": 152 }, { - "name": "policy_id", + "name": "notice_type", "type": "str", - "default": "Field(min_length=1, max_length=160)" + "line": 153 }, { - "name": "plan_type", + "name": "source_module", "type": "str", - "default": "Field(min_length=1, max_length=120)" + "line": 154 }, { - "name": "title", + "name": "source_record_id", "type": "str", - "default": "Field(min_length=1, max_length=500)" + "line": 155 }, { - "name": "citation", + "name": "registry_record_id", "type": "str", - "default": "Field(min_length=1, max_length=500)" + "line": 156 }, { - "name": "excerpt", + "name": "deadline_plan_id", "type": "str", - "default": "Field(min_length=1, max_length=5000)" + "line": 157 }, { - "name": "relevance", + "name": "publication_proof_id", "type": "str", - "default": "Field(min_length=1, max_length=2000)" + "line": 158 }, { - "name": "adoption_status", - "type": "str", - "default": "Field(default='adopted', min_length=1, max_length=80)" + "name": "rule_check_complete", + "type": "bool", + "line": 159 }, { - "name": "source_document", - "type": "str", - "default": "Field(min_length=1, max_length=500)" + "name": "template_complete", + "type": "bool", + "line": 160 + }, + { + "name": "accessibility_review_complete", + "type": "bool", + "line": 161 + }, + { + "name": "subscriber_delivery_complete", + "type": "bool", + "line": 162 + }, + { + "name": "records_export_complete", + "type": "bool", + "line": 163 } ], - "line": 97, - "doc": "" + "line": 151 }, { - "name": "PlanQuestionRequest", + "name": "RecordsExportRequest", "bases": [ "BaseModel" ], "fields": [ { - "name": "question", + "name": "notice_id", "type": "str", - "default": "Field(min_length=1, max_length=2000)" + "line": 167 }, { - "name": "plan_type", + "name": "title", "type": "str", - "default": "Field(default='comprehensive', min_length=1, max_length=120)" - } - ], - "line": 109, - "doc": "" - }, - { - "name": "PlanSynthesisRequest", - "bases": [ - "BaseModel" - ], - "fields": [ + "line": 168 + }, { - "name": "topic", + "name": "format", "type": "str", - "default": "Field(min_length=1, max_length=500)" + "line": 169 } ], - "line": 114, - "doc": "" + "line": 166 }, { - "name": "TownlightMeetingsContextRequest", + "name": "PublicationProofRequest", "bases": [ "BaseModel" ], "fields": [ { - "name": "agenda_item", + "name": "notice_id", "type": "str", - "default": "Field(min_length=1, max_length=500)" + "line": 173 }, { - "name": "topic", + "name": "notice_type", "type": "str", - "default": "Field(min_length=1, max_length=500)" - } - ], - "line": 118, - "doc": "" - }, - { - "name": "IntegrationMockRequest", - "bases": [ - "BaseModel" - ], - "fields": [ + "line": 174 + }, { - "name": "provider", + "name": "source_module", "type": "str", - "default": "Field(min_length=1, max_length=120)" + "line": 175 }, { - "name": "payload", - "type": "dict[str, object]", - "default": "Field(default_factory=dict)" + "name": "source_record_id", + "type": "str", + "line": 176 + }, + { + "name": "channel", + "type": "str", + "line": 177 + }, + { + "name": "published_at", + "type": "str", + "line": 178 + }, + { + "name": "location", + "type": "str", + "line": 179 + }, + { + "name": "confirmation_reference", + "type": "str", + "line": 180 + }, + { + "name": "statutory_basis", + "type": "str", + "line": 181 + }, + { + "name": "reviewer", + "type": "str", + "line": 182 } ], - "line": 123, - "doc": "" + "line": 172 } ], "configuration": [ - { - "variable": "TOWNLIGHT_PLANNING_POLICY_DB_URL", - "default": "", - "line": 469 - }, - { - "variable": "TOWNLIGHT_PLANNING_DEMO_MODE", - "default": "", - "line": 496 - } - ] - }, - { - "source": "installed-owned-source/townlight_planning/migrations/__init__.py", - "sha256": "daf5e64cefda400a5db1023d952e41bef6f7954db19406d63ea84770c82dccd9", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_planning/migrations/__main__.py", - "sha256": "321e543984ca92e2540d1f4d9eca54658dc608987b95bc5abc61b651b4305fd6", - "routes": [], - "models": [], - "configuration": [ - { - "variable": "TOWNLIGHT_PLANNING_POLICY_DB_URL", - "default": "", - "line": 7 - } - ] - }, - { - "source": "installed-owned-source/townlight_planning/migrations/env.py", - "sha256": "832a41b6c40d14da47178b486650eba98bff574a66652e3b614cc782db04f8df", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_planning/migrations/versions/townlight_planning_0001_sources.py", - "sha256": "807e5a18d1fa295d482f3963f7799f244f046ab98297bfc33cbd17131fb44d17", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_planning/migrations/versions/townlight_planning_0002_workflows.py", - "sha256": "7c6fcdfe4a1fa33c9289cef975a25f4b0f6746471c380226c14520f8a5f09dbf", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_planning/migrations/versions/townlight_planning_0003_municipal.py", - "sha256": "64735db3119b22b54a232e0a4486657a91b5304e4a253b14ce7cae1acb204681", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_planning/migrations/versions/townlight_planning_0004_neighborhoods.py", - "sha256": "006f8f8f9859da76189efee9035d1f89c65e0b27172b5df9e316e1aa173434f8", - "routes": [], - "models": [], - "configuration": [] + { + "environment": "TOWNLIGHT_NOTICE_WORKPAPER_DB_URL", + "line": 492 + }, + { + "environment": "TOWNLIGHT_NOTICE_TRUSTED_WRITE_TOKEN", + "line": 496 + } + ] }, { - "source": "installed-owned-source/townlight_planning/municipal.py", - "sha256": "dbd5bd841f3f90d2ab7256eafb30ed8b7ba6036bd3921e23595d7df6715b8555", + "source": "townlight_notice/notice_registry.py", + "sha256": "8a5195d4c87f4bb76e1b499bf7cc188ded3bf62d8d9c54113a9d86b04cba1418", + "bytes": 1258, "routes": [], "models": [ { - "name": "Measurement", - "bases": [ - "BundleModel" - ], + "name": "NoticeRecord", + "bases": [], "fields": [ { - "name": "recorded_on", - "type": "date", - "default": "" + "name": "notice_id", + "type": "str", + "line": 17 }, { - "name": "value", - "type": "Decimal", - "default": "Field(allow_inf_nan=False)" + "name": "notice_type", + "type": "str", + "line": 18 }, { - "name": "evidence", + "name": "owner", + "type": "str", + "line": 19 + }, + { + "name": "registry_notes", + "type": "tuple[str, ...]", + "line": 20 + }, + { + "name": "disclaimer", "type": "str", - "default": "Field(min_length=1, max_length=2000)" + "line": 21 } ], - "line": 41, - "doc": "" - }, + "line": 16 + } + ], + "configuration": [] + }, + { + "source": "townlight_notice/notice_templates.py", + "sha256": "fcd44c4e05afcd8ed6dd5c3913a8d522bf6c0bd5b7d291f2937842a5b49fd6ac", + "bytes": 2176, + "routes": [], + "models": [ { - "name": "Milestone", - "bases": [ - "BundleModel" - ], + "name": "NoticeTemplate", + "bases": [], "fields": [ + { + "name": "notice_type", + "type": "str", + "line": 14 + }, { "name": "title", "type": "str", - "default": "Field(min_length=1, max_length=255)" + "line": 15 }, { - "name": "due_on", - "type": "date", - "default": "" + "name": "source_module", + "type": "str", + "line": 16 }, { - "name": "completed_on", - "type": "date | None", - "default": "None" + "name": "template_lines", + "type": "tuple[str, ...]", + "line": 17 }, { - "name": "evidence", + "name": "required_fields", + "type": "tuple[str, ...]", + "line": 18 + }, + { + "name": "placeholders_remaining", + "type": "tuple[str, ...]", + "line": 19 + }, + { + "name": "staff_review_required", + "type": "bool", + "line": 20 + }, + { + "name": "disclaimer", "type": "str", - "default": "Field(default='', max_length=2000)" + "line": 21 } ], - "line": 53, - "doc": "" - }, + "line": 13 + } + ], + "configuration": [] + }, + { + "source": "townlight_notice/persistence.py", + "sha256": "bfc2871328900220b9dad1a01d07aeae6f0f7e7b1ab25e66a2908b5766f9d2d6", + "bytes": 11387, + "routes": [], + "models": [ { - "name": "InitiativeInput", - "bases": [ - "BundleModel" - ], + "name": "StoredNoticeRecord", + "bases": [], "fields": [ { - "name": "expected_revision", - "type": "str | None", - "default": "Field(default=None, min_length=36, max_length=36)" + "name": "record_id", + "type": "str", + "line": 67 }, { - "name": "title", + "name": "notice_id", "type": "str", - "default": "Field(min_length=1, max_length=500)" + "line": 68 }, { - "name": "policy", - "type": "PolicySelection", - "default": "" + "name": "notice_type", + "type": "str", + "line": 69 }, { - "name": "responsible_staff", + "name": "owner", "type": "str", - "default": "Field(min_length=1, max_length=255)" + "line": 70 }, { - "name": "target", - "type": "Decimal", - "default": "Field(allow_inf_nan=False)" + "name": "registry_notes", + "type": "tuple[str, ...]", + "line": 71 }, { - "name": "unit", + "name": "disclaimer", "type": "str", - "default": "Field(min_length=1, max_length=80)" + "line": 72 }, { - "name": "due_on", - "type": "date", - "default": "" + "name": "created_at", + "type": "datetime", + "line": 73 + } + ], + "line": 66 + }, + { + "name": "StoredDeadlinePlan", + "bases": [], + "fields": [ + { + "name": "plan_id", + "type": "str", + "line": 78 }, { - "name": "status", - "type": "Literal['planned', 'active', 'completed', 'cancelled']", - "default": "'planned'" + "name": "notice_type", + "type": "str", + "line": 79 }, { - "name": "milestones", - "type": "list[Milestone]", - "default": "Field(default_factory=list, max_length=100)" + "name": "event_date", + "type": "date", + "line": 80 }, { - "name": "measurements", - "type": "list[Measurement]", - "default": "Field(default_factory=list, max_length=1000)" + "name": "reminders", + "type": "tuple[str, ...]", + "line": 81 }, { - "name": "note", + "name": "staff_review_required", + "type": "bool", + "line": 82 + }, + { + "name": "disclaimer", "type": "str", - "default": "Field(min_length=1, max_length=5000)" + "line": 83 + }, + { + "name": "created_at", + "type": "datetime", + "line": 84 } ], - "line": 66, - "doc": "" + "line": 77 }, { - "name": "AmendmentInput", - "bases": [ - "BundleModel" - ], + "name": "StoredPublicationProof", + "bases": [], "fields": [ { - "name": "expected_revision", - "type": "str | None", - "default": "Field(default=None, min_length=36, max_length=36)" + "name": "proof_id", + "type": "str", + "line": 89 }, { - "name": "title", + "name": "notice_id", "type": "str", - "default": "Field(min_length=1, max_length=500)" + "line": 90 }, { - "name": "policy", - "type": "PolicySelection", - "default": "" + "name": "notice_type", + "type": "str", + "line": 91 }, { - "name": "proposal", + "name": "source_module", "type": "str", - "default": "Field(min_length=1, max_length=20000)" + "line": 92 }, { - "name": "responsible_staff", + "name": "source_record_id", "type": "str", - "default": "Field(min_length=1, max_length=255)" + "line": 93 }, { - "name": "status", - "type": "Literal['draft', 'review', 'adopted', 'withdrawn']", - "default": "'draft'" + "name": "channel", + "type": "str", + "line": 94 }, { - "name": "review_note", + "name": "published_at", "type": "str", - "default": "Field(default='', max_length=5000)" + "line": 95 }, { - "name": "adoption_revision", - "type": "str | None", - "default": "Field(default=None, min_length=36, max_length=36)" + "name": "location", + "type": "str", + "line": 96 }, { - "name": "note", + "name": "confirmation_reference", + "type": "str", + "line": 97 + }, + { + "name": "statutory_basis", + "type": "str", + "line": 98 + }, + { + "name": "reviewer", + "type": "str", + "line": 99 + }, + { + "name": "proof_notes", + "type": "tuple[str, ...]", + "line": 100 + }, + { + "name": "compliance_status", + "type": "str", + "line": 101 + }, + { + "name": "disclaimer", "type": "str", - "default": "Field(min_length=1, max_length=5000)" + "line": 102 + }, + { + "name": "created_at", + "type": "datetime", + "line": 103 } ], - "line": 90, - "doc": "" + "line": 88 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_planning/municipal_api.py", - "sha256": "b71876bd1b6f354f7a9ad8d06f19d8ae7c071a0315f19421d3ff4df07bb8dc1f", - "routes": [ - { - "method": "POST", - "path": "/api/v1/townlight_planning/initiatives", - "router": "router", - "prefix_resolved": true, - "name": "create_initiative", - "signature": "data: InitiativeInput, actor=Depends(staff), repo=Depends(municipal)", - "returns": "", - "line": 17, - "doc": "", - "decorator": "router.post('/initiatives', status_code=201)", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_planning/initiatives/{item_id}/revisions", - "router": "router", - "prefix_resolved": true, - "name": "update_initiative", - "signature": "item_id: str, data: InitiativeInput, actor=Depends(staff), repo=Depends(municipal)", - "returns": "", - "line": 22, - "doc": "", - "decorator": "router.post('/initiatives/{item_id}/revisions')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_planning/amendments", - "router": "router", - "prefix_resolved": true, - "name": "create_amendment", - "signature": "data: AmendmentInput, actor=Depends(staff), repo=Depends(municipal)", - "returns": "", - "line": 29, - "doc": "", - "decorator": "router.post('/amendments', status_code=201)", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_planning/amendments/{item_id}/revisions", - "router": "router", - "prefix_resolved": true, - "name": "update_amendment", - "signature": "item_id: str, data: AmendmentInput, actor=Depends(staff), repo=Depends(municipal)", - "returns": "", - "line": 34, - "doc": "", - "decorator": "router.post('/amendments/{item_id}/revisions')", - "errors": [] - }, - { - "method": "GET", - "path": "/api/v1/townlight_planning/municipal-work/{item_id}/history", - "router": "router", - "prefix_resolved": true, - "name": "history", - "signature": "item_id: str, actor=Depends(staff), repo=Depends(municipal)", - "returns": "", - "line": 41, - "doc": "", - "decorator": "router.get('/municipal-work/{item_id}/history')", - "errors": [ - "HTTPException(404, 'Municipal workflow not found')" - ] - }, - { - "method": "GET", - "path": "/api/v1/townlight_planning/progress/targets", - "router": "router", - "prefix_resolved": true, - "name": "progress", - "signature": "policy_id: str | None=None, offset: int=Query(0, ge=0, le=100000), limit: int=Query(50, ge=1, le=100), actor=Depends(staff), repo=Depends(municipal)", - "returns": "", - "line": 49, - "doc": "", - "decorator": "router.get('/progress/targets')", - "errors": [] - }, + "source": "townlight_notice/public_ui.py", + "sha256": "d3c07a7bd9c4bbef24d49107824941812ee5d04bce9ee53a2c83a63e541aa32e", + "bytes": 6462, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "townlight_notice/publication_check.py", + "sha256": "e19f0d812ddd348aca7f30e9bcf28cd6d15dc5552a1e79a04f0d35f5f04997ac", + "bytes": 1107, + "routes": [], + "models": [ { - "method": "GET", - "path": "/api/v1/townlight_planning/amendments/history", - "router": "router", - "prefix_resolved": true, - "name": "amendments", - "signature": "plan_type: str | None=None, offset: int=Query(0, ge=0, le=100000), limit: int=Query(50, ge=1, le=100), actor=Depends(staff), repo=Depends(municipal)", - "returns": "", - "line": 60, - "doc": "", - "decorator": "router.get('/amendments/history')", - "errors": [] + "name": "PublicationChecklist", + "bases": [], + "fields": [ + { + "name": "notice_type", + "type": "str", + "line": 12 + }, + { + "name": "checklist", + "type": "tuple[str, ...]", + "line": 13 + }, + { + "name": "proof_required", + "type": "bool", + "line": 14 + }, + { + "name": "disclaimer", + "type": "str", + "line": 15 + } + ], + "line": 11 } ], - "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_planning/persistence.py", - "sha256": "30d920165ab9b4f9675a0d61dd887587823b6c075ef160e3a56670db95d2cc7e", + "source": "townlight_notice/publication_proof.py", + "sha256": "807dd53445c1fdfa6e0c6bc5988ad4be5c255abfefd5acefaf60dc13a3fc350f", + "bytes": 2390, "routes": [], "models": [ { - "name": "StoredStaffAnalysis", + "name": "PublicationProof", "bases": [], "fields": [ { - "name": "analysis_id", + "name": "notice_id", "type": "str", - "default": "" + "line": 12 }, { - "name": "project_name", + "name": "notice_type", "type": "str", - "default": "" + "line": 13 }, { - "name": "proposal", + "name": "source_module", "type": "str", - "default": "" + "line": 14 }, { - "name": "policy_id", + "name": "source_record_id", "type": "str", - "default": "" + "line": 15 }, { - "name": "heading", + "name": "channel", "type": "str", - "default": "" + "line": 16 }, { - "name": "bullets", - "type": "tuple[str, ...]", - "default": "" + "name": "published_at", + "type": "str", + "line": 17 }, { - "name": "citations", - "type": "tuple[str, ...]", - "default": "" + "name": "location", + "type": "str", + "line": 18 }, { - "name": "review_required", - "type": "bool", - "default": "" + "name": "confirmation_reference", + "type": "str", + "line": 19 }, { - "name": "disclaimer", + "name": "statutory_basis", "type": "str", - "default": "" + "line": 20 }, { - "name": "created_at", - "type": "datetime", - "default": "" + "name": "reviewer", + "type": "str", + "line": 21 + }, + { + "name": "proof_notes", + "type": "tuple[str, ...]", + "line": 22 + }, + { + "name": "compliance_status", + "type": "str", + "line": 23 + }, + { + "name": "disclaimer", + "type": "str", + "line": 24 } ], - "line": 51, - "doc": "" + "line": 11 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_planning/plan_workflows.py", - "sha256": "e69084e3608fa33bbc6ab140d4570efa3850cb04317000b407c5a5f5ca635115", + "source": "townlight_notice/records_export.py", + "sha256": "faa93c41f8f38bc89b4924e328a7ae354b45ad1478236bd02e924dd4bd8c8f6c", + "bytes": 1290, "routes": [], "models": [ { - "name": "PlanPolicyIngestRecord", + "name": "NoticeRecordsExport", "bases": [], "fields": [ { - "name": "topic_key", + "name": "notice_id", "type": "str", - "default": "" + "line": 12 }, { - "name": "policy", - "type": "PlanPolicy", - "default": "" + "name": "title", + "type": "str", + "line": 13 }, { - "name": "adoption_status", - "type": "PlanStatus", - "default": "" + "name": "checklist", + "type": "tuple[str, ...]", + "line": 14 }, { - "name": "source_document", + "name": "retention_note", + "type": "str", + "line": 15 + }, + { + "name": "disclaimer", "type": "str", - "default": "" + "line": 16 } ], - "line": 14, - "doc": "" - }, + "line": 11 + } + ], + "configuration": [] + }, + { + "source": "townlight_notice/statutory_rules.py", + "sha256": "0f56cf2c90af07981225565e44ecfc6e7e5468440f4141cc8ee1448703b8fe0a", + "bytes": 6430, + "routes": [], + "models": [ { - "name": "PlanQuestionAnswer", + "name": "NoticeRule", "bases": [], "fields": [ { - "name": "status", + "name": "notice_type", "type": "str", - "default": "" + "line": 13 }, { - "name": "answer", - "type": "str", - "default": "" + "name": "minimum_lead_days", + "type": "int", + "line": 14 }, { - "name": "citations", - "type": "tuple[str, ...]", - "default": "" + "name": "required_publications", + "type": "int", + "line": 15 }, { - "name": "source_policy_ids", + "name": "required_channels", "type": "tuple[str, ...]", - "default": "" + "line": 16 }, { - "name": "review_required", - "type": "bool", - "default": "" + "name": "required_content", + "type": "tuple[str, ...]", + "line": 17 }, { - "name": "disclaimer", - "type": "str", - "default": "DISCLAIMER" + "name": "emergency_path_allowed", + "type": "bool", + "line": 18 } ], - "line": 22, - "doc": "" + "line": 12 }, { - "name": "PlanAmendment", + "name": "StatutoryRuleCheck", "bases": [], "fields": [ { - "name": "amendment_id", + "name": "notice_type", "type": "str", - "default": "" + "line": 23 }, { - "name": "plan_type", - "type": "str", - "default": "" + "name": "event_date", + "type": "date", + "line": 24 }, { - "name": "title", - "type": "str", - "default": "" + "name": "required_deadline_date", + "type": "date", + "line": 25 }, { - "name": "adoption_status", - "type": "PlanStatus", - "default": "" + "name": "publication_dates", + "type": "tuple[date, ...]", + "line": 26 }, { - "name": "adopted_date", - "type": "str | None", - "default": "" + "name": "channels", + "type": "tuple[str, ...]", + "line": 27 }, { - "name": "citation", - "type": "str", - "default": "" + "name": "required_publications", + "type": "int", + "line": 28 }, { - "name": "summary", - "type": "str", - "default": "" - } - ], - "line": 32, - "doc": "" - }, - { - "name": "ProgressTarget", - "bases": [], - "fields": [ + "name": "required_channels", + "type": "tuple[str, ...]", + "line": 29 + }, { - "name": "target_id", - "type": "str", - "default": "" + "name": "missing_channels", + "type": "tuple[str, ...]", + "line": 30 }, { - "name": "policy_id", - "type": "str", - "default": "" + "name": "required_content", + "type": "tuple[str, ...]", + "line": 31 }, { - "name": "metric", - "type": "str", - "default": "" + "name": "missing_content", + "type": "tuple[str, ...]", + "line": 32 }, { - "name": "status", + "name": "statutory_basis", "type": "str", - "default": "" + "line": 33 }, { - "name": "evidence", + "name": "deadline_status", "type": "str", - "default": "" + "line": 34 }, { - "name": "citation", + "name": "publication_count_status", "type": "str", - "default": "" + "line": 35 }, { - "name": "updated_at", - "type": "datetime", - "default": "" + "name": "staff_review_required", + "type": "bool", + "line": 36 + }, + { + "name": "disclaimer", + "type": "str", + "line": 37 } ], - "line": 43, - "doc": "" + "line": 22 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_planning/policy_lookup.py", - "sha256": "eef53ba621332d75f069f00ddcac34c19bca42d469a697fd22555eb3d11c68b2", + "source": "townlight_notice/subscriber_delivery.py", + "sha256": "2defdbcd6c807b2f4c9171afe21559d5b566acaef5376aecb1a5e7faeeb58f94", + "bytes": 3445, "routes": [], "models": [ { - "name": "PlanPolicy", + "name": "Subscriber", "bases": [], "fields": [ { - "name": "policy_id", - "type": "str", - "default": "" - }, - { - "name": "plan_type", + "name": "subscriber_id", "type": "str", - "default": "" + "line": 12 }, { - "name": "title", + "name": "name", "type": "str", - "default": "" + "line": 13 }, { - "name": "citation", + "name": "email", "type": "str", - "default": "" + "line": 14 }, { - "name": "excerpt", - "type": "str", - "default": "" + "name": "channels", + "type": "tuple[str, ...]", + "line": 15 }, { - "name": "relevance", + "name": "language", "type": "str", - "default": "" + "line": 16 }, { - "name": "disclaimer", - "type": "str", - "default": "DISCLAIMER" + "name": "active", + "type": "bool", + "line": 17 } ], - "line": 16, - "doc": "" - } - ], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_planning/policy_service.py", - "sha256": "c5e5461fadea4b32cba43366e1c9795ecb4cd8212db30734f5eadd24a9144808", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_planning/public_explore.py", - "sha256": "c5cbb2de92661538857e52b25f2e0bc4e7cd4f5c9d91eb0fa7d0518b28374720", - "routes": [], - "models": [ + "line": 11 + }, { - "name": "Exploration", + "name": "SubscriberDeliveryPlan", "bases": [], "fields": [ { - "name": "query", + "name": "notice_id", "type": "str", - "default": "''" + "line": 22 }, { - "name": "plan_type", + "name": "notice_type", "type": "str", - "default": "''" + "line": 23 }, { - "name": "goal", + "name": "audience", "type": "str", - "default": "''" + "line": 24 }, { - "name": "topic", - "type": "str", - "default": "''" + "name": "active_subscriber_count", + "type": "int", + "line": 25 }, { - "name": "neighborhood", - "type": "str", - "default": "''" + "name": "suppressed_subscriber_count", + "type": "int", + "line": 26 }, { - "name": "plans", - "type": "list", - "default": "field(default_factory=list)" + "name": "delivery_channels", + "type": "tuple[str, ...]", + "line": 27 }, { - "name": "total", - "type": "int", - "default": "0" + "name": "email_recipients", + "type": "tuple[str, ...]", + "line": 28 }, { - "name": "review_required", + "name": "missing_required_channels", + "type": "tuple[str, ...]", + "line": 29 + }, + { + "name": "language_review_required", "type": "bool", - "default": "True" + "line": 30 }, { - "name": "disclaimer", - "type": "str", - "default": "''" + "name": "staff_review_required", + "type": "bool", + "line": 31 }, { - "name": "empty_reason", - "type": "str | None", - "default": "None" + "name": "delivery_notes", + "type": "tuple[str, ...]", + "line": 32 }, { - "name": "facets", - "type": "dict", - "default": "field(default_factory=dict)" + "name": "disclaimer", + "type": "str", + "line": 33 } ], - "line": 34, - "doc": "One exploration request and what the persisted sources support for it." + "line": 21 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_planning/public_explore_ui.py", - "sha256": "bd137701e16391a4ee820c4c88b5db583944491d5fc487ff7580b1083e944e5d", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_planning/public_ui.py", - "sha256": "8551ce36f854a4a7fc4573a20b73dbb0b6f01d7b60b7267d8c73b5f21f246ccc", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_planning/records_export.py", - "sha256": "6894fb9450f5d0177ebf86babcd489be1a789a714ce2c3c825c7afd5ed51bb23", + "source": "townlight_notice/workflow.py", + "sha256": "b88b0fe7488519206ed84a22e69d5577c5746dece7d47e7d91b673abc4d1b8e1", + "bytes": 14094, "routes": [], "models": [ { - "name": "PolicyExport", - "bases": [], + "name": "NoticeDraft", + "bases": [ + "BaseModel" + ], "fields": [ { "name": "title", "type": "str", - "default": "" + "line": 33 }, { - "name": "policy_id", + "name": "body", "type": "str", - "default": "" + "line": 34 }, { - "name": "format", + "name": "notice_type", "type": "str", - "default": "" + "line": 35 }, { - "name": "checklist", - "type": "tuple[str, ...]", - "default": "" + "name": "statutory_basis", + "type": "str", + "line": 36 }, { - "name": "retention_note", - "type": "str", - "default": "" + "name": "event_date", + "type": "date", + "line": 37 + }, + { + "name": "lead_days", + "type": "int", + "line": 38 } ], - "line": 11, - "doc": "" + "line": 31 } ], "configuration": [] + } + ] + }, + "station": { + "repository": "townlight/station", + "repository_head": "4b5afac07dda1c7f725993d06860a820959d7e06", + "working_tree_modified": true, + "principal_import": "townlight_station", + "source": [ + { + "source": "beta-1/townlight_station/__init__.py", + "sha256": "0e4ae6948a7b82358592fa123efcb0f2f19edd0322d93e8077da9db1dcde1ccc", + "bytes": 132, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "beta-1/townlight_station/air.py", + "sha256": "07bbb24d673c73ecb17274965c3aeefaca4b904c2a16af772009088c65b37cb5", + "bytes": 10038, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "beta-1/townlight_station/airplay.py", + "sha256": "1a55dd17541478f97a86d7ff4e3054c6d998c95070bf86bb0d27fa5eeea1d231", + "bytes": 13211, + "routes": [], + "models": [], + "configuration": [] }, { - "source": "installed-owned-source/townlight_planning/source_api.py", - "sha256": "4af39debaf4f9cbb219c294ddfeaea642495d45e492e62852049372e296f1df4", + "source": "beta-1/townlight_station/api.py", + "sha256": "fa99dd6f913fb5020ce4790db6043bd080424bcd99f2e8d97e576daa96432a36", + "bytes": 14339, "routes": [ + { + "method": "GET", + "declared_path": "/health", + "function": "health", + "line": 80 + }, + { + "method": "GET", + "declared_path": "/v1/identity", + "function": "identity", + "line": 85 + }, { "method": "POST", - "path": "/api/v1/townlight_planning/source-imports", - "router": "router", - "prefix_resolved": true, - "name": "import_sources", - "signature": "request: ImportRequest, actor: str=Depends(staff), repo=Depends(repository)", - "returns": "", - "line": 51, - "doc": "", - "decorator": "router.post('/source-imports')", - "errors": [ - "HTTPException(409, str(exc))" - ] - }, - { - "method": "GET", - "path": "/api/v1/townlight_planning/source-plans/{plan_id}/history", - "router": "router", - "prefix_resolved": true, - "name": "source_history", - "signature": "plan_id: str, _actor=Depends(staff), repo=Depends(repository)", - "returns": "", - "line": 63, - "doc": "", - "decorator": "router.get('/source-plans/{plan_id}/history')", - "errors": [] - }, - { - "method": "GET", - "path": "/api/v1/townlight_planning/source-revisions/{revision_id}", - "router": "router", - "prefix_resolved": true, - "name": "source_revision", - "signature": "revision_id: str, _actor=Depends(staff), repo=Depends(repository)", - "returns": "", - "line": 68, - "doc": "", - "decorator": "router.get('/source-revisions/{revision_id}')", - "errors": [ - "HTTPException(404, 'Planning source revision not found.')" - ] - }, - { - "method": "GET", - "path": "/api/v1/townlight_planning/source-revisions/{revision_id}/documents/{document_id}", - "router": "router", - "prefix_resolved": true, - "name": "source_document", - "signature": "revision_id: str, document_id: str, _actor=Depends(staff), repo=Depends(repository)", - "returns": "", - "line": 76, - "doc": "", - "decorator": "router.get('/source-revisions/{revision_id}/documents/{document_id}')", - "errors": [ - "HTTPException(404, 'Planning source document not found.')" - ] - } - ], - "models": [ + "declared_path": "/v1/recordings", + "function": "capture", + "line": 90 + }, { - "name": "ImportRequest", - "bases": [ - "BundleModel" - ], - "fields": [ - { - "name": "bundle", - "type": "PlanBundle", - "default": "" - }, - { - "name": "expected_previous_revision", - "type": "str | None", - "default": "Field(default=None, min_length=36, max_length=36)" - } - ], - "line": 45, - "doc": "" - } - ], - "configuration": [ + "method": "GET", + "declared_path": "/v1/recordings/{identity}", + "function": "get_record", + "line": 192 + }, { - "variable": "TOWNLIGHT_PLANNING_POLICY_DB_URL", - "default": "", - "line": 31 - } - ] - }, - { - "source": "installed-owned-source/townlight_planning/source_bundle.py", - "sha256": "f6547516067e27697dfcd6ba80de6e2ca03d1473370209aa354a5bf95b7db98a", - "routes": [], + "method": "GET", + "declared_path": "/v1/recordings/{identity}/content", + "function": "content", + "line": 196 + }, + { + "method": "POST", + "declared_path": "/v1/recordings/{identity}/retry", + "function": "retry", + "line": 207 + }, + { + "method": "GET", + "declared_path": "/v1/live-sources", + "function": "live_sources", + "line": 220 + }, + { + "method": "GET", + "declared_path": "/v1/recordings", + "function": "list_records", + "line": 225 + }, + { + "method": "POST", + "declared_path": "/v1/recordings/{identity}/stop", + "function": "stop_live", + "line": 231 + } + ], "models": [ { - "name": "SourceDocument", + "name": "Capture", "bases": [ - "BundleModel" + "BaseModel" ], "fields": [ { - "name": "document_id", - "type": "str", - "default": "Field(min_length=1, max_length=160, pattern='^[A-Za-z0-9][A-Za-z0-9._:-]*$')" + "name": "meeting_id", + "type": "UUID", + "line": 36 }, { - "name": "filename", - "type": "str", - "default": "Field(min_length=1, max_length=255)" + "name": "agenda_ids", + "type": "list[UUID]", + "line": 37 }, { - "name": "media_type", - "type": "Literal['text/plain', 'text/markdown', 'application/pdf', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document']", - "default": "" + "name": "source_file", + "type": "str | None", + "line": 38 }, { - "name": "sha256", - "type": "str", - "default": "Field(pattern='^[0-9a-f]{64}$')" + "name": "live_source_id", + "type": "str | None", + "line": 39 }, { - "name": "content_base64", + "name": "civiccast_feed_id", + "type": "str | None", + "line": 40 + }, + { + "name": "captions_file", + "type": "str | None", + "line": 41 + }, + { + "name": "idempotency_key", "type": "str", - "default": "Field(min_length=1, max_length=14000000)" + "line": 42 } ], - "line": 18, - "doc": "" - }, + "line": 34 + } + ], + "configuration": [] + }, + { + "source": "beta-1/townlight_station/boundary.py", + "sha256": "700a35e89a4e0292a5e10e53957cda336fdfd1419ade5041982c653cc6af81a3", + "bytes": 7458, + "routes": [], + "models": [ { - "name": "SourcePolicy", - "bases": [ - "BundleModel" - ], + "name": "Settings", + "bases": [], "fields": [ { - "name": "policy_id", - "type": "str", - "default": "Field(min_length=1, max_length=160)" - }, - { - "name": "document_id", - "type": "str", - "default": "Field(min_length=1, max_length=160)" - }, - { - "name": "goal", - "type": "str", - "default": "Field(min_length=1, max_length=500)" + "name": "data", + "type": "Path", + "line": 46 }, { - "name": "objective", + "name": "database_url", "type": "str", - "default": "Field(min_length=1, max_length=500)" + "line": 47 }, { - "name": "topic_key", + "name": "suite_url", "type": "str", - "default": "Field(min_length=1, max_length=160)" + "line": 48 }, { - "name": "neighborhoods", - "type": "list[str]", - "default": "Field(default_factory=list, max_length=100)" + "name": "media_source", + "type": "Path", + "line": 49 }, { - "name": "title", - "type": "str", - "default": "Field(min_length=1, max_length=500)" + "name": "media_python", + "type": "Path", + "line": 50 }, { - "name": "citation", - "type": "str", - "default": "Field(min_length=1, max_length=500)" + "name": "media_runtime", + "type": "Path", + "line": 51 }, { - "name": "anchor", - "type": "str", - "default": "Field(min_length=1, max_length=500)" + "name": "ffprobe", + "type": "Path", + "line": 52 }, { - "name": "excerpt", - "type": "str", - "default": "Field(min_length=1, max_length=20000)" + "name": "max_seconds", + "type": "int", + "line": 53 }, { - "name": "relevance", - "type": "str", - "default": "Field(min_length=1, max_length=2000)" + "name": "max_bytes", + "type": "int", + "line": 54 }, { - "name": "staff_verified", - "type": "Literal[True]", - "default": "" - } - ], - "line": 62, - "doc": "" - }, - { - "name": "AdoptionEvidence", - "bases": [ - "BundleModel" - ], - "fields": [ - { - "name": "kind", - "type": "Literal['manual-record', 'meeting-reference', 'source-document']", - "default": "" + "name": "width", + "type": "int", + "line": 55 }, { - "name": "reference", - "type": "str", - "default": "Field(min_length=1, max_length=1000)" + "name": "height", + "type": "int", + "line": 56 }, { - "name": "document_id", - "type": "str | None", - "default": "Field(default=None, min_length=1, max_length=160)" + "name": "fps", + "type": "int", + "line": 57 }, { - "name": "note", - "type": "str", - "default": "Field(min_length=1, max_length=4000)" + "name": "bitrate_kbps", + "type": "int", + "line": 58 } ], - "line": 77, - "doc": "" + "line": 45 + } + ], + "configuration": [] + }, + { + "source": "beta-1/townlight_station/cli.py", + "sha256": "b67d712170f08a90e3477d2c12b04ecef0581e6844f6ad79c661bf0e8f86b722", + "bytes": 2362, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "beta-1/townlight_station/delivery.py", + "sha256": "c0a850ee43c111e125b79504f4f12c2f99b2b04813ade8f8cfcbc6ace60c0065", + "bytes": 11456, + "routes": [ + { + "method": "GET", + "declared_path": "/v1/civiccast-feeds", + "function": "catalog", + "line": 56 }, { - "name": "PlanBundle", + "method": "POST", + "declared_path": "/v1/recordings/{identity}/youtube", + "function": "upload", + "line": 61 + }, + { + "method": "GET", + "declared_path": "/v1/youtube-uploads", + "function": "list_uploads", + "line": 92 + }, + { + "method": "POST", + "declared_path": "/v1/youtube-uploads/{identity}/retry", + "function": "retry", + "line": 98 + } + ], + "models": [ + { + "name": "Upload", "bases": [ - "BundleModel" + "BaseModel" ], "fields": [ - { - "name": "schema_version", - "type": "Literal[1]", - "default": "1" - }, - { - "name": "plan_id", - "type": "str", - "default": "Field(min_length=1, max_length=160, pattern='^[A-Za-z0-9][A-Za-z0-9._:-]*$')" - }, { "name": "title", "type": "str", - "default": "Field(min_length=1, max_length=500)" - }, - { - "name": "jurisdiction", - "type": "str", - "default": "Field(min_length=1, max_length=255)" - }, - { - "name": "plan_type", - "type": "PlanType", - "default": "" - }, - { - "name": "status", - "type": "Literal['pending', 'adopted', 'superseded']", - "default": "" - }, - { - "name": "visibility", - "type": "Literal['staff', 'public']", - "default": "'staff'" - }, - { - "name": "dataset_kind", - "type": "Literal['municipal', 'demo']", - "default": "'municipal'" - }, - { - "name": "source_date", - "type": "date", - "default": "" - }, - { - "name": "adopted_on", - "type": "date | None", - "default": "None" + "line": 48 }, { - "name": "effective_on", - "type": "date | None", - "default": "None" + "name": "privacy", + "type": "Literal['private', 'unlisted', 'public']", + "line": 49 }, { - "name": "change_note", + "name": "approval_note", "type": "str", - "default": "Field(min_length=1, max_length=4000)" + "line": 50 }, { - "name": "reviewer_label", + "name": "idempotency_key", "type": "str", - "default": "Field(min_length=1, max_length=255)" - }, - { - "name": "documents", - "type": "list[SourceDocument]", - "default": "Field(min_length=1, max_length=20)" - }, - { - "name": "policies", - "type": "list[SourcePolicy]", - "default": "Field(min_length=1, max_length=1000)" - }, - { - "name": "adoption_evidence", - "type": "list[AdoptionEvidence]", - "default": "Field(default_factory=list, max_length=100)" + "line": 51 } ], - "line": 84, - "doc": "" + "line": 46 + } + ], + "configuration": [] + }, + { + "source": "beta-1/townlight_station/feed_job.py", + "sha256": "a2e08fa43b4fb5b7f036de8fdef256cff1a6c39f2b4adabc08b09aa3fedb21f1", + "bytes": 4086, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "beta-1/townlight_station/live.py", + "sha256": "5f32afd8d2b5e74296a083436b367fec3940da6ae33123fc17842bf0c6c05cce", + "bytes": 1251, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "beta-1/townlight_station/media-lock.json", + "sha256": "df53ec1559329e1c10c49febd38664a7ced17831bd346044145155d2b3600064", + "bytes": 83333, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "beta-1/townlight_station/media_job.py", + "sha256": "15237eaa872c9772c548aaf57dced25ec51a343489b894a462d95de19507e59b", + "bytes": 4024, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "beta-1/townlight_station/operations.py", + "sha256": "69019673d277ee4850d4dd1789e0576b6883d684b0f1ead2be9f965cfdf7b7d2", + "bytes": 19402, + "routes": [ + { + "method": "POST", + "declared_path": "/v1/schedules", + "function": "create_schedule", + "line": 106 + }, + { + "method": "GET", + "declared_path": "/v1/schedules", + "function": "list_schedules", + "line": 143 + }, + { + "method": "POST", + "declared_path": "/v1/schedules/{identity}/cancel", + "function": "cancel_schedule", + "line": 151 + }, + { + "method": "POST", + "declared_path": "/v1/playouts", + "function": "create_playout", + "line": 163 + }, + { + "method": "GET", + "declared_path": "/v1/playouts", + "function": "list_playouts", + "line": 187 + }, + { + "method": "GET", + "declared_path": "/v1/playouts/{identity}", + "function": "get_playout", + "line": 194 + }, + { + "method": "GET", + "declared_path": "/v1/on-air", + "function": "on_air", + "line": 203 + }, + { + "method": "POST", + "declared_path": "/v1/on-air/live", + "function": "live_override", + "line": 215 + }, + { + "method": "POST", + "declared_path": "/v1/on-air/return-to-schedule", + "function": "return_to_schedule", + "line": 232 + }, + { + "method": "POST", + "declared_path": "/v1/playouts/{identity}/approve", + "function": "approve", + "line": 243 + }, + { + "method": "POST", + "declared_path": "/v1/playouts/{identity}/publish", + "function": "publish", + "line": 256 + }, + { + "method": "GET", + "declared_path": "/v1/public/playback/{identity}", + "function": "public_playback", + "line": 285 + }, + { + "method": "GET", + "declared_path": "/v1/public/playback/{identity}/captions", + "function": "public_captions", + "line": 301 + }, + { + "method": "GET", + "declared_path": "/v1/public/playback/{identity}/program", + "function": "public_program", + "line": 315 } ], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_planning/source_schema.py", - "sha256": "1c429c22247cda2aaec5abe6807639177f035cae843993666dbf8b2824bbdbf1", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_planning/source_store.py", - "sha256": "97022c50baa5b7e81bcc12fccd6c2e429af35f163680542cbf99b65722905d82", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_planning/staff_analysis.py", - "sha256": "71ab2f06804f1c01678f708c60a27714d7bd9b14444e1d2c8546cedb8ac1bd69", - "routes": [], "models": [ { - "name": "StaffAnalysisDraft", - "bases": [], + "name": "ScheduleRequest", + "bases": [ + "BaseModel" + ], "fields": [ { - "name": "project_name", - "type": "str", - "default": "" + "name": "meeting_id", + "type": "UUID", + "line": 60 }, { - "name": "heading", - "type": "str", - "default": "" + "name": "agenda_ids", + "type": "list[UUID]", + "line": 61 }, { - "name": "bullets", - "type": "tuple[str, ...]", - "default": "" + "name": "source_file", + "type": "str | None", + "line": 62 }, { - "name": "citations", - "type": "tuple[str, ...]", - "default": "" + "name": "live_source_id", + "type": "str | None", + "line": 63 }, { - "name": "review_required", - "type": "bool", - "default": "" + "name": "captions_file", + "type": "str | None", + "line": 64 }, { - "name": "disclaimer", + "name": "start_at", + "type": "datetime", + "line": 65 + }, + { + "name": "idempotency_key", "type": "str", - "default": "DISCLAIMER" + "line": 66 } ], - "line": 12, - "doc": "" - } - ], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_planning/workflow_api.py", - "sha256": "6a48664442a3a8bae19a8cea7676e91f53ca3360f65e912dec666504862e792b", - "routes": [ - { - "method": "POST", - "path": "/api/v1/townlight_planning/analyses", - "router": "router", - "prefix_resolved": true, - "name": "create_analysis", - "signature": "data: AnalysisInput, actor=Depends(staff), repo=Depends(workflows)", - "returns": "", - "line": 45, - "doc": "", - "decorator": "router.post('/analyses')", - "errors": [ - "HTTPException(422, 'New analyses have no previous revision.')" - ] - }, - { - "method": "POST", - "path": "/api/v1/townlight_planning/analyses/{analysis_id}/revisions", - "router": "router", - "prefix_resolved": true, - "name": "revise_analysis", - "signature": "analysis_id: str, data: AnalysisInput, actor=Depends(staff), repo=Depends(workflows)", - "returns": "", - "line": 52, - "doc": "", - "decorator": "router.post('/analyses/{analysis_id}/revisions')", - "errors": [ - "HTTPException(422, 'Supply the analysis previous revision.')" - ] - }, - { - "method": "GET", - "path": "/api/v1/townlight_planning/analyses/{analysis_id}", - "router": "router", - "prefix_resolved": true, - "name": "read_analysis", - "signature": "analysis_id: str, revision_id: str | None=None, actor=Depends(staff), repo=Depends(workflows)", - "returns": "", - "line": 59, - "doc": "", - "decorator": "router.get('/analyses/{analysis_id}')", - "errors": [ - "HTTPException(404, 'Analysis not found.')" - ] - }, - { - "method": "GET", - "path": "/api/v1/townlight_planning/analyses/{analysis_id}/history", - "router": "router", - "prefix_resolved": true, - "name": "analysis_history", - "signature": "analysis_id: str, actor=Depends(staff), repo=Depends(workflows)", - "returns": "", - "line": 67, - "doc": "", - "decorator": "router.get('/analyses/{analysis_id}/history')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_planning/analyses/{analysis_id}/snapshots", - "router": "router", - "prefix_resolved": true, - "name": "create_snapshot", - "signature": "analysis_id: str, data: SnapshotInput, actor=Depends(staff), repo=Depends(workflows)", - "returns": "", - "line": 77, - "doc": "", - "decorator": "router.post('/analyses/{analysis_id}/snapshots')", - "errors": [] - }, - { - "method": "GET", - "path": "/api/v1/townlight_planning/snapshots/{snapshot_id}", - "router": "router", - "prefix_resolved": true, - "name": "read_snapshot", - "signature": "snapshot_id: str, actor=Depends(staff), repo=Depends(workflows)", - "returns": "", - "line": 82, - "doc": "", - "decorator": "router.get('/snapshots/{snapshot_id}')", - "errors": [ - "HTTPException(404, 'Snapshot not found.')" - ] - }, - { - "method": "GET", - "path": "/api/v1/townlight_planning/snapshots/{snapshot_id}/export", - "router": "router", - "prefix_resolved": true, - "name": "export_snapshot", - "signature": "snapshot_id: str, actor=Depends(staff), repo=Depends(workflows)", - "returns": "", - "line": 90, - "doc": "", - "decorator": "router.get('/snapshots/{snapshot_id}/export')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_planning/snapshots/{snapshot_id}/access-advice", - "router": "router", - "prefix_resolved": true, - "name": "access_advice", - "signature": "snapshot_id: str, actor=Depends(staff), repo=Depends(workflows)", - "returns": "", - "line": 98, - "doc": "", - "decorator": "router.post('/snapshots/{snapshot_id}/access-advice')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_planning/policies/search", - "router": "router", - "prefix_resolved": true, - "name": "search_policies", - "signature": "data: SearchInput, is_staff=Depends(audience), sources=Depends(repository)", - "returns": "", - "line": 108, - "doc": "", - "decorator": "router.post('/policies/search')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_planning/connections/search", - "router": "router", - "prefix_resolved": true, - "name": "search_connections", - "signature": "data: ConnectionSearch, actor=Depends(staff), repo=Depends(workflows)", - "returns": "", - "line": 118, - "doc": "", - "decorator": "router.post('/connections/search')", - "errors": [] - }, - { - "method": "GET", - "path": "/api/v1/townlight_planning/policy-sources/{revision_id}/documents/{document_id}", - "router": "router", - "prefix_resolved": true, - "name": "public_original", - "signature": "revision_id: str, document_id: str, sources=Depends(repository)", - "returns": "", - "line": 123, - "doc": "", - "decorator": "router.get('/policy-sources/{revision_id}/documents/{document_id}')", - "errors": [ - "HTTPException(404, 'Public policy source unavailable.')", - "HTTPException(404, 'Public policy document not found.')" - ] - } - ], - "models": [ + "line": 58 + }, { - "name": "SnapshotInput", + "name": "PlayoutRequest", "bases": [ - "BundleModel" + "BaseModel" ], "fields": [ { - "name": "expected_revision", + "name": "recording_id", + "type": "UUID", + "line": 71 + }, + { + "name": "mode", "type": "str", - "default": "Field(min_length=36, max_length=36)" + "line": 72 }, { - "name": "visibility", - "type": "Literal['staff_only', 'public']", - "default": "'staff_only'" + "name": "idempotency_key", + "type": "str", + "line": 73 } ], - "line": 71, - "doc": "" + "line": 69 }, { - "name": "SearchInput", + "name": "ApprovalRequest", "bases": [ - "BundleModel" + "BaseModel" ], "fields": [ { - "name": "query", + "name": "note", "type": "str", - "default": "Field(min_length=1, max_length=2000)" - }, - { - "name": "plan_type", - "type": "str | None", - "default": "Field(default=None, max_length=40)" + "line": 78 } ], - "line": 102, - "doc": "" + "line": 76 }, { - "name": "ConnectionSearch", + "name": "LiveOverrideRequest", "bases": [ - "BundleModel" + "BaseModel" ], "fields": [ { - "name": "provider", - "type": "Literal['meetings', 'zoning']", - "default": "" + "name": "live_source_id", + "type": "str", + "line": 85 }, { - "name": "query", + "name": "reason", "type": "str", - "default": "Field(min_length=1, max_length=500)" + "line": 86 } ], - "line": 112, - "doc": "" + "line": 81 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_planning/workflow_models.py", - "sha256": "d22e978fe778d7f4fdc3989a043370d9f6966b1e4920ed2c75698c73a8ee4e04", - "routes": [], - "models": [ + "source": "beta-1/townlight_station/operator.py", + "sha256": "6471894a1240b611a2bf006867ce79848630f6dc69270e29e54b71dbb26f3837", + "bytes": 6737, + "routes": [ { - "name": "PolicySelection", - "bases": [ - "BundleModel" - ], - "fields": [ - { - "name": "plan_id", - "type": "str", - "default": "Field(min_length=1, max_length=160)" - }, - { - "name": "revision_id", - "type": "str", - "default": "Field(min_length=36, max_length=36)" - }, - { - "name": "policy_id", - "type": "str", - "default": "Field(min_length=1, max_length=160)" - } - ], - "line": 7, - "doc": "" + "method": "POST", + "declared_path": "/v1/operator-ticket", + "function": "issue", + "line": 51 }, { - "name": "LinkedSource", - "bases": [ - "BundleModel" - ], - "fields": [ - { - "name": "provider", - "type": "Literal['meetings', 'zoning']", - "default": "" - }, - { - "name": "source_id", - "type": "str", - "default": "Field(min_length=1, max_length=200)" - }, - { - "name": "expected_sha256", - "type": "str", - "default": "Field(pattern='^[0-9a-f]{64}$')" - }, - { - "name": "relation", - "type": "Literal['adoption-evidence', 'hearing', 'context', 'precedent']", - "default": "" - } - ], - "line": 13, - "doc": "" + "method": "POST", + "declared_path": "/operator/session", + "function": "exchange", + "line": 60 }, { - "name": "Consideration", + "method": "POST", + "declared_path": "/operator/logout", + "function": "logout", + "line": 75 + }, + { + "method": "GET", + "declared_path": "/operator/catalog", + "function": "catalog", + "line": 82 + }, + { + "method": "GET", + "declared_path": "/operator/meeting/{identity}", + "function": "meeting", + "line": 102 + }, + { + "method": "POST", + "declared_path": "/operator/handoff", + "function": "handoff", + "line": 106 + }, + { + "method": "GET", + "declared_path": "/", + "function": "page", + "line": 124 + }, + { + "method": "GET", + "declared_path": "/operator.js", + "function": "script", + "line": 128 + }, + { + "method": "GET", + "declared_path": "/operator.css", + "function": "style", + "line": 132 + } + ], + "models": [ + { + "name": "Ticket", "bases": [ - "BundleModel" + "BaseModel" ], "fields": [ { - "name": "policy", - "type": "PolicySelection", - "default": "" - }, - { - "name": "stance", - "type": "Literal['supporting', 'conflicting', 'uncertain']", - "default": "" - }, - { - "name": "note", + "name": "ticket", "type": "str", - "default": "Field(min_length=1, max_length=5000)" + "line": 15 } ], - "line": 20, - "doc": "" + "line": 13 }, { - "name": "AnalysisInput", + "name": "Handoff", "bases": [ - "BundleModel" + "BaseModel" ], "fields": [ { - "name": "expected_previous_revision", - "type": "str | None", - "default": "Field(default=None, min_length=36, max_length=36)" - }, - { - "name": "project_name", - "type": "str", - "default": "Field(min_length=1, max_length=500)" - }, - { - "name": "proposal", - "type": "str", - "default": "Field(min_length=1, max_length=10000)" - }, - { - "name": "selected_policies", - "type": "list[PolicySelection]", - "default": "Field(min_length=1, max_length=50)" - }, - { - "name": "considerations", - "type": "list[Consideration]", - "default": "Field(default_factory=list, max_length=100)" - }, - { - "name": "analysis_text", - "type": "str", - "default": "Field(default='', max_length=50000)" - }, - { - "name": "public_summary", - "type": "str", - "default": "Field(default='', max_length=10000)" - }, - { - "name": "staff_notes", - "type": "str", - "default": "Field(default='', max_length=10000)" - }, - { - "name": "audience", - "type": "Literal['staff', 'public']", - "default": "'staff'" - }, - { - "name": "review_state", - "type": "Literal['draft', 'reviewed']", - "default": "'draft'" - }, - { - "name": "reviewer_label", - "type": "str", - "default": "Field(default='', max_length=255)" + "name": "request_id", + "type": "UUID", + "line": 20 }, { - "name": "reviewed_on", - "type": "date | None", - "default": "None" + "name": "recording_id", + "type": "UUID", + "line": 21 }, { - "name": "review_notes", + "name": "expected_sha256", "type": "str", - "default": "Field(default='', max_length=5000)" - }, - { - "name": "linked_sources", - "type": "list[LinkedSource]", - "default": "Field(default_factory=list, max_length=50)" + "line": 22 } ], - "line": 26, - "doc": "" + "line": 18 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_planning/workflow_schema.py", - "sha256": "11d864214fabc6d509351fdc7f3e3eb90a910a5db1a137f84a7a8efca5d0002e", + "source": "beta-1/townlight_station/packaging.py", + "sha256": "e53a0b87870b728f6ee5015672e08f9ca05eab0e3c33f5d4c8ecb08b88d92158", + "bytes": 3726, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "beta-1/townlight_station/store.py", + "sha256": "a075061d7de057e3dbc523ae499ff4160e9ea8db65e6a2816ec2b7bfda62a313", + "bytes": 5756, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "beta-1/townlight_station/ui/index.html", + "sha256": "89f91f83f2fb28e34aa77ec361209a3c7049b7d38ef48d3f13befc30dbbf5c79", + "bytes": 383, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "beta-1/townlight_station/ui/operator.css", + "sha256": "689079902c8b58f4737a47bdc8a4352f9845c21d0d6bbc017660bf1c21015ec9", + "bytes": 1723, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "beta-1/townlight_station/ui/operator.js", + "sha256": "0e55284e2359e62006879948dd6e0f90fc4d6f1095230cafd58e5af3651ae2e7", + "bytes": 202782, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "beta-1/townlight_station/vod_job.py", + "sha256": "d55a20bdf377142d6acd857aaca86d17468837ee638311dd3ac0fb76b571821d", + "bytes": 4583, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "beta-1/townlight_station/windows_service.py", + "sha256": "8eebfbe5d14fcae26cbd67ff712e7980444b9ae2a2e600283dc577025552a050", + "bytes": 3456, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_planning/workflow_store.py", - "sha256": "4d4fec6d6c876997726ff1d8f2ff39302f44228fae748edc013739267d210741", + "source": "beta-1/townlight_station/worker.py", + "sha256": "dd69aaf49e1af7a887a104b1aee7c5a0f459dc95d6a3d520bacb88ad82748e32", + "bytes": 21320, "routes": [], "models": [], "configuration": [] } - ], - "bridge": [ + ] + }, + "runtime": { + "repository": "townlight/townlight", + "repository_head": "1bad62a1107e9f50bee17ea01ee5cc2e3d0a8bea", + "working_tree_modified": true, + "principal_import": "townlight_runtime", + "source": [ + { + "source": "desktop/runtime/python-services/townlight_runtime/__init__.py", + "sha256": "db3facb7198193860bfabca8f0942a86c69e0739b28475fc6ab43d82ba7515dd", + "bytes": 118, + "routes": [], + "models": [], + "configuration": [] + }, { - "source": "installed-owned-source/townlight_runtime/planning_bridge.py", - "sha256": "74a855b995b7f323873b9c788cd15bd4b0ebe3fc1c53879596e1b5043c2825bb", + "source": "desktop/runtime/python-services/townlight_runtime/access_bridge.py", + "sha256": "2a6631747d98cb0e2681fc06455c699a0f1d92584c74d5ca7beae5b9df128ecb", + "bytes": 21767, "routes": [ + { + "method": "GET", + "declared_path": "/state", + "function": "access_state", + "line": 190 + }, + { + "method": "POST", + "declared_path": "/review-context", + "function": "review_context", + "line": 195 + }, + { + "method": "POST", + "declared_path": "/reviews", + "function": "save_review", + "line": 209 + }, + { + "method": "POST", + "declared_path": "/reviews/{review_id}/delete", + "function": "delete_review", + "line": 239 + }, + { + "method": "POST", + "declared_path": "/tools", + "function": "tool", + "line": 255 + }, + { + "method": "POST", + "declared_path": "/rewrite-context", + "function": "rewrite_context", + "line": 285 + }, + { + "method": "POST", + "declared_path": "/rewrite-result", + "function": "rewrite_result", + "line": 300 + }, + { + "method": "POST", + "declared_path": "/reviews/{review_id}/export", + "function": "prepare_export", + "line": 334 + }, { "method": "POST", - "path": "/desktop/v1/planning/imports/preview", - "router": "router", - "prefix_resolved": true, - "name": "preview_import", - "signature": "body: Import, identity=Depends(actor)", - "returns": "", - "line": 80, - "doc": "", - "decorator": "router.post('/imports/preview')", - "errors": [ - "HTTPException(422, 'Invalid source bundle; verify metadata, excerpts, anchors and original hashes.')" - ] - }, - { - "method": "POST", - "path": "/desktop/v1/planning/imports", - "router": "router", - "prefix_resolved": true, - "name": "import_source", - "signature": "request: Request, body: Import, identity=Depends(actor)", - "returns": "", - "line": 89, - "doc": "", - "decorator": "router.post('/imports')", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/planning/sources", - "router": "router", - "prefix_resolved": true, - "name": "source_list", - "signature": "request: Request, limit: int=Query(50, ge=1, le=100), offset: int=Query(0, ge=0, le=100000), identity=Depends(actor)", - "returns": "", - "line": 98, - "doc": "", - "decorator": "router.get('/sources')", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/planning/sources/{plan_id}/history", - "router": "router", - "prefix_resolved": true, - "name": "source_history", - "signature": "request: Request, plan_id: str, offset: int=Query(0, ge=0, le=100000), identity=Depends(actor)", - "returns": "", - "line": 104, - "doc": "", - "decorator": "router.get('/sources/{plan_id}/history')", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/planning/revisions/{revision_id}", - "router": "router", - "prefix_resolved": true, - "name": "revision", - "signature": "request: Request, revision_id: UUID, identity=Depends(actor)", - "returns": "", - "line": 109, - "doc": "", - "decorator": "router.get('/revisions/{revision_id}')", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/planning/revisions/{revision_id}/documents/{document_id}", - "router": "router", - "prefix_resolved": true, - "name": "staff_original", - "signature": "request: Request, revision_id: UUID, document_id: str, identity=Depends(actor)", - "returns": "", - "line": 127, - "doc": "", - "decorator": "router.get('/revisions/{revision_id}/documents/{document_id}')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/planning/policies/search", - "router": "router", - "prefix_resolved": true, - "name": "policies", - "signature": "request: Request, body: Search, identity=Depends(actor)", - "returns": "", - "line": 137, - "doc": "", - "decorator": "router.post('/policies/search')", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/planning/analyses", - "router": "router", - "prefix_resolved": true, - "name": "analyses", - "signature": "request: Request, limit: int=Query(50, ge=1, le=100), offset: int=Query(0, ge=0, le=100000), identity=Depends(actor)", - "returns": "", - "line": 142, - "doc": "", - "decorator": "router.get('/analyses')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/planning/analyses", - "router": "router", - "prefix_resolved": true, - "name": "create_analysis", - "signature": "request: Request, body: dict, identity=Depends(actor)", - "returns": "", - "line": 155, - "doc": "", - "decorator": "router.post('/analyses')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/planning/analyses/{analysis_id}/revisions", - "router": "router", - "prefix_resolved": true, - "name": "revise_analysis", - "signature": "request: Request, analysis_id: UUID, body: dict, identity=Depends(actor)", - "returns": "", - "line": 165, - "doc": "", - "decorator": "router.post('/analyses/{analysis_id}/revisions')", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/planning/analyses/{analysis_id}", - "router": "router", - "prefix_resolved": true, - "name": "analysis", - "signature": "request: Request, analysis_id: UUID, identity=Depends(actor)", - "returns": "", - "line": 175, - "doc": "", - "decorator": "router.get('/analyses/{analysis_id}')", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/planning/analyses/{analysis_id}/history", - "router": "router", - "prefix_resolved": true, - "name": "analysis_history", - "signature": "request: Request, analysis_id: UUID, offset: int=Query(0, ge=0, le=100000), identity=Depends(actor)", - "returns": "", - "line": 180, - "doc": "", - "decorator": "router.get('/analyses/{analysis_id}/history')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/planning/analyses/{analysis_id}/snapshot-preview", - "router": "router", - "prefix_resolved": true, - "name": "preview_snapshot", - "signature": "request: Request, analysis_id: UUID, body: Snapshot, identity=Depends(actor)", - "returns": "", - "line": 190, - "doc": "", - "decorator": "router.post('/analyses/{analysis_id}/snapshot-preview')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/planning/analyses/{analysis_id}/snapshots", - "router": "router", - "prefix_resolved": true, - "name": "snapshot", - "signature": "request: Request, analysis_id: UUID, body: Snapshot, identity=Depends(actor)", - "returns": "", - "line": 195, - "doc": "", - "decorator": "router.post('/analyses/{analysis_id}/snapshots')", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/planning/snapshots", - "router": "router", - "prefix_resolved": true, - "name": "snapshots", - "signature": "request: Request, limit: int=Query(50, ge=1, le=100), offset: int=Query(0, ge=0, le=100000), identity=Depends(actor)", - "returns": "", - "line": 200, - "doc": "", - "decorator": "router.get('/snapshots')", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/planning/snapshots/{snapshot_id}", - "router": "router", - "prefix_resolved": true, - "name": "document", - "signature": "request: Request, snapshot_id: UUID, identity=Depends(actor)", - "returns": "", - "line": 206, - "doc": "", - "decorator": "router.get('/snapshots/{snapshot_id}')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/planning/snapshots/{snapshot_id}/access-advice", - "router": "router", - "prefix_resolved": true, - "name": "access_advice", - "signature": "request: Request, snapshot_id: UUID, identity=Depends(actor)", - "returns": "", - "line": 211, - "doc": "", - "decorator": "router.post('/snapshots/{snapshot_id}/access-advice')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/planning/connections/search", - "router": "router", - "prefix_resolved": true, - "name": "connections", - "signature": "request: Request, body: ConnectionSearch, identity=Depends(actor)", - "returns": "", - "line": 221, - "doc": "", - "decorator": "router.post('/connections/search')", - "errors": [] - }, - { - "method": "POST", - "path": "/townlight_planning/policies/search", - "router": "public_router", - "prefix_resolved": true, - "name": "public_policies", - "signature": "request: Request, body: Search", - "returns": "", - "line": 226, - "doc": "", - "decorator": "public_router.post('/policies/search', dependencies=[Depends(available)])", - "errors": [] - }, - { - "method": "POST", - "path": "/townlight_planning/plan-explore", - "router": "public_router", - "prefix_resolved": true, - "name": "public_plan_explore", - "signature": "request: Request, body: PublicExplore", - "returns": "", - "line": 238, - "doc": "Topic/goal/plan-type exploration over adopted public plan sources only.", - "decorator": "public_router.post('/plan-explore', dependencies=[Depends(available)])", - "errors": [] - }, - { - "method": "GET", - "path": "/townlight_planning/snapshots", - "router": "public_router", - "prefix_resolved": true, - "name": "public_snapshots", - "signature": "request: Request, limit: int=Query(50, ge=1, le=100), offset: int=Query(0, ge=0, le=100000)", - "returns": "", - "line": 254, - "doc": "", - "decorator": "public_router.get('/snapshots', dependencies=[Depends(available)])", - "errors": [] - }, - { - "method": "GET", - "path": "/townlight_planning/snapshots/{snapshot_id}", - "router": "public_router", - "prefix_resolved": true, - "name": "public_document", - "signature": "request: Request, snapshot_id: UUID", - "returns": "", - "line": 260, - "doc": "", - "decorator": "public_router.get('/snapshots/{snapshot_id}', dependencies=[Depends(available)])", - "errors": [] - }, - { - "method": "GET", - "path": "/townlight_planning/revisions/{revision_id}/documents/{document_id}", - "router": "public_router", - "prefix_resolved": true, - "name": "public_original", - "signature": "request: Request, revision_id: UUID, document_id: str", - "returns": "", - "line": 265, - "doc": "", - "decorator": "public_router.get('/revisions/{revision_id}/documents/{document_id}', dependencies=[Depends(available)])", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/planning/progress/targets", - "router": "router", - "prefix_resolved": true, - "name": "municipal_progress", - "signature": "request: Request, offset: int=Query(0, ge=0, le=100000), identity=Depends(actor)", - "returns": "", - "line": 270, - "doc": "", - "decorator": "router.get('/progress/targets')", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/planning/amendments/history", - "router": "router", - "prefix_resolved": true, - "name": "municipal_amendments", - "signature": "request: Request, offset: int=Query(0, ge=0, le=100000), identity=Depends(actor)", - "returns": "", - "line": 275, - "doc": "", - "decorator": "router.get('/amendments/history')", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/planning/municipal-work/{item_id}/history", - "router": "router", - "prefix_resolved": true, - "name": "municipal_history", - "signature": "request: Request, item_id: UUID, identity=Depends(actor)", - "returns": "", - "line": 280, - "doc": "", - "decorator": "router.get('/municipal-work/{item_id}/history')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/planning/initiatives", - "router": "router", - "prefix_resolved": true, - "name": "create_initiative", - "signature": "request: Request, body: InitiativeInput, identity=Depends(actor)", - "returns": "", - "line": 285, - "doc": "", - "decorator": "router.post('/initiatives')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/planning/initiatives/{item_id}/revisions", - "router": "router", - "prefix_resolved": true, - "name": "update_initiative", - "signature": "request: Request, item_id: UUID, body: InitiativeInput, identity=Depends(actor)", - "returns": "", - "line": 290, - "doc": "", - "decorator": "router.post('/initiatives/{item_id}/revisions')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/planning/amendments", - "router": "router", - "prefix_resolved": true, - "name": "create_amendment", - "signature": "request: Request, body: AmendmentInput, identity=Depends(actor)", - "returns": "", - "line": 295, - "doc": "", - "decorator": "router.post('/amendments')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/planning/amendments/{item_id}/revisions", - "router": "router", - "prefix_resolved": true, - "name": "update_amendment", - "signature": "request: Request, item_id: UUID, body: AmendmentInput, identity=Depends(actor)", - "returns": "", - "line": 300, - "doc": "", - "decorator": "router.post('/amendments/{item_id}/revisions')", - "errors": [] + "declared_path": "/drafts/{draft_id}/export", + "function": "export_draft", + "line": 345 + }, + { + "method": "POST", + "declared_path": "/exports/{artifact_id}/complete", + "function": "complete_export", + "line": 373 } ], "models": [ { - "name": "Import", + "name": "ReviewInput", "bases": [ - "BundleModel" + "BaseModel" ], "fields": [ { - "name": "bundle", - "type": "dict", - "default": "" + "name": "title", + "type": "str", + "line": 84 }, { - "name": "expected_previous_revision", - "type": "str | None", - "default": "Field(default=None, min_length=36, max_length=36)" + "name": "body", + "type": "str", + "line": 85 + }, + { + "name": "hasAltText", + "type": "bool", + "line": 86 + }, + { + "name": "language", + "type": "str", + "line": 87 } ], - "line": 74, - "doc": "" + "line": 82 }, { - "name": "Search", + "name": "SaveReview", "bases": [ - "BundleModel" + "ReviewInput" ], "fields": [ { - "name": "query", - "type": "str", - "default": "Field(min_length=1, max_length=2000)" + "name": "ai_analysis", + "type": "str | None", + "line": 92 }, { - "name": "plan_type", + "name": "ai_analysis_model", "type": "str | None", - "default": "Field(default=None, max_length=40)" + "line": 93 + }, + { + "name": "ai_outcome", + "type": "Literal['generated', 'unavailable', 'failed']", + "line": 94 } ], - "line": 131, - "doc": "" + "line": 90 }, { - "name": "Snapshot", + "name": "FormPlan", "bases": [ - "BundleModel" + "ToolInput" ], "fields": [ { - "name": "expected_revision", - "type": "UUID", - "default": "" + "name": "action", + "type": "Literal['form-plan']", + "line": 102 }, { - "name": "visibility", - "type": "Literal['staff_only', 'public']", - "default": "" + "name": "formName", + "type": "str", + "line": 103 + }, + { + "name": "fields", + "type": "list[str]", + "line": 104 } ], - "line": 184, - "doc": "" + "line": 101 }, { - "name": "ConnectionSearch", + "name": "PublishingPlan", "bases": [ - "BundleModel" + "ToolInput" ], "fields": [ { - "name": "provider", - "type": "Literal['meetings', 'zoning']", - "default": "" + "name": "action", + "type": "Literal['publishing-workflow']", + "line": 108 }, { - "name": "query", + "name": "title", "type": "str", - "default": "Field(min_length=1, max_length=500)" + "line": 109 + }, + { + "name": "hasReview", + "type": "bool", + "line": 110 + }, + { + "name": "hasPlainLanguage", + "type": "bool", + "line": 111 + }, + { + "name": "hasTranslationReview", + "type": "bool", + "line": 112 } ], - "line": 215, - "doc": "" + "line": 107 }, { - "name": "PublicExplore", + "name": "AdaPlan", "bases": [ - "BundleModel" + "ToolInput" ], "fields": [ { - "name": "goal", - "type": "str", - "default": "Field(default='', max_length=500)" - }, - { - "name": "topic", - "type": "str", - "default": "Field(default='', max_length=160)" + "name": "action", + "type": "Literal['ada-title-ii']", + "line": 116 }, { - "name": "neighborhood", + "name": "serviceArea", "type": "str", - "default": "Field(default='', max_length=255)" + "line": 117 }, { - "name": "plan_type", - "type": "str", - "default": "Field(default='', max_length=120)" + "name": "hasCoordinatorReview", + "type": "bool", + "line": 118 } ], - "line": 230, - "doc": "" - } - ], - "configuration": [] - } - ] - }, - "permitting": { - "package": "townlight_permitting", - "source": [ - { - "source": "installed-owned-source/townlight_permitting/__init__.py", - "sha256": "a5b97430c7d8d5cfff984857fe16a7c72868d652340640cb9bdcdfe39ddb209c", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_permitting/connections.py", - "sha256": "4159a4eb4a407bebbefeb49bb760788cff3ac51a45c34af094d3be4b5a746798", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_permitting/intake_review.py", - "sha256": "694f531a12e56c283579e92f85651d08da776e916021ab19f4d7108c3120b41d", - "routes": [], - "models": [ + "line": 115 + }, { - "name": "IntakeReadiness", - "bases": [], + "name": "TaggedPlan", + "bases": [ + "ToolInput" + ], "fields": [ { - "name": "project_type", - "type": "str", - "default": "" + "name": "action", + "type": "Literal['tagged-pdf']", + "line": 122 }, { - "name": "status", - "type": "str", - "default": "" - }, + "name": "headingLevels", + "type": "list[Annotated[int, Field(ge=0, le=4294967295, strict=True)]]", + "line": 123 + } + ], + "line": 121 + }, + { + "name": "RewriteInput", + "bases": [ + "ToolInput" + ], + "fields": [ { - "name": "missing_or_unclear", - "type": "tuple[str, ...]", - "default": "" + "name": "action", + "type": "Literal['plain-language', 'language-variant']", + "line": 130 }, { - "name": "next_step", + "name": "text", "type": "str", - "default": "" + "line": 131 }, { - "name": "disclaimer", + "name": "language", "type": "str", - "default": "DISCLAIMER" + "line": 132 } ], - "line": 11, - "doc": "" - } - ], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_permitting/integration_mocks.py", - "sha256": "d1f1b614d502ada64a87d879703e9afa72402b69e8df5a1cf25cbd78f783e111", - "routes": [], - "models": [ + "line": 129 + }, { - "name": "IntegrationMockResult", - "bases": [], + "name": "RewriteResult", + "bases": [ + "RewriteInput" + ], "fields": [ { - "name": "scenario", - "type": "str", - "default": "" - }, - { - "name": "status", - "type": "str", - "default": "" + "name": "outcome", + "type": "Literal['generated', 'unavailable']", + "line": 136 }, { - "name": "review_required", - "type": "bool", - "default": "" + "name": "generated", + "type": "str | None", + "line": 137 }, { - "name": "findings", - "type": "tuple[str, ...]", - "default": "" - }, + "name": "model", + "type": "str | None", + "line": 138 + } + ], + "line": 135 + }, + { + "name": "ExportReceipt", + "bases": [ + "ToolInput" + ], + "fields": [ { - "name": "boundary", + "name": "export_path", "type": "str", - "default": "" + "line": 142 } ], - "line": 10, - "doc": "" + "line": 141 + } + ], + "configuration": [] + }, + { + "source": "desktop/runtime/python-services/townlight_runtime/code_bridge.py", + "sha256": "62a20112343434f75867e6feefeca235688b9e6f37b08410f332a3a0e185774c", + "bytes": 5279, + "routes": [ + { + "method": "POST", + "declared_path": "/imports", + "function": "imports", + "line": 46 + }, + { + "method": "GET", + "declared_path": "/sources", + "function": "sources", + "line": 55 + }, + { + "method": "GET", + "declared_path": "/workspace", + "function": "workspace", + "line": 60 + }, + { + "method": "GET", + "declared_path": "/lookup", + "function": "lookup", + "line": 68 + }, + { + "method": "GET", + "declared_path": "/sections/{section_id}/history", + "function": "section_history", + "line": 77 + }, + { + "method": "GET", + "declared_path": "/citation", + "function": "citation", + "line": 82 + }, + { + "method": "GET", + "declared_path": "/search", + "function": "search", + "line": 89 + }, + { + "method": "GET", + "declared_path": "/imports", + "function": "list_imports", + "line": 100 + }, + { + "method": "GET", + "declared_path": "/imports/{job_id}/tree", + "function": "import_tree", + "line": 105 + }, + { + "method": "GET", + "declared_path": "/imports/{job_id}/provenance", + "function": "import_provenance", + "line": 110 + }, + { + "method": "GET", + "declared_path": "/export", + "function": "export_section", + "line": 115 + }, + { + "method": "POST", + "declared_path": "/questions", + "function": "questions", + "line": 120 + }, + { + "method": "POST", + "declared_path": "/sections/{section_id}/notes", + "function": "create_note", + "line": 125 + }, + { + "method": "GET", + "declared_path": "/sections/{section_id}/notes", + "function": "list_notes", + "line": 130 + }, + { + "method": "POST", + "declared_path": "/sections/{section_id}/summaries", + "function": "create_summary", + "line": 135 + }, + { + "method": "POST", + "declared_path": "/summaries/{summary_id}/approve", + "function": "approve_summary", + "line": 140 + }, + { + "method": "GET", + "declared_path": "/sections/{section_id}/summaries", + "function": "list_summaries", + "line": 145 } ], + "models": [], + "configuration": [] + }, + { + "source": "desktop/runtime/python-services/townlight_runtime/code_meetings.py", + "sha256": "dafae58b355e09ae4fcf81037c25801d48fe38ca7f0f379d5ca44e9145e808a3", + "bytes": 13399, + "routes": [], + "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_permitting/main.py", - "sha256": "d1186d8d291225cfff5dc66e40ab435d899d8a059506a6be6f3b413b7a5c8b90", + "source": "desktop/runtime/python-services/townlight_runtime/code_meetings_bridge.py", + "sha256": "eed7d1036cdc81b98288246e960194057d90edd6df6d3634a7f9cfce1ddc52e0", + "bytes": 4635, "routes": [ { "method": "GET", - "path": "/", - "router": "app", - "prefix_resolved": true, - "name": "root", - "signature": "", - "returns": "dict[str, str]", - "line": 104, - "doc": "Return current product state without overstating unshipped behavior.", - "decorator": "app.get('/')", - "errors": [] - }, - { - "method": "GET", - "path": "/health", - "router": "app", - "prefix_resolved": true, - "name": "health", - "signature": "", - "returns": "dict[str, str]", - "line": 124, - "doc": "Return dependency/version health for deployment smoke checks.", - "decorator": "app.get('/health')", - "errors": [] - }, - { - "method": "GET", - "path": "/townlight_permitting", - "router": "app", - "prefix_resolved": true, - "name": "public_townlight_permitting_page", - "signature": "", - "returns": "str", - "line": 163, - "doc": "Return the public sample permit pre-application UI.", - "decorator": "app.get('/townlight_permitting', response_class=HTMLResponse)", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_permitting/requirements/lookup", - "router": "app", - "prefix_resolved": true, - "name": "requirement_lookup", - "signature": "request: RequirementLookupRequest", - "returns": "dict[str, object]", - "line": 170, - "doc": "", - "decorator": "app.post('/api/v1/townlight_permitting/requirements/lookup')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_permitting/intake/review", - "router": "app", - "prefix_resolved": true, - "name": "intake_review", - "signature": "request: IntakeReviewRequest, x_townlight_permitting_role: Annotated[str | None, Header()]=None, x_townlight_permitting_staff_key: Annotated[str | None, Header()]=None", - "returns": "dict[str, object]", - "line": 179, - "doc": "", - "decorator": "app.post('/api/v1/townlight_permitting/intake/review')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_permitting/pathway/explain", - "router": "app", - "prefix_resolved": true, - "name": "pathway_explain", - "signature": "request: PathwayRequest", - "returns": "dict[str, object]", - "line": 305, - "doc": "Cited likely pathway/attachments/timeline/explainer, no model call.", - "decorator": "app.post('/api/v1/townlight_permitting/pathway/explain')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_permitting/pathway/explain-assisted", - "router": "app", - "prefix_resolved": true, - "name": "pathway_explain_assisted", - "signature": "request: PathwayRequest", - "returns": "dict[str, object]", - "line": 319, - "doc": "Same, plus an actual configured-provider call; `assistance` says what ran.", - "decorator": "app.post('/api/v1/townlight_permitting/pathway/explain-assisted')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_permitting/context/development-review", - "router": "app", - "prefix_resolved": true, - "name": "development_review_context", - "signature": "request: DevelopmentReviewContextRequest", - "returns": "dict[str, object]", - "line": 339, - "doc": "", - "decorator": "app.post('/api/v1/townlight_permitting/context/development-review')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_permitting/integrations/mock/development-review", - "router": "app", - "prefix_resolved": true, - "name": "integration_mock_development_review", - "signature": "request: IntegrationMockRequest", - "returns": "dict[str, object]", - "line": 372, - "doc": "", - "decorator": "app.post('/api/v1/townlight_permitting/integrations/mock/development-review')", - "errors": [] - }, - { - "method": "GET", - "path": "/api/v1/townlight_permitting/intake/{intake_id}", - "router": "app", - "prefix_resolved": true, - "name": "get_intake_review", - "signature": "intake_id: str, x_townlight_permitting_role: Annotated[str | None, Header()]=None, x_townlight_permitting_staff_key: Annotated[str | None, Header()]=None", - "returns": "dict[str, object]", - "line": 384, - "doc": "", - "decorator": "app.get('/api/v1/townlight_permitting/intake/{intake_id}')", - "errors": [ - "HTTPException(status_code=503, detail={'message': 'Townlight Permitting intake persistence is not configured.', 'fix': 'Set TOWNLIGHT_PERMITTING_INTAKE_DB_URL to retrieve persisted intake review records.'})", - "HTTPException(status_code=404, detail={'message': 'Permit intake record not found.', 'fix': 'Use an intake_id returned by POST /api/v1/townlight_permitting/intake/review.'})" - ] - }, - { - "method": "POST", - "path": "/api/v1/townlight_permitting/submittal/outline", - "router": "app", - "prefix_resolved": true, - "name": "submittal_outline", - "signature": "request: SubmittalOutlineRequest", - "returns": "dict[str, object]", - "line": 411, - "doc": "", - "decorator": "app.post('/api/v1/townlight_permitting/submittal/outline')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_permitting/export", - "router": "app", - "prefix_resolved": true, - "name": "permit_export", - "signature": "request: PermitExportRequest", - "returns": "dict[str, object]", - "line": 421, - "doc": "", - "decorator": "app.post('/api/v1/townlight_permitting/export')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_permitting/staff/reviews", - "router": "app", - "prefix_resolved": true, - "name": "create_staff_review", - "signature": "request: StaffReviewCreateRequest, x_townlight_permitting_role: Annotated[str | None, Header()]=None, x_townlight_permitting_staff_key: Annotated[str | None, Header()]=None", - "returns": "dict[str, object]", - "line": 431, - "doc": "", - "decorator": "app.post('/api/v1/townlight_permitting/staff/reviews')", - "errors": [] - }, - { - "method": "GET", - "path": "/api/v1/townlight_permitting/staff/reviews", - "router": "app", - "prefix_resolved": true, - "name": "list_staff_reviews", - "signature": "status: str | None=None, x_townlight_permitting_role: Annotated[str | None, Header()]=None, x_townlight_permitting_staff_key: Annotated[str | None, Header()]=None", - "returns": "dict[str, object]", - "line": 449, - "doc": "", - "decorator": "app.get('/api/v1/townlight_permitting/staff/reviews')", - "errors": [] + "declared_path": "/connections", + "function": "list_connections", + "line": 87 }, { - "method": "PATCH", - "path": "/api/v1/townlight_permitting/staff/reviews/{review_id}", - "router": "app", - "prefix_resolved": true, - "name": "update_staff_review", - "signature": "review_id: str, request: StaffReviewUpdateRequest, x_townlight_permitting_role: Annotated[str | None, Header()]=None, x_townlight_permitting_staff_key: Annotated[str | None, Header()]=None", - "returns": "dict[str, object]", - "line": 466, - "doc": "", - "decorator": "app.patch('/api/v1/townlight_permitting/staff/reviews/{review_id}')", - "errors": [ - "HTTPException(status_code=404, detail={'message': 'Townlight Permitting staff review item was not found.', 'fix': 'List staff reviews and retry with an existing review_id.'})", - "HTTPException(status_code=422, detail={'message': 'Staff review update is invalid.', 'fix': str(exc)})" - ] - }, - { - "method": "GET", - "path": "/api/v1/townlight_permitting/staff/reviews/summary", - "router": "app", - "prefix_resolved": true, - "name": "staff_review_summary", - "signature": "x_townlight_permitting_role: Annotated[str | None, Header()]=None, x_townlight_permitting_staff_key: Annotated[str | None, Header()]=None", - "returns": "dict[str, object]", - "line": 498, - "doc": "", - "decorator": "app.get('/api/v1/townlight_permitting/staff/reviews/summary')", - "errors": [] + "method": "GET", + "declared_path": "/connections/{connection_id}", + "function": "get_connection", + "line": 92 + }, + { + "method": "POST", + "declared_path": "/connections", + "function": "create_connection", + "line": 97 + }, + { + "method": "POST", + "declared_path": "/connections/{connection_id}/closeout", + "function": "closeout_connection", + "line": 104 + }, + { + "method": "GET", + "declared_path": "/code-connections", + "function": "list_code_connections", + "line": 111 + }, + { + "method": "GET", + "declared_path": "/code-connections/{connection_id}", + "function": "get_code_connection", + "line": 116 + }, + { + "method": "POST", + "declared_path": "/code-connections/{connection_id}/decisions", + "function": "record_decision", + "line": 121 } ], "models": [ { - "name": "RequirementLookupRequest", + "name": "Proposal", "bases": [ - "BaseModel" + "_Strict" ], "fields": [ { - "name": "project_type", - "type": "str", - "default": "Field(min_length=1, max_length=255)" + "name": "id", + "type": "Key", + "line": 27 }, { - "name": "location_context", - "type": "str", - "default": "Field(default='', max_length=500)" - } - ], - "line": 45, - "doc": "" - }, - { - "name": "IntakeReviewRequest", - "bases": [ - "BaseModel" - ], - "fields": [ - { - "name": "proposal", + "name": "version_id", "type": "str", - "default": "Field(min_length=1, max_length=5000)" + "line": 28 }, { - "name": "project_type", - "type": "str", - "default": "Field(min_length=1, max_length=255)" - } - ], - "line": 50, - "doc": "" - }, - { - "name": "DevelopmentReviewContextRequest", - "bases": [ - "BaseModel" - ], - "fields": [ + "name": "meeting_id", + "type": "UUID", + "line": 29 + }, { - "name": "project_type", + "name": "title", "type": "str", - "default": "Field(min_length=1, max_length=255)" + "line": 30 }, { - "name": "proposal", + "name": "ordinance_number", "type": "str", - "default": "Field(min_length=1, max_length=5000)" + "line": 31 }, { - "name": "location_context", + "name": "proposed_text", "type": "str", - "default": "Field(default='', max_length=500)" + "line": 32 }, { - "name": "zoning_context_id", - "type": "str | None", - "default": "Field(default=None, max_length=160)" + "name": "supersedes_id", + "type": "Key | None", + "line": 33 }, { - "name": "code_context_id", + "name": "reconciliation_note", "type": "str | None", - "default": "Field(default=None, max_length=160)" + "line": 34 } ], - "line": 55, - "doc": "" + "line": 26 }, { - "name": "SubmittalOutlineRequest", + "name": "Decision", "bases": [ - "BaseModel" + "_Strict" ], "fields": [ { - "name": "project_name", - "type": "str", - "default": "Field(min_length=1, max_length=500)" + "name": "id", + "type": "Key", + "line": 38 }, { - "name": "proposal", - "type": "str", - "default": "Field(min_length=1, max_length=5000)" + "name": "outcome", + "type": "Literal['adopted', 'not_adopted', 'deferred', 'withdrawn']", + "line": 39 }, { - "name": "project_type", - "type": "str", - "default": "Field(min_length=1, max_length=255)" - } - ], - "line": 65, - "doc": "" - }, - { - "name": "PermitExportRequest", - "bases": [ - "BaseModel" - ], - "fields": [ + "name": "decided_at", + "type": "AwareDatetime | None", + "line": 40 + }, { - "name": "title", + "name": "decision_text", "type": "str", - "default": "Field(min_length=1, max_length=500)" + "line": 41 }, { - "name": "project_type", - "type": "str", - "default": "Field(min_length=1, max_length=255)" + "name": "supporting_references", + "type": "list[str]", + "line": 42 }, { - "name": "format", - "type": "str", - "default": "Field(default='markdown', min_length=1, max_length=40)" + "name": "supersedes_decision_id", + "type": "Key | None", + "line": 43 + }, + { + "name": "reconciliation_note", + "type": "str | None", + "line": 44 } ], - "line": 71, - "doc": "" + "line": 37 }, { - "name": "StaffReviewCreateRequest", + "name": "Closeout", "bases": [ - "BaseModel" + "_Strict" ], "fields": [ { - "name": "proposal", - "type": "str", - "default": "Field(min_length=1, max_length=5000)" + "name": "decision_id", + "type": "Key", + "line": 48 }, { - "name": "project_type", + "name": "version_id", "type": "str", - "default": "Field(min_length=1, max_length=255)" + "line": 49 }, { - "name": "reason", + "name": "source_id", "type": "str", - "default": "Field(min_length=1, max_length=1000)" + "line": 50 }, { - "name": "intake_id", - "type": "str | None", - "default": "Field(default=None, max_length=36)" - } - ], - "line": 77, - "doc": "" - }, - { - "name": "StaffReviewUpdateRequest", - "bases": [ - "BaseModel" - ], - "fields": [ - { - "name": "status", + "name": "version_label", "type": "str", - "default": "Field(min_length=1, max_length=80)" - }, - { - "name": "assigned_to", - "type": "str | None", - "default": "Field(default=None, max_length=255)" + "line": 51 }, { - "name": "resolution", - "type": "str | None", - "default": "Field(default=None, max_length=2000)" - } - ], - "line": 84, - "doc": "" - }, - { - "name": "PathwayRequest", - "bases": [ - "BaseModel" - ], - "fields": [ - { - "name": "project_type", + "name": "body", "type": "str", - "default": "Field(min_length=1, max_length=255)" + "line": 52 }, { - "name": "proposal", - "type": "str", - "default": "Field(default='', max_length=5000)" + "name": "effective_start", + "type": "date", + "line": 53 }, { - "name": "location_context", - "type": "str", - "default": "Field(default='', max_length=500)" + "name": "effective_end", + "type": "date | None", + "line": 54 }, { - "name": "use_model_assistance", + "name": "is_current", "type": "bool", - "default": "Field(default=False)" - } - ], - "line": 90, - "doc": "" - }, - { - "name": "IntegrationMockRequest", - "bases": [ - "BaseModel" - ], - "fields": [ + "line": 55 + }, { - "name": "scenario", - "type": "str", - "default": "Field(default='development-review-context', max_length=160)" + "name": "reconciliation_note", + "type": "str | None", + "line": 56 } ], - "line": 97, - "doc": "" + "line": 47 } ], - "configuration": [ + "configuration": [] + }, + { + "source": "desktop/runtime/python-services/townlight_runtime/code_public.py", + "sha256": "8c28292fed544f4db88541054f02d60d707130c11c70a1f10b42916302a02433", + "bytes": 4822, + "routes": [ { - "variable": "TOWNLIGHT_PERMITTING_INTAKE_DB_URL", - "default": "", - "line": 508 + "method": "GET", + "declared_path": "", + "function": "home", + "line": 66 }, { - "variable": "TOWNLIGHT_PERMITTING_LLM_MODEL", - "default": "", - "line": 233 + "method": "GET", + "declared_path": "/search", + "function": "search", + "line": 71 }, { - "variable": "TOWNLIGHT_PERMITTING_LLM_PROVIDER", - "default": "''", - "line": 218 + "method": "GET", + "declared_path": "/answer", + "function": "answer", + "line": 80 + }, + { + "method": "GET", + "declared_path": "/sections/{section_ref}", + "function": "detail", + "line": 91 + }, + { + "method": "GET", + "declared_path": "/sections/{section_ref}/export", + "function": "export", + "line": 109 } - ] + ], + "models": [], + "configuration": [] }, { - "source": "installed-owned-source/townlight_permitting/migrations/__init__.py", - "sha256": "01c6b95137260717ee792116a0479392b3f2da330542c55dbd181c4a93d404a3", + "source": "desktop/runtime/python-services/townlight_runtime/code_records.py", + "sha256": "d7a78ddc87493c02c78b9f027a69708b55040c8c4445644ba4b36340fd459bc4", + "bytes": 3174, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_permitting/migrations/env.py", - "sha256": "91715ad26e140d1b25b30ad38b3418d36ea63da4a195348aa5fe621c99edbe5e", + "source": "desktop/runtime/python-services/townlight_runtime/database_identity.py", + "sha256": "7aaf74fe0ab5b5e13c5527f1069e5ad15a4b66c13df98c327969b3bad2c3bd7d", + "bytes": 1624, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_permitting/migrations/versions/townlight_permitting_0001_connected.py", - "sha256": "e3fc90959836887334b429888407537140fa2d119c202886b63c538feb4e9360", + "source": "desktop/runtime/python-services/townlight_runtime/fixtures/redstone-valley-records-demo-v1.json", + "sha256": "859a65633f6f4575bb53f5db61a11b0a092cc1f9b145b828e70729cfd28e6a34", + "bytes": 6629, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_permitting/pathway.py", - "sha256": "b1e311809d61f4efab043c681efa9d711d5bf4bf76b5f33f808c1769e3687d08", - "routes": [], + "source": "desktop/runtime/python-services/townlight_runtime/inspections_bridge.py", + "sha256": "6c840905c53d00a5d7ab5f39b8ca276924098ff11929913fe9b02bba457bf553", + "bytes": 10132, + "routes": [ + { + "method": "POST", + "declared_path": "/repeat-cases", + "function": "repeat_cases", + "line": 93 + }, + { + "method": "POST", + "declared_path": "/notice-draft", + "function": "notice", + "line": 98 + }, + { + "method": "GET", + "declared_path": "/cases", + "function": "cases", + "line": 105 + }, + { + "method": "POST", + "declared_path": "/cases", + "function": "create_case", + "line": 110 + }, + { + "method": "GET", + "declared_path": "/cases/{case_id}", + "function": "case", + "line": 115 + }, + { + "method": "POST", + "declared_path": "/cases/{case_id}/revisions", + "function": "revise", + "line": 120 + }, + { + "method": "GET", + "declared_path": "/cases/{case_id}/history", + "function": "history", + "line": 125 + }, + { + "method": "POST", + "declared_path": "/cases/{case_id}/packets", + "function": "packet", + "line": 135 + }, + { + "method": "GET", + "declared_path": "/packets/{packet_id}", + "function": "document", + "line": 140 + }, + { + "method": "GET", + "declared_path": "/evidence/supported-types", + "function": "supported_types", + "line": 179 + }, + { + "method": "POST", + "declared_path": "/evidence/retain", + "function": "retain", + "line": 188 + }, + { + "method": "POST", + "declared_path": "/media/analyse", + "function": "media_analyse", + "line": 199 + }, + { + "method": "POST", + "declared_path": "/connections/search", + "function": "connections", + "line": 234 + } + ], "models": [ { - "name": "AssistantProvider", + "name": "RepeatLookup", "bases": [ - "Protocol" + "Model" ], "fields": [ { - "name": "name", + "name": "property_reference", "type": "str", - "default": "" + "line": 89 } ], - "line": 74, - "doc": "Structural type of the townlight_core LLM provider used for the explainer." + "line": 88 }, { - "name": "PathwayStage", - "bases": [], + "name": "Packet", + "bases": [ + "Model" + ], "fields": [ { - "name": "key", - "type": "str", - "default": "" - }, - { - "name": "label", - "type": "str", - "default": "" - }, - { - "name": "source_id", - "type": "str", - "default": "" + "name": "expected_revision", + "type": "UUID", + "line": 130 }, { - "name": "typical_time", - "type": "str", - "default": "" + "name": "visibility", + "type": "Literal['staff_only', 'records_copy']", + "line": 131 } ], - "line": 91, - "doc": "A cited step in the pre-application pathway.\n\n``source_id`` is resolved through the configured public source providers;\nthe displayed citation and text are copied from the resolved source so the\npathway can never show a citation that does not exist." + "line": 129 }, { - "name": "Pathway", - "bases": [], + "name": "EvidenceItem", + "bases": [ + "Model" + ], "fields": [ { - "name": "project_type", + "name": "filename", "type": "str", - "default": "" + "line": 145 }, { - "name": "title", + "name": "media_type", "type": "str", - "default": "" - }, - { - "name": "stages", - "type": "tuple[PathwayStage, ...]", - "default": "" + "line": 146 }, { - "name": "attachments_citation", + "name": "description", "type": "str", - "default": "" + "line": 147 }, { - "name": "attachments", - "type": "tuple[str, ...]", - "default": "" + "name": "content_base64", + "type": "str", + "line": 148 }, { - "name": "note", + "name": "sha256", "type": "str", - "default": "''" + "line": 149 } ], - "line": 106, - "doc": "" + "line": 144 }, { - "name": "PathwayExplanation", - "bases": [], + "name": "EvidenceItems", + "bases": [ + "Model" + ], "fields": [ { - "name": "project_type", - "type": "str", - "default": "" - }, - { - "name": "title", - "type": "str", - "default": "" - }, - { - "name": "likely_permits", - "type": "list[dict[str, str]]", - "default": "field(default_factory=list)" - }, - { - "name": "attachments", - "type": "list[dict[str, str]]", - "default": "field(default_factory=list)" - }, - { - "name": "timeline", - "type": "list[dict[str, str]]", - "default": "field(default_factory=list)" - }, - { - "name": "unavailable", - "type": "list[dict[str, str]]", - "default": "field(default_factory=list)" - }, - { - "name": "fee", - "type": "dict[str, object]", - "default": "field(default_factory=dict)" - }, - { - "name": "resident_explanation", - "type": "str", - "default": "''" - }, - { - "name": "assistance", - "type": "dict[str, object]", - "default": "field(default_factory=dict)" - }, - { - "name": "review_required", - "type": "bool", - "default": "True" - }, - { - "name": "determination_made", - "type": "bool", - "default": "False" - }, + "name": "items", + "type": "list[EvidenceItem]", + "line": 153 + } + ], + "line": 152 + }, + { + "name": "CodeLink", + "bases": [ + "Model" + ], + "fields": [ { - "name": "citations", - "type": "list[str]", - "default": "field(default_factory=list)" + "name": "provider", + "type": "Literal['code']", + "line": 157 }, { - "name": "boundary", + "name": "source_id", "type": "str", - "default": "BOUNDARY" + "line": 158 }, { - "name": "disclaimer", + "name": "expected_sha256", "type": "str", - "default": "DISCLAIMER" + "line": 159 } ], - "line": 132, - "doc": "Assembled, citation-checked pre-application explanation." - } - ], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_permitting/persistence.py", - "sha256": "cea7301cde02497e65601351e58100b3211cf79e85e3036f251107f7d21fe95b", - "routes": [], - "models": [ + "line": 156 + }, { - "name": "StoredIntakeReview", - "bases": [], + "name": "MediaAnalysis", + "bases": [ + "Model" + ], "fields": [ { - "name": "intake_id", - "type": "str", - "default": "" - }, - { - "name": "project_type", - "type": "str", - "default": "" + "name": "items", + "type": "list[EvidenceItem]", + "line": 163 }, { - "name": "proposal", - "type": "str", - "default": "" + "name": "code_links", + "type": "list[CodeLink]", + "line": 164 }, { - "name": "status", + "name": "inspector_supplied_text", "type": "str", - "default": "" - }, - { - "name": "missing_or_unclear", - "type": "tuple[str, ...]", - "default": "" - }, + "line": 165 + } + ], + "line": 162 + }, + { + "name": "Search", + "bases": [ + "Model" + ], + "fields": [ { - "name": "next_step", - "type": "str", - "default": "" + "name": "provider", + "type": "Literal['code']", + "line": 229 }, { - "name": "disclaimer", + "name": "query", "type": "str", - "default": "" - }, - { - "name": "created_at", - "type": "datetime", - "default": "" + "line": 230 } ], - "line": 72, - "doc": "" + "line": 228 + } + ], + "configuration": [] + }, + { + "source": "desktop/runtime/python-services/townlight_runtime/meetings_bridge.py", + "sha256": "c188c7f52163681ffbd3dcee61da2f7cba24df6839adb421be804087dca4ff4c", + "bytes": 29127, + "routes": [ + { + "method": "POST", + "declared_path": "/meetings/{meeting_id}/stages", + "function": "record_meeting_stage", + "line": 106 + }, + { + "method": "POST", + "declared_path": "/meetings", + "function": "create_meeting", + "line": 128 + }, + { + "method": "GET", + "declared_path": "/meetings/{meeting_id}", + "function": "get_meeting", + "line": 136 + }, + { + "method": "POST", + "declared_path": "/agenda-items", + "function": "create_agenda_item", + "line": 141 + }, + { + "method": "GET", + "declared_path": "/agenda-items/{item_id}", + "function": "get_agenda_item", + "line": 148 + }, + { + "method": "POST", + "declared_path": "/agenda-items/{item_id}/reviews", + "function": "record_agenda_review", + "line": 164 + }, + { + "method": "POST", + "declared_path": "/agenda-items/{item_id}/meeting", + "function": "assign_agenda", + "line": 170 + }, + { + "method": "GET", + "declared_path": "/notices/{notice_id}/template", + "function": "notice_template", + "line": 249 + }, + { + "method": "POST", + "declared_path": "/notices/{notice_id}/document", + "function": "notice_document", + "line": 264 + }, + { + "method": "POST", + "declared_path": "/meetings/{meeting_id}/notice-checks", + "function": "check_notice", + "line": 278 + }, + { + "method": "POST", + "declared_path": "/notices/{notice_id}/proof", + "function": "record_notice_proof", + "line": 295 + }, + { + "method": "POST", + "declared_path": "/meetings/{meeting_id}/transcripts", + "function": "capture_transcript", + "line": 332 + }, + { + "method": "POST", + "declared_path": "/meetings/{meeting_id}/action-items", + "function": "capture_action_item", + "line": 344 + }, + { + "method": "POST", + "declared_path": "/meetings/{meeting_id}/archive", + "function": "archive_meeting", + "line": 356 + }, + { + "method": "GET", + "declared_path": "", + "function": "public_archive_index", + "line": 399 + }, + { + "method": "GET", + "declared_path": "/{record_id}", + "function": "public_archive_detail", + "line": 407 }, { - "name": "StaffReviewQueueItem", - "bases": [], + "method": "GET", + "declared_path": "/{record_id}/{kind}.txt", + "function": "public_archive_download", + "line": 417 + }, + { + "method": "POST", + "declared_path": "/meetings/{meeting_id}/packet-snapshots", + "function": "capture_packet", + "line": 441 + }, + { + "method": "POST", + "declared_path": "/packets/{packet_id}/deliver", + "function": "export_packet", + "line": 462 + }, + { + "method": "POST", + "declared_path": "/minutes/{draft_id}/decisions", + "function": "decide_minutes", + "line": 475 + }, + { + "method": "POST", + "declared_path": "/meetings/{meeting_id}/motions", + "function": "capture_motion", + "line": 498 + }, + { + "method": "POST", + "declared_path": "/motions/{motion_id}/corrections", + "function": "correct_motion", + "line": 505 + }, + { + "method": "POST", + "declared_path": "/motions/{motion_id}/votes", + "function": "capture_vote", + "line": 511 + }, + { + "method": "POST", + "declared_path": "/votes/{vote_id}/corrections", + "function": "correct_vote", + "line": 517 + }, + { + "method": "POST", + "declared_path": "/meetings/{meeting_id}/minutes/drafts", + "function": "create_minutes", + "line": 523 + }, + { + "method": "GET", + "declared_path": "/meetings/{meeting_id}/proceedings", + "function": "proceedings", + "line": 532 + }, + { + "method": "GET", + "declared_path": "/station/catalog", + "function": "station_catalog", + "line": 552 + } + ], + "models": [ + { + "name": "MeetingInput", + "bases": [ + "BaseModel" + ], "fields": [ { - "name": "review_id", + "name": "title", "type": "str", - "default": "" + "line": 85 }, { - "name": "intake_id", - "type": "str | None", - "default": "" + "name": "scheduled_start", + "type": "AwareDatetime", + "line": 86 }, { - "name": "project_type", + "name": "location", "type": "str", - "default": "" + "line": 87 }, { - "name": "proposal", - "type": "str", - "default": "" - }, + "name": "meeting_type", + "type": "Literal['regular', 'special', 'emergency', 'closed_session', 'executive']", + "line": 88 + } + ], + "line": 83 + }, + { + "name": "AgendaInput", + "bases": [ + "BaseModel" + ], + "fields": [ { - "name": "status", + "name": "title", "type": "str", - "default": "" + "line": 93 }, { - "name": "reason", + "name": "department_name", "type": "str", - "default": "" - }, + "line": 94 + } + ], + "line": 91 + }, + { + "name": "MeetingStageInput", + "bases": [ + "BaseModel" + ], + "fields": [ { - "name": "assigned_to", - "type": "str | None", - "default": "" + "name": "to_status", + "type": "Literal['SCHEDULED', 'NOTICED', 'PACKET_POSTED', 'IN_PROGRESS', 'RECESSED', 'ADJOURNED', 'TRANSCRIPT_READY', 'MINUTES_DRAFTED', 'MINUTES_POSTED', 'MINUTES_ADOPTED', 'MINUTES_SIGNED', 'ARCHIVED', 'CANCELLED']", + "line": 99 }, { - "name": "resolution", + "name": "statutory_basis", "type": "str | None", - "default": "" - }, - { - "name": "created_by", - "type": "str", - "default": "" - }, - { - "name": "created_at", - "type": "datetime", - "default": "" - }, - { - "name": "updated_at", - "type": "datetime", - "default": "" - }, + "line": 102 + } + ], + "line": 97 + }, + { + "name": "AgendaReviewInput", + "bases": [ + "BaseModel" + ], + "fields": [ { - "name": "visibility", - "type": "str", - "default": "'staff_only'" + "name": "to_status", + "type": "Literal['DRAFTED', 'SUBMITTED', 'DEPT_APPROVED', 'LEGAL_REVIEWED', 'CLERK_ACCEPTED', 'ON_AGENDA', 'IN_PACKET', 'POSTED', 'HEARD', 'DISPOSED', 'ARCHIVED']", + "line": 154 } ], - "line": 84, - "doc": "" + "line": 152 }, { - "name": "StaffReviewSummary", - "bases": [], + "name": "AgendaAssignment", + "bases": [ + "BaseModel" + ], "fields": [ { - "name": "total_items", - "type": "int", - "default": "" - }, + "name": "meeting_id", + "type": "UUID", + "line": 160 + } + ], + "line": 158 + }, + { + "name": "MotionInput", + "bases": [ + "BaseModel" + ], + "fields": [ { - "name": "by_status", - "type": "dict[str, int]", - "default": "" + "name": "text", + "type": "str", + "line": 180 }, { - "name": "open_items", - "type": "int", - "default": "" - }, + "name": "seconded_by", + "type": "str | None", + "line": 181 + } + ], + "line": 178 + }, + { + "name": "MotionCorrection", + "bases": [ + "BaseModel" + ], + "fields": [ { - "name": "generated_at", - "type": "datetime", - "default": "" + "name": "text", + "type": "str", + "line": 186 }, { - "name": "visibility", + "name": "reason", "type": "str", - "default": "'staff_only'" + "line": 187 } ], - "line": 100, - "doc": "" - } - ], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_permitting/public_ui.py", - "sha256": "0f06685bd18b171987cc08413bc930112f400a03468c0f27e98badba6b732f29", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_permitting/records_export.py", - "sha256": "231801e8bd30b92f0fe6aeb0a8f2aed2d5097acae5f2cc5eda2e18f9c9a1fae8", - "routes": [], - "models": [ + "line": 184 + }, { - "name": "PermitExport", - "bases": [], + "name": "VoteInput", + "bases": [ + "BaseModel" + ], "fields": [ { - "name": "title", + "name": "voter_name", "type": "str", - "default": "" + "line": 192 }, { - "name": "project_type", + "name": "vote", "type": "str", - "default": "" - }, + "line": 193 + } + ], + "line": 190 + }, + { + "name": "VoteCorrection", + "bases": [ + "BaseModel" + ], + "fields": [ { - "name": "format", + "name": "vote", "type": "str", - "default": "" - }, - { - "name": "checklist", - "type": "tuple[str, ...]", - "default": "" + "line": 198 }, { - "name": "retention_note", + "name": "reason", "type": "str", - "default": "" + "line": 199 } ], - "line": 11, - "doc": "" - } - ], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_permitting/requirement_lookup.py", - "sha256": "f9a1fbd111096e7d4c00cc6cb7f25b9cf91af522f26c743f86234a0ecffe783c", - "routes": [], - "models": [ + "line": 196 + }, { - "name": "PermitRequirement", - "bases": [], + "name": "SourceInput", + "bases": [ + "BaseModel" + ], "fields": [ { - "name": "requirement_id", + "name": "source_id", "type": "str", - "default": "" + "line": 204 }, { - "name": "project_type", + "name": "label", "type": "str", - "default": "" + "line": 205 }, { - "name": "title", + "name": "text", "type": "str", - "default": "" - }, + "line": 206 + } + ], + "line": 202 + }, + { + "name": "SentenceInput", + "bases": [ + "BaseModel" + ], + "fields": [ { - "name": "citation", + "name": "text", "type": "str", - "default": "" + "line": 211 }, { - "name": "required_materials", - "type": "tuple[str, ...]", - "default": "" - }, + "name": "citations", + "type": "list[str]", + "line": 212 + } + ], + "line": 209 + }, + { + "name": "DraftInput", + "bases": [ + "BaseModel" + ], + "fields": [ { - "name": "staff_note", - "type": "str", - "default": "" + "name": "source_materials", + "type": "list[SourceInput]", + "line": 217 }, { - "name": "disclaimer", - "type": "str", - "default": "DISCLAIMER" + "name": "sentences", + "type": "list[SentenceInput]", + "line": 218 } ], - "line": 16, - "doc": "" - } - ], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_permitting/sources.py", - "sha256": "8e26b8c98635689f985e14d57a0137f6538145c50414da918ba0cb41a7f489a3", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_permitting/submittal_outline.py", - "sha256": "f6465de3058d51bb47b7d278e10b67a2ac1ac46aeefa2563eabd041dcb54aae1", - "routes": [], - "models": [ + "line": 215 + }, { - "name": "SubmittalOutline", - "bases": [], + "name": "MinutesDecision", + "bases": [ + "BaseModel" + ], "fields": [ { - "name": "project_name", - "type": "str", - "default": "" + "name": "action", + "type": "Literal['post', 'adopt', 'sign']", + "line": 223 }, { - "name": "heading", + "name": "note", "type": "str", - "default": "" + "line": 224 + } + ], + "line": 221 + }, + { + "name": "NoticeInput", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "notice_type", + "type": "Literal['regular', 'special', 'emergency', 'closed_session', 'executive']", + "line": 229 }, { - "name": "required_materials", - "type": "tuple[str, ...]", - "default": "" + "name": "posted_at", + "type": "AwareDatetime", + "line": 230 }, { - "name": "applicant_message", - "type": "str", - "default": "" + "name": "minimum_notice_hours", + "type": "int", + "line": 231 }, { - "name": "review_required", - "type": "bool", - "default": "" + "name": "statutory_basis", + "type": "str | None", + "line": 232 }, { - "name": "disclaimer", - "type": "str", - "default": "DISCLAIMER" + "name": "approved_by", + "type": "str | None", + "line": 233 } ], - "line": 12, - "doc": "" - } - ], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_permitting/workflow_models.py", - "sha256": "3d09f3ae137c5c48091e22a60a3e732ea3ec299236778d377df55807bb8bbfdd", - "routes": [], - "models": [ + "line": 227 + }, { - "name": "Material", + "name": "NoticeProofInput", "bases": [ - "Model" + "BaseModel" ], "fields": [ { - "name": "material_id", + "name": "location", "type": "str", - "default": "Field(pattern='^[a-zA-Z0-9_-]{1,80}$')" + "line": 238 }, { - "name": "description", + "name": "note", "type": "str", - "default": "Field(min_length=1, max_length=2000)" + "line": 239 }, { - "name": "citation", - "type": "str", - "default": "Field(min_length=1, max_length=1000)" + "name": "document_delivery_id", + "type": "str | None", + "line": 240 } ], - "line": 20, - "doc": "" + "line": 236 }, { - "name": "PathwayStep", + "name": "NoticeDocumentInput", "bases": [ - "Model" + "BaseModel" ], "fields": [ { - "name": "step", - "type": "str", - "default": "Field(min_length=1, max_length=2000)" - }, - { - "name": "citation", - "type": "str", - "default": "Field(min_length=1, max_length=1000)" - }, - { - "name": "typical_time", + "name": "text", "type": "str", - "default": "Field(default='', max_length=1000)" + "line": 245 } ], - "line": 26, - "doc": "" + "line": 243 }, { - "name": "SourceLink", + "name": "PacketInput", "bases": [ - "Model" + "BaseModel" ], "fields": [ { - "name": "provider", - "type": "Literal['code', 'zoning']", - "default": "" - }, - { - "name": "source_id", - "type": "str", - "default": "Field(min_length=1, max_length=500)" + "name": "agenda_item_ids", + "type": "list[UUID]", + "line": 305 }, { - "name": "expected_sha256", - "type": "str", - "default": "Field(pattern='^[a-f0-9]{64}$')" + "name": "source_files", + "type": "list['ManagedSource']", + "line": 306 } ], - "line": 32, - "doc": "" + "line": 303 }, { - "name": "RequirementBundle", + "name": "TranscriptInput", "bases": [ - "Model" + "BaseModel" ], "fields": [ { - "name": "requirement_id", - "type": "str", - "default": "Field(pattern='^[a-zA-Z0-9_-]{1,100}$')" - }, - { - "name": "title", - "type": "str", - "default": "Field(min_length=1, max_length=500)" - }, - { - "name": "jurisdiction", - "type": "str", - "default": "Field(min_length=1, max_length=255)" - }, - { - "name": "project_type", - "type": "str", - "default": "Field(min_length=1, max_length=255)" - }, - { - "name": "source_reference", + "name": "source_label", "type": "str", - "default": "Field(min_length=1, max_length=1000)" - }, - { - "name": "source_date", - "type": "date", - "default": "" - }, - { - "name": "effective_on", - "type": "date", - "default": "" - }, - { - "name": "dataset_kind", - "type": "Literal['municipal', 'fictional']", - "default": "" + "line": 311 }, { - "name": "filename", + "name": "transcript_text", "type": "str", - "default": "Field(pattern='^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$')" + "line": 312 }, { - "name": "content_base64", - "type": "str", - "default": "Field(min_length=1, max_length=14000000)" - }, + "name": "correction_of_id", + "type": "UUID | None", + "line": 313 + } + ], + "line": 309 + }, + { + "name": "ActionItemInput", + "bases": [ + "BaseModel" + ], + "fields": [ { - "name": "sha256", + "name": "description", "type": "str", - "default": "Field(pattern='^[a-f0-9]{64}$')" - }, - { - "name": "materials", - "type": "list[Material]", - "default": "Field(min_length=1, max_length=100)" - }, - { - "name": "pathway", - "type": "list[PathwayStep]", - "default": "Field(default_factory=list, max_length=100)" - }, - { - "name": "fee_link", - "type": "SourceLink | None", - "default": "None" + "line": 318 }, { - "name": "staff_note", - "type": "str", - "default": "Field(default='', max_length=4000)" + "name": "assigned_to", + "type": "str | None", + "line": 319 }, { - "name": "change_note", - "type": "str", - "default": "Field(min_length=1, max_length=2000)" + "name": "source_motion_id", + "type": "UUID | None", + "line": 320 } ], - "line": 38, - "doc": "" + "line": 316 }, { - "name": "MaterialReview", + "name": "ArchiveInput", "bases": [ - "Model" + "BaseModel" ], "fields": [ { - "name": "material_id", - "type": "str", - "default": "Field(min_length=1, max_length=80)" + "name": "visibility", + "type": "Literal['public', 'closed_session']", + "line": 325 }, { - "name": "status", - "type": "Literal['not_reviewed', 'provided', 'missing', 'unclear']", - "default": "'not_reviewed'" + "name": "packet_id", + "type": "UUID | None", + "line": 326 }, { - "name": "note", + "name": "minutes_id", + "type": "UUID | None", + "line": 327 + }, + { + "name": "plain_language_summary", "type": "str", - "default": "Field(default='', max_length=2000)" + "line": 328 } ], - "line": 70, - "doc": "" + "line": 323 }, { - "name": "IntakeInput", + "name": "ManagedSource", "bases": [ - "Model" + "BaseModel" ], "fields": [ { - "name": "expected_revision", - "type": "UUID | None", - "default": "None" - }, - { - "name": "project_name", + "name": "original_path", "type": "str", - "default": "Field(min_length=1, max_length=500)" + "line": 426 }, { - "name": "project_description", + "name": "stored_path", "type": "str", - "default": "Field(min_length=1, max_length=10000)" + "line": 427 }, { - "name": "location", + "name": "file_name", "type": "str", - "default": "Field(min_length=1, max_length=1000)" + "line": 428 }, { - "name": "applicant_contact", + "name": "sha256", "type": "str", - "default": "Field(default='', max_length=2000)" + "line": 429 }, { - "name": "requirement_revision", - "type": "UUID", - "default": "" - }, + "name": "size_bytes", + "type": "int", + "line": 430 + } + ], + "line": 424 + } + ], + "configuration": [ + { + "environment": "DATABASE_URL", + "line": 38 + }, + { + "environment": "TOWNLIGHT_PROFILE_ROOT", + "line": 434 + } + ] + }, + { + "source": "desktop/runtime/python-services/townlight_runtime/migrate.py", + "sha256": "072bcee7c652a1858a69cac4056fd7a6ecd0d19e59ca7affa536fb32d39ea081", + "bytes": 6108, + "routes": [], + "models": [], + "configuration": [ + { + "environment": "DATABASE_URL", + "line": 41 + } + ] + }, + { + "source": "desktop/runtime/python-services/townlight_runtime/native_accounts.py", + "sha256": "497fb326fccb61dec69b58daf35a382ab832adeed190e65d2a7f87098fb3c6e7", + "bytes": 4090, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/runtime/python-services/townlight_runtime/notice_bridge.py", + "sha256": "23de374634960f6ee5b07f13f445fcec07af84a44d6393def6559224f4231b4b", + "bytes": 7532, + "routes": [ + { + "method": "GET", + "declared_path": "/notices", + "function": "inventory", + "line": 69 + }, + { + "method": "POST", + "declared_path": "/notices", + "function": "create", + "line": 74 + }, + { + "method": "GET", + "declared_path": "/notices/{notice_id}", + "function": "read", + "line": 79 + }, + { + "method": "POST", + "declared_path": "/notices/{notice_id}/revisions", + "function": "edit", + "line": 85 + }, + { + "method": "POST", + "declared_path": "/notices/{notice_id}/review", + "function": "review", + "line": 90 + }, + { + "method": "POST", + "declared_path": "/notices/{notice_id}/approval", + "function": "approve", + "line": 95 + }, + { + "method": "POST", + "declared_path": "/notices/{notice_id}/proof", + "function": "proof", + "line": 100 + }, + { + "method": "POST", + "declared_path": "/notices/{notice_id}/archive", + "function": "archive", + "line": 110 + }, + { + "method": "GET", + "declared_path": "/archives/{archive_id}", + "function": "export", + "line": 115 + }, + { + "method": "POST", + "declared_path": "/archives/{archive_id}/records", + "function": "handoff", + "line": 127 + } + ], + "models": [ + { + "name": "Version", + "bases": [ + "BaseModel" + ], + "fields": [ { - "name": "materials", - "type": "list[MaterialReview]", - "default": "Field(min_length=1, max_length=100)" - }, + "name": "sequence", + "type": "int", + "line": 50 + } + ], + "line": 48 + }, + { + "name": "Revision", + "bases": [ + "Version" + ], + "fields": [ { - "name": "linked_sources", - "type": "list[SourceLink]", - "default": "Field(default_factory=list, max_length=30)" - }, + "name": "document", + "type": "NoticeDraft", + "line": 54 + } + ], + "line": 53 + }, + { + "name": "Review", + "bases": [ + "Version" + ], + "fields": [ { - "name": "staff_notes", + "name": "note", "type": "str", - "default": "Field(default='', max_length=10000)" - }, + "line": 58 + } + ], + "line": 57 + }, + { + "name": "Proof", + "bases": [ + "Version" + ], + "fields": [ { - "name": "assigned_to", + "name": "filename", "type": "str", - "default": "Field(default='', max_length=255)" + "line": 62 }, { - "name": "review_state", - "type": "Literal['draft', 'follow_up', 'reviewed']", - "default": "'draft'" + "name": "content_base64", + "type": "str", + "line": 63 }, { - "name": "review_notes", + "name": "location", "type": "str", - "default": "Field(default='', max_length=4000)" + "line": 64 }, { - "name": "public_summary", + "name": "published_at", "type": "str", - "default": "Field(default='', max_length=10000)" + "line": 65 + } + ], + "line": 61 + }, + { + "name": "Handoff", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "request_id", + "type": "UUID", + "line": 123 } ], - "line": 76, - "doc": "" + "line": 121 } ], "configuration": [] }, { - "source": "installed-owned-source/townlight_permitting/workflow_schema.py", - "sha256": "07dfc3dfafd5131ffee8b087add38fd7ebf446c2cf104100920636e732aaee59", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_permitting/workflow_store.py", - "sha256": "c3415dd94aaed609a593d28b60d0719f2dc1a504a5f15391d9708714038ea259", - "routes": [], - "models": [], - "configuration": [] - } - ], - "bridge": [ - { - "source": "installed-owned-source/townlight_runtime/permitting_bridge.py", - "sha256": "786abd0dfc18ed0ce7ada70fcd120f96795d8e1ee46f38ca0770a8217b4d6e1d", + "source": "desktop/runtime/python-services/townlight_runtime/permitting_bridge.py", + "sha256": "3505589503441a72fe6c6094b6cd6d31a111ce633f912e85ccd72edd08cf2535", + "bytes": 9103, "routes": [ { "method": "POST", - "path": "/desktop/v1/permitting/requirements", - "router": "router", - "prefix_resolved": true, - "name": "import_requirements", - "signature": "request: Request, body: Import, identity=Depends(actor)", - "returns": "", - "line": 85, - "doc": "", - "decorator": "router.post('/requirements')", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/permitting/requirements", - "router": "router", - "prefix_resolved": true, - "name": "requirements", - "signature": "request: Request, offset: int=Query(0, ge=0, le=100000), identity=Depends(actor)", - "returns": "", - "line": 91, - "doc": "", - "decorator": "router.get('/requirements')", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/permitting/requirements/{revision_id}", - "router": "router", - "prefix_resolved": true, - "name": "requirement", - "signature": "request: Request, revision_id: UUID, identity=Depends(actor)", - "returns": "", - "line": 96, - "doc": "", - "decorator": "router.get('/requirements/{revision_id}')", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/permitting/cases", - "router": "router", - "prefix_resolved": true, - "name": "cases", - "signature": "request: Request, offset: int=Query(0, ge=0, le=100000), identity=Depends(actor)", - "returns": "", - "line": 101, - "doc": "", - "decorator": "router.get('/cases')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/permitting/cases", - "router": "router", - "prefix_resolved": true, - "name": "create_case", - "signature": "request: Request, body: IntakeInput, identity=Depends(actor)", - "returns": "", - "line": 106, - "doc": "", - "decorator": "router.post('/cases')", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/permitting/cases/{case_id}", - "router": "router", - "prefix_resolved": true, - "name": "case", - "signature": "request: Request, case_id: UUID, identity=Depends(actor)", - "returns": "", - "line": 111, - "doc": "", - "decorator": "router.get('/cases/{case_id}')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/permitting/cases/{case_id}/revisions", - "router": "router", - "prefix_resolved": true, - "name": "revise", - "signature": "request: Request, case_id: UUID, body: IntakeInput, identity=Depends(actor)", - "returns": "", - "line": 116, - "doc": "", - "decorator": "router.post('/cases/{case_id}/revisions')", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/permitting/cases/{case_id}/history", - "router": "router", - "prefix_resolved": true, - "name": "history", - "signature": "request: Request, case_id: UUID, identity=Depends(actor)", - "returns": "", - "line": 121, - "doc": "", - "decorator": "router.get('/cases/{case_id}/history')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/permitting/cases/{case_id}/packets", - "router": "router", - "prefix_resolved": true, - "name": "packet", - "signature": "request: Request, case_id: UUID, body: Packet, identity=Depends(actor)", - "returns": "", - "line": 131, - "doc": "", - "decorator": "router.post('/cases/{case_id}/packets')", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/permitting/packets/{packet_id}", - "router": "router", - "prefix_resolved": true, - "name": "document", - "signature": "request: Request, packet_id: UUID, identity=Depends(actor)", - "returns": "", - "line": 136, - "doc": "", - "decorator": "router.get('/packets/{packet_id}')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/permitting/pathway", - "router": "router", - "prefix_resolved": true, - "name": "pathway", - "signature": "request: Request, body: Pathway, identity=Depends(actor)", - "returns": "", - "line": 149, - "doc": "Cited likely permit pathway, attachments and timeline; informational only.\n\n``use_model_assistance`` does not exist here: the resident live-model\nassistance flag (F-07) stays excluded, so only the deterministic cited\npathway is reachable from the shared shell.", - "decorator": "router.post('/pathway')", - "errors": [ - "HTTPException(503, f'Configured public permit sources unavailable: {exc}')" - ] - }, - { - "method": "POST", - "path": "/desktop/v1/permitting/connections/search", - "router": "router", - "prefix_resolved": true, - "name": "connections", - "signature": "request: Request, body: Search, identity=Depends(actor)", - "returns": "", - "line": 199, - "doc": "", - "decorator": "router.post('/connections/search')", - "errors": [] + "declared_path": "/requirements", + "function": "import_requirements", + "line": 85 + }, + { + "method": "GET", + "declared_path": "/requirements", + "function": "requirements", + "line": 91 + }, + { + "method": "GET", + "declared_path": "/requirements/{revision_id}", + "function": "requirement", + "line": 96 + }, + { + "method": "GET", + "declared_path": "/cases", + "function": "cases", + "line": 101 + }, + { + "method": "POST", + "declared_path": "/cases", + "function": "create_case", + "line": 106 + }, + { + "method": "GET", + "declared_path": "/cases/{case_id}", + "function": "case", + "line": 111 + }, + { + "method": "POST", + "declared_path": "/cases/{case_id}/revisions", + "function": "revise", + "line": 116 + }, + { + "method": "GET", + "declared_path": "/cases/{case_id}/history", + "function": "history", + "line": 121 + }, + { + "method": "POST", + "declared_path": "/cases/{case_id}/packets", + "function": "packet", + "line": 131 + }, + { + "method": "GET", + "declared_path": "/packets/{packet_id}", + "function": "document", + "line": 136 + }, + { + "method": "POST", + "declared_path": "/pathway", + "function": "pathway", + "line": 149 + }, + { + "method": "POST", + "declared_path": "/connections/search", + "function": "connections", + "line": 199 } ], "models": [ @@ -35683,16 +33749,15 @@ { "name": "bundle", "type": "RequirementBundle", - "default": "" + "line": 80 }, { "name": "expected_revision", "type": "UUID | None", - "default": "None" + "line": 81 } ], - "line": 79, - "doc": "" + "line": 79 }, { "name": "Packet", @@ -35703,16 +33768,15 @@ { "name": "expected_revision", "type": "UUID", - "default": "" + "line": 126 }, { "name": "visibility", "type": "Literal['staff_only', 'records_copy']", - "default": "" + "line": 127 } ], - "line": 125, - "doc": "" + "line": 125 }, { "name": "Pathway", @@ -35723,31 +33787,30 @@ { "name": "project_type", "type": "str", - "default": "Field(min_length=1, max_length=120)" + "line": 141 }, { "name": "proposal", "type": "str", - "default": "Field(default='', max_length=4000)" + "line": 142 }, { "name": "location_context", "type": "str", - "default": "Field(default='', max_length=1000)" + "line": 143 }, { "name": "requirement_revision", "type": "UUID | None", - "default": "None" + "line": 144 }, { "name": "fee_link", "type": "SourceLink | None", - "default": "None" + "line": 145 } ], - "line": 140, - "doc": "" + "line": 140 }, { "name": "Search", @@ -35758,2683 +33821,1653 @@ { "name": "provider", "type": "Literal['code', 'zoning']", - "default": "" + "line": 194 }, { "name": "query", "type": "str", - "default": "Field(min_length=1, max_length=500)" + "line": 195 } ], - "line": 193, - "doc": "" + "line": 193 } ], "configuration": [] - } - ] - }, - "inspections": { - "package": "townlight_inspections", - "source": [ - { - "source": "installed-owned-source/townlight_inspections/__init__.py", - "sha256": "eff685acecf3985653f811403aaabc6862d52ce7e343c38aa5242f40d4266c47", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_inspections/_whistle_driver.py", - "sha256": "90ce9276c7d1de4d3259a2c00ff581e5d55d28dd8da913ed7b8bd2d7c89a5264", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_inspections/adapters.py", - "sha256": "ab76d8c1a8b57167acf759390b49a3941f04b4483a606be2abbae69f4f8165db", - "routes": [], - "models": [], - "configuration": [] }, { - "source": "installed-owned-source/townlight_inspections/case_lookup.py", - "sha256": "b68030ecdf6a7f83ed35aec636afcb70c5ce247a40ed7d60a3283655bfdb3214", - "routes": [], - "models": [ + "source": "desktop/runtime/python-services/townlight_runtime/planning_bridge.py", + "sha256": "9722286324a54d1dd831ae2f978c8337450b98bd90dee74fe15ff8cbd771992c", + "bytes": 14570, + "routes": [ { - "name": "RepeatCaseResult", - "bases": [], - "fields": [ - { - "name": "property_reference", - "type": "str", - "default": "" - }, - { - "name": "violation_type", - "type": "str", - "default": "" - }, - { - "name": "repeat_case_count", - "type": "int", - "default": "" - }, - { - "name": "related_case_ids", - "type": "tuple[str, ...]", - "default": "" - }, - { - "name": "staff_note", - "type": "str", - "default": "" - }, - { - "name": "disclaimer", - "type": "str", - "default": "DISCLAIMER" - } - ], - "line": 15, - "doc": "" - } - ], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_inspections/connections.py", - "sha256": "82221673e19e1bd48215cfc9dbeab837070cd9a6bdd3f3cf57cf3034f3ac3bef", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_inspections/integration_mocks.py", - "sha256": "dfc700d977badb104db5abddded3120b1bff99445a6bbf18f7a6925c9087c797", - "routes": [], - "models": [ + "method": "POST", + "declared_path": "/imports/preview", + "function": "preview_import", + "line": 80 + }, { - "name": "IntegrationMockResult", - "bases": [], - "fields": [ - { - "name": "scenario", - "type": "str", - "default": "" - }, - { - "name": "status", - "type": "str", - "default": "" - }, - { - "name": "review_required", - "type": "bool", - "default": "" - }, - { - "name": "findings", - "type": "tuple[str, ...]", - "default": "" - }, - { - "name": "boundary", - "type": "str", - "default": "" - } - ], - "line": 10, - "doc": "" - } - ], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_inspections/main.py", - "sha256": "16306b47d0e6e526176c050b2eb2edb6a047edea3bb5f313df48c026a81cc53e", - "routes": [ + "method": "POST", + "declared_path": "/imports", + "function": "import_source", + "line": 89 + }, + { + "method": "GET", + "declared_path": "/sources", + "function": "source_list", + "line": 98 + }, + { + "method": "GET", + "declared_path": "/sources/{plan_id}/history", + "function": "source_history", + "line": 104 + }, + { + "method": "GET", + "declared_path": "/revisions/{revision_id}", + "function": "revision", + "line": 109 + }, + { + "method": "GET", + "declared_path": "/revisions/{revision_id}/documents/{document_id}", + "function": "staff_original", + "line": 127 + }, + { + "method": "POST", + "declared_path": "/policies/search", + "function": "policies", + "line": 137 + }, + { + "method": "GET", + "declared_path": "/analyses", + "function": "analyses", + "line": 142 + }, + { + "method": "POST", + "declared_path": "/analyses", + "function": "create_analysis", + "line": 155 + }, + { + "method": "POST", + "declared_path": "/analyses/{analysis_id}/revisions", + "function": "revise_analysis", + "line": 165 + }, + { + "method": "GET", + "declared_path": "/analyses/{analysis_id}", + "function": "analysis", + "line": 175 + }, + { + "method": "GET", + "declared_path": "/analyses/{analysis_id}/history", + "function": "analysis_history", + "line": 180 + }, + { + "method": "POST", + "declared_path": "/analyses/{analysis_id}/snapshot-preview", + "function": "preview_snapshot", + "line": 190 + }, + { + "method": "POST", + "declared_path": "/analyses/{analysis_id}/snapshots", + "function": "snapshot", + "line": 195 + }, + { + "method": "GET", + "declared_path": "/snapshots", + "function": "snapshots", + "line": 200 + }, + { + "method": "GET", + "declared_path": "/snapshots/{snapshot_id}", + "function": "document", + "line": 206 + }, + { + "method": "POST", + "declared_path": "/snapshots/{snapshot_id}/access-advice", + "function": "access_advice", + "line": 211 + }, + { + "method": "POST", + "declared_path": "/connections/search", + "function": "connections", + "line": 221 + }, + { + "method": "POST", + "declared_path": "/policies/search", + "function": "public_policies", + "line": 226 + }, + { + "method": "POST", + "declared_path": "/plan-explore", + "function": "public_plan_explore", + "line": 238 + }, + { + "method": "GET", + "declared_path": "/snapshots", + "function": "public_snapshots", + "line": 254 + }, + { + "method": "GET", + "declared_path": "/snapshots/{snapshot_id}", + "function": "public_document", + "line": 260 + }, + { + "method": "GET", + "declared_path": "/revisions/{revision_id}/documents/{document_id}", + "function": "public_original", + "line": 265 + }, + { + "method": "GET", + "declared_path": "/progress/targets", + "function": "municipal_progress", + "line": 270 + }, + { + "method": "GET", + "declared_path": "/amendments/history", + "function": "municipal_amendments", + "line": 275 + }, + { + "method": "GET", + "declared_path": "/municipal-work/{item_id}/history", + "function": "municipal_history", + "line": 280 + }, + { + "method": "POST", + "declared_path": "/initiatives", + "function": "create_initiative", + "line": 285 + }, { - "method": "GET", - "path": "/", - "router": "app", - "prefix_resolved": true, - "name": "root", - "signature": "", - "returns": "dict[str, str]", - "line": 130, - "doc": "Return current product state without overstating unshipped behavior.", - "decorator": "app.get('/')", - "errors": [] - }, - { - "method": "GET", - "path": "/health", - "router": "app", - "prefix_resolved": true, - "name": "health", - "signature": "", - "returns": "dict[str, str]", - "line": 150, - "doc": "Return dependency/version health for deployment smoke checks.", - "decorator": "app.get('/health')", - "errors": [] - }, - { - "method": "GET", - "path": "/townlight_inspections", - "router": "app", - "prefix_resolved": true, - "name": "public_townlight_inspections_page", - "signature": "", - "returns": "str", - "line": 162, - "doc": "Return the public sample inspection support UI.", - "decorator": "app.get('/townlight_inspections', response_class=HTMLResponse)", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_inspections/cases/repeat-lookup", - "router": "app", - "prefix_resolved": true, - "name": "repeat_case_lookup", - "signature": "request: RepeatCaseLookupRequest", - "returns": "dict[str, object]", - "line": 169, - "doc": "", - "decorator": "app.post('/api/v1/townlight_inspections/cases/repeat-lookup')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_inspections/reports/draft", - "router": "app", - "prefix_resolved": true, - "name": "inspection_report_draft", - "signature": "request: ReportDraftRequest", - "returns": "dict[str, object]", - "line": 178, - "doc": "", - "decorator": "app.post('/api/v1/townlight_inspections/reports/draft')", - "errors": [] - }, - { - "method": "GET", - "path": "/api/v1/townlight_inspections/reports/{report_id}", - "router": "app", - "prefix_resolved": true, - "name": "get_inspection_report", - "signature": "report_id: str", - "returns": "dict[str, object]", - "line": 215, - "doc": "", - "decorator": "app.get('/api/v1/townlight_inspections/reports/{report_id}')", - "errors": [ - "HTTPException(status_code=503, detail={'message': 'Townlight Inspections case persistence is not configured.', 'fix': 'Set TOWNLIGHT_INSPECTIONS_CASE_DB_URL to retrieve persisted inspection report records.'})", - "HTTPException(status_code=404, detail={'message': 'Inspection report record not found.', 'fix': 'Use a report_id returned by POST /api/v1/townlight_inspections/reports/draft.'})" - ] - }, - { - "method": "POST", - "path": "/api/v1/townlight_inspections/evidence/retain", - "router": "app", - "prefix_resolved": true, - "name": "retain_evidence_route", - "signature": "request: EvidenceRetainRequest", - "returns": "dict[str, object]", - "line": 291, - "doc": "Retain original evidence bytes (photos, documents and raw audio) with hashes.", - "decorator": "app.post('/api/v1/townlight_inspections/evidence/retain')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_inspections/media/analyse", - "router": "app", - "prefix_resolved": true, - "name": "media_analyse", - "signature": "request: MediaAnalysisRequest", - "returns": "dict[str, object]", - "line": 307, - "doc": "Draft-only analysis of retained media; inspector review always required.", - "decorator": "app.post('/api/v1/townlight_inspections/media/analyse')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_inspections/notices/draft", - "router": "app", - "prefix_resolved": true, - "name": "notice_draft", - "signature": "request: NoticeDraftRequest", - "returns": "dict[str, object]", - "line": 325, - "doc": "", - "decorator": "app.post('/api/v1/townlight_inspections/notices/draft')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_inspections/context/inspection-review", - "router": "app", - "prefix_resolved": true, - "name": "inspection_review_context", - "signature": "request: InspectionContextRequest", - "returns": "dict[str, object]", - "line": 336, - "doc": "", - "decorator": "app.post('/api/v1/townlight_inspections/context/inspection-review')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_inspections/integrations/mock/inspection-context", - "router": "app", - "prefix_resolved": true, - "name": "integration_mock_inspection_context", - "signature": "request: IntegrationMockRequest", - "returns": "dict[str, object]", - "line": 365, - "doc": "", - "decorator": "app.post('/api/v1/townlight_inspections/integrations/mock/inspection-context')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_inspections/export", - "router": "app", - "prefix_resolved": true, - "name": "inspection_export", - "signature": "request: InspectionExportRequest", - "returns": "dict[str, object]", - "line": 377, - "doc": "", - "decorator": "app.post('/api/v1/townlight_inspections/export')", - "errors": [] - }, - { - "method": "POST", - "path": "/api/v1/townlight_inspections/staff/reviews", - "router": "app", - "prefix_resolved": true, - "name": "create_staff_review", - "signature": "request: StaffReviewCreateRequest, _staff_principal: object=Depends(_require_staff_key)", - "returns": "dict[str, object]", - "line": 387, - "doc": "", - "decorator": "app.post('/api/v1/townlight_inspections/staff/reviews')", - "errors": [] - }, - { - "method": "GET", - "path": "/api/v1/townlight_inspections/staff/reviews", - "router": "app", - "prefix_resolved": true, - "name": "list_staff_reviews", - "signature": "status: str | None=None, _staff_principal: object=Depends(_require_staff_key)", - "returns": "dict[str, object]", - "line": 403, - "doc": "", - "decorator": "app.get('/api/v1/townlight_inspections/staff/reviews')", - "errors": [] + "method": "POST", + "declared_path": "/initiatives/{item_id}/revisions", + "function": "update_initiative", + "line": 290 }, { - "method": "PATCH", - "path": "/api/v1/townlight_inspections/staff/reviews/{review_id}", - "router": "app", - "prefix_resolved": true, - "name": "update_staff_review", - "signature": "review_id: str, request: StaffReviewUpdateRequest, _staff_principal: object=Depends(_require_staff_key)", - "returns": "dict[str, object]", - "line": 418, - "doc": "", - "decorator": "app.patch('/api/v1/townlight_inspections/staff/reviews/{review_id}')", - "errors": [ - "HTTPException(status_code=404, detail={'message': 'Townlight Inspections staff review item was not found.', 'fix': 'List staff reviews and retry with an existing review_id.'})", - "HTTPException(status_code=422, detail={'message': 'Staff review update is invalid.', 'fix': str(exc)})" - ] - }, - { - "method": "GET", - "path": "/api/v1/townlight_inspections/staff/reviews/summary", - "router": "app", - "prefix_resolved": true, - "name": "staff_review_summary", - "signature": "_staff_principal: object=Depends(_require_staff_key)", - "returns": "dict[str, object]", - "line": 448, - "doc": "", - "decorator": "app.get('/api/v1/townlight_inspections/staff/reviews/summary')", - "errors": [] + "method": "POST", + "declared_path": "/amendments", + "function": "create_amendment", + "line": 295 + }, + { + "method": "POST", + "declared_path": "/amendments/{item_id}/revisions", + "function": "update_amendment", + "line": 300 } ], "models": [ { - "name": "RepeatCaseLookupRequest", + "name": "Import", "bases": [ - "BaseModel" + "BundleModel" ], "fields": [ { - "name": "property_reference", - "type": "str", - "default": "" + "name": "bundle", + "type": "dict", + "line": 75 }, { - "name": "violation_type", - "type": "str", - "default": "''" + "name": "expected_previous_revision", + "type": "str | None", + "line": 76 } ], - "line": 50, - "doc": "" + "line": 74 }, { - "name": "ReportDraftRequest", + "name": "Search", "bases": [ - "BaseModel" + "BundleModel" ], "fields": [ { - "name": "inspection_id", - "type": "str", - "default": "" - }, - { - "name": "property_reference", - "type": "str", - "default": "" - }, - { - "name": "inspector_notes", - "type": "str", - "default": "" - }, - { - "name": "photo_observations", - "type": "list[str]", - "default": "[]" - }, - { - "name": "voice_notes", + "name": "query", "type": "str", - "default": "''" + "line": 132 }, { - "name": "analysis", - "type": "AnalysisRecord | None", - "default": "None" + "name": "plan_type", + "type": "str | None", + "line": 133 } ], - "line": 55, - "doc": "" + "line": 131 }, { - "name": "NoticeDraftRequest", + "name": "Snapshot", "bases": [ - "BaseModel" + "BundleModel" ], "fields": [ { - "name": "case_id", - "type": "str", - "default": "" - }, - { - "name": "property_reference", - "type": "str", - "default": "" - }, - { - "name": "violation_type", - "type": "str", - "default": "" + "name": "expected_revision", + "type": "UUID", + "line": 185 }, { - "name": "observations", - "type": "list[str]", - "default": "" + "name": "visibility", + "type": "Literal['staff_only', 'public']", + "line": 186 } ], - "line": 64, - "doc": "" + "line": 184 }, { - "name": "InspectionExportRequest", + "name": "ConnectionSearch", "bases": [ - "BaseModel" + "BundleModel" ], "fields": [ { - "name": "title", - "type": "str", - "default": "" - }, - { - "name": "case_id", - "type": "str", - "default": "" + "name": "provider", + "type": "Literal['meetings', 'zoning']", + "line": 216 }, { - "name": "format", + "name": "query", "type": "str", - "default": "'markdown'" + "line": 217 } ], - "line": 71, - "doc": "" + "line": 215 }, { - "name": "InspectionContextRequest", + "name": "PublicExplore", "bases": [ - "BaseModel" + "BundleModel" ], "fields": [ { - "name": "inspection_id", - "type": "str", - "default": "" - }, - { - "name": "property_reference", - "type": "str", - "default": "" - }, - { - "name": "violation_type", + "name": "goal", "type": "str", - "default": "" + "line": 231 }, { - "name": "code_context_id", + "name": "topic", "type": "str", - "default": "''" + "line": 232 }, { - "name": "case_context_id", + "name": "neighborhood", "type": "str", - "default": "''" + "line": 233 }, { - "name": "source_date_status", + "name": "plan_type", "type": "str", - "default": "'current'" + "line": 234 } ], - "line": 77, - "doc": "" - }, + "line": 230 + } + ], + "configuration": [] + }, + { + "source": "desktop/runtime/python-services/townlight_runtime/planning_connections.py", + "sha256": "116b2e0cf1d1acaba1d5135f746a91e283cbd5fb238631379a4672496d96ae77", + "bytes": 2494, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/runtime/python-services/townlight_runtime/records_cutover.py", + "sha256": "e0c2f9b4ef95e913c8c096bf5bc472bde66ff1eab1d1775026e8923f900675e0", + "bytes": 4650, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/runtime/python-services/townlight_runtime/records_demo.py", + "sha256": "fe5d902ba81e6c55bcce095ce7eb13071254c028c2dd730393a7cce10c6a7263", + "bytes": 7341, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/runtime/python-services/townlight_runtime/records_import.py", + "sha256": "7baa9f06e3d046711b4111bb2ba28e89adcaed156bd896ec3caeab03feb2622e", + "bytes": 8613, + "routes": [], + "models": [ { - "name": "IntegrationMockRequest", - "bases": [ - "BaseModel" - ], + "name": "ImportPreflight", + "bases": [], "fields": [ { - "name": "scenario", - "type": "str", - "default": "'inspection-context'" - }, - { - "name": "role", - "type": "str", - "default": "'staff'" + "name": "source_path", + "type": "Path", + "line": 30 }, { - "name": "code_context_id", - "type": "str", - "default": "''" + "name": "source_bytes", + "type": "bytes", + "line": 31 }, { - "name": "case_context_id", + "name": "source_sha256", "type": "str", - "default": "''" + "line": 32 }, { - "name": "official_finding", - "type": "bool", - "default": "False" + "name": "original", + "type": "dict", + "line": 33 }, { - "name": "citation_issued", - "type": "bool", - "default": "False" + "name": "records", + "type": "tuple[RecordsView, ...]", + "line": 34 }, { - "name": "fine_amount", - "type": "str | None", - "default": "None" + "name": "verified_files", + "type": "tuple[tuple[str, str, int], ...]", + "line": 35 }, { - "name": "photo_analysis_source", + "name": "legacy_audit_head", "type": "str", - "default": "'inspector_observation'" + "line": 36 }, { - "name": "source_date_status", - "type": "str", - "default": "'current'" + "name": "unhashed_audit_entries", + "type": "int", + "line": 37 } ], - "line": 86, - "doc": "" - }, + "line": 29 + } + ], + "configuration": [] + }, + { + "source": "desktop/runtime/python-services/townlight_runtime/records_import_access.py", + "sha256": "51ccf503c5901e60d836a657972539a880e723285482821d418065053addf8fa", + "bytes": 3191, + "routes": [], + "models": [ { - "name": "EvidenceItemRequest", + "name": "Finding", "bases": [ "BaseModel" ], "fields": [ { - "name": "filename", - "type": "str", - "default": "" - }, - { - "name": "media_type", - "type": "str", - "default": "" - }, - { - "name": "description", - "type": "str", - "default": "''" - }, - { - "name": "content_base64", + "name": "code", "type": "str", - "default": "" + "line": 12 }, { - "name": "sha256", + "name": "severity", "type": "str", - "default": "" - } - ], - "line": 98, - "doc": "" - }, - { - "name": "EvidenceRetainRequest", - "bases": [ - "BaseModel" - ], - "fields": [ - { - "name": "items", - "type": "list[EvidenceItemRequest]", - "default": "" - } - ], - "line": 106, - "doc": "" - }, - { - "name": "MediaAnalysisRequest", - "bases": [ - "BaseModel" - ], - "fields": [ - { - "name": "items", - "type": "list[EvidenceItemRequest]", - "default": "" - }, - { - "name": "code_links", - "type": "list[dict[str, str]]", - "default": "[]" + "line": 13 }, { - "name": "inspector_supplied_text", - "type": "str", - "default": "''" - } - ], - "line": 110, - "doc": "" - }, - { - "name": "StaffReviewCreateRequest", - "bases": [ - "BaseModel" - ], - "fields": [ - { - "name": "inspection_id", + "name": "message", "type": "str", - "default": "" + "line": 14 }, { - "name": "property_reference", + "name": "fix", "type": "str", - "default": "" + "line": 15 }, { - "name": "reason", + "name": "wcag_reference", "type": "str", - "default": "" - }, - { - "name": "report_id", - "type": "str | None", - "default": "None" + "line": 16 } ], - "line": 116, - "doc": "" + "line": 10 }, { - "name": "StaffReviewUpdateRequest", + "name": "Review", "bases": [ "BaseModel" ], "fields": [ { - "name": "status", + "name": "review_id", "type": "str", - "default": "" + "line": 21 }, { - "name": "assigned_to", - "type": "str | None", - "default": "None" - }, - { - "name": "resolution", - "type": "str | None", - "default": "None" - } - ], - "line": 123, - "doc": "" - } - ], - "configuration": [ - { - "variable": "TOWNLIGHT_INSPECTIONS_CASE_DB_URL", - "default": "", - "line": 456 - } - ] - }, - { - "source": "installed-owned-source/townlight_inspections/media_analysis.py", - "sha256": "be51101ee98596bca3055f99136531e3a76e28f2dc584148cf26098d75a94c5a", - "routes": [], - "models": [ - { - "name": "RetainedEvidence", - "bases": [], - "fields": [ + "name": "title", + "type": "str", + "line": 22 + }, { - "name": "filename", + "name": "body", "type": "str", - "default": "" + "line": 23 }, { - "name": "media_type", + "name": "has_alt_text", + "type": "bool", + "line": 24 + }, + { + "name": "language", "type": "str", - "default": "" + "line": 25 }, { - "name": "description", + "name": "status", "type": "str", - "default": "" + "line": 26 }, { - "name": "size_bytes", - "type": "int", - "default": "" + "name": "findings", + "type": "list[Finding]", + "line": 27 }, { - "name": "sha256", + "name": "disclaimer", "type": "str", - "default": "" + "line": 28 }, { - "name": "raw", - "type": "bytes", - "default": "field(repr=False)" - } - ], - "line": 55, - "doc": "Original evidence bytes with their verified digest and provenance." - }, - { - "name": "VisionProvider", - "bases": [ - "Protocol" - ], - "fields": [ + "name": "ai_analysis", + "type": "str | None", + "line": 29 + }, { - "name": "name", - "type": "str", - "default": "" + "name": "ai_analysis_model", + "type": "str | None", + "line": 30 }, { - "name": "supports_images", - "type": "bool", - "default": "" + "name": "created_at_unix_seconds", + "type": "int", + "line": 31 } ], - "line": 110, - "doc": "The owned townlight_core provider shape (multimodal generate)." + "line": 19 }, { - "name": "TranscriptionProvider", + "name": "Event", "bases": [ - "Protocol" + "BaseModel" ], "fields": [ { - "name": "name", + "name": "event_id", "type": "str", - "default": "" - } - ], - "line": 121, - "doc": "Adapter that turns retained audio bytes into text." - }, - { - "name": "MediaAnalysis", - "bases": [], - "fields": [ - { - "name": "draft_observations", - "type": "list[dict[str, Any]]", - "default": "field(default_factory=list)" - }, - { - "name": "cited_sections", - "type": "list[dict[str, str]]", - "default": "field(default_factory=list)" - }, - { - "name": "unavailable", - "type": "list[dict[str, str]]", - "default": "field(default_factory=list)" + "line": 36 }, { - "name": "retained", - "type": "list[dict[str, Any]]", - "default": "field(default_factory=list)" + "name": "action", + "type": "str", + "line": 37 }, { - "name": "runtime", - "type": "dict[str, Any]", - "default": "field(default_factory=dict)" + "name": "subject_id", + "type": "str | None", + "line": 38 }, { - "name": "review_required", - "type": "bool", - "default": "True" + "name": "actor", + "type": "str", + "line": 39 }, { - "name": "determination_made", - "type": "bool", - "default": "False" - }, + "name": "created_at_unix_seconds", + "type": "int", + "line": 40 + } + ], + "line": 34 + } + ], + "configuration": [] + }, + { + "source": "desktop/runtime/python-services/townlight_runtime/records_import_store.py", + "sha256": "e5f116e7620d86cca0b46f37561dd7b1f714c83178be681f51bd6a9db942edcd", + "bytes": 16872, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/runtime/python-services/townlight_runtime/records_snapshot.py", + "sha256": "aa5bb7ee752f961c1cda5f5ebd1001d0fe603bdf3fa39857a7f28363ef8bb87d", + "bytes": 7220, + "routes": [ + { + "method": "GET", + "declared_path": "/state", + "function": "suite_state", + "line": 67 + }, + { + "method": "POST", + "declared_path": "/search", + "function": "search", + "line": 85 + } + ], + "models": [ + { + "name": "SearchInput", + "bases": [ + "BaseModel" + ], + "fields": [ { - "name": "boundary", + "name": "query", "type": "str", - "default": "BOUNDARY" + "line": 73 } ], - "line": 139, - "doc": "Result of a draft-only analysis pass." + "line": 71 + } + ], + "configuration": [] + }, + { + "source": "desktop/runtime/python-services/townlight_runtime/services.py", + "sha256": "c2839cde26f3bd8937d492c33129b6709898c3213a8f57416710c2e8253e10bf", + "bytes": 23688, + "routes": [ + { + "method": "GET", + "declared_path": "/health", + "function": "runtime_health", + "line": 443 + }, + { + "method": "GET", + "declared_path": "/modules", + "function": "runtime_health", + "line": 443 + }, + { + "method": "GET", + "declared_path": "/ready", + "function": "domain_ready", + "line": 448 } ], + "models": [], + "configuration": [ + { + "environment": "TOWNLIGHT_PROFILE_ROOT", + "line": 56 + }, + { + "environment": "TOWNLIGHT_DATA_DIR", + "line": 61 + }, + { + "environment": "LOCALAPPDATA", + "line": 64 + }, + { + "environment": "JWT_SECRET_FILE", + "line": 92 + }, + { + "environment": "FIRST_ADMIN_PASSWORD_FILE", + "line": 93 + }, + { + "environment": "ENCRYPTION_KEY", + "line": 94 + }, + { + "environment": "PORTAL_MODE", + "line": 99 + }, + { + "environment": "OLLAMA_BASE_URL", + "line": 100 + }, + { + "environment": "TOWNLIGHT_MEETINGS_OLLAMA_BASE_URL", + "line": 101 + }, + { + "environment": "TOWNLIGHT_CORE_LLM_PROVIDER", + "line": 102 + }, + { + "environment": "DATABASE_URL", + "line": 103 + }, + { + "environment": "DATABASE_URL", + "line": 148 + }, + { + "environment": "TOWNLIGHT_RUNTIME_HOST", + "line": 483 + }, + { + "environment": "TESTING", + "line": 113 + }, + { + "environment": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", + "line": 242 + }, + { + "environment": "DATABASE_URL", + "line": 302 + }, + { + "environment": "TOWNLIGHT_RUNTIME_PORT", + "line": 486 + } + ] + }, + { + "source": "desktop/runtime/python-services/townlight_runtime/storage.py", + "sha256": "d5c7aaa30c2b781ef9869de8cf9414e11ddfc855824439ba8d292bfb1fd1b9c3", + "bytes": 1016, + "routes": [], + "models": [], + "configuration": [ + { + "environment": "TOWNLIGHT_FILE_STORAGE_DIR", + "line": 12 + }, + { + "environment": "TOWNLIGHT_DATA_DIR", + "line": 15 + } + ] + }, + { + "source": "desktop/runtime/python-services/townlight_runtime/townlight_records_alembic/alembic/env.py", + "sha256": "8928b9156c23c2d63337d21c908784f87077cb515c758d3ccf0d6f88ac07ce45", + "bytes": 2922, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/runtime/python-services/townlight_runtime/townlight_records_alembic/alembic/versions/001_initial.py", + "sha256": "cac7c6704232487a16a7443e45ccaa18a28bbd9d5b2bec975ef57c39d5165381", + "bytes": 4352, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/runtime/python-services/townlight_runtime/townlight_records_alembic/alembic/versions/002_documents.py", + "sha256": "21474b7be697e152f256622a5396aa19b8defe67614aa1decaf9b1809aea496f", + "bytes": 3862, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/runtime/python-services/townlight_runtime/townlight_records_alembic/alembic/versions/003_model_registry.py", + "sha256": "a4a1bf77d4e82f8b4ea763d5e65ef5ba6286c906a4e8f02b38b604ed1a442e2a", + "bytes": 1223, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/runtime/python-services/townlight_runtime/townlight_records_alembic/alembic/versions/004_search.py", + "sha256": "ee9a39dcb25fbcdf16de136673655bd01c71b107cca27c41dacf8879a7fad948", + "bytes": 3541, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/runtime/python-services/townlight_runtime/townlight_records_alembic/alembic/versions/005_requests.py", + "sha256": "0a55883877cd95959d495b8865efec727f18b8bbb86bf8269a938d876e575e55", + "bytes": 3782, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/runtime/python-services/townlight_runtime/townlight_records_alembic/alembic/versions/006_exemptions.py", + "sha256": "c2935f1b3fa8771375a78fe065bb5274721a87c1650efb0146be4091ee475675", + "bytes": 3843, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/runtime/python-services/townlight_runtime/townlight_records_alembic/alembic/versions/008_extend_request_status_enum.py", + "sha256": "b98949215e447bbef20643a34445f21018e9c1719c78634dca1485740911c3f4", + "bytes": 1156, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/runtime/python-services/townlight_runtime/townlight_records_alembic/alembic/versions/009_fee_waivers.py", + "sha256": "3374202e15d16b5e1f64679bd6720c27ed2ebe63993c045bf75e6cc68b8fadb8", + "bytes": 1446, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/runtime/python-services/townlight_runtime/townlight_records_alembic/alembic/versions/010_remove_sent_status.py", + "sha256": "45aca2a0b308c0b3e519f087711e6229ff92edc5bedf538e8572c433245336c7", + "bytes": 4012, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/runtime/python-services/townlight_runtime/townlight_records_alembic/alembic/versions/011_fix_schema_drift.py", + "sha256": "a152698912070e923c7909ed98105bb29a739222b4cd5695e26e95351cf8d698", + "bytes": 4011, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/runtime/python-services/townlight_runtime/townlight_records_alembic/alembic/versions/012_add_liaison_public_roles.py", + "sha256": "f5823d9a088125f055f6e6c2c5577a94002a899836b03e8a3f54adec50826879", + "bytes": 2217, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/runtime/python-services/townlight_runtime/townlight_records_alembic/alembic/versions/013_add_connector_types.py", + "sha256": "234267eca383c478fa62403d7c34f93c0c2d721c557f40442febcb087da5baa0", + "bytes": 1524, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/runtime/python-services/townlight_runtime/townlight_records_alembic/alembic/versions/014_p6a_idempotency.py", + "sha256": "3f6d96173809739a5990f53f855b63f169419810f6d68fffb28d5ab240cb1282", + "bytes": 3476, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/runtime/python-services/townlight_runtime/townlight_records_alembic/alembic/versions/015_p6b_scheduler.py", + "sha256": "92c3929d3b951b22bd65d67e41409b07b19420dbe87442e45cabeeffd6fba945", + "bytes": 7272, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/runtime/python-services/townlight_runtime/townlight_records_alembic/alembic/versions/016_p7_sync_failures.py", + "sha256": "99344bf472ac7fc854aeb78ae8bb9687543d20d65d1c097947f8a89aff543339", + "bytes": 3955, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/runtime/python-services/townlight_runtime/townlight_records_alembic/alembic/versions/017_rename_connector_enum_values.py", + "sha256": "0d419b2ee2d571a96a947f700c73bfee07561cffa55ebb62d12aaaf3148522cc", + "bytes": 2053, + "routes": [], + "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_inspections/migrations/__init__.py", - "sha256": "e18fc02330135cd7d0dd678a3e17f9e81966a9e187c3ed0ec002439fa8d3bbb1", + "source": "desktop/runtime/python-services/townlight_runtime/townlight_records_alembic/alembic/versions/018_city_profile_state_nullable.py", + "sha256": "5b78e57ccd12ecb2c322f144403cea522e802d9ee8abd9459c70deac06c53b8f", + "bytes": 2068, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_inspections/migrations/env.py", - "sha256": "9612897b28e02e86d1fa5b9ed48d951b76bb5a87151112d0c1cdbe10a0d343e3", + "source": "desktop/runtime/python-services/townlight_runtime/townlight_records_alembic/alembic/versions/019_encrypt_connection_config.py", + "sha256": "7665ba8bc10db28244384d8cdcf55162907e9657a75899464b037e075802f8a9", + "bytes": 5735, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_inspections/migrations/versions/townlight_inspections_0001_connected.py", - "sha256": "0e71ed311993f45634eb42ba22f5c2b2c4a3854639b221857af76f826d1b68de", + "source": "desktop/runtime/python-services/townlight_runtime/townlight_records_alembic/alembic/versions/020_phase2_consumer_app_backfill.py", + "sha256": "2376c670acb4bf7ae9fb4a6e323641c5e59231c413262b2c6e6b4c1a6c0e287c", + "bytes": 2601, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_inspections/notice_draft.py", - "sha256": "ef44c7d6bcf131bc703f6d0282510fe8a49cc6b5988f6252d01353e15551a2f6", + "source": "desktop/runtime/python-services/townlight_runtime/townlight_records_alembic/alembic/versions/021_first_admin_password_rotation.py", + "sha256": "365d7fdfe5d733077649d00fe6983fdefd0dc2d9fc078b9cea0753d0d5f734e7", + "bytes": 796, "routes": [], - "models": [ - { - "name": "NoticeDraft", - "bases": [], - "fields": [ - { - "name": "case_id", - "type": "str", - "default": "" - }, - { - "name": "property_reference", - "type": "str", - "default": "" - }, - { - "name": "heading", - "type": "str", - "default": "" - }, - { - "name": "draft_body", - "type": "str", - "default": "" - }, - { - "name": "required_staff_actions", - "type": "tuple[str, ...]", - "default": "" - }, - { - "name": "disclaimer", - "type": "str", - "default": "DISCLAIMER" - } - ], - "line": 11, - "doc": "" - } - ], + "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_inspections/persistence.py", - "sha256": "a4c75976a7fe2cc25d2c9a9074eee1a2870eb47bcf6890564d2fb31b113579e3", + "source": "desktop/runtime/python-services/townlight_runtime/townlight_records_alembic/alembic/versions/022_native_records_mapping.py", + "sha256": "1ae8180ca83c5863c1718274e5435fe1419ec48a4737ccf2434f531a4f2fd7b8", + "bytes": 4271, "routes": [], - "models": [ - { - "name": "StoredInspectionReport", - "bases": [], - "fields": [ - { - "name": "report_id", - "type": "str", - "default": "" - }, - { - "name": "inspection_id", - "type": "str", - "default": "" - }, - { - "name": "property_reference", - "type": "str", - "default": "" - }, - { - "name": "summary", - "type": "str", - "default": "" - }, - { - "name": "observation_bullets", - "type": "tuple[str, ...]", - "default": "" - }, - { - "name": "inspector_review_required", - "type": "bool", - "default": "" - }, - { - "name": "disclaimer", - "type": "str", - "default": "" - }, - { - "name": "created_at", - "type": "datetime", - "default": "" - } - ], - "line": 70, - "doc": "" - }, - { - "name": "StaffReviewQueueItem", - "bases": [], - "fields": [ - { - "name": "review_id", - "type": "str", - "default": "" - }, - { - "name": "report_id", - "type": "str | None", - "default": "" - }, - { - "name": "inspection_id", - "type": "str", - "default": "" - }, - { - "name": "property_reference", - "type": "str", - "default": "" - }, - { - "name": "status", - "type": "str", - "default": "" - }, - { - "name": "reason", - "type": "str", - "default": "" - }, - { - "name": "assigned_to", - "type": "str | None", - "default": "" - }, - { - "name": "resolution", - "type": "str | None", - "default": "" - }, - { - "name": "created_by", - "type": "str", - "default": "" - }, - { - "name": "created_at", - "type": "datetime", - "default": "" - }, - { - "name": "updated_at", - "type": "datetime", - "default": "" - }, - { - "name": "visibility", - "type": "str", - "default": "'staff_only'" - } - ], - "line": 82, - "doc": "" - }, - { - "name": "StaffReviewSummary", - "bases": [], - "fields": [ - { - "name": "total_items", - "type": "int", - "default": "" - }, - { - "name": "by_status", - "type": "dict[str, int]", - "default": "" - }, - { - "name": "open_items", - "type": "int", - "default": "" - }, - { - "name": "generated_at", - "type": "datetime", - "default": "" - }, - { - "name": "visibility", - "type": "str", - "default": "'staff_only'" - } - ], - "line": 98, - "doc": "" - } - ], + "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_inspections/public_ui.py", - "sha256": "c14bd5b3d45dc1434edeffb931cd6abb8804bff675989769c8eb89c85a46f965", + "source": "desktop/runtime/python-services/townlight_runtime/townlight_records_alembic/alembic/versions/023_native_records_lifecycle.py", + "sha256": "00633480cbda11121fc6f98aa10b978ca24213a3626ddd4106c1aa5f660e599e", + "bytes": 6067, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_inspections/records_export.py", - "sha256": "6adcb9a04cbff7d9d455f41598a0bdb1dfd736aa13f439a61f1e2ed98f8b49bb", + "source": "desktop/runtime/python-services/townlight_runtime/townlight_records_alembic/alembic/versions/024_records_file_evidence.py", + "sha256": "09c48872ab8e378d709542e20f8495cb1857146b78238e73de570a21151f2fcf", + "bytes": 2553, "routes": [], - "models": [ - { - "name": "InspectionExport", - "bases": [], - "fields": [ - { - "name": "title", - "type": "str", - "default": "" - }, - { - "name": "case_id", - "type": "str", - "default": "" - }, - { - "name": "format", - "type": "str", - "default": "" - }, - { - "name": "checklist", - "type": "tuple[str, ...]", - "default": "" - }, - { - "name": "retention_note", - "type": "str", - "default": "" - } - ], - "line": 9, - "doc": "" - } - ], + "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_inspections/report_draft.py", - "sha256": "40faeb3103ac9ba5ae45fd74136d5cff0a96c5fa73acb96f4a16a34d1cb7ebd5", + "source": "desktop/runtime/python-services/townlight_runtime/townlight_records_alembic/alembic/versions/025_records_artifacts.py", + "sha256": "b4f4c62211d57b123978fe78ae3dc0c7503110ccae9422776e1bd6d13d003b8a", + "bytes": 2526, "routes": [], - "models": [ - { - "name": "InspectionReportDraft", - "bases": [], - "fields": [ - { - "name": "inspection_id", - "type": "str", - "default": "" - }, - { - "name": "property_reference", - "type": "str", - "default": "" - }, - { - "name": "summary", - "type": "str", - "default": "" - }, - { - "name": "observation_bullets", - "type": "tuple[str, ...]", - "default": "" - }, - { - "name": "inspector_review_required", - "type": "bool", - "default": "" - }, - { - "name": "cited_sections", - "type": "tuple[str, ...]", - "default": "()" - }, - { - "name": "disclaimer", - "type": "str", - "default": "DISCLAIMER" - } - ], - "line": 11, - "doc": "" - } - ], + "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_inspections/transcription.py", - "sha256": "0289536c591fa63b6bfa25512444c4a36edc1f160a93d195d3e5aea9e718289f", + "source": "desktop/runtime/python-services/townlight_runtime/townlight_records_alembic/alembic/versions/026_native_public_actor.py", + "sha256": "3958251d4c9710ffc20572ee7dcc0fe2dbc169e6f56bd1461d6c1239c2ac231c", + "bytes": 631, "routes": [], "models": [], - "configuration": [ + "configuration": [] + }, + { + "source": "desktop/runtime/python-services/townlight_runtime/townlight_records_alembic/alembic/versions/027_import_artifact_order.py", + "sha256": "9ef98e386a1dc848a1fab6893b009198d70556020482df207618519a3301faf8", + "bytes": 430, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/runtime/python-services/townlight_runtime/townlight_records_alembic/alembic/versions/787207afc66a_phase2_extensions_12_new_tables_and_.py", + "sha256": "4d3c03861b6061058d19953a8deb8d8c46cdba775154bf05eed055ee16b26e24", + "bytes": 18344, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/runtime/python-services/townlight_runtime/townlight_records_alembic/alembic.ini", + "sha256": "60e69c28e3c87e101995977223073125b196202555e1fc18902feed2afdc7e7e", + "bytes": 524, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/runtime/python-services/townlight_runtime/zoning_bridge.py", + "sha256": "9bb3476d8f8365285cd486b86bdc27b0e28d34519610fdc379d2c58d42d2de54", + "bytes": 15192, + "routes": [ + { + "method": "POST", + "declared_path": "/imports", + "function": "imports", + "line": 68 + }, + { + "method": "POST", + "declared_path": "/parcels/lookup", + "function": "parcel_lookup", + "line": 91 + }, + { + "method": "GET", + "declared_path": "/questions/{question_id}/history", + "function": "question_history", + "line": 209 + }, + { + "method": "POST", + "declared_path": "/meetings/search", + "function": "search_meetings", + "line": 216 + }, + { + "method": "POST", + "declared_path": "/questions/{question_id}/meetings", + "function": "link_meeting", + "line": 242 + }, { - "variable": "TOWNLIGHT_INSPECTIONS_FFMPEG", - "default": "", - "line": 53 + "method": "POST", + "declared_path": "/questions/{question_id}/snapshots", + "function": "create_snapshot", + "line": 259 }, { - "variable": "TOWNLIGHT_INSPECTIONS_TEXTFLOWKIT_PYTHON", - "default": "", - "line": 49 - } - ] - }, - { - "source": "installed-owned-source/townlight_inspections/workflow_models.py", - "sha256": "7f61e6c7bde5b79202b562d9183c5558d5504fe19eda9ed8fe52541d92152377", - "routes": [], - "models": [ + "method": "POST", + "declared_path": "/rules", + "function": "create_rule", + "line": 291 + }, { - "name": "AnalysisObservation", - "bases": [ - "Model" - ], - "fields": [ - { - "name": "source", - "type": "str", - "default": "Field(min_length=1, max_length=64)" - }, - { - "name": "filename", - "type": "str", - "default": "Field(default='', max_length=160)" - }, - { - "name": "media_type", - "type": "str", - "default": "Field(default='', max_length=80)" - }, - { - "name": "text", - "type": "str", - "default": "Field(min_length=1, max_length=4000)" - }, - { - "name": "adapter", - "type": "str", - "default": "Field(default='', max_length=120)" - }, - { - "name": "citation_source_ids", - "type": "list[str]", - "default": "Field(default_factory=list, max_length=30)" - } - ], - "line": 23, - "doc": "One draft observation, named with the adapter that actually produced it." + "method": "POST", + "declared_path": "/questions", + "function": "create_question", + "line": 300 }, { - "name": "CitedSection", - "bases": [ - "Model" - ], - "fields": [ - { - "name": "source_id", - "type": "str", - "default": "Field(min_length=1, max_length=500)" - }, - { - "name": "citation", - "type": "str", - "default": "Field(min_length=1, max_length=500)" - }, - { - "name": "title", - "type": "str", - "default": "Field(default='', max_length=500)" - }, - { - "name": "version", - "type": "str", - "default": "Field(default='', max_length=80)" - } - ], - "line": 40, - "doc": "One resolved public Code section; never a caller-supplied quotation." + "method": "GET", + "declared_path": "/workspace", + "function": "get_workspace", + "line": 313 }, { - "name": "AnalysisRecord", - "bases": [ - "Model" - ], - "fields": [ - { - "name": "observations", - "type": "list[AnalysisObservation]", - "default": "Field(default_factory=list, max_length=30)" - }, - { - "name": "cited_sections", - "type": "list[CitedSection]", - "default": "Field(default_factory=list, max_length=30)" - }, - { - "name": "unavailable", - "type": "list[str]", - "default": "Field(default_factory=list, max_length=30)" - }, - { - "name": "runtime", - "type": "dict", - "default": "Field(default_factory=dict)" - }, - { - "name": "review_required", - "type": "bool", - "default": "True" - } - ], - "line": 49, - "doc": "The adapter output that accompanies a saved inspection draft." + "method": "POST", + "declared_path": "/questions/{question_id}/reviews", + "function": "create_review", + "line": 318 }, { - "name": "AnalysisRecord", + "method": "POST", + "declared_path": "/outlines", + "function": "create_outline", + "line": 325 + }, + { + "method": "POST", + "declared_path": "/code-context", + "function": "create_code_context", + "line": 332 + }, + { + "method": "POST", + "declared_path": "/standards/process-explanation", + "function": "standards_explanation", + "line": 373 + }, + { + "method": "POST", + "declared_path": "/questions", + "function": "public_question", + "line": 423 + }, + { + "method": "POST", + "declared_path": "/parcels/lookup", + "function": "public_parcel_lookup", + "line": 434 + } + ], + "models": [ + { + "name": "_ParcelLookupIn", "bases": [ - "Model" + "BaseModel" ], "fields": [ { - "name": "observations", - "type": "list[AnalysisObservation]", - "default": "Field(default_factory=list, max_length=30)" - }, - { - "name": "cited_sections", - "type": "list[CitedSection]", - "default": "Field(default_factory=list, max_length=30)" - }, - { - "name": "unavailable", - "type": "list[str]", - "default": "Field(default_factory=list, max_length=30)" - }, - { - "name": "runtime", - "type": "dict", - "default": "Field(default_factory=dict)" + "name": "jurisdiction", + "type": "str", + "line": 63 }, { - "name": "review_required", - "type": "bool", - "default": "True" + "name": "query", + "type": "str", + "line": 64 } ], - "line": 74, - "doc": "The adapter output that accompanies a saved inspection draft." + "line": 60 }, { - "name": "Evidence", + "name": "Question", "bases": [ - "Model" + "Strict" ], "fields": [ { - "name": "filename", + "name": "jurisdiction", "type": "str", - "default": "Field(pattern='^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$')" + "line": 151 }, { - "name": "description", + "name": "query", "type": "str", - "default": "Field(min_length=1, max_length=2000)" + "line": 152 }, { - "name": "media_type", - "type": "Literal['text/plain', 'image/jpeg', 'image/png', 'image/webp', 'application/pdf', 'audio/webm', 'audio/ogg', 'audio/wav', 'audio/mpeg', 'audio/mp4']", - "default": "" - }, - { - "name": "content_base64", + "name": "question", "type": "str", - "default": "Field(min_length=1, max_length=14000000)" + "line": 153 }, { - "name": "sha256", - "type": "str", - "default": "Field(pattern='^[a-f0-9]{64}$')" - } - ], - "line": 118, - "doc": "" - }, - { - "name": "SourceLink", - "bases": [ - "Model" - ], - "fields": [ - { - "name": "provider", - "type": "Literal['code']", - "default": "'code'" + "name": "kind", + "type": "Literal['use', 'dimension']", + "line": 154 }, { - "name": "source_id", + "name": "key", "type": "str", - "default": "Field(min_length=1, max_length=500)" + "line": 155 }, { - "name": "expected_sha256", - "type": "str", - "default": "Field(pattern='^[a-f0-9]{64}$')" + "name": "audience", + "type": "Literal['resident', 'staff']", + "line": 156 } ], - "line": 138, - "doc": "" + "line": 150 }, { - "name": "InspectionInput", + "name": "Rule", "bases": [ - "Model" + "Strict" ], "fields": [ { - "name": "expected_revision", - "type": "UUID | None", - "default": "None" - }, - { - "name": "title", - "type": "str", - "default": "Field(min_length=1, max_length=500)" - }, - { - "name": "property_reference", - "type": "str", - "default": "Field(min_length=1, max_length=1000)" - }, - { - "name": "inspection_reference", - "type": "str", - "default": "Field(min_length=1, max_length=160)" - }, - { - "name": "dataset_kind", - "type": "Literal['municipal', 'fictional']", - "default": "" - }, - { - "name": "inspector_notes", - "type": "str", - "default": "Field(min_length=1, max_length=10000)" - }, - { - "name": "photo_observations", - "type": "list[str]", - "default": "Field(default_factory=list, max_length=30)" - }, - { - "name": "voice_notes", + "name": "jurisdiction", "type": "str", - "default": "Field(default='', max_length=10000)" - }, - { - "name": "evidence", - "type": "list[Evidence]", - "default": "Field(default_factory=list, max_length=10)" - }, - { - "name": "linked_sources", - "type": "list[SourceLink]", - "default": "Field(default_factory=list, max_length=30)" + "line": 160 }, { - "name": "assigned_to", + "name": "zone_code", "type": "str", - "default": "Field(default='', max_length=255)" + "line": 161 }, { - "name": "staff_notes", + "name": "key", "type": "str", - "default": "Field(default='', max_length=10000)" + "line": 162 }, { - "name": "notice_draft", + "name": "section_number", "type": "str", - "default": "Field(default='', max_length=10000)" - }, - { - "name": "review_state", - "type": "Literal['draft', 'follow_up', 'reviewed']", - "default": "'draft'" + "line": 163 }, { - "name": "review_notes", - "type": "str", - "default": "Field(default='', max_length=4000)" + "name": "kind", + "type": "Literal['use', 'dimension']", + "line": 164 }, { - "name": "public_summary", + "name": "value", "type": "str", - "default": "Field(default='', max_length=10000)" + "line": 165 }, { - "name": "analysis", - "type": "AnalysisRecord | None", - "default": "None" + "name": "overlay_code", + "type": "str | None", + "line": 166 } ], - "line": 144, - "doc": "" - } - ], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_inspections/workflow_schema.py", - "sha256": "2f8638e3319939ce8b3f7b0b1ef59013f3344b8bcaf9be7d1ad6f3bd4b30ac68", - "routes": [], - "models": [], - "configuration": [] - }, - { - "source": "installed-owned-source/townlight_inspections/workflow_store.py", - "sha256": "df4ff48879d5f8fe31d71a410a99ed8c359676ab05a267db65e1468cb4764146", - "routes": [], - "models": [], - "configuration": [] - } - ], - "bridge": [ - { - "source": "installed-owned-source/townlight_runtime/inspections_bridge.py", - "sha256": "b7429c3ab988005a198795d6f1dfc3f785c7f96f61410903f8cb0ad38c6f512c", - "routes": [ - { - "method": "POST", - "path": "/desktop/v1/inspections/repeat-cases", - "router": "router", - "prefix_resolved": true, - "name": "repeat_cases", - "signature": "request: Request, body: RepeatLookup, identity=Depends(actor)", - "returns": "", - "line": 93, - "doc": "", - "decorator": "router.post('/repeat-cases')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/inspections/notice-draft", - "router": "router", - "prefix_resolved": true, - "name": "notice", - "signature": "request: Request, body: InspectionInput, identity=Depends(actor)", - "returns": "", - "line": 98, - "doc": "", - "decorator": "router.post('/notice-draft')", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/inspections/cases", - "router": "router", - "prefix_resolved": true, - "name": "cases", - "signature": "request: Request, offset: int=Query(0, ge=0, le=100000), identity=Depends(actor)", - "returns": "", - "line": 105, - "doc": "", - "decorator": "router.get('/cases')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/inspections/cases", - "router": "router", - "prefix_resolved": true, - "name": "create_case", - "signature": "request: Request, body: InspectionInput, identity=Depends(actor)", - "returns": "", - "line": 110, - "doc": "", - "decorator": "router.post('/cases')", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/inspections/cases/{case_id}", - "router": "router", - "prefix_resolved": true, - "name": "case", - "signature": "request: Request, case_id: UUID, identity=Depends(actor)", - "returns": "", - "line": 115, - "doc": "", - "decorator": "router.get('/cases/{case_id}')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/inspections/cases/{case_id}/revisions", - "router": "router", - "prefix_resolved": true, - "name": "revise", - "signature": "request: Request, case_id: UUID, body: InspectionInput, identity=Depends(actor)", - "returns": "", - "line": 120, - "doc": "", - "decorator": "router.post('/cases/{case_id}/revisions')", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/inspections/cases/{case_id}/history", - "router": "router", - "prefix_resolved": true, - "name": "history", - "signature": "request: Request, case_id: UUID, identity=Depends(actor)", - "returns": "", - "line": 125, - "doc": "", - "decorator": "router.get('/cases/{case_id}/history')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/inspections/cases/{case_id}/packets", - "router": "router", - "prefix_resolved": true, - "name": "packet", - "signature": "request: Request, case_id: UUID, body: Packet, identity=Depends(actor)", - "returns": "", - "line": 135, - "doc": "", - "decorator": "router.post('/cases/{case_id}/packets')", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/inspections/packets/{packet_id}", - "router": "router", - "prefix_resolved": true, - "name": "document", - "signature": "request: Request, packet_id: UUID, identity=Depends(actor)", - "returns": "", - "line": 140, - "doc": "", - "decorator": "router.get('/packets/{packet_id}')", - "errors": [] - }, - { - "method": "GET", - "path": "/desktop/v1/inspections/evidence/supported-types", - "router": "router", - "prefix_resolved": true, - "name": "supported_types", - "signature": "identity=Depends(actor)", - "returns": "", - "line": 179, - "doc": "The media types this deployment's product model actually accepts.", - "decorator": "router.get('/evidence/supported-types')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/inspections/evidence/retain", - "router": "router", - "prefix_resolved": true, - "name": "retain", - "signature": "request: Request, body: EvidenceItems, identity=Depends(actor)", - "returns": "", - "line": 188, - "doc": "", - "decorator": "router.post('/evidence/retain')", - "errors": [] - }, - { - "method": "POST", - "path": "/desktop/v1/inspections/media/analyse", - "router": "router", - "prefix_resolved": true, - "name": "media_analyse", - "signature": "request: Request, body: MediaAnalysis, identity=Depends(actor)", - "returns": "", - "line": 199, - "doc": "Run the configured adapters over retained originals; draft only.\n\nThe result carries the same observations/citations the product route returns\nplus ``analysis_record``: the exact ``AnalysisRecord`` the caller puts on its\ncase payload, so the reviewed draft is the analysed one.", - "decorator": "router.post('/media/analyse')", - "errors": [ - "HTTPException(503, str(exc))" - ] - }, - { - "method": "POST", - "path": "/desktop/v1/inspections/connections/search", - "router": "router", - "prefix_resolved": true, - "name": "connections", - "signature": "request: Request, body: Search, identity=Depends(actor)", - "returns": "", - "line": 234, - "doc": "", - "decorator": "router.post('/connections/search')", - "errors": [] - } - ], - "models": [ + "line": 159 + }, { - "name": "RepeatLookup", + "name": "Review", "bases": [ - "Model" + "Strict" ], "fields": [ { - "name": "property_reference", + "name": "answer", + "type": "str", + "line": 170 + }, + { + "name": "notes", "type": "str", - "default": "Field(min_length=1, max_length=1000)" + "line": 171 + }, + { + "name": "queue_status", + "type": "Literal['open', 'in_review', 'resolved', 'closed']", + "line": 172 } ], - "line": 88, - "doc": "" + "line": 169 }, { - "name": "Packet", + "name": "Outline", "bases": [ - "Model" + "Strict" ], "fields": [ { - "name": "expected_revision", - "type": "UUID", - "default": "" + "name": "title", + "type": "str", + "line": 176 }, { - "name": "visibility", - "type": "Literal['staff_only', 'records_copy']", - "default": "" + "name": "question_ids", + "type": "list[UUID]", + "line": 177 } ], - "line": 129, - "doc": "" + "line": 175 }, { - "name": "EvidenceItem", + "name": "CodeContext", "bases": [ - "Model" + "Strict" ], "fields": [ { - "name": "filename", - "type": "str", - "default": "Field(min_length=1, max_length=151)" - }, - { - "name": "media_type", - "type": "str", - "default": "Field(min_length=1, max_length=80)" - }, - { - "name": "description", - "type": "str", - "default": "Field(default='', max_length=2000)" - }, - { - "name": "content_base64", + "name": "section_number", "type": "str", - "default": "Field(min_length=1, max_length=14000000)" + "line": 181 }, { - "name": "sha256", - "type": "str", - "default": "Field(pattern='^[a-f0-9]{64}$')" + "name": "as_of", + "type": "date | None", + "line": 182 } ], - "line": 144, - "doc": "" + "line": 180 }, { - "name": "EvidenceItems", + "name": "MeetingSearch", "bases": [ - "Model" + "Strict" ], "fields": [ { - "name": "items", - "type": "list[EvidenceItem]", - "default": "Field(min_length=1, max_length=10)" + "name": "query", + "type": "str", + "line": 186 } ], - "line": 152, - "doc": "" + "line": 185 }, { - "name": "CodeLink", + "name": "MeetingLink", "bases": [ - "Model" + "Strict" ], "fields": [ - { - "name": "provider", - "type": "Literal['code']", - "default": "'code'" - }, { "name": "source_id", "type": "str", - "default": "Field(min_length=1, max_length=500)" + "line": 190 }, { "name": "expected_sha256", "type": "str", - "default": "Field(pattern='^[a-f0-9]{64}$')" + "line": 191 + }, + { + "name": "relation", + "type": "Literal['hearing', 'context', 'precedent']", + "line": 192 } ], - "line": 156, - "doc": "" + "line": 189 }, { - "name": "MediaAnalysis", + "name": "SourceSnapshot", "bases": [ - "Model" + "Strict" ], "fields": [ { - "name": "items", - "type": "list[EvidenceItem]", - "default": "Field(min_length=1, max_length=10)" - }, - { - "name": "code_links", - "type": "list[CodeLink]", - "default": "Field(default_factory=list, max_length=30)" + "name": "visibility", + "type": "Literal['public', 'staff_only']", + "line": 196 }, { - "name": "inspector_supplied_text", - "type": "str", - "default": "Field(default='', max_length=10000)" + "name": "meeting_event_ids", + "type": "list[UUID]", + "line": 197 } ], - "line": 162, - "doc": "" + "line": 195 }, { - "name": "Search", + "name": "StandardsExplanation", "bases": [ - "Model" + "BaseModel" ], "fields": [ { - "name": "provider", - "type": "Literal['code']", - "default": "" + "name": "question", + "type": "str", + "line": 345 }, { - "name": "query", + "name": "process_section", + "type": "str", + "line": 346 + }, + { + "name": "zone_code", "type": "str", - "default": "Field(min_length=1, max_length=500)" + "line": 347 + }, + { + "name": "rule_types", + "type": "list[str]", + "line": 348 + }, + { + "name": "observed", + "type": "dict[str, str]", + "line": 349 } ], - "line": 228, - "doc": "" + "line": 342 } ], + "configuration": [ + { + "environment": "TOWNLIGHT_ZONING_PARCEL_RULE_DB_URL", + "line": 359 + } + ] + }, + { + "source": "desktop/runtime/python-services/townlight_runtime/zoning_records.py", + "sha256": "c4cb908e45e90baeaedff9fd4c668ca65229e129bc298b4d893d515046e73449", + "bytes": 1700, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/src-tauri/src/atomic_io.rs", + "sha256": "f48017db219a365b17988522616e2f5ab332986936064712fb12c5f228ab3d35", + "bytes": 5543, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/src-tauri/src/auth.rs", + "sha256": "e5d5febef258b15f03edb006f2204467e87890b08259db1f8ffeec5f208ee156", + "bytes": 45187, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/src-tauri/src/code_client.rs", + "sha256": "7f07c7b90ccf97bfb8883541525417d598c6f385d54a9694d65e9ac40890cdad", + "bytes": 9186, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/src-tauri/src/demo_fixture.rs", + "sha256": "118bf6c8ebdc6fe8d7210bb08c7f7aae7c7f58b99ca25a805f74b49264b51725", + "bytes": 9823, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/src-tauri/src/domain_client.rs", + "sha256": "95e608acfac2f5621205314a61a317f50437f53b1bbee9cdd2e59431ee893a2c", + "bytes": 41159, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/src-tauri/src/domain_files.rs", + "sha256": "85e715da4f8b0762bd2496755c76cbc1b7bc3e81f7d23995cf3ecc16b55a5095", + "bytes": 13384, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/src-tauri/src/first_run.rs", + "sha256": "45e42d7fae458cf4546bedb6b55d5e25cdc617ebda8fc612cef9e0838124b00f", + "bytes": 56023, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/src-tauri/src/inspections_client.rs", + "sha256": "88f582cd2941c27ddd1245df18666d6cfe95ad5523225ea2186bc6d3a5a6643c", + "bytes": 4521, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/src-tauri/src/local_paths.rs", + "sha256": "f07d2a74cef04beaa64cf92a37eef8e1095dbc16d8c8d48e679702666a1b6f19", + "bytes": 4291, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/src-tauri/src/local_shell.rs", + "sha256": "feeb5b6b396c0ad3eea0ecc8505068745eaaf0354bac1e97274aad9a68971100", + "bytes": 2428, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/src-tauri/src/main.rs", + "sha256": "a0b4dd53a0b7c2c4a4e10ae19d236c5bafadc5c3d01065ed89a6fdbfbac31378", + "bytes": 80956, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/src-tauri/src/model.rs", + "sha256": "dbec92b4eb25790ac05c55cde83458819559d5918c97dee0c57258b0cdb36d4c", + "bytes": 100505, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/src-tauri/src/module_registry.rs", + "sha256": "d7afcece112c88cd421932c4502446280dffbbf732ee99b06951a2054edf050a", + "bytes": 61224, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/src-tauri/src/notice_client.rs", + "sha256": "6ae504993b9f503b05dbc4acbbedf58a52895c19f9c16298723de094a17d4ae3", + "bytes": 2591, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/src-tauri/src/permitting_client.rs", + "sha256": "2efc10f71c22cb9167b2f4c6e2ab9c24a6ea3301d37a1bdc04c0e3a76fbd882a", + "bytes": 4373, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/src-tauri/src/planning_client.rs", + "sha256": "5733d0364c2d28d6e98af4ea5357c6b22d1f605f69c58630ce561327112eee1f", + "bytes": 10603, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/src-tauri/src/profile_gate.rs", + "sha256": "5efaedda31be755a165b86d34e87c71d54cd01db94efdcc2b596d50d54cd5b66", + "bytes": 1809, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/src-tauri/src/profile_identity.rs", + "sha256": "04f49fc1fcf51adadf958a100204db63c8527034fbb679df15a589794c01fb3a", + "bytes": 2536, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/src-tauri/src/records_authority.rs", + "sha256": "87f47a88d1675425dbea11bb630c552d32d2b04c7dcf5010af6cf1ef32c1ab11", + "bytes": 2970, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/src-tauri/src/supervisor.rs", + "sha256": "9266597ef98e59e965241df5b9e48face47c1f2483af634733c67a3de352616a", + "bytes": 212785, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/src-tauri/src/workflows.rs", + "sha256": "f0a1a9fdfd3b62852c88a3997c6425510078194727cd5d605b411ce68b2abee0", + "bytes": 42706, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/src-tauri/src/zoning_client.rs", + "sha256": "3ffa1fe93379491ca5efb00fefc4044ae35479bd04479f674bc0f2ee77e4ee85", + "bytes": 4140, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/src/code/client.ts", + "sha256": "82e69121ebba5c8d617a4b9afcc7b6a9d9fa360464bb1a62778cbfe2ea40e22c", + "bytes": 5805, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/src/code/view.js", + "sha256": "cd4de8e1f4caae9a7a5331e1f34beadf2a8faef00883b14ac6a4e8be06be53e6", + "bytes": 10101, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/src/inspections/view.js", + "sha256": "7f3bb66fbaf5f78705c729e2db82dafd77b6c0ea6a2accd2aed57ad057d980bf", + "bytes": 17631, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/src/main.js", + "sha256": "2d4697da1f1370bf326e45d323bec739b15ba2dcc259825388549953f971093e", + "bytes": 356385, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/src/meetings/client.ts", + "sha256": "ba12839650f17a66d5eff5782c0e5feb1a9ad7abfbe1442958b86d9f7813e1cc", + "bytes": 6896, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/src/meetings/view.js", + "sha256": "3d12d5fde231bd777eb3717aac068a8397afe4b2182debff3711592c9881ac24", + "bytes": 17252, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/src/notice/view.js", + "sha256": "05fdae1f9647ea84ef1afee51dda4aad72fdf2765dd32dab8e987c043b14cbf1", + "bytes": 9626, + "routes": [], + "models": [], "configuration": [] - } - ] - }, - "station": { - "package": "townlight_station", - "source": [ + }, { - "source": "installed-owned-source/townlight_station/__init__.py", - "sha256": "0e4ae6948a7b82358592fa123efcb0f2f19edd0322d93e8077da9db1dcde1ccc", + "source": "desktop/src/permitting/view.js", + "sha256": "261b6bcbdffc4c107bfddcfb46c7c8013de78e94b22171560034e3353e545a01", + "bytes": 19392, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_station/air.py", - "sha256": "501f3ab5cd85ef7409e692496b8ab8146c3f894a0c3c963fb40d44a71088a97f", + "source": "desktop/src/planning/client.ts", + "sha256": "90f5f834e301189b907bcf2cc6a83ecd5b9f5bc10199a61b7cd06224905c6584", + "bytes": 1249, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_station/airplay.py", - "sha256": "49efe58ba56e37260c24e9ac329f942f6520c3f16d341b0d4ece803750ce0988", + "source": "desktop/src/planning/municipal.js", + "sha256": "b3e0cb7dd66e81584d317a6f270e9cf1892147805349e1f3ec91e453ece90d70", + "bytes": 9154, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_station/api.py", - "sha256": "ac098e06290f5888924bb7a211a3925107161c9e01634f998f7303f05a854b18", - "routes": [ - { - "method": "GET", - "path": "/health", - "router": "app", - "prefix_resolved": true, - "name": "health", - "signature": "", - "returns": "", - "line": 79, - "doc": "", - "decorator": "app.get('/health')", - "errors": [] - }, - { - "method": "GET", - "path": "/v1/identity", - "router": "app", - "prefix_resolved": true, - "name": "identity", - "signature": "proof: str | None=Header(default=None, alias='X-Townlight-Session')", - "returns": "", - "line": 84, - "doc": "", - "decorator": "app.get('/v1/identity')", - "errors": [] - }, - { - "method": "POST", - "path": "/v1/recordings", - "router": "app", - "prefix_resolved": true, - "name": "capture", - "signature": "data: Capture, proof: str | None=Header(default=None, alias='X-Townlight-Session')", - "returns": "", - "line": 89, - "doc": "", - "decorator": "app.post('/v1/recordings', status_code=202)", - "errors": [ - "HTTPException(422, 'Select one recorded file or live input; live input preserves embedded captions')", - "HTTPException(422, 'Configured live input not found')", - "HTTPException(422, 'Source file missing or exceeds configured limit')", - "HTTPException(422, 'Caption sidecar missing or too large')", - "HTTPException(409, 'Agenda item does not belong to this meeting')", - "HTTPException(409, 'Station is busy; live recording must start immediately')", - "HTTPException(429, 'Station queue is full; no capture accepted')", - "HTTPException(409, 'Idempotency key already describes different source evidence')" - ] - }, - { - "method": "GET", - "path": "/v1/recordings/{identity}", - "router": "app", - "prefix_resolved": true, - "name": "get_record", - "signature": "identity: UUID, proof: str | None=Header(default=None, alias='X-Townlight-Session')", - "returns": "", - "line": 187, - "doc": "", - "decorator": "app.get('/v1/recordings/{identity}')", - "errors": [] - }, - { - "method": "GET", - "path": "/v1/recordings/{identity}/content", - "router": "app", - "prefix_resolved": true, - "name": "content", - "signature": "identity: UUID, proof: str | None=Header(default=None, alias='X-Townlight-Session')", - "returns": "", - "line": 191, - "doc": "", - "decorator": "app.get('/v1/recordings/{identity}/content')", - "errors": [ - "HTTPException(409, 'Recording is not complete')", - "HTTPException(409, 'Recording integrity failure')" - ] - }, - { - "method": "POST", - "path": "/v1/recordings/{identity}/retry", - "router": "app", - "prefix_resolved": true, - "name": "retry", - "signature": "identity: UUID, proof: str | None=Header(default=None, alias='X-Townlight-Session')", - "returns": "", - "line": 202, - "doc": "", - "decorator": "app.post('/v1/recordings/{identity}/retry', status_code=202)", - "errors": [ - "HTTPException(404, 'Recording not found')", - "HTTPException(409, 'Only failed/interrupted recordings can be retried')", - "HTTPException(409, 'A live gap cannot be retried; start a new recording')" - ] - }, - { - "method": "GET", - "path": "/v1/live-sources", - "router": "app", - "prefix_resolved": true, - "name": "live_sources", - "signature": "proof: str | None=Header(default=None, alias='X-Townlight-Session')", - "returns": "", - "line": 215, - "doc": "", - "decorator": "app.get('/v1/live-sources')", - "errors": [] - }, - { - "method": "GET", - "path": "/v1/recordings", - "router": "app", - "prefix_resolved": true, - "name": "list_records", - "signature": "proof: str | None=Header(default=None, alias='X-Townlight-Session')", - "returns": "", - "line": 220, - "doc": "", - "decorator": "app.get('/v1/recordings')", - "errors": [] - }, - { - "method": "POST", - "path": "/v1/recordings/{identity}/stop", - "router": "app", - "prefix_resolved": true, - "name": "stop_live", - "signature": "identity: UUID, proof: str | None=Header(default=None, alias='X-Townlight-Session')", - "returns": "", - "line": 226, - "doc": "", - "decorator": "app.post('/v1/recordings/{identity}/stop', status_code=202)", - "errors": [ - "HTTPException(404, 'Recording not found')", - "HTTPException(409, 'This recording is not live')", - "HTTPException(409, 'Recording already ended')" - ] - } - ], - "models": [ - { - "name": "Capture", - "bases": [ - "BaseModel" - ], - "fields": [ - { - "name": "meeting_id", - "type": "UUID", - "default": "" - }, - { - "name": "agenda_ids", - "type": "list[UUID]", - "default": "Field(default_factory=list, max_length=100)" - }, - { - "name": "source_file", - "type": "str | None", - "default": "Field(default=None, pattern='^[A-Za-z0-9][A-Za-z0-9_.-]{0,180}$')" - }, - { - "name": "live_source_id", - "type": "str | None", - "default": "Field(default=None, pattern='^[A-Za-z0-9_-]{1,64}$')" - }, - { - "name": "captions_file", - "type": "str | None", - "default": "Field(default=None, pattern='^[A-Za-z0-9][A-Za-z0-9_.-]{0,180}\\\\.srt$')" - }, - { - "name": "idempotency_key", - "type": "str", - "default": "Field(min_length=1, max_length=100)" - } - ], - "line": 34, - "doc": "" - } - ], + "source": "desktop/src/planning/planning.css", + "sha256": "477e8f96587001e6d67f406bea2768d112fa519ae2e8cde55e18ad2eda678cfb", + "bytes": 7003, + "routes": [], + "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_station/boundary.py", - "sha256": "e3b39156fb3fd3e0c4ff1dc9370ce133b9163ee689eeb4be0f5e235833e5336e", + "source": "desktop/src/planning/view.js", + "sha256": "9b3b76c9ec43ac09df553469ed20263ba60c2cde65cfcaa8e32a591f59078a36", + "bytes": 44120, "routes": [], - "models": [ - { - "name": "Settings", - "bases": [], - "fields": [ - { - "name": "data", - "type": "Path", - "default": "" - }, - { - "name": "database_url", - "type": "str", - "default": "" - }, - { - "name": "suite_url", - "type": "str", - "default": "" - }, - { - "name": "media_source", - "type": "Path", - "default": "" - }, - { - "name": "media_python", - "type": "Path", - "default": "" - }, - { - "name": "media_runtime", - "type": "Path", - "default": "" - }, - { - "name": "ffprobe", - "type": "Path", - "default": "" - }, - { - "name": "max_seconds", - "type": "int", - "default": "7200" - }, - { - "name": "max_bytes", - "type": "int", - "default": "2147483647" - }, - { - "name": "width", - "type": "int", - "default": "1920" - }, - { - "name": "height", - "type": "int", - "default": "1080" - }, - { - "name": "fps", - "type": "int", - "default": "30" - }, - { - "name": "bitrate_kbps", - "type": "int", - "default": "6000" - } - ], - "line": 45, - "doc": "" - } - ], + "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_station/cli.py", - "sha256": "ffbd1fc7ce709ff255d4b5f190fda532d395c9febddf5c281fdff3345f19a9c9", + "source": "desktop/src/records/access-client.ts", + "sha256": "6c284a448745a2f3872b2a36dbe1ccd30d0426212362f8c944a923061656b5a7", + "bytes": 3525, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_station/live.py", - "sha256": "a35de110d5dbfdcf0b98425baf4b664fc4d0324c640c737086936dbe17adc829", + "source": "desktop/src/records/client.ts", + "sha256": "9df93865a964bbb3ba991956f89bc51053511a6497e92b230f01a7a366420e6c", + "bytes": 6675, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_station/media_job.py", - "sha256": "15237eaa872c9772c548aaf57dced25ec51a343489b894a462d95de19507e59b", + "source": "desktop/src/records/code-sources.ts", + "sha256": "52755e6d4248bbfc6268c62f9c663edef7526497dac27acb29b887d5b7b9d0d4", + "bytes": 4716, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_station/operations.py", - "sha256": "69019673d277ee4850d4dd1789e0576b6883d684b0f1ead2be9f965cfdf7b7d2", - "routes": [ - { - "method": "POST", - "path": "/v1/schedules", - "router": "app", - "prefix_resolved": true, - "name": "create_schedule", - "signature": "data: ScheduleRequest, proof: str | None=Header(default=None, alias='X-Townlight-Session')", - "returns": "", - "line": 106, - "doc": "", - "decorator": "app.post('/v1/schedules', status_code=202)", - "errors": [ - "HTTPException(422, 'Select one recorded file or live input; live input preserves embedded captions')", - "HTTPException(422, 'Configured live input not found')", - "HTTPException(422, 'Source file missing from managed ingest')", - "HTTPException(422, 'Caption sidecar missing from managed ingest')", - "HTTPException(409, 'Agenda item does not belong to this meeting')" - ] - }, - { - "method": "GET", - "path": "/v1/schedules", - "router": "app", - "prefix_resolved": true, - "name": "list_schedules", - "signature": "proof: str | None=Header(default=None, alias='X-Townlight-Session')", - "returns": "", - "line": 143, - "doc": "", - "decorator": "app.get('/v1/schedules')", - "errors": [] - }, - { - "method": "POST", - "path": "/v1/schedules/{identity}/cancel", - "router": "app", - "prefix_resolved": true, - "name": "cancel_schedule", - "signature": "identity: UUID, proof: str | None=Header(default=None, alias='X-Townlight-Session')", - "returns": "", - "line": 151, - "doc": "", - "decorator": "app.post('/v1/schedules/{identity}/cancel', status_code=202)", - "errors": [ - "HTTPException(409, 'Only a schedule that has not started can be cancelled')" - ] - }, - { - "method": "POST", - "path": "/v1/playouts", - "router": "app", - "prefix_resolved": true, - "name": "create_playout", - "signature": "data: PlayoutRequest, proof: str | None=Header(default=None, alias='X-Townlight-Session')", - "returns": "", - "line": 163, - "doc": "", - "decorator": "app.post('/v1/playouts', status_code=202)", - "errors": [ - "HTTPException(404, 'Recording not found')", - "HTTPException(409, 'Only a complete, verified recording can be committed to air')" - ] - }, - { - "method": "GET", - "path": "/v1/playouts", - "router": "app", - "prefix_resolved": true, - "name": "list_playouts", - "signature": "proof: str | None=Header(default=None, alias='X-Townlight-Session')", - "returns": "", - "line": 187, - "doc": "", - "decorator": "app.get('/v1/playouts')", - "errors": [] - }, - { - "method": "GET", - "path": "/v1/playouts/{identity}", - "router": "app", - "prefix_resolved": true, - "name": "get_playout", - "signature": "identity: UUID, proof: str | None=Header(default=None, alias='X-Townlight-Session')", - "returns": "", - "line": 194, - "doc": "", - "decorator": "app.get('/v1/playouts/{identity}')", - "errors": [ - "HTTPException(404, 'Playout not found')" - ] - }, - { - "method": "GET", - "path": "/v1/on-air", - "router": "app", - "prefix_resolved": true, - "name": "on_air", - "signature": "proof: str | None=Header(default=None, alias='X-Townlight-Session')", - "returns": "", - "line": 203, - "doc": "", - "decorator": "app.get('/v1/on-air')", - "errors": [] - }, - { - "method": "POST", - "path": "/v1/on-air/live", - "router": "app", - "prefix_resolved": true, - "name": "live_override", - "signature": "data: LiveOverrideRequest, proof: str | None=Header(default=None, alias='X-Townlight-Session')", - "returns": "", - "line": 215, - "doc": "Put a configured live input on air, in place of the scheduled program.", - "decorator": "app.post('/v1/on-air/live', status_code=202)", - "errors": [ - "HTTPException(422, 'Configured live input not found')" - ] - }, - { - "method": "POST", - "path": "/v1/on-air/return-to-schedule", - "router": "app", - "prefix_resolved": true, - "name": "return_to_schedule", - "signature": "proof: str | None=Header(default=None, alias='X-Townlight-Session')", - "returns": "", - "line": 232, - "doc": "", - "decorator": "app.post('/v1/on-air/return-to-schedule', status_code=202)", - "errors": [] - }, - { - "method": "POST", - "path": "/v1/playouts/{identity}/approve", - "router": "app", - "prefix_resolved": true, - "name": "approve", - "signature": "identity: UUID, data: ApprovalRequest, proof: str | None=Header(default=None, alias='X-Townlight-Session')", - "returns": "", - "line": 243, - "doc": "", - "decorator": "app.post('/v1/playouts/{identity}/approve', status_code=202)", - "errors": [ - "HTTPException(409, 'Only a rendered playout can be approved for public playback')" - ] - }, - { - "method": "POST", - "path": "/v1/playouts/{identity}/publish", - "router": "app", - "prefix_resolved": true, - "name": "publish", - "signature": "identity: UUID, proof: str | None=Header(default=None, alias='X-Townlight-Session')", - "returns": "", - "line": 256, - "doc": "", - "decorator": "app.post('/v1/playouts/{identity}/publish', status_code=202)", - "errors": [ - "HTTPException(404, 'Playout not found')", - "HTTPException(409, 'Explicit staff approval is required before public playback')" - ] - }, - { - "method": "GET", - "path": "/v1/public/playback/{identity}", - "router": "app", - "prefix_resolved": true, - "name": "public_playback", - "signature": "identity: UUID", - "returns": "", - "line": 285, - "doc": "", - "decorator": "app.get('/v1/public/playback/{identity}')", - "errors": [ - "HTTPException(404, 'Playback not found')", - "HTTPException(409, 'Playback integrity failure')" - ] - }, - { - "method": "GET", - "path": "/v1/public/playback/{identity}/captions", - "router": "app", - "prefix_resolved": true, - "name": "public_captions", - "signature": "identity: UUID", - "returns": "", - "line": 301, - "doc": "", - "decorator": "app.get('/v1/public/playback/{identity}/captions')", - "errors": [ - "HTTPException(404, 'Captions not found')", - "HTTPException(409, 'Caption integrity failure')" - ] - }, - { - "method": "GET", - "path": "/v1/public/playback/{identity}/program", - "router": "app", - "prefix_resolved": true, - "name": "public_program", - "signature": "identity: UUID", - "returns": "", - "line": 315, - "doc": "", - "decorator": "app.get('/v1/public/playback/{identity}/program')", - "errors": [ - "HTTPException(404, 'Playback not found')", - "HTTPException(409, 'Playback integrity failure')" - ] - } - ], - "models": [ - { - "name": "ScheduleRequest", - "bases": [ - "BaseModel" - ], - "fields": [ - { - "name": "meeting_id", - "type": "UUID", - "default": "" - }, - { - "name": "agenda_ids", - "type": "list[UUID]", - "default": "Field(default_factory=list, max_length=100)" - }, - { - "name": "source_file", - "type": "str | None", - "default": "Field(default=None, pattern='^[A-Za-z0-9][A-Za-z0-9_.-]{0,180}$')" - }, - { - "name": "live_source_id", - "type": "str | None", - "default": "Field(default=None, pattern='^[A-Za-z0-9_-]{1,64}$')" - }, - { - "name": "captions_file", - "type": "str | None", - "default": "Field(default=None, pattern='^[A-Za-z0-9][A-Za-z0-9_.-]{0,180}\\\\.srt$')" - }, - { - "name": "start_at", - "type": "datetime", - "default": "" - }, - { - "name": "idempotency_key", - "type": "str", - "default": "Field(min_length=1, max_length=100)" - } - ], - "line": 58, - "doc": "" - }, - { - "name": "PlayoutRequest", - "bases": [ - "BaseModel" - ], - "fields": [ - { - "name": "recording_id", - "type": "UUID", - "default": "" - }, - { - "name": "mode", - "type": "str", - "default": "Field(pattern='^(dry-run|commit)$')" - }, - { - "name": "idempotency_key", - "type": "str", - "default": "Field(min_length=1, max_length=100)" - } - ], - "line": 69, - "doc": "" - }, - { - "name": "ApprovalRequest", - "bases": [ - "BaseModel" - ], - "fields": [ - { - "name": "note", - "type": "str", - "default": "Field(min_length=3, max_length=500)" - } - ], - "line": 76, - "doc": "" - }, - { - "name": "LiveOverrideRequest", - "bases": [ - "BaseModel" - ], - "fields": [ - { - "name": "live_source_id", - "type": "str", - "default": "Field(pattern='^[A-Za-z0-9_-]{1,64}$')" - }, - { - "name": "reason", - "type": "str", - "default": "Field(min_length=3, max_length=200)" - } - ], - "line": 81, - "doc": "An on-air override naming an administrator-configured live input." - } - ], + "source": "desktop/src/records/controller.ts", + "sha256": "f57adefbdb21a06a96b818b043f9be7e1d52d081738085bae1d95f9172efebb9", + "bytes": 3420, + "routes": [], + "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_station/operator.py", - "sha256": "6471894a1240b611a2bf006867ce79848630f6dc69270e29e54b71dbb26f3837", - "routes": [ - { - "method": "POST", - "path": "/v1/operator-ticket", - "router": "app", - "prefix_resolved": true, - "name": "issue", - "signature": "proof: str | None=Header(default=None, alias='X-Townlight-Session')", - "returns": "", - "line": 51, - "doc": "", - "decorator": "app.post('/v1/operator-ticket')", - "errors": [ - "HTTPException(429, 'Too many outstanding operator launches')" - ] - }, - { - "method": "POST", - "path": "/operator/session", - "router": "app", - "prefix_resolved": true, - "name": "exchange", - "signature": "data: Ticket, request: Request", - "returns": "", - "line": 60, - "doc": "", - "decorator": "app.post('/operator/session')", - "errors": [ - "HTTPException(401, 'Launch link expired or already used; reopen Station from the signed-in staff session')", - "HTTPException(429, 'Operator session capacity reached')" - ] - }, - { - "method": "POST", - "path": "/operator/logout", - "router": "app", - "prefix_resolved": true, - "name": "logout", - "signature": "request: Request", - "returns": "", - "line": 75, - "doc": "", - "decorator": "app.post('/operator/logout')", - "errors": [] - }, - { - "method": "GET", - "path": "/operator/catalog", - "router": "app", - "prefix_resolved": true, - "name": "catalog", - "signature": "proof: str | None=Header(default=None, alias='X-Townlight-Session')", - "returns": "", - "line": 82, - "doc": "", - "decorator": "app.get('/operator/catalog')", - "errors": [] - }, - { - "method": "GET", - "path": "/operator/meeting/{identity}", - "router": "app", - "prefix_resolved": true, - "name": "meeting", - "signature": "identity: UUID, proof: str | None=Header(default=None, alias='X-Townlight-Session')", - "returns": "", - "line": 102, - "doc": "", - "decorator": "app.get('/operator/meeting/{identity}')", - "errors": [] - }, - { - "method": "POST", - "path": "/operator/handoff", - "router": "app", - "prefix_resolved": true, - "name": "handoff", - "signature": "data: Handoff, proof: str | None=Header(default=None, alias='X-Townlight-Session')", - "returns": "", - "line": 106, - "doc": "", - "decorator": "app.post('/operator/handoff')", - "errors": [ - "HTTPException(result.status_code if result.status_code in (401, 403, 404, 409, 422) else 503, 'Records did not accept the recording. Check your Records role and request, then retry.')", - "HTTPException(503, 'Records unavailable. Retry safely; existing attachments are preserved.')" - ] - }, - { - "method": "GET", - "path": "/", - "router": "app", - "prefix_resolved": true, - "name": "page", - "signature": "", - "returns": "", - "line": 124, - "doc": "", - "decorator": "app.get('/')", - "errors": [] - }, - { - "method": "GET", - "path": "/operator.js", - "router": "app", - "prefix_resolved": true, - "name": "script", - "signature": "", - "returns": "", - "line": 128, - "doc": "", - "decorator": "app.get('/operator.js')", - "errors": [] - }, - { - "method": "GET", - "path": "/operator.css", - "router": "app", - "prefix_resolved": true, - "name": "style", - "signature": "", - "returns": "", - "line": 132, - "doc": "", - "decorator": "app.get('/operator.css')", - "errors": [] - } - ], - "models": [ - { - "name": "Ticket", - "bases": [ - "BaseModel" - ], - "fields": [ - { - "name": "ticket", - "type": "str", - "default": "Field(min_length=32, max_length=128)" - } - ], - "line": 13, - "doc": "" - }, - { - "name": "Handoff", - "bases": [ - "BaseModel" - ], - "fields": [ - { - "name": "request_id", - "type": "UUID", - "default": "" - }, - { - "name": "recording_id", - "type": "UUID", - "default": "" - }, - { - "name": "expected_sha256", - "type": "str", - "default": "Field(pattern='^[0-9a-f]{64}$')" - } - ], - "line": 18, - "doc": "" - } - ], + "source": "desktop/src/records/meetings-sources.ts", + "sha256": "ba5be1b8f0c1854ec777a69e7f5e307785f34d4a929179eabbcea6cf09712c6f", + "bytes": 3211, + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "desktop/src/records/planning-sources.ts", + "sha256": "98217a4d2c88068c036e9c9d5c2ba8e89f47fc74cc8054e3d4230c421199cbad", + "bytes": 3383, + "routes": [], + "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_station/packaging.py", - "sha256": "e4b1cbdfaab908f44d8acafb0e024fa99439a66eaedfaeb2655a63293b626e82", + "source": "desktop/src/records/view.js", + "sha256": "78b60d7322fffa44e77e9431ed194fae3470fc0210f81801aa2961c186b73db1", + "bytes": 26073, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_station/store.py", - "sha256": "d9aca0003057897a435c7c310559620f727a1703d625bd87af5c7c505d7e3fbd", + "source": "desktop/src/records/zoning-sources.ts", + "sha256": "333ba5a17c34e45627b04b185e4259a128cb624b2842943be770aa1db323064c", + "bytes": 3340, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_station/vod_job.py", - "sha256": "dfb3669fa0331fdb481cf765825e67cdf8432ed8c40eff9b5f2b7b34f42648f8", + "source": "desktop/src/styles.css", + "sha256": "9e3baf03bb8bc258d3fd4548ba0d1fdab73edde1fc30f20bf055675ee6b7ee99", + "bytes": 19655, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_station/windows_service.py", - "sha256": "ed2c3b73b8033413b2d28700a686ee6f71f01db11b3d95c4a2d2109d340c782f", + "source": "desktop/src/zoning/client.ts", + "sha256": "aac2300bcc8ca6be214937da2905b03e65cecd4ae671a35052ec0f2e59f8b9ee", + "bytes": 5810, "routes": [], "models": [], "configuration": [] }, { - "source": "installed-owned-source/townlight_station/worker.py", - "sha256": "f026f53950f3e7dc881831ad1c15818caf5fed27cb2f01fd3ebb0992121be2a1", + "source": "desktop/src/zoning/view.js", + "sha256": "3548b0755bde1ec2db0396e03f4f56f5b3dfa679fa25da7f1473844cfa4a5b4d", + "bytes": 11823, "routes": [], "models": [], "configuration": [] } - ], - "bridge": [] + ] } } -} \ No newline at end of file +} diff --git a/docs/history/pre-naming-2026-11/source-inventory.json b/docs/history/pre-naming-2026-11/source-inventory.json new file mode 100644 index 0000000..7b307de --- /dev/null +++ b/docs/history/pre-naming-2026-11/source-inventory.json @@ -0,0 +1,38440 @@ +{ + "candidate_source_sha256": "84a23e1297e42d17b16cfc9e51b2dd78bc46414c0de8ad7ebd2466c1a409d06b", + "basis": "Immutable corresponding source of signed candidate; AST extraction is not executed endpoint acceptance. Router mounts require runtime OpenAPI or source include_router context.", + "products": { + "core": { + "package": "townlight_core", + "source": [ + { + "source": "installed-owned-source/townlight_core/__init__.py", + "sha256": "22823aa2e5f34ff62c57276cc877fc52fb6c654877b5e3756d6dccdb40f7dc15", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/audit/__init__.py", + "sha256": "9066c9b752564f42427bb925f2ec72e92007f389fbec24b3bde90655cfb3c9d9", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/audit/primitives.py", + "sha256": "293ba8cf2d89165bf50d1fb019c05a4a1e5a1ca22c3703be25f6c96014491d3a", + "routes": [], + "models": [ + { + "name": "AuditActor", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "actor_id", + "type": "str", + "default": "" + }, + { + "name": "actor_type", + "type": "str", + "default": "" + }, + { + "name": "display_name", + "type": "str | None", + "default": "None" + } + ], + "line": 55, + "doc": "Actor that initiated an auditable action." + }, + { + "name": "AuditSubject", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "subject_id", + "type": "str", + "default": "" + }, + { + "name": "subject_type", + "type": "str", + "default": "" + }, + { + "name": "display_name", + "type": "str | None", + "default": "None" + } + ], + "line": 65, + "doc": "Record, document, workflow, or other entity affected by an action." + }, + { + "name": "AuditEvent", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "event_id", + "type": "str", + "default": "Field(default_factory=lambda: str(uuid4()))" + }, + { + "name": "actor", + "type": "AuditActor", + "default": "" + }, + { + "name": "action", + "type": "str", + "default": "" + }, + { + "name": "subject", + "type": "AuditSubject", + "default": "" + }, + { + "name": "source_module", + "type": "str", + "default": "" + }, + { + "name": "timestamp", + "type": "datetime", + "default": "Field(default_factory=_utc_now)" + }, + { + "name": "metadata", + "type": "dict[str, Any]", + "default": "Field(default_factory=dict)" + }, + { + "name": "previous_hash", + "type": "str | None", + "default": "None" + }, + { + "name": "current_hash", + "type": "str | None", + "default": "None" + } + ], + "line": 75, + "doc": "One audit event with deterministic hash-chain fields." + }, + { + "name": "AuditHashChain", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "events", + "type": "list[AuditEvent]", + "default": "Field(default_factory=list)" + } + ], + "line": 159, + "doc": "In-memory helper for building and verifying hash-chained events." + }, + { + "name": "PersistedAuditLogEntry", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "previous_hash", + "type": "str", + "default": "Field(default=ZERO_HASH, min_length=64, max_length=64)" + }, + { + "name": "entry_hash", + "type": "str", + "default": "Field(min_length=64, max_length=64)" + }, + { + "name": "timestamp", + "type": "datetime | str", + "default": "" + }, + { + "name": "actor_id", + "type": "str | None", + "default": "None" + }, + { + "name": "action", + "type": "str", + "default": "" + }, + { + "name": "details", + "type": "dict[str, Any] | None", + "default": "None" + }, + { + "name": "entry_id", + "type": "int | str | None", + "default": "None" + } + ], + "line": 192, + "doc": "Storage-neutral view of a legacy persisted audit-log row.\n\nThis model preserves the historical Townlight Records hash formula for\ndatabase-backed ``audit_log`` rows. It intentionally lives beside, rather\nthan replacing, ``AuditEvent`` because existing deployed rows must continue\nto verify after modules move their reusable audit math into Townlight Core." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/auth/__init__.py", + "sha256": "7a3f307c6fc4ac465688b2ad83b49b85d551721d248e569d0acbb8bf0db49f5a", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/auth/bearer.py", + "sha256": "6515b07ecf4be9fc344ab05eeef891b165f3e0310387dfa3a59fc2531c5dacb9", + "routes": [], + "models": [ + { + "name": "AuthenticatedPrincipal", + "bases": [], + "fields": [ + { + "name": "token_fingerprint", + "type": "str | None", + "default": "" + }, + { + "name": "roles", + "type": "frozenset[str]", + "default": "" + }, + { + "name": "auth_method", + "type": "str", + "default": "'bearer'" + }, + { + "name": "subject", + "type": "str | None", + "default": "None" + }, + { + "name": "provider", + "type": "str | None", + "default": "None" + } + ], + "line": 16, + "doc": "Represents the caller that satisfied a bearer-token role check." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/auth/department_scope.py", + "sha256": "57905c13074c10acdf07f7a353634bf3e51b1f42f67cd6f7b3d8920dca91f7d1", + "routes": [], + "models": [ + { + "name": "DepartmentGrant", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "scope_id", + "type": "str", + "default": "Field(min_length=2, max_length=64)" + }, + { + "name": "subject", + "type": "str", + "default": "Field(min_length=1, max_length=320)" + }, + { + "name": "department_id", + "type": "UUID", + "default": "" + }, + { + "name": "sequence", + "type": "int", + "default": "Field(ge=1)" + }, + { + "name": "action", + "type": "GrantAction", + "default": "" + }, + { + "name": "roles", + "type": "tuple[str, ...]", + "default": "()" + }, + { + "name": "recorded_by", + "type": "str", + "default": "Field(min_length=1, max_length=128)" + }, + { + "name": "recorded_at", + "type": "AwareDatetime", + "default": "" + }, + { + "name": "content_sha256", + "type": "str", + "default": "Field(min_length=64, max_length=64)" + } + ], + "line": 148, + "doc": "One persisted grant/revoke event for a subject in one scope and department.\n\nRows are append-only: a ``revoke`` event does not delete the earlier ``grant`` event, it\nsupersedes it. ``sequence`` is monotonic per ``(scope_id, subject, department_id)`` so the\nactive state is always the highest-sequence event." + }, + { + "name": "DepartmentEntitlement", + "bases": [], + "fields": [ + { + "name": "department_id", + "type": "UUID", + "default": "" + }, + { + "name": "roles", + "type": "frozenset[str]", + "default": "" + }, + { + "name": "granted_by", + "type": "str", + "default": "" + }, + { + "name": "granted_at", + "type": "datetime", + "default": "" + } + ], + "line": 210, + "doc": "A department this subject may reach, with the roles granted there." + }, + { + "name": "DepartmentAuthority", + "bases": [], + "fields": [ + { + "name": "scope_id", + "type": "str", + "default": "" + }, + { + "name": "subject", + "type": "str", + "default": "" + }, + { + "name": "auth_method", + "type": "str", + "default": "" + }, + { + "name": "provider", + "type": "str | None", + "default": "" + }, + { + "name": "roles", + "type": "frozenset[str]", + "default": "" + }, + { + "name": "entitlements", + "type": "tuple[DepartmentEntitlement, ...]", + "default": "" + }, + { + "name": "resolved_at", + "type": "datetime", + "default": "" + }, + { + "name": "grants_digest", + "type": "str", + "default": "" + }, + { + "name": "provenance", + "type": "Literal['persisted-grant']", + "default": "'persisted-grant'" + }, + { + "name": "_token", + "type": "Any", + "default": "field(default=None, repr=False, compare=False)" + } + ], + "line": 220, + "doc": "The only object Core consumers may use to scope search, exports and model context.\n\nInstances are produced by :func:`resolve_department_authority`. Direct construction raises\n:class:`AuthorityProvenanceError`, because a hand-built authority would be exactly the\n\"trust the caller's department claim\" hole this contract exists to close." + }, + { + "name": "GrantOutcome", + "bases": [], + "fields": [ + { + "name": "grant", + "type": "DepartmentGrant", + "default": "" + }, + { + "name": "inserted", + "type": "bool", + "default": "" + } + ], + "line": 437, + "doc": "Result of an append attempt. ``inserted`` is False for an exact repeat." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/auth/staff_key.py", + "sha256": "ef7dc371bcd7f419d6266cc61aad01884f263edbcca5db7d5ba4dc1e91d251db", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/auth/suite_session.py", + "sha256": "e33e13634568261accb2ba6706402de013975f3c58117b987cced3cd92c0db2e", + "routes": [], + "models": [ + { + "name": "SuiteSessionPrincipal", + "bases": [], + "fields": [ + { + "name": "subject", + "type": "str", + "default": "" + }, + { + "name": "roles", + "type": "frozenset[str]", + "default": "" + }, + { + "name": "session_id", + "type": "str", + "default": "" + } + ], + "line": 35, + "doc": "Immutable principal decoded from a shared Townlight staff session." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/auth/trusted_headers.py", + "sha256": "771e7cbf1f5d73dafad082d97ebb6e350a49b15362ce50eb36b261172e3b9c5c", + "routes": [], + "models": [ + { + "name": "TrustedHeaderAuthConfig", + "bases": [], + "fields": [ + { + "name": "provider_name", + "type": "str", + "default": "" + }, + { + "name": "principal_header_name", + "type": "str", + "default": "" + }, + { + "name": "roles_header_name", + "type": "str", + "default": "" + }, + { + "name": "trusted_proxy_cidrs", + "type": "tuple[str, ...]", + "default": "" + } + ], + "line": 17, + "doc": "Service-specific trusted-header auth settings loaded from env/defaults." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/catalog/__init__.py", + "sha256": "e323a7808ae719b4b90530c238dc945a107ee1cf9a9050cb00d7efbf5aa1a823", + "routes": [], + "models": [ + { + "name": "SystemInput", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "vendor_name", + "type": "str", + "default": "Field(min_length=1, max_length=200)" + }, + { + "name": "access_protocol", + "type": "str", + "default": "Field(min_length=1, max_length=50)" + }, + { + "name": "data_shape", + "type": "str", + "default": "Field(min_length=1, max_length=50)" + }, + { + "name": "common_record_types", + "type": "list[str]", + "default": "Field(max_length=100)" + }, + { + "name": "redaction_tier", + "type": "int", + "default": "Field(ge=1, le=3)" + }, + { + "name": "discovery_hints", + "type": "dict", + "default": "Field(default_factory=dict)" + } + ], + "line": 16, + "doc": "" + }, + { + "name": "DomainInput", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "domain", + "type": "str", + "default": "Field(min_length=1, max_length=100)" + }, + { + "name": "systems", + "type": "list[SystemInput]", + "default": "Field(max_length=500)" + } + ], + "line": 38, + "doc": "" + }, + { + "name": "CatalogInput", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "catalog_version", + "type": "str", + "default": "Field(min_length=1, max_length=20)" + }, + { + "name": "domains", + "type": "list[DomainInput]", + "default": "Field(max_length=100)" + } + ], + "line": 44, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/city_profile/__init__.py", + "sha256": "c22e26dac2fcb454cbf91bcbf23311fdef9bf854fbb2bba2d76149945986bd72", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/city_profile/models.py", + "sha256": "e34b6bbc69f44656ad22217de2b911b5c437fb226b594439f935705c95a47ed6", + "routes": [], + "models": [ + { + "name": "DepartmentProfile", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "name", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "slug", + "type": "str", + "default": "Field(min_length=1, pattern='^[a-z0-9][a-z0-9-]*$')" + }, + { + "name": "public_email", + "type": "str | None", + "default": "Field(default=None, min_length=3)" + }, + { + "name": "public_phone", + "type": "str | None", + "default": "Field(default=None, min_length=3)" + } + ], + "line": 16, + "doc": "A city department surfaced during local onboarding." + }, + { + "name": "DeploymentProfile", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "mode", + "type": "Literal['local_demo', 'local', 'self_hosted']", + "default": "'local_demo'" + }, + { + "name": "allow_outbound_services", + "type": "bool", + "default": "False" + } + ], + "line": 27, + "doc": "Deployment posture for a profile without acting as an installer." + }, + { + "name": "ModuleEnablement", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "name", + "type": "str", + "default": "Field(min_length=1, pattern='^[a-z0-9][a-z0-9_-]*$')" + }, + { + "name": "enabled", + "type": "bool", + "default": "True" + }, + { + "name": "settings", + "type": "dict[str, Any]", + "default": "Field(default_factory=dict)" + } + ], + "line": 36, + "doc": "Per-module enablement flags and local configuration metadata." + }, + { + "name": "CityProfile", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "city_name", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "timezone", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "departments", + "type": "list[DepartmentProfile]", + "default": "Field(default_factory=list)" + }, + { + "name": "enabled_modules", + "type": "list[ModuleEnablement]", + "default": "Field(default_factory=list)" + }, + { + "name": "default_llm_provider", + "type": "str", + "default": "'ollama'" + }, + { + "name": "file_drop_roots", + "type": "list[Path]", + "default": "Field(default_factory=list)" + }, + { + "name": "public_contact", + "type": "dict[str, str]", + "default": "Field(default_factory=dict)" + }, + { + "name": "deployment", + "type": "DeploymentProfile", + "default": "Field(default_factory=DeploymentProfile)" + } + ], + "line": 46, + "doc": "Local city profile loaded from trusted JSON/YAML configuration." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/connectors/__init__.py", + "sha256": "92d5a39aa8241f8fed6405fd0a8b3068994fdeb66ea3f80975ff708dde673870", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/connectors/delta.py", + "sha256": "d99e5624e0eebcc434146909d65040eba0023cc84b2d5d03ce1de2b36c70e52f", + "routes": [], + "models": [ + { + "name": "VendorDeltaRequestPlan", + "bases": [], + "fields": [ + { + "name": "connector", + "type": "str", + "default": "" + }, + { + "name": "request_url", + "type": "str", + "default": "" + }, + { + "name": "delta_enabled", + "type": "bool", + "default": "" + }, + { + "name": "cursor_param", + "type": "str | None", + "default": "" + }, + { + "name": "cursor_value", + "type": "str | None", + "default": "" + }, + { + "name": "message", + "type": "str", + "default": "" + }, + { + "name": "fix", + "type": "str", + "default": "" + } + ], + "line": 19, + "doc": "Storage-neutral plan for a full or cursor-based vendor pull." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/connectors/imports.py", + "sha256": "1ed6dafe0072eb57327e7d61b12df801f79bfb9ea7ea1738548afb5a002e0606", + "routes": [], + "models": [ + { + "name": "ConnectorImportError", + "bases": [ + "ValueError" + ], + "fields": [ + { + "name": "message", + "type": "str", + "default": "" + }, + { + "name": "fix", + "type": "str", + "default": "" + } + ], + "line": 13, + "doc": "Actionable validation error for local connector import payloads." + }, + { + "name": "ImportedAgendaItem", + "bases": [], + "fields": [ + { + "name": "external_item_id", + "type": "str", + "default": "" + }, + { + "name": "title", + "type": "str", + "default": "" + }, + { + "name": "department", + "type": "str | None", + "default": "" + }, + { + "name": "connector", + "type": "str", + "default": "" + } + ], + "line": 27, + "doc": "Normalized agenda item imported from a local connector payload." + }, + { + "name": "ImportedMeeting", + "bases": [], + "fields": [ + { + "name": "connector", + "type": "str", + "default": "" + }, + { + "name": "external_meeting_id", + "type": "str", + "default": "" + }, + { + "name": "title", + "type": "str", + "default": "" + }, + { + "name": "scheduled_start", + "type": "str", + "default": "" + }, + { + "name": "agenda_items", + "type": "tuple[ImportedAgendaItem, ...]", + "default": "" + } + ], + "line": 49, + "doc": "Normalized meeting imported from a local connector payload." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/connectors/manifest.py", + "sha256": "15caa167acce428facdf7683085d47dd4a01b02cc2d05df25d6aa1d157bb79bd", + "routes": [], + "models": [ + { + "name": "ManifestFile", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "path", + "type": "str", + "default": "" + }, + { + "name": "byte_size", + "type": "int", + "default": "Field(ge=0)" + }, + { + "name": "sha256", + "type": "str", + "default": "" + }, + { + "name": "media_type", + "type": "str | None", + "default": "None" + }, + { + "name": "description", + "type": "str | None", + "default": "None" + } + ], + "line": 43, + "doc": "A file entry recorded in an import or export manifest." + }, + { + "name": "_ManifestBase", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "manifest_version", + "type": "str", + "default": "'1.0'" + }, + { + "name": "module_name", + "type": "str", + "default": "" + }, + { + "name": "module_version", + "type": "str", + "default": "" + }, + { + "name": "townlight_core_version", + "type": "str", + "default": "" + }, + { + "name": "purpose", + "type": "ManifestPurpose", + "default": "" + }, + { + "name": "source_files", + "type": "list[ManifestFile]", + "default": "Field(default_factory=list)" + }, + { + "name": "generated_files", + "type": "list[ManifestFile]", + "default": "Field(default_factory=list)" + }, + { + "name": "limitations", + "type": "list[str]", + "default": "Field(default_factory=list)" + } + ], + "line": 79, + "doc": "" + }, + { + "name": "ImportManifest", + "bases": [ + "_ManifestBase" + ], + "fields": [ + { + "name": "purpose", + "type": "ImportPurpose", + "default": "" + } + ], + "line": 123, + "doc": "Manifest for offline file-drop, CSV, or GeoJSON imports." + }, + { + "name": "ExportManifest", + "bases": [ + "_ManifestBase" + ], + "fields": [ + { + "name": "purpose", + "type": "ExportPurpose", + "default": "'static_export_bundle'" + } + ], + "line": 135, + "doc": "Manifest for an offline static export bundle." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/connectors/sync.py", + "sha256": "ef8bb329bf9d385fd96c617e58a8495989dd76a5d641e0afae3fcf3cba2ca503", + "routes": [], + "models": [ + { + "name": "SyncRetryPolicy", + "bases": [], + "fields": [ + { + "name": "max_attempts", + "type": "int", + "default": "3" + }, + { + "name": "base_delay_seconds", + "type": "float", + "default": "1.0" + }, + { + "name": "jitter_factor", + "type": "float", + "default": "0.2" + }, + { + "name": "max_backoff_seconds", + "type": "float", + "default": "30.0" + }, + { + "name": "retry_after_cap_seconds", + "type": "float", + "default": "600.0" + } + ], + "line": 28, + "doc": "HTTP retry policy for live vendor connector calls." + }, + { + "name": "SyncCircuitPolicy", + "bases": [], + "fields": [ + { + "name": "full_failure_threshold", + "type": "int", + "default": "5" + }, + { + "name": "grace_period_failure_threshold", + "type": "int", + "default": "2" + }, + { + "name": "grace_period_reason", + "type": "str", + "default": "'grace_period'" + } + ], + "line": 43, + "doc": "Circuit-breaker thresholds shared by live connector consumers." + }, + { + "name": "SyncCircuitState", + "bases": [], + "fields": [ + { + "name": "connector", + "type": "str", + "default": "" + }, + { + "name": "source_name", + "type": "str", + "default": "'connector source'" + }, + { + "name": "consecutive_failure_count", + "type": "int", + "default": "0" + }, + { + "name": "active_failure_count", + "type": "int", + "default": "0" + }, + { + "name": "sync_paused", + "type": "bool", + "default": "False" + }, + { + "name": "sync_paused_at", + "type": "datetime | None", + "default": "None" + }, + { + "name": "sync_paused_reason", + "type": "str | None", + "default": "None" + }, + { + "name": "last_sync_status", + "type": "str | None", + "default": "None" + }, + { + "name": "last_error_at", + "type": "datetime | None", + "default": "None" + } + ], + "line": 52, + "doc": "Storage-neutral state needed to compute live-sync health." + }, + { + "name": "SyncRunResult", + "bases": [], + "fields": [ + { + "name": "records_discovered", + "type": "int", + "default": "" + }, + { + "name": "records_succeeded", + "type": "int", + "default": "" + }, + { + "name": "records_failed", + "type": "int", + "default": "" + }, + { + "name": "retries_attempted", + "type": "int", + "default": "0" + }, + { + "name": "error_summary", + "type": "str | None", + "default": "None" + } + ], + "line": 71, + "doc": "Normalized result summary for one connector sync run." + }, + { + "name": "SyncOperatorStatus", + "bases": [], + "fields": [ + { + "name": "connector", + "type": "str", + "default": "" + }, + { + "name": "source_name", + "type": "str", + "default": "" + }, + { + "name": "health_status", + "type": "SyncHealthStatus", + "default": "" + }, + { + "name": "consecutive_failure_count", + "type": "int", + "default": "" + }, + { + "name": "active_failure_count", + "type": "int", + "default": "" + }, + { + "name": "sync_paused", + "type": "bool", + "default": "" + }, + { + "name": "sync_paused_reason", + "type": "str | None", + "default": "" + }, + { + "name": "message", + "type": "str", + "default": "" + }, + { + "name": "fix", + "type": "str", + "default": "" + } + ], + "line": 94, + "doc": "Actionable health copy that can be rendered directly in module UIs." + }, + { + "name": "SyncSourceStatus", + "bases": [], + "fields": [ + { + "name": "connector", + "type": "str", + "default": "" + }, + { + "name": "source_name", + "type": "str", + "default": "" + }, + { + "name": "health_status", + "type": "SyncHealthStatus", + "default": "" + }, + { + "name": "consecutive_failure_count", + "type": "int", + "default": "" + }, + { + "name": "active_failure_count", + "type": "int", + "default": "" + }, + { + "name": "sync_paused", + "type": "bool", + "default": "" + }, + { + "name": "sync_paused_reason", + "type": "str | None", + "default": "" + }, + { + "name": "last_sync_status", + "type": "str | None", + "default": "" + }, + { + "name": "next_sync_at", + "type": "datetime | None", + "default": "" + }, + { + "name": "message", + "type": "str", + "default": "" + }, + { + "name": "fix", + "type": "str", + "default": "" + } + ], + "line": 122, + "doc": "Storage-neutral status projection for module connector source lists." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/db/__init__.py", + "sha256": "19fc1241d2d81b136813d1ca7ebb47d3831a5ffccec8b548237577ddcd65aebb", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/exemptions/__init__.py", + "sha256": "83575c21379e697bbbc42b124c8674d8dc99020006f4806237eed0fb71083173", + "routes": [], + "models": [ + { + "name": "Rule", + "bases": [], + "fields": [ + { + "name": "id", + "type": "UUID", + "default": "" + }, + { + "name": "state_code", + "type": "str", + "default": "" + }, + { + "name": "category", + "type": "str", + "default": "" + }, + { + "name": "rule_type", + "type": "str", + "default": "" + }, + { + "name": "definition", + "type": "str", + "default": "" + }, + { + "name": "version", + "type": "int", + "default": "" + } + ], + "line": 26, + "doc": "" + }, + { + "name": "FlagResult", + "bases": [], + "fields": [ + { + "name": "category", + "type": "str", + "default": "" + }, + { + "name": "matched_text", + "type": "str", + "default": "" + }, + { + "name": "confidence", + "type": "float", + "default": "" + }, + { + "name": "rule_id", + "type": "UUID | None", + "default": "None" + }, + { + "name": "rule_type", + "type": "str", + "default": "'regex'" + }, + { + "name": "rule_version", + "type": "int | None", + "default": "None" + } + ], + "line": 36, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/exemptions/history.py", + "sha256": "b6b1e5be26a6c7a16391d34b6e50e4c08eb19d5cc25788db8917b0b46044b0ea", + "routes": [], + "models": [ + { + "name": "RuleVersionInput", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "rule_id", + "type": "UUID", + "default": "" + }, + { + "name": "state_code", + "type": "str", + "default": "Field(min_length=2, max_length=2)" + }, + { + "name": "version", + "type": "int", + "default": "Field(ge=1)" + }, + { + "name": "category", + "type": "str", + "default": "Field(min_length=1, max_length=100)" + }, + { + "name": "rule_type", + "type": "Literal['regex', 'keyword']", + "default": "" + }, + { + "name": "rule_definition", + "type": "str", + "default": "Field(min_length=1, max_length=8000)" + }, + { + "name": "citation_text", + "type": "str", + "default": "Field(min_length=1, max_length=1000)" + }, + { + "name": "citation_url", + "type": "str | None", + "default": "Field(default=None, max_length=2000)" + }, + { + "name": "effective_from", + "type": "date | None", + "default": "None" + }, + { + "name": "retrieved_at", + "type": "AwareDatetime", + "default": "" + }, + { + "name": "coverage_declaration", + "type": "Literal['synthetic-fixture', 'tenant-supplied']", + "default": "" + } + ], + "line": 93, + "doc": "One cited rule version as supplied by an authorized caller." + }, + { + "name": "RuleVersion", + "bases": [], + "fields": [ + { + "name": "rule_id", + "type": "UUID", + "default": "" + }, + { + "name": "state_code", + "type": "str", + "default": "" + }, + { + "name": "version", + "type": "int", + "default": "" + }, + { + "name": "category", + "type": "str", + "default": "" + }, + { + "name": "rule_type", + "type": "str", + "default": "" + }, + { + "name": "rule_definition", + "type": "str", + "default": "" + }, + { + "name": "citation_text", + "type": "str", + "default": "" + }, + { + "name": "citation_url", + "type": "str | None", + "default": "" + }, + { + "name": "effective_from", + "type": "date | None", + "default": "" + }, + { + "name": "retrieved_at", + "type": "object", + "default": "" + }, + { + "name": "coverage_declaration", + "type": "str", + "default": "" + }, + { + "name": "content_sha256", + "type": "str", + "default": "" + }, + { + "name": "recorded_by", + "type": "str", + "default": "" + } + ], + "line": 152, + "doc": "A persisted, immutable cited rule version." + }, + { + "name": "RecordOutcome", + "bases": [], + "fields": [ + { + "name": "rule_version", + "type": "RuleVersion", + "default": "" + }, + { + "name": "inserted", + "type": "bool", + "default": "" + }, + { + "name": "fingerprint", + "type": "str", + "default": "" + } + ], + "line": 182, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/exemptions/patterns.py", + "sha256": "b8c4ea484f1fe521295d29eebcc36703c4560d274b36c88f5af28f5abded98af", + "routes": [], + "models": [ + { + "name": "PIIPattern", + "bases": [], + "fields": [ + { + "name": "name", + "type": "str", + "default": "" + }, + { + "name": "category", + "type": "str", + "default": "" + }, + { + "name": "pattern", + "type": "re.Pattern", + "default": "" + }, + { + "name": "description", + "type": "str", + "default": "" + }, + { + "name": "confidence", + "type": "float", + "default": "" + } + ], + "line": 15, + "doc": "" + }, + { + "name": "PIIMatch", + "bases": [], + "fields": [ + { + "name": "pattern_name", + "type": "str", + "default": "" + }, + { + "name": "category", + "type": "str", + "default": "" + }, + { + "name": "matched_text", + "type": "str", + "default": "" + }, + { + "name": "start", + "type": "int", + "default": "" + }, + { + "name": "end", + "type": "int", + "default": "" + }, + { + "name": "confidence", + "type": "float", + "default": "" + } + ], + "line": 149, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/exports/__init__.py", + "sha256": "7b46221c065defc5c31f148cdc5d2464ff6f665d786499b90a0059474fe9713c", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/exports/bundle.py", + "sha256": "22075c7ad189a9eb958b16a5cb4ef759213789f63e799e78b585a671a84ea5bd", + "routes": [], + "models": [ + { + "name": "ExportBundle", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "module_name", + "type": "str", + "default": "" + }, + { + "name": "module_version", + "type": "str", + "default": "" + }, + { + "name": "townlight_core_version", + "type": "str", + "default": "TOWNLIGHT_CORE_VERSION" + }, + { + "name": "purpose", + "type": "str", + "default": "'static_export_bundle'" + }, + { + "name": "files", + "type": "list[BundleFile]", + "default": "Field(default_factory=list)" + }, + { + "name": "limitations", + "type": "list[str]", + "default": "Field(default_factory=list)" + } + ], + "line": 54, + "doc": "Description of a static export bundle that can be validated offline." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/ingest/__init__.py", + "sha256": "6bef6d820315269d126b92aafa02a6d023c6c8706e378003a0cbad434318b791", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/ingest/chunker.py", + "sha256": "cf9515ec9aecfa7a5b4bbe077c99711ecce651c6c155a4bef07475e404a96c83", + "routes": [], + "models": [ + { + "name": "Chunk", + "bases": [], + "fields": [ + { + "name": "text", + "type": "str", + "default": "" + }, + { + "name": "index", + "type": "int", + "default": "" + }, + { + "name": "page_number", + "type": "int | None", + "default": "None" + }, + { + "name": "token_count", + "type": "int", + "default": "0" + } + ], + "line": 5, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/ingest/contracts.py", + "sha256": "7536789de18c66e150ad16986c44a794c6ad3353c5dd9e1b29b10f24fa5afaca", + "routes": [], + "models": [ + { + "name": "HealthCheckResult", + "bases": [], + "fields": [ + { + "name": "status", + "type": "HealthStatus", + "default": "" + }, + { + "name": "latency_ms", + "type": "int | None", + "default": "None" + }, + { + "name": "error_message", + "type": "str | None", + "default": "None" + }, + { + "name": "records_available", + "type": "int | None", + "default": "None" + }, + { + "name": "schema_hash", + "type": "str | None", + "default": "None" + }, + { + "name": "checked_at", + "type": "datetime", + "default": "field(default_factory=lambda: datetime.now(timezone.utc))" + } + ], + "line": 18, + "doc": "" + }, + { + "name": "DiscoveredRecord", + "bases": [], + "fields": [ + { + "name": "source_path", + "type": "str", + "default": "" + }, + { + "name": "filename", + "type": "str", + "default": "" + }, + { + "name": "file_type", + "type": "str", + "default": "" + }, + { + "name": "file_size", + "type": "int", + "default": "" + }, + { + "name": "last_modified", + "type": "datetime | None", + "default": "None" + }, + { + "name": "metadata", + "type": "dict", + "default": "field(default_factory=dict)" + } + ], + "line": 28, + "doc": "A record discovered in a source system." + }, + { + "name": "FetchedDocument", + "bases": [], + "fields": [ + { + "name": "source_path", + "type": "str", + "default": "" + }, + { + "name": "filename", + "type": "str", + "default": "" + }, + { + "name": "file_type", + "type": "str", + "default": "" + }, + { + "name": "content", + "type": "bytes", + "default": "" + }, + { + "name": "file_size", + "type": "int", + "default": "" + }, + { + "name": "metadata", + "type": "dict", + "default": "field(default_factory=dict)" + } + ], + "line": 40, + "doc": "A document fetched from a source system, ready for ingest." + }, + { + "name": "SourceMaterial", + "bases": [], + "fields": [ + { + "name": "source_id", + "type": "str", + "default": "" + }, + { + "name": "label", + "type": "str", + "default": "" + }, + { + "name": "text", + "type": "str", + "default": "" + } + ], + "line": 52, + "doc": "Human-readable source text that downstream workflows may cite." + }, + { + "name": "CitedSentence", + "bases": [], + "fields": [ + { + "name": "text", + "type": "str", + "default": "" + }, + { + "name": "citations", + "type": "tuple[str, ...]", + "default": "" + } + ], + "line": 68, + "doc": "One output sentence plus the source ids it cites." + }, + { + "name": "CitationValidationError", + "bases": [], + "fields": [ + { + "name": "message", + "type": "str", + "default": "" + }, + { + "name": "fix", + "type": "str", + "default": "" + } + ], + "line": 82, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/ingest/embedder.py", + "sha256": "655ae601f7901c847507e7ef4ab7cc3b77463e7ca1011831d9006b44cb3045ea", + "routes": [], + "models": [], + "configuration": [ + { + "variable": "OLLAMA_BASE_URL", + "default": "'http://localhost:11434'", + "line": 13 + } + ] + }, + { + "source": "installed-owned-source/townlight_core/ingest/llm_extractor.py", + "sha256": "bfa082031b17b4a1af58472eb3faac4cd6cbc91f2d9a2f7e59763f5c92fa5680", + "routes": [], + "models": [], + "configuration": [ + { + "variable": "OLLAMA_BASE_URL", + "default": "'http://localhost:11434'", + "line": 15 + } + ] + }, + { + "source": "installed-owned-source/townlight_core/ingest/models.py", + "sha256": "a10de63e573ec5d4df5d258265f07695e6ed1805b3cf02897828dfe6008f73bd", + "routes": [], + "models": [ + { + "name": "DataSource", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)" + }, + { + "name": "name", + "type": "Mapped[str]", + "default": "mapped_column(String(255), unique=True)" + }, + { + "name": "source_type", + "type": "Mapped[SourceType]", + "default": "mapped_column(Enum(SourceType, name='source_type', create_type=False, values_callable=lambda e: [m.value for m in e]))" + }, + { + "name": "connection_config", + "type": "Mapped[dict[str, Any]]", + "default": "mapped_column(JSONB, default=dict)" + }, + { + "name": "is_active", + "type": "Mapped[bool]", + "default": "mapped_column(Boolean, default=True)" + }, + { + "name": "created_by", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True))" + }, + { + "name": "created_at", + "type": "Mapped[datetime]", + "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + }, + { + "name": "last_ingestion_at", + "type": "Mapped[datetime | None]", + "default": "mapped_column(DateTime(timezone=True), nullable=True)" + }, + { + "name": "discovered_source_id", + "type": "Mapped[uuid.UUID | None]", + "default": "mapped_column(nullable=True)" + }, + { + "name": "connector_template_id", + "type": "Mapped[int | None]", + "default": "mapped_column(Integer, nullable=True)" + }, + { + "name": "sync_schedule", + "type": "Mapped[str | None]", + "default": "mapped_column(String(50), nullable=True)" + }, + { + "name": "schedule_enabled", + "type": "Mapped[bool]", + "default": "mapped_column(Boolean, default=True, server_default='true')" + }, + { + "name": "last_sync_at", + "type": "Mapped[datetime | None]", + "default": "mapped_column(DateTime(timezone=True), nullable=True)" + }, + { + "name": "last_sync_cursor", + "type": "Mapped[str | None]", + "default": "mapped_column(String, nullable=True)" + }, + { + "name": "last_sync_status", + "type": "Mapped[str | None]", + "default": "mapped_column(String(20), nullable=True)" + }, + { + "name": "consecutive_failure_count", + "type": "Mapped[int]", + "default": "mapped_column(Integer, default=0, server_default='0')" + }, + { + "name": "last_error_message", + "type": "Mapped[str | None]", + "default": "mapped_column(String(500), nullable=True)" + }, + { + "name": "last_error_at", + "type": "Mapped[datetime | None]", + "default": "mapped_column(DateTime(timezone=True), nullable=True)" + }, + { + "name": "sync_paused", + "type": "Mapped[bool]", + "default": "mapped_column(Boolean, default=False, server_default='false')" + }, + { + "name": "sync_paused_at", + "type": "Mapped[datetime | None]", + "default": "mapped_column(DateTime(timezone=True), nullable=True)" + }, + { + "name": "sync_paused_reason", + "type": "Mapped[str | None]", + "default": "mapped_column(String(200), nullable=True)" + }, + { + "name": "retry_batch_size", + "type": "Mapped[int | None]", + "default": "mapped_column(Integer, nullable=True)" + }, + { + "name": "retry_time_limit_seconds", + "type": "Mapped[int | None]", + "default": "mapped_column(Integer, nullable=True)" + }, + { + "name": "health_status", + "type": "Mapped[str | None]", + "default": "mapped_column(String(20), nullable=True)" + }, + { + "name": "schema_hash", + "type": "Mapped[str | None]", + "default": "mapped_column(String(64), nullable=True)" + } + ], + "line": 36, + "doc": "Source system or corpus that owns ingested documents." + }, + { + "name": "Document", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)" + }, + { + "name": "source_id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True), ForeignKey('data_sources.id'), index=True)" + }, + { + "name": "source_path", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "filename", + "type": "Mapped[str]", + "default": "mapped_column(String(500))" + }, + { + "name": "file_type", + "type": "Mapped[str]", + "default": "mapped_column(String(50))" + }, + { + "name": "file_hash", + "type": "Mapped[str]", + "default": "mapped_column(String(64), index=True)" + }, + { + "name": "file_size", + "type": "Mapped[int]", + "default": "mapped_column(Integer, default=0)" + }, + { + "name": "ingestion_status", + "type": "Mapped[IngestionStatus]", + "default": "mapped_column(Enum(IngestionStatus, name='ingestion_status', create_type=False, values_callable=lambda e: [m.value for m in e]), default=IngestionStatus.PENDING)" + }, + { + "name": "ingestion_error", + "type": "Mapped[str | None]", + "default": "mapped_column(Text, nullable=True)" + }, + { + "name": "chunk_count", + "type": "Mapped[int]", + "default": "mapped_column(Integer, default=0)" + }, + { + "name": "ingested_at", + "type": "Mapped[datetime | None]", + "default": "mapped_column(DateTime(timezone=True), nullable=True)" + }, + { + "name": "metadata_", + "type": "Mapped[dict[str, Any] | None]", + "default": "mapped_column('metadata', JSONB, nullable=True)" + }, + { + "name": "connector_type", + "type": "Mapped[str | None]", + "default": "mapped_column(String(20), nullable=True)" + }, + { + "name": "updated_at", + "type": "Mapped[datetime | None]", + "default": "mapped_column(DateTime(timezone=True), nullable=True)" + }, + { + "name": "display_name", + "type": "Mapped[str | None]", + "default": "mapped_column(String(500), nullable=True)" + }, + { + "name": "department_id", + "type": "Mapped[uuid.UUID | None]", + "default": "mapped_column(nullable=True)" + }, + { + "name": "redaction_status", + "type": "Mapped[str]", + "default": "mapped_column(String(20), server_default='none')" + }, + { + "name": "derivative_path", + "type": "Mapped[str | None]", + "default": "mapped_column(String(1000), nullable=True)" + }, + { + "name": "original_locked", + "type": "Mapped[bool]", + "default": "mapped_column(Boolean, server_default='false')" + } + ], + "line": 75, + "doc": "One ingested file or structured record." + }, + { + "name": "DocumentChunk", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)" + }, + { + "name": "document_id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True), ForeignKey('documents.id', ondelete='CASCADE'), index=True)" + }, + { + "name": "chunk_index", + "type": "Mapped[int]", + "default": "mapped_column(Integer)" + }, + { + "name": "content_text", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "embedding", + "type": "Mapped[list[float] | None]", + "default": "mapped_column(Vector(768), nullable=True)" + }, + { + "name": "token_count", + "type": "Mapped[int]", + "default": "mapped_column(Integer, default=0)" + }, + { + "name": "page_number", + "type": "Mapped[int | None]", + "default": "mapped_column(Integer, nullable=True)" + } + ], + "line": 113, + "doc": "Sentence-aware chunk text and vector embedding for one document." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/ingest/parsers/__init__.py", + "sha256": "f6d7f512bae3794abd587b16845f42af7689ada1f994aca134389f922a445537", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/ingest/parsers/base.py", + "sha256": "d2618295496026752492dcbab6230d8973ed51f4a91984f7150e1bb064c36423", + "routes": [], + "models": [ + { + "name": "ParsedPage", + "bases": [], + "fields": [ + { + "name": "text", + "type": "str", + "default": "" + }, + { + "name": "page_number", + "type": "int | None", + "default": "None" + }, + { + "name": "metadata", + "type": "dict", + "default": "field(default_factory=dict)" + } + ], + "line": 6, + "doc": "" + }, + { + "name": "ParseResult", + "bases": [], + "fields": [ + { + "name": "pages", + "type": "list[ParsedPage]", + "default": "" + }, + { + "name": "metadata", + "type": "dict", + "default": "field(default_factory=dict)" + }, + { + "name": "file_type", + "type": "str", + "default": "''" + } + ], + "line": 12, + "doc": "" + }, + { + "name": "BaseParser", + "bases": [ + "ABC" + ], + "fields": [ + { + "name": "supported_extensions", + "type": "list[str]", + "default": "[]" + } + ], + "line": 25, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/ingest/parsers/csv_parser.py", + "sha256": "7c8208fed09911e4f8153ab3c7d1fcfc281b5aec016589b697a728769bdcb41c", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/ingest/parsers/docx.py", + "sha256": "224542a9d2ebfdf9d3ef8947c7040ec683d13b507462a9c929e167c6b05529f3", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/ingest/parsers/email.py", + "sha256": "a83333d1ed5498fd56c61b47ce897b3d2c3b221070d7d13b000ea95336ea08e1", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/ingest/parsers/html.py", + "sha256": "a0383c330920702a913140377891e3eed43f029a3c756e9dceade4eb6d81b92e", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/ingest/parsers/pdf.py", + "sha256": "fe312d998d3224a5cc10ee28c6f76f50a856075b5338370baed56d83ebbc0032", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/ingest/parsers/text.py", + "sha256": "b77c107e8446d92e1fa0ce4f11ed54906e02c2bc5980c19e344c175d635c3441", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/ingest/parsers/xlsx.py", + "sha256": "3bd37c6f389644b630d44fe4964f5f82623469ae2855c04e81437b0fbe9f8fe0", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/ingest/pipeline.py", + "sha256": "6d1cbe9794d4bf98e22ddbf18ba4bed5bb96e8a0231f87075b92eeebac4bf570", + "routes": [], + "models": [ + { + "name": "IngestHandler", + "bases": [ + "Protocol" + ], + "fields": [ + { + "name": "supported_extensions", + "type": "list[str]", + "default": "" + } + ], + "line": 19, + "doc": "Parser-like handler contract for file suffixes." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/llm/__init__.py", + "sha256": "7f8341c07da53f39684a477f9b4fe88ce425a3dc5444f9ac6560eca9787bdac5", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/llm/context.py", + "sha256": "e7df765626e5ff642e0b86c36771379662ce35594b147391fef0566835762daa", + "routes": [], + "models": [ + { + "name": "TokenBudget", + "bases": [], + "fields": [ + { + "name": "system_instruction", + "type": "int", + "default": "500" + }, + { + "name": "request_context", + "type": "int", + "default": "500" + }, + { + "name": "retrieved_chunks", + "type": "int", + "default": "5000" + }, + { + "name": "exemption_rules", + "type": "int", + "default": "500" + }, + { + "name": "output_reservation", + "type": "int", + "default": "1500" + }, + { + "name": "safety_margin", + "type": "int", + "default": "192" + } + ], + "line": 34, + "doc": "Token budget allocation for an LLM call." + }, + { + "name": "ContextBlock", + "bases": [], + "fields": [ + { + "name": "role", + "type": "str", + "default": "" + }, + { + "name": "content", + "type": "str", + "default": "" + }, + { + "name": "estimated_tokens", + "type": "int", + "default": "0" + } + ], + "line": 57, + "doc": "A block of content with its role and estimated token count." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/llm/factory.py", + "sha256": "0497147ca6d8af7c4b233a4157089fe4911bb49d0ea214f4fce9ac4c65e48aee", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/llm/providers/__init__.py", + "sha256": "4decd4720c452fa27d1b245a603d409b7dc99db1c5015dbdb3ae29d745ac61fc", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/llm/providers/anthropic.py", + "sha256": "dba9eb64c724fe8a209dbac48743f99463f99e0c1c67b1306d9126985348b267", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/llm/providers/base.py", + "sha256": "fe430884bcaf7678f625db6203312e1f1dcdce617db36870623e87b5ac066b32", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/llm/providers/config.py", + "sha256": "db4ee77e2e0a3ac16fd71df4f0979fab89d36b2ff1985c1e2d4498299810fd3a", + "routes": [], + "models": [ + { + "name": "OllamaConfig", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "base_url", + "type": "str", + "default": "Field(default='http://localhost:11434')" + }, + { + "name": "default_model", + "type": "str", + "default": "Field(default='gemma4:e4b')" + }, + { + "name": "default_embed_model", + "type": "str", + "default": "Field(default='nomic-embed-text')" + }, + { + "name": "think", + "type": "bool | str | None", + "default": "Field(default=None)" + } + ], + "line": 12, + "doc": "Config schema for OllamaProvider.\n\nAll fields have sensible defaults \u2014 Ollama runs locally and does not\nrequire credentials." + }, + { + "name": "OpenAIConfig", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "api_key", + "type": "str", + "default": "Field(min_length=1, description='OpenAI API key')" + }, + { + "name": "default_model", + "type": "str", + "default": "Field(default='gpt-4o-mini')" + }, + { + "name": "default_embed_model", + "type": "str", + "default": "Field(default='text-embedding-3-small')" + } + ], + "line": 26, + "doc": "Config schema for OpenAIProvider.\n\napi_key is required; passing it via env var is the caller's responsibility\n(e.g., `OpenAIConfig(api_key=os.environ[\"OPENAI_API_KEY\"])`)." + }, + { + "name": "AnthropicConfig", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "api_key", + "type": "str", + "default": "Field(min_length=1, description='Anthropic API key')" + }, + { + "name": "default_model", + "type": "str", + "default": "Field(default='claude-haiku-4-5')" + }, + { + "name": "max_tokens", + "type": "int", + "default": "Field(default=4096, gt=0)" + } + ], + "line": 37, + "doc": "Config schema for AnthropicProvider.\n\napi_key is required. max_tokens is a sensible default (4096) and can be\nincreased for longer outputs." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/llm/providers/ollama.py", + "sha256": "bd1c78980c464dd41c7fdc24d9c362d17d20d343c9eac3c01000609bacd47e2b", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/llm/providers/openai.py", + "sha256": "d54920131ea2f0f14b8eee8c970dce47bf5ee5886815626f09f765fd8d4f4a30", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/llm/providers/registry.py", + "sha256": "2733af50366c7e8975c1b552fbe5302ed12d284abd59e65768ac8453d3639870", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/llm/registry/__init__.py", + "sha256": "9223edf2e5652dcee6612a2593299b12e06c6e46f24b4784d9d97bdda333a3d0", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/llm/registry/models.py", + "sha256": "f58ccb6ce42a7d344c4de7432ca3623e7865a59c91646736e1d397b565e07b0e", + "routes": [], + "models": [ + { + "name": "ModelRegistry", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[int]", + "default": "mapped_column(Integer, primary_key=True)" + }, + { + "name": "model_name", + "type": "Mapped[str]", + "default": "mapped_column(String(255), nullable=False)" + }, + { + "name": "model_version", + "type": "Mapped[str | None]", + "default": "mapped_column(String(100), nullable=True)" + }, + { + "name": "parameter_count", + "type": "Mapped[str | None]", + "default": "mapped_column(String(50), nullable=True)" + }, + { + "name": "license", + "type": "Mapped[str | None]", + "default": "mapped_column(String(100), nullable=True)" + }, + { + "name": "model_card_url", + "type": "Mapped[str | None]", + "default": "mapped_column(Text, nullable=True)" + }, + { + "name": "is_active", + "type": "Mapped[bool]", + "default": "mapped_column(Boolean, nullable=False, server_default='false')" + }, + { + "name": "added_at", + "type": "Mapped[datetime | None]", + "default": "mapped_column(TIMESTAMP(timezone=True), nullable=True)" + }, + { + "name": "context_window_size", + "type": "Mapped[int | None]", + "default": "mapped_column(Integer, nullable=True)" + }, + { + "name": "supports_ner", + "type": "Mapped[bool]", + "default": "mapped_column(Boolean, nullable=False, server_default='false')" + }, + { + "name": "supports_vision", + "type": "Mapped[bool]", + "default": "mapped_column(Boolean, nullable=False, server_default='false')" + } + ], + "line": 29, + "doc": "ORM model for the model_registry table." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/llm/registry/router.py", + "sha256": "03815bc31f8b2651acee939dd370f44c91a2c92e663ebe25273986540a379b2f", + "routes": [ + { + "method": "GET", + "path": "/admin/models", + "router": "router", + "prefix_resolved": true, + "name": "list_models", + "signature": "session: AsyncSession=Depends(get_session)", + "returns": "", + "line": 46, + "doc": "", + "decorator": "router.get('', response_model=list[ModelRegistryRead])", + "errors": [] + }, + { + "method": "GET", + "path": "/admin/models/{model_id}", + "router": "router", + "prefix_resolved": true, + "name": "get_model", + "signature": "model_id: int, session: AsyncSession=Depends(get_session)", + "returns": "", + "line": 53, + "doc": "", + "decorator": "router.get('/{model_id}', response_model=ModelRegistryRead)", + "errors": [ + "HTTPException(status_code=404, detail=f'Model {model_id} not found')" + ] + }, + { + "method": "POST", + "path": "/admin/models", + "router": "router", + "prefix_resolved": true, + "name": "create_model", + "signature": "payload: ModelRegistryCreate, session: AsyncSession=Depends(get_session)", + "returns": "", + "line": 61, + "doc": "", + "decorator": "router.post('', response_model=ModelRegistryRead, status_code=201)", + "errors": [] + }, + { + "method": "PATCH", + "path": "/admin/models/{model_id}", + "router": "router", + "prefix_resolved": true, + "name": "update_model", + "signature": "model_id: int, payload: ModelRegistryUpdate, session: AsyncSession=Depends(get_session)", + "returns": "", + "line": 73, + "doc": "", + "decorator": "router.patch('/{model_id}', response_model=ModelRegistryRead)", + "errors": [ + "HTTPException(status_code=404, detail=f'Model {model_id} not found')" + ] + }, + { + "method": "DELETE", + "path": "/admin/models/{model_id}", + "router": "router", + "prefix_resolved": true, + "name": "delete_model", + "signature": "model_id: int, session: AsyncSession=Depends(get_session)", + "returns": "", + "line": 89, + "doc": "", + "decorator": "router.delete('/{model_id}', status_code=204)", + "errors": [ + "HTTPException(status_code=404, detail=f'Model {model_id} not found')" + ] + } + ], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/llm/registry/schemas.py", + "sha256": "324d0b48abc8d3d0b7a66f9763145a29fed4e81a6b8a59f865b63fb1ab980bfe", + "routes": [], + "models": [ + { + "name": "ModelRegistryCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "model_name", + "type": "str", + "default": "" + }, + { + "name": "model_version", + "type": "str | None", + "default": "None" + }, + { + "name": "parameter_count", + "type": "str | None", + "default": "None" + }, + { + "name": "license", + "type": "str | None", + "default": "None" + }, + { + "name": "model_card_url", + "type": "str | None", + "default": "None" + }, + { + "name": "is_active", + "type": "bool", + "default": "False" + }, + { + "name": "context_window_size", + "type": "int | None", + "default": "None" + }, + { + "name": "supports_ner", + "type": "bool", + "default": "False" + }, + { + "name": "supports_vision", + "type": "bool", + "default": "False" + } + ], + "line": 18, + "doc": "Schema for creating a new model_registry record (POST body)." + }, + { + "name": "ModelRegistryRead", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "id", + "type": "int", + "default": "" + }, + { + "name": "model_name", + "type": "str", + "default": "" + }, + { + "name": "model_version", + "type": "str | None", + "default": "None" + }, + { + "name": "parameter_count", + "type": "str | None", + "default": "None" + }, + { + "name": "license", + "type": "str | None", + "default": "None" + }, + { + "name": "model_card_url", + "type": "str | None", + "default": "None" + }, + { + "name": "is_active", + "type": "bool", + "default": "" + }, + { + "name": "added_at", + "type": "datetime | None", + "default": "None" + }, + { + "name": "context_window_size", + "type": "int | None", + "default": "None" + }, + { + "name": "supports_ner", + "type": "bool", + "default": "" + }, + { + "name": "supports_vision", + "type": "bool", + "default": "" + } + ], + "line": 32, + "doc": "Schema for returning a model_registry record (GET response).\n\n``from_attributes=True`` allows construction directly from an ORM instance." + }, + { + "name": "ModelRegistryUpdate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "model_name", + "type": "str | None", + "default": "None" + }, + { + "name": "model_version", + "type": "str | None", + "default": "None" + }, + { + "name": "parameter_count", + "type": "str | None", + "default": "None" + }, + { + "name": "license", + "type": "str | None", + "default": "None" + }, + { + "name": "model_card_url", + "type": "str | None", + "default": "None" + }, + { + "name": "is_active", + "type": "bool | None", + "default": "None" + }, + { + "name": "context_window_size", + "type": "int | None", + "default": "None" + }, + { + "name": "supports_ner", + "type": "bool | None", + "default": "None" + }, + { + "name": "supports_vision", + "type": "bool | None", + "default": "None" + } + ], + "line": 53, + "doc": "Schema for partially updating a model_registry record (PATCH body).\n\nEvery field is optional so callers can send only the fields they want to\nchange." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/llm/registry/service.py", + "sha256": "9280f0161a4db25de8182f214fa9d143ef2b1bfc3dac65b1b83b570ed12ee407", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/llm/structured.py", + "sha256": "9f7ad6645f2a02aa6a41207906be09a6e1adfc70a89c6eb78387e78cb807477a", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/llm/templates/__init__.py", + "sha256": "a00806b2b0d3c3b7dd966dee85db8f2ee6178697c6f222c28abe4454518ba341", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/llm/templates/engine.py", + "sha256": "cb4f72ba249be0264c827c4503b64dea8b61fe525ebb1a93870a9ba58b46d5df", + "routes": [], + "models": [ + { + "name": "RenderedPrompt", + "bases": [], + "fields": [ + { + "name": "system", + "type": "str", + "default": "" + }, + { + "name": "user", + "type": "str", + "default": "" + }, + { + "name": "template_name", + "type": "str", + "default": "" + }, + { + "name": "consumer_app", + "type": "str", + "default": "" + }, + { + "name": "version", + "type": "int", + "default": "" + } + ], + "line": 20, + "doc": "Result of rendering a PromptTemplate.\n\nAttributes:\n system: Rendered system_prompt string.\n user: Rendered user_prompt_template string.\n template_name: The source template's logical name.\n consumer_app: The source template's consumer_app namespace.\n version: The source template's version number." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/llm/templates/exceptions.py", + "sha256": "53bbdcfd915d751cc878edc148a39b52424b5c34a4d03ed8120d763464967a96", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/llm/templates/models.py", + "sha256": "c1a61785d12d40657aad28ead8f8d27c947634ab159bc48b4309788ae4ed674d", + "routes": [], + "models": [ + { + "name": "PromptTemplate", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(PG_UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)" + }, + { + "name": "template_name", + "type": "Mapped[str]", + "default": "mapped_column(String(200), nullable=False)" + }, + { + "name": "consumer_app", + "type": "Mapped[str]", + "default": "mapped_column(String(100), nullable=False, server_default='townlight_core')" + }, + { + "name": "is_override", + "type": "Mapped[bool]", + "default": "mapped_column(Boolean, nullable=False, server_default='false')" + }, + { + "name": "purpose", + "type": "Mapped[str]", + "default": "mapped_column(String(50), nullable=False)" + }, + { + "name": "system_prompt", + "type": "Mapped[str]", + "default": "mapped_column(Text, nullable=False)" + }, + { + "name": "user_prompt_template", + "type": "Mapped[str]", + "default": "mapped_column(Text, nullable=False)" + }, + { + "name": "token_budget", + "type": "Mapped[dict | None]", + "default": "mapped_column(JSONB, nullable=True)" + }, + { + "name": "model_id", + "type": "Mapped[int | None]", + "default": "mapped_column(Integer, ForeignKey('model_registry.id', ondelete='SET NULL'), nullable=True)" + }, + { + "name": "version", + "type": "Mapped[int]", + "default": "mapped_column(Integer, nullable=False, server_default='1')" + }, + { + "name": "is_active", + "type": "Mapped[bool]", + "default": "mapped_column(Boolean, nullable=False, server_default='true')" + }, + { + "name": "created_by", + "type": "Mapped[uuid.UUID | None]", + "default": "mapped_column(PG_UUID(as_uuid=True), nullable=True)" + }, + { + "name": "created_at", + "type": "Mapped[datetime]", + "default": "mapped_column(TIMESTAMP(timezone=True), nullable=False, server_default=func.now())" + } + ], + "line": 37, + "doc": "ORM model for the prompt_templates table." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/llm/templates/overrides.py", + "sha256": "6a32018a76d803c74408937b75e6d3ad597f247d533e2d8092ce7bbccc0d0cd1", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/llm/templates/resolver.py", + "sha256": "389bf9b01902b046f8986fc3415125c859bf8a4923e07d146d0cdd75587b9636", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/llm/templates/schemas.py", + "sha256": "f012308c13d12ec8e338335c5ba451d73c171605697a79a8f3dba334f4af1854", + "routes": [], + "models": [ + { + "name": "PromptTemplateCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "template_name", + "type": "str", + "default": "" + }, + { + "name": "purpose", + "type": "str", + "default": "" + }, + { + "name": "system_prompt", + "type": "str", + "default": "" + }, + { + "name": "user_prompt_template", + "type": "str", + "default": "" + }, + { + "name": "consumer_app", + "type": "str", + "default": "'townlight_core'" + }, + { + "name": "is_override", + "type": "bool", + "default": "False" + }, + { + "name": "token_budget", + "type": "dict | None", + "default": "None" + }, + { + "name": "model_id", + "type": "int | None", + "default": "None" + }, + { + "name": "version", + "type": "int", + "default": "1" + }, + { + "name": "is_active", + "type": "bool", + "default": "True" + }, + { + "name": "created_by", + "type": "uuid.UUID | None", + "default": "None" + } + ], + "line": 13, + "doc": "Fields required (or defaulted) when creating a new prompt template." + }, + { + "name": "PromptTemplateRead", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "template_name", + "type": "str", + "default": "" + }, + { + "name": "consumer_app", + "type": "str", + "default": "" + }, + { + "name": "is_override", + "type": "bool", + "default": "" + }, + { + "name": "purpose", + "type": "str", + "default": "" + }, + { + "name": "system_prompt", + "type": "str", + "default": "" + }, + { + "name": "user_prompt_template", + "type": "str", + "default": "" + }, + { + "name": "token_budget", + "type": "dict | None", + "default": "" + }, + { + "name": "model_id", + "type": "int | None", + "default": "" + }, + { + "name": "version", + "type": "int", + "default": "" + }, + { + "name": "is_active", + "type": "bool", + "default": "" + }, + { + "name": "created_by", + "type": "uuid.UUID | None", + "default": "" + }, + { + "name": "created_at", + "type": "datetime", + "default": "" + } + ], + "line": 32, + "doc": "All columns for reading a prompt template row." + }, + { + "name": "PromptTemplateUpdate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "template_name", + "type": "str | None", + "default": "None" + }, + { + "name": "purpose", + "type": "str | None", + "default": "None" + }, + { + "name": "system_prompt", + "type": "str | None", + "default": "None" + }, + { + "name": "user_prompt_template", + "type": "str | None", + "default": "None" + }, + { + "name": "consumer_app", + "type": "str | None", + "default": "None" + }, + { + "name": "is_override", + "type": "bool | None", + "default": "None" + }, + { + "name": "token_budget", + "type": "dict | None", + "default": "None" + }, + { + "name": "model_id", + "type": "int | None", + "default": "None" + }, + { + "name": "version", + "type": "int | None", + "default": "None" + }, + { + "name": "is_active", + "type": "bool | None", + "default": "None" + } + ], + "line": 52, + "doc": "Partial update schema for PATCH operations. All fields optional." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/migrations/__init__.py", + "sha256": "6cb4358063e7a281454ae36e2aa4565e9048e00d193d1da0bab81df47a453703", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/migrations/env.py", + "sha256": "208de714d58a5b3fa8f3797c05eadba49d0b46105afeb20c50e7685e298fb4cb", + "routes": [], + "models": [], + "configuration": [ + { + "variable": "DATABASE_URL", + "default": "", + "line": 64 + }, + { + "variable": "DATABASE_URL", + "default": "", + "line": 27 + } + ] + }, + { + "source": "installed-owned-source/townlight_core/migrations/guards.py", + "sha256": "c55de91c7189b39537aed6130a1e9f50817f819bd13aa4728ae4e8dd4c863aad", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/migrations/runner.py", + "sha256": "4f3b554197baf06924cc3676d42df083f14f3a9db1456a775601d975499e354e", + "routes": [], + "models": [], + "configuration": [ + { + "variable": "DATABASE_URL", + "default": "", + "line": 47 + } + ] + }, + { + "source": "installed-owned-source/townlight_core/migrations/versions/__init__.py", + "sha256": "61c059e42b35e302a4372a1c7697ca495118b123f7303306d7c54ff15173c8c6", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/migrations/versions/townlight_core_0001_baseline_v1.py", + "sha256": "69186f3f798a01d61638ae42993761c3038ced04e143ea8dd292ebc1fc63afb7", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/migrations/versions/townlight_core_0002_llm.py", + "sha256": "fa273e35f651a6298842df0de87bd5548d1a83698adc27e1385ceb28449b00cd", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/migrations/versions/townlight_core_0003_local_task_queue.py", + "sha256": "51276a0dc2737fd1fc2615f26d66d942c1df3be2ef40f1513436cd4579b1ecf0", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/migrations/versions/townlight_core_0004_catalog.py", + "sha256": "a9f46f8ca1bcde43a2796dd62891ad36840d1067220b16fdde8583a1f700a06d", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/migrations/versions/townlight_core_0005_job_leases.py", + "sha256": "a6651789d82cb0c39481f16855449bf09d65644c93a97bab1e33f8d7546157f7", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/migrations/versions/townlight_core_0006_rule_history.py", + "sha256": "ac29f724f60125de435235655a052ae3738a286467b1d6d8213a22558994a868", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/migrations/versions/townlight_core_0007_module_inventory.py", + "sha256": "41aefee7ff2de883f92eebb7a39de2f0ed8b6bd4fecf88c6ebfd62a0b3cb7456", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/migrations/versions/townlight_core_0008_department_authority.py", + "sha256": "fa7328f869594d1af2f4daceb4b362cd8ebe304b7e1ecbefaa22497d08430b4a", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/migrations/versions/townlight_core_0009_job_artifacts.py", + "sha256": "ee8952caff749c4b9df5cbc15c379f69f7066351ea5f7690525136be1481d9d8", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/models/__init__.py", + "sha256": "213b3086e533a98047d460720e7a1becd7f6196f4a6db989a39253351b8894c9", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/notifications/__init__.py", + "sha256": "988bcb1091aef4451a1566202a6ec50e3b8908770707b5ad45398923bdb2d6be", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/notifications/notice.py", + "sha256": "78c2542686403c647859b27f5a7bf7ff832cd29ca3ff4086b32c6e5fc098247b", + "routes": [], + "models": [ + { + "name": "DeadlinePlan", + "bases": [], + "fields": [ + { + "name": "notice_type", + "type": "str", + "default": "" + }, + { + "name": "event_date", + "type": "date", + "default": "" + }, + { + "name": "publish_by", + "type": "date", + "default": "" + }, + { + "name": "reminders", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "staff_review_required", + "type": "bool", + "default": "" + } + ], + "line": 13, + "doc": "Deterministic notice deadline reminders without legal determinations." + }, + { + "name": "NoticeComplianceWarning", + "bases": [], + "fields": [ + { + "name": "code", + "type": "str", + "default": "" + }, + { + "name": "message", + "type": "str", + "default": "" + }, + { + "name": "fix", + "type": "str", + "default": "" + } + ], + "line": 24, + "doc": "Actionable warning describing a notice-compliance gap." + }, + { + "name": "NoticeComplianceResult", + "bases": [], + "fields": [ + { + "name": "meeting_id", + "type": "str", + "default": "" + }, + { + "name": "notice_type", + "type": "str", + "default": "" + }, + { + "name": "scheduled_start", + "type": "datetime", + "default": "" + }, + { + "name": "posted_at", + "type": "datetime", + "default": "" + }, + { + "name": "minimum_notice_hours", + "type": "int", + "default": "" + }, + { + "name": "deadline_at", + "type": "datetime", + "default": "" + }, + { + "name": "statutory_basis", + "type": "str | None", + "default": "" + }, + { + "name": "approved_by", + "type": "str | None", + "default": "" + }, + { + "name": "compliant", + "type": "bool", + "default": "" + }, + { + "name": "http_status", + "type": "int", + "default": "" + }, + { + "name": "warnings", + "type": "tuple[NoticeComplianceWarning, ...]", + "default": "" + } + ], + "line": 36, + "doc": "Result of checking whether a meeting notice is ready to publish." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/onboarding/__init__.py", + "sha256": "d4d47bddbea571ade848657d39a128849e7b02c45a2c5476bd4ee933033a5713", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/onboarding/profile.py", + "sha256": "76f82f3b710700d4d3913a1ec5575c15499e46c11b4bb9ddffa2455710b93a93", + "routes": [], + "models": [ + { + "name": "OnboardingField", + "bases": [], + "fields": [ + { + "name": "name", + "type": "str", + "default": "" + }, + { + "name": "question", + "type": "str", + "default": "" + }, + { + "name": "kind", + "type": "str", + "default": "'text'" + } + ], + "line": 10, + "doc": "A tracked onboarding field and the default prompt used to ask for it." + }, + { + "name": "OnboardingProgress", + "bases": [], + "fields": [ + { + "name": "next_field", + "type": "str | None", + "default": "" + }, + { + "name": "next_question", + "type": "str | None", + "default": "" + }, + { + "name": "completed_fields", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "skipped_fields", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "all_complete", + "type": "bool", + "default": "" + } + ], + "line": 19, + "doc": "Skip-aware progress state for an interview-style onboarding walk." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/platform/__init__.py", + "sha256": "a8618133480c425c95c6ab8b773261aa430f600603941248148b402341ac9f94", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/platform/backup.py", + "sha256": "15396fd6bdeaebbddead4a619e11090b427dfcb8744dccd582bbbaf5ca49b407", + "routes": [], + "models": [ + { + "name": "BackupItem", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "module_id", + "type": "str", + "default": "Field(pattern='^[a-z][a-z0-9-]{1,63}$')" + }, + { + "name": "relative_path", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "size_bytes", + "type": "int", + "default": "Field(ge=0)" + }, + { + "name": "sha256", + "type": "str", + "default": "Field(pattern='^[a-f0-9]{64}$')" + }, + { + "name": "required", + "type": "bool", + "default": "True" + } + ], + "line": 15, + "doc": "One file captured in a local backup." + }, + { + "name": "BackupManifest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "schema_version", + "type": "str", + "default": "'1.0'" + }, + { + "name": "backup_id", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "city_profile_id", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "townlight_core_version", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "created_at", + "type": "datetime", + "default": "Field(default_factory=lambda: datetime.now(UTC))" + }, + { + "name": "modules", + "type": "list[str]", + "default": "Field(default_factory=list)" + }, + { + "name": "items", + "type": "list[BackupItem]", + "default": "" + } + ], + "line": 27, + "doc": "Versioned backup manifest for a Townlight local profile." + }, + { + "name": "BackupValidationResult", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "valid", + "type": "bool", + "default": "" + }, + { + "name": "missing", + "type": "list[str]", + "default": "Field(default_factory=list)" + }, + { + "name": "hash_mismatches", + "type": "list[str]", + "default": "Field(default_factory=list)" + } + ], + "line": 41, + "doc": "Result of checking a backup manifest against files on disk." + }, + { + "name": "BackupRestoreAction", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "source_relative_path", + "type": "str", + "default": "" + }, + { + "name": "target_relative_path", + "type": "str", + "default": "" + }, + { + "name": "status", + "type": "RestoreActionStatus", + "default": "" + }, + { + "name": "message", + "type": "str", + "default": "" + } + ], + "line": 51, + "doc": "One file restore action and its safety status." + }, + { + "name": "BackupRestorePlan", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "ready", + "type": "bool", + "default": "" + }, + { + "name": "actions", + "type": "list[BackupRestoreAction]", + "default": "" + }, + { + "name": "blocked_reason", + "type": "str | None", + "default": "None" + } + ], + "line": 62, + "doc": "A non-destructive restore plan." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/platform/health.py", + "sha256": "41f35066ee9a5c1ea3948605f3acf39c568a8916340598468def3502a0ec1634", + "routes": [], + "models": [ + { + "name": "PlatformHealthCheck", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "component", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "label", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "status", + "type": "PlatformHealthStatus", + "default": "" + }, + { + "name": "message", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "next_action", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "blocking", + "type": "bool", + "default": "False" + }, + { + "name": "checked_at", + "type": "datetime", + "default": "Field(default_factory=lambda: datetime.now(UTC))" + }, + { + "name": "admin_detail", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + } + ], + "line": 19, + "doc": "One health check result suitable for staff/admin health screens." + }, + { + "name": "PlatformHealthSummary", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "status", + "type": "PlatformHealthStatus", + "default": "" + }, + { + "name": "checks", + "type": "list[PlatformHealthCheck]", + "default": "" + }, + { + "name": "next_action", + "type": "str", + "default": "" + }, + { + "name": "staff_message", + "type": "str", + "default": "" + }, + { + "name": "admin_message", + "type": "str", + "default": "" + }, + { + "name": "blocked_components", + "type": "list[str]", + "default": "" + }, + { + "name": "degraded_components", + "type": "list[str]", + "default": "" + } + ], + "line": 34, + "doc": "Aggregated health status for the umbrella shell." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/platform/inventory.py", + "sha256": "b6b1936c8bc2d5ba459370e9406395b3bf899a24ba439ff92ac38ae393fe7dda", + "routes": [], + "models": [ + { + "name": "ModuleInventoryEntry", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "module_id", + "type": "str", + "default": "Field(min_length=2, max_length=64)" + }, + { + "name": "version", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "enabled", + "type": "bool", + "default": "" + }, + { + "name": "manifest", + "type": "ModuleManifest", + "default": "" + } + ], + "line": 120, + "doc": "One module the scope declares it has, plus the manifest it was installed from." + }, + { + "name": "ModuleInventory", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "scope_id", + "type": "str", + "default": "Field(min_length=2, max_length=64)" + }, + { + "name": "revision", + "type": "int", + "default": "Field(ge=1)" + }, + { + "name": "profile", + "type": "InstallProfile", + "default": "'windows_local'" + }, + { + "name": "townlight_core_version", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "entries", + "type": "list[ModuleInventoryEntry]", + "default": "Field(default_factory=list)" + } + ], + "line": 139, + "doc": "A scope's declared installed/enabled module set at one revision." + }, + { + "name": "InventoryOutcome", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "inventory", + "type": "ModuleInventory", + "default": "" + }, + { + "name": "inserted", + "type": "bool", + "default": "" + }, + { + "name": "fingerprint", + "type": "str", + "default": "" + } + ], + "line": 204, + "doc": "Result of one append attempt." + }, + { + "name": "ModuleRecommendation", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "module_id", + "type": "str", + "default": "Field(min_length=2, max_length=64)" + }, + { + "name": "action", + "type": "RecommendationAction", + "default": "" + }, + { + "name": "basis", + "type": "RecommendationBasis", + "default": "" + }, + { + "name": "reasons", + "type": "list[str]", + "default": "Field(min_length=1)" + }, + { + "name": "operator_action", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 410, + "doc": "Advisory next step for one module. Never installation or health evidence." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/platform/modules.py", + "sha256": "7d3af6bcdc8cc3af90c6c663f5e0ea4571cfe607b0c3ee76a3ce0f966cb8a0c3", + "routes": [], + "models": [ + { + "name": "ModuleDependency", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "module_id", + "type": "str", + "default": "Field(pattern=MODULE_ID_PATTERN)" + }, + { + "name": "min_version", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + }, + { + "name": "required", + "type": "bool", + "default": "True" + } + ], + "line": 46, + "doc": "Another Townlight module required by a manifest." + }, + { + "name": "ModulePermission", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "key", + "type": "str", + "default": "Field(pattern=SLUG_PATTERN)" + }, + { + "name": "label", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "description", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "surface", + "type": "ModuleSurface", + "default": "'staff'" + }, + { + "name": "roles", + "type": "list[str]", + "default": "Field(default_factory=list)" + } + ], + "line": 56, + "doc": "Permission surfaced to the shell and module manager." + }, + { + "name": "ModuleRoute", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "id", + "type": "str", + "default": "Field(pattern=SLUG_PATTERN)" + }, + { + "name": "path", + "type": "str", + "default": "Field(pattern='^/[a-z0-9/_:-]*$')" + }, + { + "name": "label", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "surface", + "type": "ModuleSurface", + "default": "'staff'" + }, + { + "name": "permission", + "type": "str | None", + "default": "Field(default=None, pattern=SLUG_PATTERN)" + } + ], + "line": 75, + "doc": "A route the desktop shell may expose for a module." + }, + { + "name": "ModuleService", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "id", + "type": "str", + "default": "Field(pattern=SLUG_PATTERN)" + }, + { + "name": "service_type", + "type": "ServiceType", + "default": "" + }, + { + "name": "description", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "required", + "type": "bool", + "default": "True" + }, + { + "name": "start_order", + "type": "int", + "default": "Field(default=100, ge=0)" + }, + { + "name": "health_check_id", + "type": "str | None", + "default": "Field(default=None, pattern=SLUG_PATTERN)" + } + ], + "line": 87, + "doc": "A local service, schema, or command needed by a module." + }, + { + "name": "ModuleMigration", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "id", + "type": "str", + "default": "Field(pattern=SLUG_PATTERN)" + }, + { + "name": "description", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "owner_schema", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + }, + { + "name": "required", + "type": "bool", + "default": "True" + } + ], + "line": 100, + "doc": "A migration contract that the installer/runtime must apply or verify." + }, + { + "name": "ModuleHealthCheck", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "id", + "type": "str", + "default": "Field(pattern=SLUG_PATTERN)" + }, + { + "name": "label", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "description", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "blocking", + "type": "bool", + "default": "True" + }, + { + "name": "surface", + "type": "Literal['staff', 'admin', 'system']", + "default": "'admin'" + }, + { + "name": "repair_action", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + } + ], + "line": 111, + "doc": "A module health check known to the umbrella health center." + }, + { + "name": "ModuleBackupHook", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "id", + "type": "str", + "default": "Field(pattern=SLUG_PATTERN)" + }, + { + "name": "label", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "includes", + "type": "list[str]", + "default": "Field(min_length=1)" + }, + { + "name": "restore_supported", + "type": "bool", + "default": "True" + } + ], + "line": 124, + "doc": "A backup/restore hook the module contributes to the shared backup plan." + }, + { + "name": "ModuleModelRequirement", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "id", + "type": "str", + "default": "Field(pattern=SLUG_PATTERN)" + }, + { + "name": "provider", + "type": "Literal['ollama', 'local', 'none', 'openai', 'anthropic']", + "default": "'ollama'" + }, + { + "name": "model_name", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "required", + "type": "bool", + "default": "True" + }, + { + "name": "local_only", + "type": "bool", + "default": "True" + }, + { + "name": "minimum_context_tokens", + "type": "int | None", + "default": "Field(default=None, ge=1)" + }, + { + "name": "checksum_sha256", + "type": "str | None", + "default": "Field(default=None, pattern='^[a-fA-F0-9]{64}$')" + }, + { + "name": "download_url", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + }, + { + "name": "license_name", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + } + ], + "line": 135, + "doc": "A model requirement declared by a module." + }, + { + "name": "ModuleRuntimeRequirement", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "kind", + "type": "RuntimeRequirementKind", + "default": "" + }, + { + "name": "name", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "description", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "required", + "type": "bool", + "default": "True" + }, + { + "name": "operator_visible", + "type": "bool", + "default": "False" + } + ], + "line": 151, + "doc": "Runtime capability needed by a module." + }, + { + "name": "ModuleManifest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "module_id", + "type": "str", + "default": "Field(pattern=MODULE_ID_PATTERN)" + }, + { + "name": "name", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "version", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "package_name", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "townlight_core_min_version", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "enabled_by_default", + "type": "bool", + "default": "True" + }, + { + "name": "surfaces", + "type": "list[ModuleSurface]", + "default": "Field(default_factory=lambda: ['staff'])" + }, + { + "name": "install_profiles", + "type": "list[InstallProfile]", + "default": "Field(default_factory=lambda: ['windows_local'])" + }, + { + "name": "dependencies", + "type": "list[ModuleDependency]", + "default": "Field(default_factory=list)" + }, + { + "name": "routes", + "type": "list[ModuleRoute]", + "default": "Field(default_factory=list)" + }, + { + "name": "permissions", + "type": "list[ModulePermission]", + "default": "Field(default_factory=list)" + }, + { + "name": "services", + "type": "list[ModuleService]", + "default": "Field(default_factory=list)" + }, + { + "name": "migrations", + "type": "list[ModuleMigration]", + "default": "Field(default_factory=list)" + }, + { + "name": "health_checks", + "type": "list[ModuleHealthCheck]", + "default": "Field(default_factory=list)" + }, + { + "name": "backup_hooks", + "type": "list[ModuleBackupHook]", + "default": "Field(default_factory=list)" + }, + { + "name": "model_requirements", + "type": "list[ModuleModelRequirement]", + "default": "Field(default_factory=list)" + }, + { + "name": "runtime_requirements", + "type": "list[ModuleRuntimeRequirement]", + "default": "Field(default_factory=list)" + }, + { + "name": "settings_schema_version", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + }, + { + "name": "metadata", + "type": "dict[str, Any]", + "default": "Field(default_factory=dict)" + } + ], + "line": 163, + "doc": "Complete manifest for a Townlight module package." + }, + { + "name": "ModuleRegistryEntry", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "module_id", + "type": "str", + "default": "Field(pattern=MODULE_ID_PATTERN)" + }, + { + "name": "name", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "version", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "enabled", + "type": "bool", + "default": "" + }, + { + "name": "locked", + "type": "bool", + "default": "False" + }, + { + "name": "status", + "type": "ModuleRegistryStatus", + "default": "" + }, + { + "name": "reason", + "type": "str | None", + "default": "None" + }, + { + "name": "manifest", + "type": "ModuleManifest", + "default": "" + } + ], + "line": 230, + "doc": "One module's resolved state in a runtime profile." + }, + { + "name": "ModuleRegistryState", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "profile", + "type": "InstallProfile", + "default": "'windows_local'" + }, + { + "name": "townlight_core_version", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "townlight_core_locked", + "type": "bool", + "default": "True" + }, + { + "name": "entries", + "type": "list[ModuleRegistryEntry]", + "default": "" + } + ], + "line": 245, + "doc": "Resolved module registry for the desktop shell and installer." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/platform/runtime.py", + "sha256": "8c9ba7958b8fa08e7b0378a78d3693d8a586714555e5de9420a10626283f579a", + "routes": [], + "models": [ + { + "name": "RuntimeActionResult", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "action", + "type": "RuntimeAction", + "default": "" + }, + { + "name": "status", + "type": "RuntimeActionStatus", + "default": "" + }, + { + "name": "title", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "message", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "next_action", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + }, + { + "name": "evidence", + "type": "dict[str, str | int | bool | None]", + "default": "Field(default_factory=dict)" + }, + { + "name": "started_at", + "type": "datetime", + "default": "Field(default_factory=lambda: datetime.now(UTC))" + }, + { + "name": "completed_at", + "type": "datetime | None", + "default": "None" + } + ], + "line": 28, + "doc": "Plain-English result returned by installer/runtime APIs." + }, + { + "name": "LocalRuntimeProfile", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "profile_id", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "city_name", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "data_root", + "type": "Path", + "default": "" + }, + { + "name": "backup_root", + "type": "Path", + "default": "" + }, + { + "name": "module_registry", + "type": "ModuleRegistryState", + "default": "" + }, + { + "name": "model_provider", + "type": "str", + "default": "'ollama'" + }, + { + "name": "local_only", + "type": "bool", + "default": "True" + }, + { + "name": "network_allowed_for", + "type": "list[str]", + "default": "Field(default_factory=list)" + } + ], + "line": 43, + "doc": "Resolved local runtime profile for one installed city." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/platform/task_queue.py", + "sha256": "438c2e7364ef0232b62a4ea379b22a679c248c8c1ab9c0b3149fd87ec8e5fb46", + "routes": [], + "models": [ + { + "name": "LocalTask", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "task_id", + "type": "Mapped[str]", + "default": "mapped_column(String(128), primary_key=True)" + }, + { + "name": "module_id", + "type": "Mapped[str]", + "default": "mapped_column(String(64), index=True)" + }, + { + "name": "task_type", + "type": "Mapped[str]", + "default": "mapped_column(String(100), index=True)" + }, + { + "name": "status", + "type": "Mapped[str]", + "default": "mapped_column(String(20), index=True, default='queued')" + }, + { + "name": "payload", + "type": "Mapped[dict[str, Any]]", + "default": "mapped_column(JSONB, default=dict)" + }, + { + "name": "attempt_count", + "type": "Mapped[int]", + "default": "mapped_column(Integer, default=0)" + }, + { + "name": "queued_at", + "type": "Mapped[datetime]", + "default": "mapped_column(DateTime(timezone=True))" + }, + { + "name": "available_at", + "type": "Mapped[datetime | None]", + "default": "mapped_column(DateTime(timezone=True), nullable=True)" + }, + { + "name": "last_error", + "type": "Mapped[str | None]", + "default": "mapped_column(Text, nullable=True)" + }, + { + "name": "idempotency_key", + "type": "Mapped[str | None]", + "default": "mapped_column(String(255), nullable=True, unique=True)" + }, + { + "name": "audit_subject_id", + "type": "Mapped[str | None]", + "default": "mapped_column(String(255), nullable=True)" + }, + { + "name": "claim_token", + "type": "Mapped[str | None]", + "default": "mapped_column(String(64), nullable=True)" + }, + { + "name": "lease_expires_at", + "type": "Mapped[datetime | None]", + "default": "mapped_column(DateTime(timezone=True), nullable=True)" + }, + { + "name": "cancelled_by", + "type": "Mapped[str | None]", + "default": "mapped_column(String(128), nullable=True)" + } + ], + "line": 27, + "doc": "Durable local task row used by the Windows local runtime." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/platform/tasks.py", + "sha256": "cbf2bf5323fb37c5ff58038d77597464b16c6637b205dcf00a03ad274d120847", + "routes": [], + "models": [ + { + "name": "TaskRetryPolicy", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "max_attempts", + "type": "int", + "default": "Field(default=3, ge=1)" + }, + { + "name": "base_delay_seconds", + "type": "int", + "default": "Field(default=30, ge=0)" + }, + { + "name": "max_delay_seconds", + "type": "int", + "default": "Field(default=3600, ge=0)" + } + ], + "line": 14, + "doc": "Retry settings for local durable task queues." + }, + { + "name": "LocalTaskEnvelope", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "task_id", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "module_id", + "type": "str", + "default": "Field(pattern='^[a-z][a-z0-9-]{1,63}$')" + }, + { + "name": "task_type", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "status", + "type": "TaskStatus", + "default": "'queued'" + }, + { + "name": "payload", + "type": "dict[str, Any]", + "default": "Field(default_factory=dict)" + }, + { + "name": "attempt_count", + "type": "int", + "default": "Field(default=0, ge=0)" + }, + { + "name": "queued_at", + "type": "datetime", + "default": "Field(default_factory=lambda: datetime.now(UTC))" + }, + { + "name": "available_at", + "type": "datetime | None", + "default": "None" + }, + { + "name": "last_error", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + }, + { + "name": "idempotency_key", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + }, + { + "name": "audit_subject_id", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + }, + { + "name": "claim_token", + "type": "str | None", + "default": "None" + }, + { + "name": "lease_expires_at", + "type": "datetime | None", + "default": "None" + } + ], + "line": 24, + "doc": "Storage-neutral task record for module-owned persistence." + }, + { + "name": "LocalTaskResult", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "task", + "type": "LocalTaskEnvelope", + "default": "" + }, + { + "name": "message", + "type": "str", + "default": "" + }, + { + "name": "retry_at", + "type": "datetime | None", + "default": "None" + } + ], + "line": 52, + "doc": "Result returned after recording a local task attempt." + }, + { + "name": "TaskQueueSummary", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "total", + "type": "int", + "default": "" + }, + { + "name": "counts", + "type": "dict[str, int]", + "default": "" + }, + { + "name": "blocked", + "type": "bool", + "default": "" + }, + { + "name": "message", + "type": "str", + "default": "" + } + ], + "line": 62, + "doc": "Counts and operator copy for a module task queue." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/provenance/__init__.py", + "sha256": "0f703072d5ba898b13a2683285eb8d57e66815356391103f27d63237467d0ab8", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/provenance/contracts.py", + "sha256": "56dfe26f57056ae1ea85fb8eb808a5259700609483d8e14e67625e123040d57c", + "routes": [], + "models": [ + { + "name": "CitationTarget", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "label", + "type": "str | None", + "default": "None" + }, + { + "name": "page", + "type": "int | None", + "default": "Field(default=None, ge=1)" + }, + { + "name": "section", + "type": "str | None", + "default": "None" + }, + { + "name": "line_start", + "type": "int | None", + "default": "Field(default=None, ge=1)" + }, + { + "name": "line_end", + "type": "int | None", + "default": "Field(default=None, ge=1)" + }, + { + "name": "parcel_id", + "type": "str | None", + "default": "None" + }, + { + "name": "anchor", + "type": "str | None", + "default": "None" + } + ], + "line": 41, + "doc": "Locator that lets an export cite a precise place in a source." + }, + { + "name": "SourceReference", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "source_id", + "type": "str", + "default": "" + }, + { + "name": "kind", + "type": "SourceKind", + "default": "" + }, + { + "name": "title", + "type": "str", + "default": "" + }, + { + "name": "source_system", + "type": "str | None", + "default": "None" + }, + { + "name": "source_path", + "type": "str | None", + "default": "None" + }, + { + "name": "source_url", + "type": "str | None", + "default": "None" + }, + { + "name": "captured_at", + "type": "datetime", + "default": "Field(default_factory=_utc_now)" + }, + { + "name": "checksum", + "type": "str | None", + "default": "None" + }, + { + "name": "retention_hint", + "type": "str | None", + "default": "None" + }, + { + "name": "sensitivity_label", + "type": "str | None", + "default": "None" + }, + { + "name": "citation_locator", + "type": "CitationTarget | None", + "default": "Field(default=None, validation_alias=AliasChoices('citation_locator', 'citation'))" + } + ], + "line": 55, + "doc": "Metadata for an original source used by Townlight Core." + }, + { + "name": "DocumentMetadata", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "document_id", + "type": "str", + "default": "" + }, + { + "name": "title", + "type": "str", + "default": "" + }, + { + "name": "source", + "type": "SourceReference", + "default": "" + }, + { + "name": "document_type", + "type": "str | None", + "default": "None" + }, + { + "name": "created_at", + "type": "datetime | None", + "default": "None" + }, + { + "name": "captured_at", + "type": "datetime", + "default": "Field(default_factory=_utc_now)" + }, + { + "name": "checksum", + "type": "str | None", + "default": "None" + }, + { + "name": "retention_hint", + "type": "str | None", + "default": "None" + }, + { + "name": "sensitivity_label", + "type": "str | None", + "default": "None" + } + ], + "line": 81, + "doc": "Document-level descriptive metadata for export manifests." + }, + { + "name": "ProvenanceBundle", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "bundle_id", + "type": "str", + "default": "" + }, + { + "name": "generated_at", + "type": "datetime", + "default": "Field(default_factory=_utc_now)" + }, + { + "name": "sources", + "type": "list[SourceReference]", + "default": "Field(default_factory=list)" + }, + { + "name": "documents", + "type": "list[DocumentMetadata]", + "default": "Field(default_factory=list)" + } + ], + "line": 104, + "doc": "Serializable manifest of sources and documents behind an export." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/release_provenance.py", + "sha256": "52df52fe6354b741a0cfb759156601fc6682aa34caed7cead9e624ac70e1faf7", + "routes": [], + "models": [], + "configuration": [ + { + "variable": "GH_TOKEN", + "default": "", + "line": 62 + }, + { + "variable": "GITHUB_TOKEN", + "default": "", + "line": 62 + } + ] + }, + { + "source": "installed-owned-source/townlight_core/scaffold/__init__.py", + "sha256": "313ad60b0afe49ab6d7632c99d96a13deec90466a74e1d4d375a6c663e4a2266", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/scaffold/__main__.py", + "sha256": "926a8bb2eede99ffb44ac34a5ff57950df4de748280d37edb38a8cf1c8441819", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/scaffold/cli.py", + "sha256": "a2228cce93986f97ae26cbdc5ce402ea31c5e83685b6b2cf31c1e52a4ee669d5", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/scaffold/project.py", + "sha256": "343d74719e25beec71fdc0b855f4e1a38db1e338e3a4b62ef1c7b3951e070587", + "routes": [], + "models": [ + { + "name": "PlannedFile", + "bases": [], + "fields": [ + { + "name": "relative_path", + "type": "str", + "default": "" + }, + { + "name": "content", + "type": "str", + "default": "" + }, + { + "name": "executable", + "type": "bool", + "default": "False" + } + ], + "line": 33, + "doc": "One file the generator will create, relative to the project root." + }, + { + "name": "ProjectPlan", + "bases": [], + "fields": [ + { + "name": "spec", + "type": "ModuleSpec", + "default": "" + }, + { + "name": "project_root_name", + "type": "str", + "default": "" + }, + { + "name": "files", + "type": "tuple[PlannedFile, ...]", + "default": "field(default_factory=tuple)" + } + ], + "line": 46, + "doc": "" + }, + { + "name": "GenerationResult", + "bases": [], + "fields": [ + { + "name": "spec", + "type": "ModuleSpec", + "default": "" + }, + { + "name": "project_root", + "type": "Path", + "default": "" + }, + { + "name": "created", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "dry_run", + "type": "bool", + "default": "" + } + ], + "line": 57, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/scaffold/spec.py", + "sha256": "603e6d89700bf64b4ffc285c06446b9cf9f66b318613de01ca8b5ef94cc134d2", + "routes": [], + "models": [ + { + "name": "ModuleSpec", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "module_id", + "type": "str", + "default": "Field(pattern=MODULE_ID_PATTERN)" + }, + { + "name": "name", + "type": "str", + "default": "Field(min_length=1, max_length=120)" + }, + { + "name": "description", + "type": "str", + "default": "Field(min_length=12, max_length=500)" + }, + { + "name": "version", + "type": "str", + "default": "'0.1.0'" + }, + { + "name": "townlight_core_min_version", + "type": "str", + "default": "'1.3.0.dev1'" + }, + { + "name": "permission_key", + "type": "str | None", + "default": "Field(default=None, pattern=SLUG_PATTERN)" + }, + { + "name": "staff_roles", + "type": "tuple[str, ...]", + "default": "('staff',)" + }, + { + "name": "route_path", + "type": "str | None", + "default": "Field(default=None, pattern=ROUTE_PATH_PATTERN)" + } + ], + "line": 65, + "doc": "Everything the generator needs, already validated.\n\n``module_id`` is the only identity; ``package_name``, import path, env-var\nprefix and migration revision ids are derived from it so a caller cannot\ncreate an inconsistent project." + }, + { + "name": "ScaffoldOptions", + "bases": [], + "fields": [ + { + "name": "dry_run", + "type": "bool", + "default": "False" + } + ], + "line": 165, + "doc": "Non-identity options, kept out of the persisted manifest." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/scheduling/__init__.py", + "sha256": "f887d66fc8bf298e094c46bae19fa42b67e5d26911522913d8c5a546d606b4cc", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/scheduling/cron.py", + "sha256": "a7c5688dc5a3e5c410466cc92a7d884a88a50fe92974d0a7642b0fbe954f0b08", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/search/__init__.py", + "sha256": "2450f3768c47b0e2869ca1056b188d41b9ba58f88a0865cad5ad854f03801908", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/security/__init__.py", + "sha256": "376e78b0875c2fd3074935b586cef2b806c371f140085ffc40eeb6aed09b9211", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/security/at_rest.py", + "sha256": "eb339fa93cff4af29df7f01b3f5552fff56c6bdc676fef6cb9aad8356a610d3e", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/security/config_validation.py", + "sha256": "e4064bf0394ffc7cdc0aafccfc689a2a17667cfd31d8455dc6f8a623d963af45", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/security/host_validation.py", + "sha256": "3e62ec5540713eea903409c88c4e2255b0dd8d54a9d5d23fc69ad15e03c15045", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/tasks/__init__.py", + "sha256": "2b30985e76210900397d5e65b5060786e8fec6478d8762690e8971a37c49d5f1", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/tasks/artifacts.py", + "sha256": "fbb9db7c76ce4b3bd91b3412ba2cfdcc52d3c67959ef117a0a765ee9dc3d972f", + "routes": [], + "models": [ + { + "name": "JobArtifact", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "artifact_id", + "type": "Mapped[str]", + "default": "mapped_column(String(64), primary_key=True)" + }, + { + "name": "task_id", + "type": "Mapped[str]", + "default": "mapped_column(String(128), index=True)" + }, + { + "name": "module_id", + "type": "Mapped[str]", + "default": "mapped_column(String(64))" + }, + { + "name": "task_type", + "type": "Mapped[str]", + "default": "mapped_column(String(100))" + }, + { + "name": "claim_token", + "type": "Mapped[str]", + "default": "mapped_column(String(64))" + }, + { + "name": "attempt_count", + "type": "Mapped[int]", + "default": "mapped_column(Integer, default=0)" + }, + { + "name": "artifact_name", + "type": "Mapped[str]", + "default": "mapped_column(String(200))" + }, + { + "name": "relative_path", + "type": "Mapped[str]", + "default": "mapped_column(String(400))" + }, + { + "name": "artifact_sha256", + "type": "Mapped[str]", + "default": "mapped_column(String(64))" + }, + { + "name": "artifact_bytes", + "type": "Mapped[int]", + "default": "mapped_column(BigInteger, default=0)" + }, + { + "name": "artifact_kind", + "type": "Mapped[str]", + "default": "mapped_column(String(40))" + }, + { + "name": "source_sha256", + "type": "Mapped[str]", + "default": "mapped_column(String(64))" + }, + { + "name": "source_label", + "type": "Mapped[str]", + "default": "mapped_column(String(200))" + }, + { + "name": "recorded_by", + "type": "Mapped[str]", + "default": "mapped_column(String(128))" + }, + { + "name": "recorded_at", + "type": "Mapped[datetime]", + "default": "mapped_column(DateTime(timezone=True))" + } + ], + "line": 96, + "doc": "Append-only acceptance record for one artifact produced by one claimed job." + }, + { + "name": "ArtifactStore", + "bases": [], + "fields": [ + { + "name": "root", + "type": "Path", + "default": "" + } + ], + "line": 119, + "doc": "A configured artifact root. Every published path must resolve inside it." + }, + { + "name": "SourceBinding", + "bases": [], + "fields": [ + { + "name": "sha256", + "type": "str", + "default": "" + }, + { + "name": "label", + "type": "str", + "default": "" + } + ], + "line": 141, + "doc": "The synthetic or real source a derivative was computed from." + }, + { + "name": "ArtifactProposal", + "bases": [], + "fields": [ + { + "name": "name", + "type": "str", + "default": "" + }, + { + "name": "kind", + "type": "str", + "default": "" + }, + { + "name": "content", + "type": "bytes", + "default": "" + }, + { + "name": "source", + "type": "SourceBinding", + "default": "" + } + ], + "line": 149, + "doc": "Caller-supplied intent. The hash is recomputed and never taken from here." + }, + { + "name": "PreparedArtifact", + "bases": [], + "fields": [ + { + "name": "store", + "type": "ArtifactStore", + "default": "" + }, + { + "name": "staging_path", + "type": "Path", + "default": "" + }, + { + "name": "name", + "type": "str", + "default": "" + }, + { + "name": "kind", + "type": "str", + "default": "" + }, + { + "name": "sha256", + "type": "str", + "default": "" + }, + { + "name": "size", + "type": "int", + "default": "" + }, + { + "name": "source", + "type": "SourceBinding", + "default": "" + } + ], + "line": 159, + "doc": "A staged, hash-verified file that is not yet published or recorded." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/tasks/leased.py", + "sha256": "eef2a9e339274c1caccde7cb3295a9d5bd88da6561090cbfc0a6bf10c8d29e1d", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/tasks/registry.py", + "sha256": "96bf04036bdc4be3b9097d7bc85f447105fd5d82e8ef548cd3d88354f7b3fce8", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/tasks/worker.py", + "sha256": "106d83f412c66d939e5d9a55276b51020c078ee89763135dc53f7c02ae20f76f", + "routes": [], + "models": [], + "configuration": [ + { + "variable": "DATABASE_URL", + "default": "", + "line": 34 + }, + { + "variable": "TOWNLIGHT_CORE_TASK_HANDLER_MODULES", + "default": "", + "line": 37 + } + ] + }, + { + "source": "installed-owned-source/townlight_core/testing/__init__.py", + "sha256": "359cfd4ae5b7324db08f496a0ee5043456f1ce60a4ae34fa75761a8790b88d50", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/testing/mock_city.py", + "sha256": "c1bac5478d09e0958115da8d4f55f4d5211ec1531062e76829381f5a6c47e389", + "routes": [], + "models": [ + { + "name": "MockCityVendorContract", + "bases": [], + "fields": [ + { + "name": "connector", + "type": "str", + "default": "" + }, + { + "name": "vendor_name", + "type": "str", + "default": "" + }, + { + "name": "interface_status", + "type": "str", + "default": "" + }, + { + "name": "method", + "type": "str", + "default": "" + }, + { + "name": "path", + "type": "str", + "default": "" + }, + { + "name": "auth_method", + "type": "str", + "default": "" + }, + { + "name": "delta_query_param", + "type": "str", + "default": "" + }, + { + "name": "sample_payload", + "type": "dict[str, Any]", + "default": "" + }, + { + "name": "notes", + "type": "str", + "default": "" + } + ], + "line": 90, + "doc": "" + }, + { + "name": "MockCityIdpContract", + "bases": [], + "fields": [ + { + "name": "provider", + "type": "str", + "default": "" + }, + { + "name": "interface_status", + "type": "str", + "default": "" + }, + { + "name": "issuer", + "type": "str", + "default": "" + }, + { + "name": "audience", + "type": "str", + "default": "" + }, + { + "name": "authorization_url", + "type": "str", + "default": "" + }, + { + "name": "token_url", + "type": "str", + "default": "" + }, + { + "name": "jwks_path", + "type": "str", + "default": "" + }, + { + "name": "role_claims", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "algorithms", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "client_id", + "type": "str", + "default": "" + }, + { + "name": "redirect_uri", + "type": "str", + "default": "" + }, + { + "name": "staff_subject", + "type": "str", + "default": "" + }, + { + "name": "staff_email", + "type": "str", + "default": "" + }, + { + "name": "staff_roles", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "notes", + "type": "str", + "default": "" + } + ], + "line": 116, + "doc": "" + }, + { + "name": "MockCityBackupRetentionContract", + "bases": [], + "fields": [ + { + "name": "city", + "type": "str", + "default": "" + }, + { + "name": "interface_status", + "type": "str", + "default": "" + }, + { + "name": "backup_scope", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "restore_proof_required", + "type": "bool", + "default": "" + }, + { + "name": "manifest_required_fields", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "retention_years", + "type": "int", + "default": "" + }, + { + "name": "restore_test_interval_days", + "type": "int", + "default": "" + }, + { + "name": "off_host_storage", + "type": "str", + "default": "" + }, + { + "name": "encryption_at_rest_required", + "type": "bool", + "default": "" + }, + { + "name": "immutable_retention_required", + "type": "bool", + "default": "" + }, + { + "name": "legal_hold_supported", + "type": "bool", + "default": "" + }, + { + "name": "approval_artifact", + "type": "str", + "default": "" + }, + { + "name": "notes", + "type": "str", + "default": "" + } + ], + "line": 154, + "doc": "" + }, + { + "name": "MockCityContractCheck", + "bases": [], + "fields": [ + { + "name": "connector", + "type": "str", + "default": "" + }, + { + "name": "ok", + "type": "bool", + "default": "" + }, + { + "name": "message", + "type": "str", + "default": "" + }, + { + "name": "fix", + "type": "str", + "default": "" + }, + { + "name": "normalized_external_meeting_id", + "type": "str | None", + "default": "None" + }, + { + "name": "delta_request_url", + "type": "str | None", + "default": "None" + } + ], + "line": 188, + "doc": "" + }, + { + "name": "MockCityIdpCheck", + "bases": [], + "fields": [ + { + "name": "provider", + "type": "str", + "default": "" + }, + { + "name": "ok", + "type": "bool", + "default": "" + }, + { + "name": "message", + "type": "str", + "default": "" + }, + { + "name": "fix", + "type": "str", + "default": "" + }, + { + "name": "auth_method", + "type": "str | None", + "default": "None" + }, + { + "name": "subject", + "type": "str | None", + "default": "None" + }, + { + "name": "roles", + "type": "tuple[str, ...]", + "default": "()" + } + ], + "line": 208, + "doc": "" + }, + { + "name": "MockCityBackupRetentionCheck", + "bases": [], + "fields": [ + { + "name": "city", + "type": "str", + "default": "" + }, + { + "name": "ok", + "type": "bool", + "default": "" + }, + { + "name": "message", + "type": "str", + "default": "" + }, + { + "name": "fix", + "type": "str", + "default": "" + }, + { + "name": "checked_fields", + "type": "tuple[str, ...]", + "default": "()" + } + ], + "line": 230, + "doc": "" + }, + { + "name": "DemoTownFixtureContract", + "bases": [], + "fields": [ + { + "name": "schema_version", + "type": "str", + "default": "" + }, + { + "name": "fixture_id", + "type": "str", + "default": "" + }, + { + "name": "fixture_version", + "type": "str", + "default": "" + }, + { + "name": "deterministic_seed", + "type": "str", + "default": "" + }, + { + "name": "generated_at", + "type": "str", + "default": "" + }, + { + "name": "municipality", + "type": "dict[str, Any]", + "default": "" + }, + { + "name": "sources", + "type": "tuple[dict[str, Any], ...]", + "default": "" + }, + { + "name": "records", + "type": "tuple[dict[str, Any], ...]", + "default": "" + }, + { + "name": "requests", + "type": "tuple[dict[str, Any], ...]", + "default": "" + }, + { + "name": "expected", + "type": "dict[str, Any]", + "default": "" + } + ], + "line": 248, + "doc": "Versioned, deterministic and independently authored municipal demo data." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/verification/__init__.py", + "sha256": "79e2b135ad90bfad95db77a54f7d2c65d96eb13bb8ad1ed0a35e3655dc03a0e7", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_core/verification/browser_evidence.py", + "sha256": "493219d45f5c50d5c514a4ea9534ccfab35979d0c58a577a2e9afd01328c7fe1", + "routes": [], + "models": [ + { + "name": "BrowserReleaseEvidenceResult", + "bases": [], + "fields": [ + { + "name": "version", + "type": "str", + "default": "" + }, + { + "name": "reviewed_at", + "type": "str", + "default": "" + }, + { + "name": "page", + "type": "Path", + "default": "" + }, + { + "name": "screenshots", + "type": "dict[str, Path]", + "default": "" + } + ], + "line": 23, + "doc": "" + } + ], + "configuration": [] + } + ], + "bridge": [ + { + "source": "installed-owned-source/townlight_runtime/services.py", + "sha256": "5dfb0f58ea1f94185081426a3734905c78624d7bcd5407fd2c4e0fa1fb054a6b", + "routes": [ + { + "method": "GET", + "path": "/health", + "router": "app", + "prefix_resolved": true, + "name": "runtime_health", + "signature": "", + "returns": "", + "line": 439, + "doc": "", + "decorator": "app.get('/health')", + "errors": [] + }, + { + "method": "GET", + "path": "/modules", + "router": "app", + "prefix_resolved": true, + "name": "runtime_health", + "signature": "", + "returns": "", + "line": 439, + "doc": "", + "decorator": "app.get('/modules')", + "errors": [] + }, + { + "method": "GET", + "path": "/ready", + "router": "app", + "prefix_resolved": true, + "name": "domain_ready", + "signature": "", + "returns": "", + "line": 444, + "doc": "", + "decorator": "app.get('/ready')", + "errors": [] + } + ], + "models": [], + "configuration": [ + { + "variable": "TOWNLIGHT_PROFILE_ROOT", + "default": "", + "line": 56 + }, + { + "variable": "TOWNLIGHT_DATA_DIR", + "default": "", + "line": 61 + }, + { + "variable": "LOCALAPPDATA", + "default": "", + "line": 64 + }, + { + "variable": "DATABASE_URL", + "default": "", + "line": 148 + }, + { + "variable": "TOWNLIGHT_RUNTIME_HOST", + "default": "DEFAULT_HOST", + "line": 479 + }, + { + "variable": "TESTING", + "default": "", + "line": 113 + }, + { + "variable": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", + "default": "''", + "line": 240 + }, + { + "variable": "DATABASE_URL", + "default": "", + "line": 300 + }, + { + "variable": "TOWNLIGHT_RUNTIME_PORT", + "default": "str(DEFAULT_PORT)", + "line": 482 + } + ] + } + ] + }, + "records": { + "package": "app", + "source": [ + { + "source": "installed-owned-source/app/__init__.py", + "sha256": "faef907da0d1b1e4b467dc711514a24f6112ff32809ee7e7e6065c684ab7f2b9", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/admin/__init__.py", + "sha256": "5724a9ba19246885896a1603eecc360d7cb5b5cc6c745f635553158f7c46431d", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/admin/router.py", + "sha256": "daea85a6114138f50a2a3da4bff8736c1140174599440b07cac35aee27694b7d", + "routes": [ + { + "method": "GET", + "path": "/admin/status", + "router": "router", + "prefix_resolved": true, + "name": "system_status", + "signature": "request: Request, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 53, + "doc": "", + "decorator": "router.get('/status', response_model=SystemStatus)", + "errors": [] + }, + { + "method": "GET", + "path": "/admin/users", + "router": "router", + "prefix_resolved": true, + "name": "list_users", + "signature": "session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 100, + "doc": "List all users. Admin only.", + "decorator": "router.get('/users', response_model=list[UserRead])", + "errors": [] + }, + { + "method": "POST", + "path": "/admin/users", + "router": "router", + "prefix_resolved": true, + "name": "create_user", + "signature": "body: AdminUserCreateRequest, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 127, + "doc": "Create a new user. Admin only.", + "decorator": "router.post('/users', response_model=AdminUserCreateResponse, status_code=201)", + "errors": [ + "_HTTPException(status_code=422, detail=f'Invalid role: {body.role}')", + "_HTTPException(status_code=400, detail=str(e))" + ] + }, + { + "method": "PATCH", + "path": "/admin/users/{user_id}", + "router": "router", + "prefix_resolved": true, + "name": "update_user", + "signature": "user_id: uuid.UUID, body: UserUpdateRequest, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 178, + "doc": "Update user fields. Admin only.\n\nGuards against self-demotion: admins cannot change their own role.", + "decorator": "router.patch('/users/{user_id}', response_model=AdminUserCreateResponse)", + "errors": [ + "HTTPException(status_code=404, detail='User not found')", + "HTTPException(status_code=400, detail='Cannot change your own role. Another admin must do this.')", + "HTTPException(status_code=400, detail='Cannot deactivate your own account.')", + "HTTPException(status_code=422, detail=f'Invalid role: {body.role}')" + ] + }, + { + "method": "GET", + "path": "/admin/models", + "router": "router", + "prefix_resolved": true, + "name": "list_models", + "signature": "user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 239, + "doc": "", + "decorator": "router.get('/models', response_model=OllamaStatus)", + "errors": [] + }, + { + "method": "GET", + "path": "/admin/models/registry", + "router": "router", + "prefix_resolved": true, + "name": "list_model_registry", + "signature": "session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 265, + "doc": "", + "decorator": "router.get('/models/registry', response_model=list[ModelRegistryRead])", + "errors": [] + }, + { + "method": "POST", + "path": "/admin/models/registry", + "router": "router", + "prefix_resolved": true, + "name": "register_model", + "signature": "data: ModelRegistryCreate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 276, + "doc": "", + "decorator": "router.post('/models/registry', response_model=ModelRegistryRead, status_code=201)", + "errors": [] + }, + { + "method": "PATCH", + "path": "/admin/models/registry/{model_id}", + "router": "router", + "prefix_resolved": true, + "name": "update_model_registry", + "signature": "model_id: int, data: ModelRegistryUpdate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 305, + "doc": "", + "decorator": "router.patch('/models/registry/{model_id}', response_model=ModelRegistryRead)", + "errors": [ + "HTTPException(status_code=404, detail='Model not found')" + ] + }, + { + "method": "DELETE", + "path": "/admin/models/registry/{model_id}", + "router": "router", + "prefix_resolved": true, + "name": "delete_model_registry", + "signature": "model_id: int, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 330, + "doc": "", + "decorator": "router.delete('/models/registry/{model_id}', status_code=204)", + "errors": [ + "HTTPException(status_code=404, detail='Model not found')" + ] + }, + { + "method": "GET", + "path": "/admin/fee-schedules", + "router": "router", + "prefix_resolved": true, + "name": "list_fee_schedules", + "signature": "jurisdiction: str | None=None, limit: int=50, offset: int=0, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 354, + "doc": "List all fee schedules. Admin only.", + "decorator": "router.get('/fee-schedules', response_model=list[FeeScheduleRead])", + "errors": [] + }, + { + "method": "POST", + "path": "/admin/fee-schedules", + "router": "router", + "prefix_resolved": true, + "name": "create_fee_schedule", + "signature": "data: FeeScheduleCreate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 371, + "doc": "Create a new fee schedule. Admin only.", + "decorator": "router.post('/fee-schedules', response_model=FeeScheduleRead, status_code=201)", + "errors": [] + }, + { + "method": "PATCH", + "path": "/admin/fee-schedules/{schedule_id}", + "router": "router", + "prefix_resolved": true, + "name": "update_fee_schedule", + "signature": "schedule_id: uuid.UUID, data: FeeScheduleUpdate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 398, + "doc": "Update a fee schedule. Admin only.", + "decorator": "router.patch('/fee-schedules/{schedule_id}', response_model=FeeScheduleRead)", + "errors": [ + "HTTPException(status_code=404, detail='Fee schedule not found')" + ] + }, + { + "method": "DELETE", + "path": "/admin/fee-schedules/{schedule_id}", + "router": "router", + "prefix_resolved": true, + "name": "delete_fee_schedule", + "signature": "schedule_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 424, + "doc": "Delete a fee schedule. Admin only.", + "decorator": "router.delete('/fee-schedules/{schedule_id}', status_code=204)", + "errors": [ + "HTTPException(status_code=404, detail='Fee schedule not found')" + ] + }, + { + "method": "GET", + "path": "/admin/coverage-gaps", + "router": "router", + "prefix_resolved": true, + "name": "get_coverage_gaps", + "signature": "session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 454, + "doc": "Identify coverage gaps across jurisdictions, departments, and exemption categories.\n\nReturns:\n- Jurisdictions (state codes) that have no exemption rules\n- Departments with no assigned staff users\n- Exemption categories without any active rules", + "decorator": "router.get('/coverage-gaps', response_model=CoverageGapResponse)", + "errors": [] + } + ], + "models": [ + { + "name": "SystemStatus", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "version", + "type": "str", + "default": "" + }, + { + "name": "database", + "type": "str", + "default": "" + }, + { + "name": "ollama", + "type": "str", + "default": "" + }, + { + "name": "redis", + "type": "str", + "default": "" + }, + { + "name": "user_count", + "type": "int", + "default": "" + }, + { + "name": "audit_log_count", + "type": "int", + "default": "" + }, + { + "name": "suite_session", + "type": "dict | None", + "default": "None" + } + ], + "line": 31, + "doc": "" + }, + { + "name": "OllamaModelInfo", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "name", + "type": "str", + "default": "" + }, + { + "name": "size", + "type": "int | None", + "default": "None" + }, + { + "name": "details", + "type": "dict | None", + "default": "None" + } + ], + "line": 41, + "doc": "" + }, + { + "name": "OllamaStatus", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "models", + "type": "list[OllamaModelInfo]", + "default": "" + } + ], + "line": 47, + "doc": "" + }, + { + "name": "AdminUserCreateRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "email", + "type": "str", + "default": "" + }, + { + "name": "password", + "type": "str", + "default": "" + }, + { + "name": "full_name", + "type": "str", + "default": "''" + }, + { + "name": "role", + "type": "str", + "default": "'staff'" + } + ], + "line": 109, + "doc": "" + }, + { + "name": "AdminUserCreateResponse", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "email", + "type": "str", + "default": "" + }, + { + "name": "full_name", + "type": "str", + "default": "" + }, + { + "name": "role", + "type": "str", + "default": "" + }, + { + "name": "is_active", + "type": "bool", + "default": "" + } + ], + "line": 116, + "doc": "" + }, + { + "name": "UserUpdateRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "full_name", + "type": "str | None", + "default": "None" + }, + { + "name": "role", + "type": "str | None", + "default": "None" + }, + { + "name": "department_id", + "type": "uuid.UUID | None", + "default": "None" + }, + { + "name": "is_active", + "type": "bool | None", + "default": "None" + } + ], + "line": 170, + "doc": "" + }, + { + "name": "CoverageGapResponse", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "jurisdictions_without_rules", + "type": "list[str]", + "default": "" + }, + { + "name": "departments_without_staff", + "type": "list[dict]", + "default": "" + }, + { + "name": "uncovered_categories", + "type": "list[str]", + "default": "" + }, + { + "name": "total_gaps", + "type": "int", + "default": "" + } + ], + "line": 446, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/analytics/__init__.py", + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/analytics/router.py", + "sha256": "a82bc140c0e152301bc9583a8a291974876f068eb3a4fac1b342056ecb217316", + "routes": [ + { + "method": "GET", + "path": "/analytics/operational", + "router": "router", + "prefix_resolved": false, + "name": "get_operational_metrics", + "signature": "session: AsyncSession=Depends(get_async_session), user=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 33, + "doc": "", + "decorator": "router.get('/analytics/operational', response_model=OperationalMetrics)", + "errors": [] + } + ], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/audit/__init__.py", + "sha256": "35d25b33770f3cd458121ab4d8a6cdb87c32e7b8282bb674c8bf93bca6a5d82d", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/audit/logger.py", + "sha256": "1ad570f68753023d56827f8fa672822e50e234d32259b218682b815ee02cd0e8", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/audit/middleware.py", + "sha256": "c9283a66fbe43933edf30895e9b242380a99769127bd6536937dd56652e01a96", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/audit/router.py", + "sha256": "fc933066a2355e924c0f7c359d9249591c0f8024eadc455246b4b0b536f7d67f", + "routes": [ + { + "method": "GET", + "path": "/audit/logs", + "router": "router", + "prefix_resolved": true, + "name": "list_audit_logs", + "signature": "query: AuditLogQuery=Depends(), session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 16, + "doc": "", + "decorator": "router.get('/logs', response_model=list[AuditLogRead])", + "errors": [] + }, + { + "method": "GET", + "path": "/audit/verify", + "router": "router", + "prefix_resolved": true, + "name": "verify_audit_chain", + "signature": "session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 40, + "doc": "", + "decorator": "router.get('/verify', response_model=AuditChainVerification)", + "errors": [] + }, + { + "method": "GET", + "path": "/audit/export", + "router": "router", + "prefix_resolved": true, + "name": "export_audit_logs", + "signature": "format: str='json', start_date: str | None=None, end_date: str | None=None, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 51, + "doc": "", + "decorator": "router.get('/export')", + "errors": [] + } + ], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/auth/__init__.py", + "sha256": "40ae31146583108d88187effd6cdc081314021177425b6bdb1cb7b72530d5c4b", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/auth/backend.py", + "sha256": "5a91017634252d0e8c959fa1ec1ae2163b118a4901ecc0bb1233448e8ca498bb", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/auth/department_authority.py", + "sha256": "f234cf04a5755dc3c0bd76230ef5145d4e7d26876c21b6776924ed95ea3e80eb", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/auth/dependencies.py", + "sha256": "28390a14cf9b4550ed09772d0f8c922e4e27cfb75639dd7d853dbeea1e28433d", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/auth/desktop_session.py", + "sha256": "ce8ff9e910ca8b7f36d8c8616a65d593d48fba3588538edfa6731ea6ada8a36b", + "routes": [], + "models": [ + { + "name": "NativeDesktopPrincipal", + "bases": [], + "fields": [ + { + "name": "email", + "type": "str", + "default": "" + }, + { + "name": "display_name", + "type": "str", + "default": "" + }, + { + "name": "role", + "type": "str", + "default": "" + }, + { + "name": "expires_at_unix_seconds", + "type": "int", + "default": "" + } + ], + "line": 39, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/auth/manager.py", + "sha256": "337f7d5b6d89973c352259c21512da56e6308a6e3e6967f035a31916b52c2bbb", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/auth/native_identity.py", + "sha256": "3d2536b13f38c52d93c4ab54887bf232a3b9181fe1b485165e1fd6a81fe687d0", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/auth/router.py", + "sha256": "9574ed42379df9ef05d9c13409c01f715538e00bb9e3c884b884cd2c1c8495fc", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/auth/suite_session.py", + "sha256": "126a453ff01029cfe7abbbb5a3ecbf6c3ba562957ce929eb7854ff682576d071", + "routes": [], + "models": [ + { + "name": "SuiteSessionUser", + "bases": [], + "fields": [ + { + "name": "email", + "type": "str", + "default": "" + }, + { + "name": "roles", + "type": "frozenset[str]", + "default": "" + }, + { + "name": "must_change_password", + "type": "bool", + "default": "False" + } + ], + "line": 180, + "doc": "" + }, + { + "name": "SuiteSession", + "bases": [], + "fields": [ + { + "name": "subject", + "type": "str", + "default": "" + }, + { + "name": "roles", + "type": "frozenset[str]", + "default": "" + }, + { + "name": "session_id", + "type": "str", + "default": "" + } + ], + "line": 187, + "doc": "" + }, + { + "name": "Principal", + "bases": [], + "fields": [ + { + "name": "subject", + "type": "str", + "default": "" + }, + { + "name": "roles", + "type": "frozenset[str]", + "default": "" + }, + { + "name": "session_id", + "type": "str", + "default": "" + } + ], + "line": 85, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/catalog/__init__.py", + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/catalog/loader.py", + "sha256": "8ec0239d327824d28d18425904c64ef2bbfc2d04c65a4c5deb64904d5354912d", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/catalog/router.py", + "sha256": "8720ef17e4106e738c2ed3672af4051dfe36b617a9da8eae8fa54a9c23de13d8", + "routes": [ + { + "method": "GET", + "path": "/catalog/domains", + "router": "router", + "prefix_resolved": false, + "name": "list_domains", + "signature": "session: AsyncSession=Depends(get_async_session), user=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 12, + "doc": "", + "decorator": "router.get('/catalog/domains')", + "errors": [] + }, + { + "method": "GET", + "path": "/catalog/systems", + "router": "router", + "prefix_resolved": false, + "name": "list_systems", + "signature": "domain: str | None=None, session: AsyncSession=Depends(get_async_session), user=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 16, + "doc": "", + "decorator": "router.get('/catalog/systems')", + "errors": [] + }, + { + "method": "GET", + "path": "/catalog/connectors", + "router": "router", + "prefix_resolved": false, + "name": "list_connectors", + "signature": "domain: str, session: AsyncSession=Depends(get_async_session), user=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 20, + "doc": "", + "decorator": "router.get('/catalog/connectors')", + "errors": [] + }, + { + "method": "POST", + "path": "/catalog/load", + "router": "router", + "prefix_resolved": false, + "name": "trigger_catalog_load", + "signature": "session: AsyncSession=Depends(get_async_session), user=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 24, + "doc": "", + "decorator": "router.post('/catalog/load', status_code=200)", + "errors": [ + "HTTPException(409, 'Catalog missing, changed or incomplete; existing data preserved. Review a new catalog version.')" + ] + } + ], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/city_profile/__init__.py", + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/city_profile/router.py", + "sha256": "e0b9d83c16dcb8e6ad6b2ca3bd2c4300ff0aa9ff89609a7f5bd7cc5dde835682", + "routes": [ + { + "method": "GET", + "path": "/city-profile", + "router": "router", + "prefix_resolved": false, + "name": "get_city_profile", + "signature": "session: AsyncSession=Depends(get_async_session), user=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 32, + "doc": "", + "decorator": "router.get('/city-profile', response_model=CityProfileRead | None)", + "errors": [] + }, + { + "method": "POST", + "path": "/city-profile", + "router": "router", + "prefix_resolved": false, + "name": "create_city_profile", + "signature": "data: CityProfileCreate, session: AsyncSession=Depends(get_async_session), user=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 42, + "doc": "", + "decorator": "router.post('/city-profile', response_model=CityProfileRead, status_code=201)", + "errors": [ + "HTTPException(409, 'City profile already exists. Use PATCH to update.')" + ] + }, + { + "method": "PATCH", + "path": "/city-profile", + "router": "router", + "prefix_resolved": false, + "name": "update_city_profile", + "signature": "data: CityProfileUpdate, session: AsyncSession=Depends(get_async_session), user=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 76, + "doc": "", + "decorator": "router.patch('/city-profile', response_model=CityProfileRead)", + "errors": [ + "HTTPException(404, 'No city profile exists. Use POST to create one.')" + ] + } + ], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/config.py", + "sha256": "52725fbeb02c75717ae638e8d0cdf2d527656fb8bac5b5b5572d48d6e794a1c5", + "routes": [], + "models": [ + { + "name": "Settings", + "bases": [ + "BaseSettings" + ], + "fields": [ + { + "name": "database_url", + "type": "str", + "default": "'postgresql+asyncpg://townlight_records:townlight_records@postgres:5432/townlight_records'" + }, + { + "name": "jwt_secret", + "type": "str", + "default": "'CHANGE-ME'" + }, + { + "name": "jwt_secret_file", + "type": "str", + "default": "'/run/secrets/jwt_secret'" + }, + { + "name": "jwt_lifetime_seconds", + "type": "int", + "default": "3600" + }, + { + "name": "first_admin_email", + "type": "str", + "default": "'admin@example.gov'" + }, + { + "name": "first_admin_password", + "type": "str", + "default": "'CHANGE-ME'" + }, + { + "name": "first_admin_password_file", + "type": "str", + "default": "'/run/secrets/first_admin_password'" + }, + { + "name": "ollama_base_url", + "type": "str", + "default": "'http://ollama:11434'" + }, + { + "name": "redis_url", + "type": "str", + "default": "'redis://redis:6379/0'" + }, + { + "name": "audit_retention_days", + "type": "int", + "default": "1095" + }, + { + "name": "cors_origins", + "type": "list[str]", + "default": "['http://localhost:8080']" + }, + { + "name": "embedding_model", + "type": "str", + "default": "'nomic-embed-text'" + }, + { + "name": "chat_model", + "type": "str", + "default": "'gemma4:e4b'" + }, + { + "name": "vision_model", + "type": "str", + "default": "'gemma4:e4b'" + }, + { + "name": "smtp_host", + "type": "str", + "default": "''" + }, + { + "name": "smtp_port", + "type": "int", + "default": "587" + }, + { + "name": "smtp_username", + "type": "str", + "default": "''" + }, + { + "name": "smtp_password", + "type": "str", + "default": "''" + }, + { + "name": "smtp_from_email", + "type": "str", + "default": "'noreply@townlight_records.local'" + }, + { + "name": "smtp_use_tls", + "type": "bool", + "default": "True" + }, + { + "name": "connector_host_allowlist", + "type": "Annotated[list[str], NoDecode]", + "default": "[]" + }, + { + "name": "portal_mode", + "type": "Literal['public', 'private']", + "default": "'private'" + }, + { + "name": "encryption_key", + "type": "str", + "default": "'CHANGE-ME-generate-with-fernet-generate-key'" + }, + { + "name": "testing", + "type": "bool", + "default": "False" + }, + { + "name": "authority_scope_id", + "type": "str", + "default": "''" + } + ], + "line": 24, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/connectors/__init__.py", + "sha256": "858f35a785e1714492e27337991099f9891ab9e0b6325427213d0458b7e7508f", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/connectors/base.py", + "sha256": "61772e641cda2c08df5c95ce7cbefe725b550b1fd67f54cb550ea847c9927688", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/connectors/file_system.py", + "sha256": "d61c6ed4b906cb10697949ed9810ce14853301af1706cc02ba6605fec1d385a6", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/connectors/imap_email.py", + "sha256": "a6353f14d4f083e999e089bd8c536438a9355ac0bab5c94b03ab30f4f0ef084d", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/connectors/manual_drop.py", + "sha256": "4130a495cb691d56d6c9cc493bf85edb520f86c89846a241ed216ca652b4d2ac", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/connectors/odbc.py", + "sha256": "636c23aa66537775c674efe095a1c9e27dc670a6370a742e325c1ea5039243db", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/connectors/rest_api.py", + "sha256": "52e26ea1923a25ed7704f090e37745be39a0fb80e38a4b5cdb315a08d16373f2", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/connectors/retry.py", + "sha256": "bba511cd51d7727835e24540b5c8c4660dbab43776d34cbaf2a618b207c36726", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/database.py", + "sha256": "cbf900a24999134b812e06749cd897a8f36e1885a05fb6b837363788ae2e990f", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/datasources/__init__.py", + "sha256": "f8a2f02b77cc7a4a879305cceee97e5ee272213e93c635792e42a1c3e5afaa75", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/datasources/router.py", + "sha256": "67dc17fea9f4259bcf8c4f376c447bdcd775ae59fd6e805a981873fe87bf36c4", + "routes": [ + { + "method": "POST", + "path": "/datasources/", + "router": "router", + "prefix_resolved": true, + "name": "create_datasource", + "signature": "data: DataSourceCreate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 70, + "doc": "", + "decorator": "router.post('/', response_model=DataSourceAdminRead, status_code=201)", + "errors": [ + "HTTPException(status_code=409, detail='Name already taken')" + ] + }, + { + "method": "GET", + "path": "/datasources/", + "router": "router", + "prefix_resolved": true, + "name": "list_datasources", + "signature": "session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 89, + "doc": "", + "decorator": "router.get('/', response_model=list[DataSourceRead])", + "errors": [] + }, + { + "method": "PATCH", + "path": "/datasources/{source_id}", + "router": "router", + "prefix_resolved": true, + "name": "update_datasource", + "signature": "source_id: uuid.UUID, data: DataSourceUpdate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 137, + "doc": "", + "decorator": "router.patch('/{source_id}', response_model=DataSourceAdminRead)", + "errors": [ + "HTTPException(status_code=404, detail='Data source not found')" + ] + }, + { + "method": "POST", + "path": "/datasources/{source_id}/ingest", + "router": "router", + "prefix_resolved": true, + "name": "trigger_ingestion", + "signature": "source_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 156, + "doc": "", + "decorator": "router.post('/{source_id}/ingest')", + "errors": [ + "HTTPException(status_code=404, detail='Data source not found')" + ] + }, + { + "method": "POST", + "path": "/datasources/upload", + "router": "router", + "prefix_resolved": true, + "name": "upload_file", + "signature": "file: UploadFile=File(...), session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 165, + "doc": "", + "decorator": "router.post('/upload')", + "errors": [ + "HTTPException(status_code=413, detail='File too large (max 100 MB)')" + ] + }, + { + "method": "POST", + "path": "/datasources/documents/{document_id}/re-ingest", + "router": "router", + "prefix_resolved": true, + "name": "re_ingest_document", + "signature": "document_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 201, + "doc": "Re-ingest a failed document. Resets status to pending and queues for processing.", + "decorator": "router.post('/documents/{document_id}/re-ingest')", + "errors": [ + "HTTPException(status_code=404, detail='Document not found')", + "HTTPException(status_code=400, detail=f'Can only re-ingest failed documents (current: {doc.ingestion_status.value})')" + ] + }, + { + "method": "GET", + "path": "/datasources/stats", + "router": "router", + "prefix_resolved": true, + "name": "ingestion_stats", + "signature": "session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 236, + "doc": "", + "decorator": "router.get('/stats', response_model=IngestionStats)", + "errors": [] + }, + { + "method": "POST", + "path": "/datasources/test-connection", + "router": "router", + "prefix_resolved": true, + "name": "test_connection", + "signature": "body: TestConnectionRequest, user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 277, + "doc": "Test connectivity to a data source without persisting anything.\n\nThis endpoint validates the connection parameters and attempts a test\nconnection. Credentials are NOT persisted, NOT logged, and NOT returned.", + "decorator": "router.post('/test-connection', response_model=TestConnectionResponse)", + "errors": [] + } + ], + "models": [ + { + "name": "TestConnectionRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "source_type", + "type": "str", + "default": "" + }, + { + "name": "host", + "type": "str | None", + "default": "None" + }, + { + "name": "port", + "type": "int | None", + "default": "None" + }, + { + "name": "path", + "type": "str | None", + "default": "None" + }, + { + "name": "username", + "type": "str | None", + "default": "None" + }, + { + "name": "password", + "type": "str | None", + "default": "None" + }, + { + "name": "rest_api_config", + "type": "dict[str, Any] | None", + "default": "None" + }, + { + "name": "odbc_config", + "type": "dict[str, Any] | None", + "default": "None" + } + ], + "line": 250, + "doc": "Dedicated schema for test-connection. NOT the create schema.\n\nSecurity: credentials in this request body are never persisted, never\nwritten to audit logs, and never returned in the response." + }, + { + "name": "TestConnectionResponse", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "success", + "type": "bool", + "default": "" + }, + { + "name": "message", + "type": "str", + "default": "" + }, + { + "name": "latency_ms", + "type": "int | None", + "default": "None" + }, + { + "name": "status", + "type": "str | None", + "default": "None" + }, + { + "name": "warning", + "type": "str | None", + "default": "None" + }, + { + "name": "differing_keys", + "type": "list[str] | None", + "default": "None" + } + ], + "line": 267, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/datasources/sync_failures_router.py", + "sha256": "6d942272770c5968245a2c2455883971eef01afd28c3fb6620efcf435ae0daa5", + "routes": [ + { + "method": "GET", + "path": "/datasources/{source_id}/sync-failures", + "router": "router", + "prefix_resolved": true, + "name": "list_sync_failures", + "signature": "source_id: uuid.UUID, status: Optional[str]=Query(None, description='Filter by status'), limit: int=Query(50, ge=1, le=500), offset: int=Query(0, ge=0), db: AsyncSession=Depends(get_async_session), current_user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 26, + "doc": "", + "decorator": "router.get('/{source_id}/sync-failures', response_model=list[SyncFailureRead])", + "errors": [] + }, + { + "method": "POST", + "path": "/datasources/{source_id}/sync-failures/{failure_id}/retry", + "router": "router", + "prefix_resolved": true, + "name": "retry_sync_failure", + "signature": "source_id: uuid.UUID, failure_id: uuid.UUID, db: AsyncSession=Depends(get_async_session), current_user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 43, + "doc": "", + "decorator": "router.post('/{source_id}/sync-failures/{failure_id}/retry')", + "errors": [ + "HTTPException(status_code=404, detail='Sync failure not found')" + ] + }, + { + "method": "POST", + "path": "/datasources/{source_id}/sync-failures/{failure_id}/dismiss", + "router": "router", + "prefix_resolved": true, + "name": "dismiss_sync_failure", + "signature": "source_id: uuid.UUID, failure_id: uuid.UUID, db: AsyncSession=Depends(get_async_session), current_user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 59, + "doc": "", + "decorator": "router.post('/{source_id}/sync-failures/{failure_id}/dismiss')", + "errors": [ + "HTTPException(status_code=404, detail='Sync failure not found')" + ] + }, + { + "method": "POST", + "path": "/datasources/{source_id}/sync-failures/retry-all", + "router": "router", + "prefix_resolved": true, + "name": "retry_all_sync_failures", + "signature": "source_id: uuid.UUID, status: str=Query(..., description='Status to reset \u2014 required'), db: AsyncSession=Depends(get_async_session), current_user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 76, + "doc": "", + "decorator": "router.post('/{source_id}/sync-failures/retry-all')", + "errors": [] + }, + { + "method": "POST", + "path": "/datasources/{source_id}/sync-failures/dismiss-all", + "router": "router", + "prefix_resolved": true, + "name": "dismiss_all_sync_failures", + "signature": "source_id: uuid.UUID, status: str=Query(..., description='Status to dismiss \u2014 required'), db: AsyncSession=Depends(get_async_session), current_user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 97, + "doc": "", + "decorator": "router.post('/{source_id}/sync-failures/dismiss-all')", + "errors": [] + }, + { + "method": "POST", + "path": "/datasources/{source_id}/unpause", + "router": "router", + "prefix_resolved": true, + "name": "unpause_source", + "signature": "source_id: uuid.UUID, db: AsyncSession=Depends(get_async_session), current_user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 120, + "doc": "", + "decorator": "router.post('/{source_id}/unpause')", + "errors": [ + "HTTPException(status_code=404, detail='Data source not found')" + ] + }, + { + "method": "GET", + "path": "/datasources/{source_id}/sync-run-log", + "router": "router", + "prefix_resolved": true, + "name": "get_sync_run_log", + "signature": "source_id: uuid.UUID, limit: int=Query(20, ge=1, le=100), db: AsyncSession=Depends(get_async_session), current_user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 137, + "doc": "", + "decorator": "router.get('/{source_id}/sync-run-log', response_model=list[SyncRunLogRead])", + "errors": [] + } + ], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/departments/__init__.py", + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/departments/router.py", + "sha256": "1c5f50b50572ecd7003903f2d3e9433027c86ebffe5a44d821b2e5ed05f0a39d", + "routes": [ + { + "method": "POST", + "path": "/departments/", + "router": "router", + "prefix_resolved": true, + "name": "create_department", + "signature": "data: DepartmentCreate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 18, + "doc": "", + "decorator": "router.post('/', response_model=DepartmentRead, status_code=201)", + "errors": [ + "HTTPException(status_code=409, detail='Department code already exists')" + ] + }, + { + "method": "GET", + "path": "/departments/", + "router": "router", + "prefix_resolved": true, + "name": "list_departments", + "signature": "session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 43, + "doc": "", + "decorator": "router.get('/', response_model=list[DepartmentRead])", + "errors": [] + }, + { + "method": "GET", + "path": "/departments/{dept_id}", + "router": "router", + "prefix_resolved": true, + "name": "get_department", + "signature": "dept_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 54, + "doc": "", + "decorator": "router.get('/{dept_id}', response_model=DepartmentRead)", + "errors": [ + "HTTPException(status_code=404, detail='Department not found')" + ] + }, + { + "method": "PATCH", + "path": "/departments/{dept_id}", + "router": "router", + "prefix_resolved": true, + "name": "update_department", + "signature": "dept_id: uuid.UUID, data: DepartmentUpdate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 66, + "doc": "", + "decorator": "router.patch('/{dept_id}', response_model=DepartmentRead)", + "errors": [ + "HTTPException(status_code=404, detail='Department not found')", + "HTTPException(status_code=409, detail='Department code already exists')" + ] + }, + { + "method": "DELETE", + "path": "/departments/{dept_id}", + "router": "router", + "prefix_resolved": true, + "name": "delete_department", + "signature": "dept_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 100, + "doc": "", + "decorator": "router.delete('/{dept_id}', status_code=204)", + "errors": [ + "HTTPException(status_code=404, detail='Department not found')", + "HTTPException(status_code=409, detail=f'Cannot delete department with {user_count} assigned users')" + ] + } + ], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/desktop_bridge/__init__.py", + "sha256": "707138dfa41f7f4e91957a523e3c3394ce52803778c5b278b3cc77d4a5b1c30f", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/desktop_bridge/projection.py", + "sha256": "5267b17ae6be18258ea0e225ffb0d53c56aeaf674d9426856b8db804f801008c", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/desktop_bridge/records.py", + "sha256": "407b2ca9974caa761c00daee3b585ca915c2fe649a69a0dd58f42342b39821d1", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/desktop_bridge/router.py", + "sha256": "7c02e0a222c36aecb84b105a918309a811f40249c3f55756d87cfa2646c4ef1b", + "routes": [ + { + "method": "GET", + "path": "/desktop/v1/public/records-state", + "router": "router", + "prefix_resolved": true, + "name": "public_records_state", + "signature": "request: Request, session: AsyncSession=Depends(get_async_session)", + "returns": "", + "line": 134, + "doc": "", + "decorator": "router.get('/public/records-state', dependencies=[Depends(native_public_shell)], response_model=RecordsStateRead)", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/public/requests", + "router": "router", + "prefix_resolved": true, + "name": "public_records_intake", + "signature": "data: PublicIntake, request: Request, session: AsyncSession=Depends(get_async_session)", + "returns": "", + "line": 144, + "doc": "", + "decorator": "router.post('/public/requests', dependencies=[Depends(native_public_shell)])", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/public/lookup", + "router": "router", + "prefix_resolved": true, + "name": "public_records_lookup", + "signature": "data: PublicLookup, request: Request, session: AsyncSession=Depends(get_async_session)", + "returns": "", + "line": 153, + "doc": "", + "decorator": "router.post('/public/lookup', dependencies=[Depends(native_public_shell)])", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/public/messages", + "router": "router", + "prefix_resolved": true, + "name": "public_records_message", + "signature": "data: PublicMessage, request: Request, session: AsyncSession=Depends(get_async_session)", + "returns": "", + "line": 160, + "doc": "", + "decorator": "router.post('/public/messages', dependencies=[Depends(native_public_shell)])", + "errors": [ + "HTTPException(400, str(error))" + ] + }, + { + "method": "POST", + "path": "/desktop/v1/permitting-sources/search", + "router": "router", + "prefix_resolved": true, + "name": "search_permitting_sources", + "signature": "data: MeetingsSearch, request: Request, actor: User=Depends(native_records_user)", + "returns": "", + "line": 204, + "doc": "", + "decorator": "router.post('/permitting-sources/search')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/requests/{request_id}/permitting-sources", + "router": "router", + "prefix_resolved": true, + "name": "attach_permitting_source", + "signature": "request_id: uuid.UUID, data: MeetingsSourceSelection, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", + "returns": "", + "line": 213, + "doc": "", + "decorator": "router.post('/requests/{request_id}/permitting-sources', response_model=RecordsOperationRead)", + "errors": [ + "HTTPException(404, 'Records request not found.')", + "HTTPException(404, 'Reviewed Permitting copy not found or no longer permitted.')", + "HTTPException(409, 'Permitting source changed; search again before attaching.')", + "HTTPException(422, 'Source attachment not confirmed; existing evidence retained.')" + ] + }, + { + "method": "POST", + "path": "/desktop/v1/inspections-sources/search", + "router": "router", + "prefix_resolved": true, + "name": "search_inspections_sources", + "signature": "data: MeetingsSearch, request: Request, actor: User=Depends(native_records_user)", + "returns": "", + "line": 239, + "doc": "", + "decorator": "router.post('/inspections-sources/search')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/requests/{request_id}/inspections-sources", + "router": "router", + "prefix_resolved": true, + "name": "attach_inspections_source", + "signature": "request_id: uuid.UUID, data: MeetingsSourceSelection, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", + "returns": "", + "line": 248, + "doc": "", + "decorator": "router.post('/requests/{request_id}/inspections-sources', response_model=RecordsOperationRead)", + "errors": [ + "HTTPException(404, 'Records request not found.')", + "HTTPException(404, 'Reviewed Inspections copy not found or no longer permitted.')", + "HTTPException(409, 'Inspections source changed; search again before attaching.')", + "HTTPException(422, 'Source attachment not confirmed; existing evidence retained.')" + ] + }, + { + "method": "POST", + "path": "/desktop/v1/planning-sources/search", + "router": "router", + "prefix_resolved": true, + "name": "search_planning_sources", + "signature": "data: MeetingsSearch, request: Request, actor: User=Depends(native_records_user)", + "returns": "", + "line": 274, + "doc": "", + "decorator": "router.post('/planning-sources/search')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/requests/{request_id}/planning-sources", + "router": "router", + "prefix_resolved": true, + "name": "attach_planning_source", + "signature": "request_id: uuid.UUID, data: MeetingsSourceSelection, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", + "returns": "", + "line": 283, + "doc": "", + "decorator": "router.post('/requests/{request_id}/planning-sources', response_model=RecordsOperationRead)", + "errors": [ + "HTTPException(404, 'Records request not found.')", + "HTTPException(404, 'Permitted Planning source not found.')", + "HTTPException(409, 'Planning source changed; search again before attaching.')", + "HTTPException(422, 'Source attachment not confirmed; existing evidence retained.')" + ] + }, + { + "method": "POST", + "path": "/desktop/v1/zoning-sources/search", + "router": "router", + "prefix_resolved": true, + "name": "search_zoning_sources", + "signature": "data: MeetingsSearch, request: Request, actor: User=Depends(native_records_user)", + "returns": "", + "line": 310, + "doc": "", + "decorator": "router.post('/zoning-sources/search')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/requests/{request_id}/zoning-sources", + "router": "router", + "prefix_resolved": true, + "name": "attach_zoning_source", + "signature": "request_id: uuid.UUID, data: MeetingsSourceSelection, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", + "returns": "", + "line": 319, + "doc": "", + "decorator": "router.post('/requests/{request_id}/zoning-sources', response_model=RecordsOperationRead)", + "errors": [ + "HTTPException(404, 'Records request not found.')", + "HTTPException(404, 'Permitted Zoning source not found.')", + "HTTPException(409, 'Zoning source changed; search again before attaching.')", + "HTTPException(422, 'Source attachment not confirmed; existing evidence retained.')" + ] + }, + { + "method": "GET", + "path": "/desktop/v1/records-state", + "router": "router", + "prefix_resolved": true, + "name": "get_native_records_state", + "signature": "session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", + "returns": "", + "line": 346, + "doc": "", + "decorator": "router.get('/records-state', response_model=RecordsStateRead)", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/meetings-sources/search", + "router": "router", + "prefix_resolved": true, + "name": "search_meetings_sources", + "signature": "data: MeetingsSearch, request: Request, actor: User=Depends(native_records_user)", + "returns": "", + "line": 355, + "doc": "", + "decorator": "router.post('/meetings-sources/search')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/requests/{request_id}/meetings-sources", + "router": "router", + "prefix_resolved": true, + "name": "attach_meetings_source", + "signature": "request_id: uuid.UUID, data: MeetingsSourceSelection, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", + "returns": "", + "line": 364, + "doc": "", + "decorator": "router.post('/requests/{request_id}/meetings-sources', response_model=RecordsOperationRead)", + "errors": [ + "HTTPException(404, 'Records request not found.')", + "HTTPException(404, 'Permitted Meetings source not found.')", + "HTTPException(409, 'Meetings source changed; search again before attaching.')", + "HTTPException(422, 'Source attachment not confirmed; existing evidence retained.')" + ] + }, + { + "method": "POST", + "path": "/desktop/v1/code-sources/search", + "router": "router", + "prefix_resolved": true, + "name": "search_code_sources", + "signature": "data: CodeSearch, request: Request, actor: User=Depends(native_records_user)", + "returns": "", + "line": 389, + "doc": "", + "decorator": "router.post('/code-sources/search')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/requests/{request_id}/code-sources", + "router": "router", + "prefix_resolved": true, + "name": "attach_code_source", + "signature": "request_id: uuid.UUID, data: CodeSourceSelection, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", + "returns": "", + "line": 398, + "doc": "", + "decorator": "router.post('/requests/{request_id}/code-sources', response_model=RecordsOperationRead)", + "errors": [ + "HTTPException(404, 'Records request not found.')", + "HTTPException(404, 'Permitted Code source not found.')", + "HTTPException(409, 'Code source changed; search again before attaching.')", + "HTTPException(422, 'Source attachment not confirmed; existing evidence retained.')" + ] + }, + { + "method": "POST", + "path": "/desktop/v1/notifications/{notification_id}/sent", + "router": "router", + "prefix_resolved": true, + "name": "mark_native_notification_sent", + "signature": "notification_id: uuid.UUID, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", + "returns": "", + "line": 423, + "doc": "", + "decorator": "router.post('/notifications/{notification_id}/sent', response_model=RecordsStateRead)", + "errors": [ + "HTTPException(404, 'Records notification not found.')", + "HTTPException(400, 'This local notification is already marked sent.')" + ] + }, + { + "method": "POST", + "path": "/desktop/v1/requests/{request_id}/documents", + "router": "router", + "prefix_resolved": true, + "name": "attach_native_document", + "signature": "request_id: uuid.UUID, data: AttachDocument, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", + "returns": "", + "line": 443, + "doc": "", + "decorator": "router.post('/requests/{request_id}/documents', response_model=RecordsOperationRead)", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/requests/{request_id}/documents/{attachment_id}/release-copy", + "router": "router", + "prefix_resolved": true, + "name": "attach_native_release_copy", + "signature": "request_id: uuid.UUID, attachment_id: uuid.UUID, data: AttachReleaseCopy, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", + "returns": "", + "line": 453, + "doc": "", + "decorator": "router.post('/requests/{request_id}/documents/{attachment_id}/release-copy', response_model=RecordsOperationRead)", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/requests/{request_id}/artifacts", + "router": "router", + "prefix_resolved": true, + "name": "prepare_native_artifact", + "signature": "request_id: uuid.UUID, data: PrepareArtifact, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", + "returns": "", + "line": 463, + "doc": "", + "decorator": "router.post('/requests/{request_id}/artifacts', response_model=ArtifactPlan)", + "errors": [ + "HTTPException(404, 'Records request not found.')", + "HTTPException(400, str(error))" + ] + }, + { + "method": "POST", + "path": "/desktop/v1/requests/{request_id}/artifacts/{artifact_id}/complete", + "router": "router", + "prefix_resolved": true, + "name": "complete_native_artifact", + "signature": "request_id: uuid.UUID, artifact_id: uuid.UUID, data: CompleteArtifact, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", + "returns": "", + "line": 481, + "doc": "", + "decorator": "router.post('/requests/{request_id}/artifacts/{artifact_id}/complete', response_model=RecordsOperationRead)", + "errors": [ + "HTTPException(404, 'Records request not found.')", + "HTTPException(400, str(error))" + ] + }, + { + "method": "POST", + "path": "/desktop/v1/requests", + "router": "router", + "prefix_resolved": true, + "name": "create_native_request", + "signature": "data: StaffRecordsIntake, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", + "returns": "", + "line": 500, + "doc": "", + "decorator": "router.post('/requests', response_model=NativeRequestRead, status_code=201)", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/requests/{request_id}", + "router": "router", + "prefix_resolved": true, + "name": "get_native_request", + "signature": "request_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", + "returns": "", + "line": 521, + "doc": "", + "decorator": "router.get('/requests/{request_id}', response_model=NativeRequestRead)", + "errors": [ + "HTTPException(404, 'Records request not found.')" + ] + }, + { + "method": "GET", + "path": "/desktop/v1/requests/{request_id}/view", + "router": "router", + "prefix_resolved": true, + "name": "get_native_request_view", + "signature": "request_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", + "returns": "", + "line": 537, + "doc": "", + "decorator": "router.get('/requests/{request_id}/view', response_model=RecordsView)", + "errors": [ + "HTTPException(404, 'Records request not found.')" + ] + }, + { + "method": "GET", + "path": "/desktop/v1/requests/{request_id}/draft-context", + "router": "router", + "prefix_resolved": true, + "name": "native_draft_context", + "signature": "request_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", + "returns": "", + "line": 549, + "doc": "", + "decorator": "router.get('/requests/{request_id}/draft-context')", + "errors": [ + "HTTPException(404, 'Records request not found.')", + "HTTPException(400, str(error))" + ] + }, + { + "method": "POST", + "path": "/desktop/v1/requests/{request_id}/generated-draft", + "router": "router", + "prefix_resolved": true, + "name": "native_generated_draft", + "signature": "request_id: uuid.UUID, data: GeneratedDraft, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", + "returns": "", + "line": 575, + "doc": "", + "decorator": "router.post('/requests/{request_id}/generated-draft', response_model=RecordsOperationRead)", + "errors": [ + "HTTPException(404, 'Records request not found.')", + "HTTPException(409, 'The draft changed during generation. Refresh before generating again.')", + "HTTPException(400, str(error))" + ] + }, + { + "method": "POST", + "path": "/desktop/v1/requests/{request_id}/actions", + "router": "router", + "prefix_resolved": true, + "name": "native_request_operation", + "signature": "request_id: uuid.UUID, command: RecordsCommand, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", + "returns": "", + "line": 605, + "doc": "", + "decorator": "router.post('/requests/{request_id}/actions', response_model=RecordsOperationRead)", + "errors": [ + "HTTPException(404, 'Records request not found.')", + "HTTPException(400, str(error))" + ] + } + ], + "models": [ + { + "name": "MeetingsSearch", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "query", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + } + ], + "line": 38, + "doc": "" + }, + { + "name": "MeetingsSourceSelection", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "source_id", + "type": "str", + "default": "Field(min_length=1, max_length=200)" + }, + { + "name": "expected_sha256", + "type": "str", + "default": "Field(pattern='^[0-9a-f]{64}$')" + } + ], + "line": 43, + "doc": "" + }, + { + "name": "CodeSearch", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "query", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + }, + { + "name": "as_of", + "type": "date | None", + "default": "None" + } + ], + "line": 49, + "doc": "" + }, + { + "name": "CodeSourceSelection", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "source_id", + "type": "str", + "default": "Field(min_length=1, max_length=200)" + }, + { + "name": "expected_sha256", + "type": "str", + "default": "Field(pattern='^[0-9a-f]{64}$')" + }, + { + "name": "as_of", + "type": "date | None", + "default": "None" + } + ], + "line": 55, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/desktop_bridge/schemas.py", + "sha256": "753dd5474d532912bc50118fe9add74613cbc3b17a062dd93681309ac590926d", + "routes": [], + "models": [ + { + "name": "StaffRecordsIntake", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "requester", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "summary", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "deadline", + "type": "str", + "default": "" + }, + { + "name": "deadlineBasis", + "type": "str", + "default": "''" + } + ], + "line": 10, + "doc": "Existing native create-records-request input; no caller-supplied actor." + }, + { + "name": "NativeRequestRead", + "bases": [ + "RequestRead" + ], + "fields": [ + { + "name": "desktop_id", + "type": "str | None", + "default": "" + }, + { + "name": "public_tracking_number", + "type": "str | None", + "default": "" + }, + { + "name": "submitted_via", + "type": "str", + "default": "" + }, + { + "name": "deadline_label", + "type": "str", + "default": "" + }, + { + "name": "deadline_basis", + "type": "str", + "default": "" + }, + { + "name": "deadline_reviewed_at", + "type": "datetime | None", + "default": "" + } + ], + "line": 28, + "doc": "" + }, + { + "name": "AssignmentPayload", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "assignedTo", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 41, + "doc": "" + }, + { + "name": "DeadlinePayload", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "deadline", + "type": "str", + "default": "" + }, + { + "name": "deadlineBasis", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 45, + "doc": "" + }, + { + "name": "CalculateDeadlinePayload", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "deadlineReceivedDate", + "type": "str", + "default": "" + }, + { + "name": "deadlineRuleName", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "deadlineDayCount", + "type": "str", + "default": "" + }, + { + "name": "deadlineDayType", + "type": "str", + "default": "" + }, + { + "name": "deadlineBasis", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 52, + "doc": "" + }, + { + "name": "ClarificationPayload", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "clarificationNote", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 77, + "doc": "" + }, + { + "name": "MessagePayload", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "requestMessageBody", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 81, + "doc": "" + }, + { + "name": "SearchNotePayload", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "sourceNote", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "citation", + "type": "str", + "default": "''" + } + ], + "line": 85, + "doc": "" + }, + { + "name": "SearchReceiptPayload", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "searchQuery", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "searchLocations", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "searchResultTitle", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "searchResultCitation", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "searchResultSummary", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "searchResultStatus", + "type": "str", + "default": "''" + }, + { + "name": "searchReviewer", + "type": "str", + "default": "''" + } + ], + "line": 90, + "doc": "" + }, + { + "name": "ExemptionNotePayload", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "exemptionNote", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 100, + "doc": "" + }, + { + "name": "ExemptionDecisionPayload", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "exemptionSource", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "exemptionKind", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "exemptionFinding", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "exemptionDecision", + "type": "Literal['release', 'redact', 'exempt']", + "default": "" + }, + { + "name": "exemptionBasis", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "exemptionReviewer", + "type": "str", + "default": "''" + } + ], + "line": 104, + "doc": "" + }, + { + "name": "FeeEstimatePayload", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "feeEstimate", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 118, + "doc": "" + }, + { + "name": "FeeLinePayload", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "feeLineDescription", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "feeScheduleBasis", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "feeLineAmount", + "type": "str", + "default": "" + } + ], + "line": 122, + "doc": "" + }, + { + "name": "FeeWaiverPayload", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "feeWaiverReason", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 140, + "doc": "" + }, + { + "name": "DraftPayload", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "responseDraft", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "citation", + "type": "str", + "default": "''" + } + ], + "line": 144, + "doc": "" + }, + { + "name": "ApprovalPayload", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "approvalNote", + "type": "str", + "default": "''" + } + ], + "line": 149, + "doc": "" + }, + { + "name": "AssignCommand", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "action", + "type": "Literal['assign-records-request']", + "default": "" + }, + { + "name": "payload", + "type": "AssignmentPayload", + "default": "" + } + ], + "line": 153, + "doc": "" + }, + { + "name": "DeadlineCommand", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "action", + "type": "Literal['set-records-deadline']", + "default": "" + }, + { + "name": "payload", + "type": "DeadlinePayload", + "default": "" + } + ], + "line": 158, + "doc": "" + }, + { + "name": "CalculateDeadlineCommand", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "action", + "type": "Literal['calculate-records-deadline']", + "default": "" + }, + { + "name": "payload", + "type": "CalculateDeadlinePayload", + "default": "" + } + ], + "line": 163, + "doc": "" + }, + { + "name": "ClarificationCommand", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "action", + "type": "Literal['request-records-clarification']", + "default": "" + }, + { + "name": "payload", + "type": "ClarificationPayload", + "default": "" + } + ], + "line": 168, + "doc": "" + }, + { + "name": "MessageCommand", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "action", + "type": "Literal['add-records-message']", + "default": "" + }, + { + "name": "payload", + "type": "MessagePayload", + "default": "" + } + ], + "line": 173, + "doc": "" + }, + { + "name": "SearchNoteCommand", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "action", + "type": "Literal['record-records-search']", + "default": "" + }, + { + "name": "payload", + "type": "SearchNotePayload", + "default": "" + } + ], + "line": 178, + "doc": "" + }, + { + "name": "SearchReceiptCommand", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "action", + "type": "Literal['record-records-search-session']", + "default": "" + }, + { + "name": "payload", + "type": "SearchReceiptPayload", + "default": "" + } + ], + "line": 183, + "doc": "" + }, + { + "name": "ExemptionNoteCommand", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "action", + "type": "Literal['add-records-exemption-review']", + "default": "" + }, + { + "name": "payload", + "type": "ExemptionNotePayload", + "default": "" + } + ], + "line": 188, + "doc": "" + }, + { + "name": "ExemptionDecisionCommand", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "action", + "type": "Literal['add-records-exemption-decision']", + "default": "" + }, + { + "name": "payload", + "type": "ExemptionDecisionPayload", + "default": "" + } + ], + "line": 193, + "doc": "" + }, + { + "name": "FeeEstimateCommand", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "action", + "type": "Literal['estimate-records-fee']", + "default": "" + }, + { + "name": "payload", + "type": "FeeEstimatePayload", + "default": "" + } + ], + "line": 198, + "doc": "" + }, + { + "name": "FeeLineCommand", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "action", + "type": "Literal['add-records-fee-line']", + "default": "" + }, + { + "name": "payload", + "type": "FeeLinePayload", + "default": "" + } + ], + "line": 203, + "doc": "" + }, + { + "name": "FeeWaiverCommand", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "action", + "type": "Literal['waive-records-fee']", + "default": "" + }, + { + "name": "payload", + "type": "FeeWaiverPayload", + "default": "" + } + ], + "line": 208, + "doc": "" + }, + { + "name": "DraftCommand", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "action", + "type": "Literal['draft-records-response']", + "default": "" + }, + { + "name": "payload", + "type": "DraftPayload", + "default": "" + } + ], + "line": 213, + "doc": "" + }, + { + "name": "ApprovalCommand", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "action", + "type": "Literal['approve-records-response']", + "default": "" + }, + { + "name": "payload", + "type": "ApprovalPayload", + "default": "Field(default_factory=ApprovalPayload)" + } + ], + "line": 218, + "doc": "" + }, + { + "name": "FinishCommand", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "action", + "type": "Literal['fulfill-records-request', 'close-records-request']", + "default": "" + }, + { + "name": "payload", + "type": "NativePayload", + "default": "Field(default_factory=NativePayload)" + } + ], + "line": 223, + "doc": "" + }, + { + "name": "TimelineView", + "bases": [ + "NativeView" + ], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "action", + "type": "str", + "default": "" + }, + { + "name": "actor", + "type": "str", + "default": "" + }, + { + "name": "note", + "type": "str", + "default": "" + }, + { + "name": "created_at_unix_seconds", + "type": "int", + "default": "" + } + ], + "line": 241, + "doc": "" + }, + { + "name": "PublicStatusView", + "bases": [ + "NativeView" + ], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "label", + "type": "str", + "default": "" + }, + { + "name": "summary", + "type": "str", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "created_at_unix_seconds", + "type": "int", + "default": "" + } + ], + "line": 249, + "doc": "" + }, + { + "name": "MessageView", + "bases": [ + "NativeView" + ], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "author", + "type": "str", + "default": "" + }, + { + "name": "author_role", + "type": "str", + "default": "" + }, + { + "name": "body", + "type": "str", + "default": "" + }, + { + "name": "visibility", + "type": "str", + "default": "" + }, + { + "name": "created_at_unix_seconds", + "type": "int", + "default": "" + } + ], + "line": 257, + "doc": "" + }, + { + "name": "FeeLineView", + "bases": [ + "NativeView" + ], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "description", + "type": "str", + "default": "" + }, + { + "name": "schedule_basis", + "type": "str", + "default": "" + }, + { + "name": "amount_cents", + "type": "int", + "default": "" + }, + { + "name": "created_at_unix_seconds", + "type": "int", + "default": "" + } + ], + "line": 266, + "doc": "" + }, + { + "name": "ExemptionDecisionView", + "bases": [ + "NativeView" + ], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "source", + "type": "str", + "default": "" + }, + { + "name": "kind", + "type": "str", + "default": "" + }, + { + "name": "finding", + "type": "str", + "default": "" + }, + { + "name": "decision", + "type": "Literal['release', 'redact', 'exempt']", + "default": "" + }, + { + "name": "basis", + "type": "str", + "default": "" + }, + { + "name": "reviewer", + "type": "str", + "default": "" + }, + { + "name": "created_at_unix_seconds", + "type": "int", + "default": "" + } + ], + "line": 274, + "doc": "" + }, + { + "name": "SearchResultView", + "bases": [ + "NativeView" + ], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "title", + "type": "str", + "default": "" + }, + { + "name": "citation", + "type": "str", + "default": "" + }, + { + "name": "summary", + "type": "str", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "" + } + ], + "line": 285, + "doc": "" + }, + { + "name": "SearchReceiptView", + "bases": [ + "NativeView" + ], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "query", + "type": "str", + "default": "" + }, + { + "name": "locations", + "type": "str", + "default": "" + }, + { + "name": "reviewer", + "type": "str", + "default": "" + }, + { + "name": "results", + "type": "list[SearchResultView]", + "default": "" + }, + { + "name": "created_at_unix_seconds", + "type": "int", + "default": "" + } + ], + "line": 293, + "doc": "" + }, + { + "name": "RecordsView", + "bases": [ + "NativeView" + ], + "fields": [ + { + "name": "request_id", + "type": "str", + "default": "" + }, + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "public_tracking_number", + "type": "str", + "default": "" + }, + { + "name": "requester", + "type": "str", + "default": "" + }, + { + "name": "requester_contact", + "type": "str", + "default": "" + }, + { + "name": "submitted_via", + "type": "str", + "default": "" + }, + { + "name": "summary", + "type": "str", + "default": "" + }, + { + "name": "deadline", + "type": "str", + "default": "" + }, + { + "name": "deadline_basis", + "type": "str", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "assigned_to", + "type": "str", + "default": "" + }, + { + "name": "clarification_notes", + "type": "list[str]", + "default": "" + }, + { + "name": "search_notes", + "type": "list[str]", + "default": "" + }, + { + "name": "search_sessions", + "type": "list[SearchReceiptView]", + "default": "" + }, + { + "name": "exemption_reviews", + "type": "list[str]", + "default": "" + }, + { + "name": "exemption_decisions", + "type": "list[ExemptionDecisionView]", + "default": "" + }, + { + "name": "fee_estimate", + "type": "str", + "default": "" + }, + { + "name": "fee_line_items", + "type": "list[FeeLineView]", + "default": "" + }, + { + "name": "fee_waiver_reason", + "type": "str", + "default": "" + }, + { + "name": "citations", + "type": "list[str]", + "default": "" + }, + { + "name": "response_draft", + "type": "str", + "default": "" + }, + { + "name": "approval_notes", + "type": "list[str]", + "default": "" + }, + { + "name": "exports", + "type": "list[str]", + "default": "" + }, + { + "name": "documents", + "type": "list['RecordsDocumentView']", + "default": "Field(default_factory=list)" + }, + { + "name": "release_packages", + "type": "list['ReleasePackageView']", + "default": "Field(default_factory=list)" + }, + { + "name": "timeline", + "type": "list[TimelineView]", + "default": "" + }, + { + "name": "public_status_events", + "type": "list[PublicStatusView]", + "default": "" + }, + { + "name": "messages", + "type": "list[MessageView]", + "default": "" + }, + { + "name": "deadline_reviewed_at_unix_seconds", + "type": "int | None", + "default": "" + }, + { + "name": "approved_at_unix_seconds", + "type": "int | None", + "default": "" + }, + { + "name": "fulfilled_at_unix_seconds", + "type": "int | None", + "default": "" + }, + { + "name": "closed_at_unix_seconds", + "type": "int | None", + "default": "" + }, + { + "name": "created_at_unix_seconds", + "type": "int", + "default": "" + } + ], + "line": 302, + "doc": "" + }, + { + "name": "RecordsOperationRead", + "bases": [ + "NativeView" + ], + "fields": [ + { + "name": "action", + "type": "str", + "default": "" + }, + { + "name": "message", + "type": "str", + "default": "" + }, + { + "name": "request", + "type": "RecordsView", + "default": "" + } + ], + "line": 339, + "doc": "" + }, + { + "name": "RecordsStateRead", + "bases": [ + "NativeView" + ], + "fields": [ + { + "name": "demo_fixture", + "type": "dict | None", + "default": "None" + }, + { + "name": "records_requests", + "type": "list[RecordsView]", + "default": "" + }, + { + "name": "notification_events", + "type": "list['NotificationView']", + "default": "Field(default_factory=list)" + }, + { + "name": "publication_events", + "type": "list['PublicationView']", + "default": "Field(default_factory=list)" + }, + { + "name": "audit_entries", + "type": "list['AuditView']", + "default": "Field(default_factory=list)" + } + ], + "line": 345, + "doc": "" + }, + { + "name": "ManagedFileReceipt", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "original_path", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "stored_path", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "file_name", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + }, + { + "name": "sha256", + "type": "str", + "default": "Field(pattern='^[0-9a-f]{64}$')" + }, + { + "name": "size_bytes", + "type": "int", + "default": "Field(ge=0, le=2147483647, strict=True)" + } + ], + "line": 353, + "doc": "" + }, + { + "name": "AttachDocument", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "title", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "citation", + "type": "str", + "default": "''" + }, + { + "name": "file", + "type": "ManagedFileReceipt", + "default": "" + } + ], + "line": 361, + "doc": "" + }, + { + "name": "AttachReleaseCopy", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "status", + "type": "Literal['release-ready copy', 'redacted copy']", + "default": "" + }, + { + "name": "note", + "type": "str", + "default": "''" + }, + { + "name": "added_by", + "type": "str", + "default": "''" + }, + { + "name": "file", + "type": "ManagedFileReceipt", + "default": "" + } + ], + "line": 367, + "doc": "" + }, + { + "name": "RecordsDocumentView", + "bases": [ + "NativeView" + ], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "attachment_id", + "type": "str", + "default": "" + }, + { + "name": "title", + "type": "str", + "default": "" + }, + { + "name": "original_path", + "type": "str", + "default": "" + }, + { + "name": "stored_path", + "type": "str", + "default": "" + }, + { + "name": "citation", + "type": "str", + "default": "" + }, + { + "name": "sha256", + "type": "str", + "default": "" + }, + { + "name": "size_bytes", + "type": "int", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "added_by", + "type": "str", + "default": "" + }, + { + "name": "created_at_unix_seconds", + "type": "int", + "default": "" + }, + { + "name": "release_original_path", + "type": "str", + "default": "''" + }, + { + "name": "release_stored_path", + "type": "str", + "default": "''" + }, + { + "name": "release_file_name", + "type": "str", + "default": "''" + }, + { + "name": "release_sha256", + "type": "str", + "default": "''" + }, + { + "name": "release_size_bytes", + "type": "int", + "default": "0" + }, + { + "name": "release_status", + "type": "str", + "default": "''" + }, + { + "name": "release_note", + "type": "str", + "default": "''" + }, + { + "name": "release_added_by", + "type": "str", + "default": "''" + }, + { + "name": "release_added_at_unix_seconds", + "type": "int | None", + "default": "None" + } + ], + "line": 374, + "doc": "" + }, + { + "name": "ReleasePackageView", + "bases": [ + "NativeView" + ], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "export_path", + "type": "str", + "default": "" + }, + { + "name": "package_hash", + "type": "str", + "default": "" + }, + { + "name": "document_count", + "type": "int", + "default": "" + }, + { + "name": "release_artifact_count", + "type": "int", + "default": "" + }, + { + "name": "search_session_count", + "type": "int", + "default": "" + }, + { + "name": "release_count", + "type": "int", + "default": "" + }, + { + "name": "redacted_count", + "type": "int", + "default": "" + }, + { + "name": "exempt_count", + "type": "int", + "default": "" + }, + { + "name": "created_at_unix_seconds", + "type": "int", + "default": "" + } + ], + "line": 397, + "doc": "" + }, + { + "name": "PrepareArtifact", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "kind", + "type": "Literal['response', 'release-package']", + "default": "" + } + ], + "line": 410, + "doc": "" + }, + { + "name": "ArtifactPlan", + "bases": [ + "NativeView" + ], + "fields": [ + { + "name": "artifact_id", + "type": "str", + "default": "" + }, + { + "name": "file_name", + "type": "str", + "default": "" + }, + { + "name": "content", + "type": "str", + "default": "" + }, + { + "name": "sha256", + "type": "str", + "default": "" + }, + { + "name": "created_at_unix_seconds", + "type": "int", + "default": "" + } + ], + "line": 414, + "doc": "" + }, + { + "name": "CompleteArtifact", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "export_path", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 422, + "doc": "" + }, + { + "name": "PublicIntake", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "requester", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "requesterContact", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "summary", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "deadline", + "type": "str", + "default": "''" + } + ], + "line": 426, + "doc": "" + }, + { + "name": "PublicLookup", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "trackingNumber", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "requesterContact", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 433, + "doc": "" + }, + { + "name": "PublicMessage", + "bases": [ + "PublicLookup" + ], + "fields": [ + { + "name": "publicRequestMessage", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 438, + "doc": "" + }, + { + "name": "GeneratedDraft", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "text", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "model", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "previous_response_sha256", + "type": "str", + "default": "Field(pattern='^[0-9a-f]{64}$')" + } + ], + "line": 442, + "doc": "" + }, + { + "name": "NotificationView", + "bases": [ + "NativeView" + ], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "notification_id", + "type": "str", + "default": "" + }, + { + "name": "module_id", + "type": "str", + "default": "" + }, + { + "name": "record_id", + "type": "str", + "default": "" + }, + { + "name": "audience", + "type": "str", + "default": "" + }, + { + "name": "channel", + "type": "str", + "default": "" + }, + { + "name": "subject", + "type": "str", + "default": "" + }, + { + "name": "body", + "type": "str", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "created_at_unix_seconds", + "type": "int", + "default": "" + }, + { + "name": "sent_at_unix_seconds", + "type": "int | None", + "default": "" + } + ], + "line": 448, + "doc": "" + }, + { + "name": "PublicationView", + "bases": [ + "NativeView" + ], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "source_module", + "type": "str", + "default": "" + }, + { + "name": "source_record_id", + "type": "str", + "default": "" + }, + { + "name": "record_type", + "type": "str", + "default": "" + }, + { + "name": "public_payload", + "type": "str", + "default": "" + }, + { + "name": "payload_hash", + "type": "str", + "default": "" + }, + { + "name": "published_at_unix_seconds", + "type": "int", + "default": "" + }, + { + "name": "retracted_at_unix_seconds", + "type": "int | None", + "default": "None" + }, + { + "name": "retracted_by", + "type": "str", + "default": "''" + } + ], + "line": 462, + "doc": "" + }, + { + "name": "AuditView", + "bases": [ + "NativeView" + ], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "module_id", + "type": "str", + "default": "" + }, + { + "name": "action", + "type": "str", + "default": "" + }, + { + "name": "summary", + "type": "str", + "default": "" + }, + { + "name": "created_at_unix_seconds", + "type": "int", + "default": "" + }, + { + "name": "previous_hash", + "type": "str", + "default": "" + }, + { + "name": "entry_hash", + "type": "str", + "default": "" + } + ], + "line": 474, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/desktop_bridge/station.py", + "sha256": "2f53398b6a897f804419ea5025895bb7dc468d8891dc553b20bb14cb5d0a8084", + "routes": [ + { + "method": "GET", + "path": "/station/context", + "router": "router", + "prefix_resolved": false, + "name": "context", + "signature": "request: Request, capability: Literal['capture', 'read'], proof: str | None=Header(default=None, alias='X-Townlight-Session'), session: AsyncSession=Depends(get_async_session)", + "returns": "", + "line": 43, + "doc": "", + "decorator": "router.get('/station/context')", + "errors": [ + "HTTPException(403, 'This staff role cannot perform this Station operation')", + "HTTPException(401, str(exc))" + ] + }, + { + "method": "POST", + "path": "/requests/{request_id}/station-recordings", + "router": "router", + "prefix_resolved": false, + "name": "attach", + "signature": "request_id: UUID, data: Selection, request: Request, actor=Depends(station_actor), session: AsyncSession=Depends(get_async_session)", + "returns": "", + "line": 79, + "doc": "", + "decorator": "router.post('/requests/{request_id}/station-recordings', response_model=RecordsOperationRead)", + "errors": [ + "HTTPException(404, 'Records request not found')", + "HTTPException(409, str(exc))", + "HTTPException(422, 'Station evidence not attached; existing evidence preserved')", + "HTTPException(response.status_code, 'Station denied this recording')", + "HTTPException(409, 'Station recording is incomplete or changed; refresh selection')" + ] + } + ], + "models": [ + { + "name": "Selection", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "recording_id", + "type": "UUID", + "default": "" + }, + { + "name": "expected_sha256", + "type": "str", + "default": "Field(pattern='^[0-9a-f]{64}$')" + } + ], + "line": 61, + "doc": "" + } + ], + "configuration": [ + { + "variable": "TOWNLIGHT_STATION_URL", + "default": "''", + "line": 33 + } + ] + }, + { + "source": "installed-owned-source/app/documents/__init__.py", + "sha256": "2795a0001b651166674cb0b501f64e0030e84816d5b4335f3189529510e2b10b", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/documents/router.py", + "sha256": "12c9facd2481a2294883f665516bd5e0bf3a487ee76c7eb747eb4b95aa80fefe", + "routes": [ + { + "method": "GET", + "path": "/documents/", + "router": "router", + "prefix_resolved": true, + "name": "list_documents", + "signature": "source_id: uuid.UUID | None=None, status: IngestionStatus | None=None, limit: int=Query(default=50, le=500), offset: int=0, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 31, + "doc": "", + "decorator": "router.get('/', response_model=list[DocumentRead])", + "errors": [] + }, + { + "method": "GET", + "path": "/documents/{document_id}", + "router": "router", + "prefix_resolved": true, + "name": "get_document", + "signature": "document_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 47, + "doc": "", + "decorator": "router.get('/{document_id}', response_model=DocumentRead)", + "errors": [ + "HTTPException(status_code=404, detail='Document not found')" + ] + }, + { + "method": "GET", + "path": "/documents/{document_id}/chunks", + "router": "router", + "prefix_resolved": true, + "name": "list_chunks", + "signature": "document_id: uuid.UUID, limit: int=Query(default=50, le=500), offset: int=0, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 57, + "doc": "", + "decorator": "router.get('/{document_id}/chunks', response_model=list[DocumentChunkRead])", + "errors": [ + "HTTPException(status_code=404, detail='Document not found')" + ] + } + ], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/exemptions/__init__.py", + "sha256": "2fd238ebecb0a427697f59094dad0d088962ebe3029a8a540d14957160714341", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/exemptions/engine.py", + "sha256": "56001a7259c4ca1a206ee528ceced69bd2764534133db61b9fcf5d01a26a8253", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/exemptions/llm_reviewer.py", + "sha256": "ab13ae2f8dde8c66debff2f9276787887524f7bf785833fcddc569816b1be8b4", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/exemptions/patterns.py", + "sha256": "364df5cffdccda747ecbf9d69775f0cce92610c6b253b5b78b91a0ac409ef9eb", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/exemptions/router.py", + "sha256": "4c35393f13a282194f4225b02e7b6d233b6e9b979371d6e318c7e5ed1df97dca", + "routes": [ + { + "method": "POST", + "path": "/exemptions/rules/", + "router": "router", + "prefix_resolved": true, + "name": "create_rule", + "signature": "data: ExemptionRuleCreate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 34, + "doc": "", + "decorator": "router.post('/rules/', response_model=ExemptionRuleRead, status_code=201)", + "errors": [] + }, + { + "method": "GET", + "path": "/exemptions/rules/", + "router": "router", + "prefix_resolved": true, + "name": "list_rules", + "signature": "state_code: str | None=None, enabled: bool | None=None, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 61, + "doc": "", + "decorator": "router.get('/rules/', response_model=list[ExemptionRuleRead])", + "errors": [] + }, + { + "method": "PATCH", + "path": "/exemptions/rules/{rule_id}", + "router": "router", + "prefix_resolved": true, + "name": "update_rule", + "signature": "rule_id: uuid.UUID, data: ExemptionRuleUpdate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 77, + "doc": "", + "decorator": "router.patch('/rules/{rule_id}', response_model=ExemptionRuleRead)", + "errors": [ + "HTTPException(status_code=404, detail='Rule not found')" + ] + }, + { + "method": "GET", + "path": "/exemptions/rules/{rule_id}/history", + "router": "router", + "prefix_resolved": true, + "name": "get_rule_history", + "signature": "rule_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 109, + "doc": "Get audit history for an exemption rule.", + "decorator": "router.get('/rules/{rule_id}/history')", + "errors": [ + "HTTPException(status_code=404, detail='Rule not found')" + ] + }, + { + "method": "POST", + "path": "/exemptions/rules/{rule_id}/test", + "router": "router", + "prefix_resolved": true, + "name": "test_rule", + "signature": "rule_id: uuid.UUID, body: RuleTestRequest, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 162, + "doc": "Test a rule against sample text. Returns match results.\n\nUses the `regex` library with timeout=2s to prevent ReDoS on\nadmin-entered patterns.", + "decorator": "router.post('/rules/{rule_id}/test', response_model=RuleTestResponse)", + "errors": [ + "HTTPException(status_code=404, detail='Rule not found')", + "HTTPException(status_code=422, detail=f'Invalid regex pattern: {e}')", + "HTTPException(status_code=408, detail='Regex execution timed out (possible catastrophic backtracking)')", + "HTTPException(status_code=400, detail='LLM-based rules cannot be tested with sample text \u2014 they require full document context.')" + ] + }, + { + "method": "POST", + "path": "/exemptions/scan/{request_id}", + "router": "router", + "prefix_resolved": true, + "name": "scan_for_exemptions", + "signature": "request_id: uuid.UUID, state_code: str=Query(default='CO', pattern='^[A-Z]{2}$'), use_llm: bool=False, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 228, + "doc": "Scan all documents attached to a request for exemptions.", + "decorator": "router.post('/scan/{request_id}')", + "errors": [ + "HTTPException(status_code=404, detail='Request not found')", + "HTTPException(status_code=422, detail=f'Scan incomplete: {exc}')" + ] + }, + { + "method": "GET", + "path": "/exemptions/flags/{request_id}", + "router": "router", + "prefix_resolved": true, + "name": "list_flags", + "signature": "request_id: uuid.UUID, status: FlagStatus | None=None, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 300, + "doc": "", + "decorator": "router.get('/flags/{request_id}', response_model=list[ExemptionFlagRead])", + "errors": [ + "HTTPException(status_code=404, detail='Request not found')" + ] + }, + { + "method": "PATCH", + "path": "/exemptions/flags/{flag_id}", + "router": "router", + "prefix_resolved": true, + "name": "review_flag", + "signature": "flag_id: uuid.UUID, data: ExemptionFlagReview, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 321, + "doc": "", + "decorator": "router.patch('/flags/{flag_id}', response_model=ExemptionFlagRead)", + "errors": [ + "HTTPException(status_code=404, detail='Flag not found')", + "HTTPException(status_code=400, detail='Status must be accepted, rejected, or reviewed')" + ] + }, + { + "method": "GET", + "path": "/exemptions/dashboard/accuracy", + "router": "router", + "prefix_resolved": true, + "name": "exemption_accuracy", + "signature": "department_id: uuid.UUID | None=None, date_from: datetime | None=None, date_to: datetime | None=None, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 365, + "doc": "Acceptance/rejection rates by category, optionally filtered by department.", + "decorator": "router.get('/dashboard/accuracy', response_model=list[ExemptionAccuracyReport])", + "errors": [] + }, + { + "method": "GET", + "path": "/exemptions/dashboard/export", + "router": "router", + "prefix_resolved": true, + "name": "export_flag_data", + "signature": "format: str='json', date_from: datetime | None=None, date_to: datetime | None=None, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 423, + "doc": "Export exemption flag data as JSON or CSV.", + "decorator": "router.get('/dashboard/export')", + "errors": [] + }, + { + "method": "GET", + "path": "/exemptions/dashboard", + "router": "router", + "prefix_resolved": true, + "name": "exemption_dashboard", + "signature": "session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 480, + "doc": "", + "decorator": "router.get('/dashboard', response_model=ExemptionDashboard)", + "errors": [] + }, + { + "method": "GET", + "path": "/exemptions/templates/", + "router": "router", + "prefix_resolved": true, + "name": "list_templates", + "signature": "template_type: str | None=None, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 519, + "doc": "", + "decorator": "router.get('/templates/', response_model=list[DisclosureTemplateRead])", + "errors": [] + }, + { + "method": "POST", + "path": "/exemptions/templates/", + "router": "router", + "prefix_resolved": true, + "name": "create_template", + "signature": "data: DisclosureTemplateCreate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 532, + "doc": "", + "decorator": "router.post('/templates/', response_model=DisclosureTemplateRead, status_code=201)", + "errors": [] + }, + { + "method": "GET", + "path": "/exemptions/templates/{template_id}/render", + "router": "router", + "prefix_resolved": true, + "name": "render_template", + "signature": "template_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 556, + "doc": "Render a template with city profile variables substituted.", + "decorator": "router.get('/templates/{template_id}/render', response_model=DisclosureTemplateRendered)", + "errors": [ + "HTTPException(status_code=404, detail='Template not found')" + ] + }, + { + "method": "PUT", + "path": "/exemptions/templates/{template_id}", + "router": "router", + "prefix_resolved": true, + "name": "update_template", + "signature": "template_id: uuid.UUID, data: DisclosureTemplateUpdate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 609, + "doc": "", + "decorator": "router.put('/templates/{template_id}', response_model=DisclosureTemplateRead)", + "errors": [ + "HTTPException(status_code=404, detail='Template not found')" + ] + } + ], + "models": [ + { + "name": "RuleTestRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "sample_text", + "type": "str", + "default": "" + } + ], + "line": 144, + "doc": "" + }, + { + "name": "RuleTestMatch", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "matched_text", + "type": "str", + "default": "" + }, + { + "name": "start", + "type": "int", + "default": "" + }, + { + "name": "end", + "type": "int", + "default": "" + } + ], + "line": 148, + "doc": "" + }, + { + "name": "RuleTestResponse", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "rule_id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "rule_type", + "type": "str", + "default": "" + }, + { + "name": "matched", + "type": "bool", + "default": "" + }, + { + "name": "matches", + "type": "list[RuleTestMatch]", + "default": "" + } + ], + "line": 154, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/ingestion/__init__.py", + "sha256": "b9960370edcad325db1bbc1a812416b99100a86c1db220b67a69e46f503ec5ad", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/ingestion/cron_utils.py", + "sha256": "63ca640af21a0a25da5e49ff745ffecb800dd18f4dd9e4ba886b123855334876", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/ingestion/scheduler.py", + "sha256": "cf90a00bb1eafc4e3327499461afbab3bc2202a726b5871551fc8a5c1638e734", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/ingestion/sync_runner.py", + "sha256": "0cab2a9f8b4caf7f199796d9c748fc165a04ec95f6181960ef84f74956fb9488", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/ingestion/tasks.py", + "sha256": "fb9dabc97a0ea8d8ddbceec5a2a98ef5cdbafb92eee41ecb702b4cb7860bddd9", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/llm/__init__.py", + "sha256": "0411eee4d07aefa5002fbec9e0d426ee45fd2f9e589b56803b1668f6493d51e5", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/llm/client.py", + "sha256": "8504ba9c8ee46c902b4a6d9004dccce92f66f20b388c8a55484bb8324169ded1", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/llm/context_manager.py", + "sha256": "aec2aac65a8e04a4a754ff44a6c4b37afdbf46a24156d5092c98f57aea436cc0", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/main.py", + "sha256": "abb959c23054e8fdd12fb4918ea6c1149ef3cc7b1fee268697baf36f07af9fc2", + "routes": [ + { + "method": "GET", + "path": "/config/portal-mode", + "router": "app", + "prefix_resolved": true, + "name": "get_portal_mode", + "signature": "", + "returns": "PortalModeResponse", + "line": 210, + "doc": "", + "decorator": "app.get('/config/portal-mode', tags=['public'], response_model=PortalModeResponse, summary=\"Get the deployment's current portal posture.\")", + "errors": [] + }, + { + "method": "GET", + "path": "/health", + "router": "app", + "prefix_resolved": true, + "name": "health", + "signature": "", + "returns": "", + "line": 266, + "doc": "", + "decorator": "app.get('/health')", + "errors": [] + } + ], + "models": [ + { + "name": "PortalModeResponse", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "mode", + "type": "Literal['public', 'private']", + "default": "Field(description='Active portal posture for this deployment. ``public`` = minimal resident surface (landing + authenticated records-request submission + resident registration) reachable without staff auth. ``private`` = staff-only; no public routes, no resident self-registration.')" + } + ], + "line": 17, + "doc": "T5D \u2014 schema for ``GET /config/portal-mode``.\n\nExposed to the frontend on boot so it can branch routing without a\nuser-identity lookup. The payload is intentionally the single field\nbelow \u2014 no staff config, no user state, no schema version." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/models/__init__.py", + "sha256": "85380f990a3bf800137f3e67775ba042f57a8a6b54d304845f43e1cb2a0b80c5", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/models/audit.py", + "sha256": "df56686024ce0b50fc6ffe0fe20d4775314cd3bd60302ae85d8b9f860ca053bb", + "routes": [], + "models": [ + { + "name": "AuditLog", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[int]", + "default": "mapped_column(primary_key=True, autoincrement=True)" + }, + { + "name": "prev_hash", + "type": "Mapped[str]", + "default": "mapped_column(String(64), default='0' * 64)" + }, + { + "name": "entry_hash", + "type": "Mapped[str]", + "default": "mapped_column(String(64), index=True)" + }, + { + "name": "timestamp", + "type": "Mapped[datetime]", + "default": "mapped_column(DateTime(timezone=True), server_default=func.now(), index=True)" + }, + { + "name": "user_id", + "type": "Mapped[uuid.UUID | None]", + "default": "mapped_column(UUID(as_uuid=True), nullable=True, index=True)" + }, + { + "name": "action", + "type": "Mapped[str]", + "default": "mapped_column(String(100), index=True)" + }, + { + "name": "resource_type", + "type": "Mapped[str]", + "default": "mapped_column(String(100), index=True)" + }, + { + "name": "resource_id", + "type": "Mapped[str | None]", + "default": "mapped_column(String(255), nullable=True)" + }, + { + "name": "details", + "type": "Mapped[dict | None]", + "default": "mapped_column(JSONB, nullable=True)" + }, + { + "name": "ai_generated", + "type": "Mapped[bool]", + "default": "mapped_column(Boolean, default=False)" + } + ], + "line": 11, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/models/city_profile.py", + "sha256": "cc91186429d3a0afe01cd36ec8dd97bda3aa99e6297d25aeeae81fafcc31fe04", + "routes": [], + "models": [ + { + "name": "CityProfile", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(primary_key=True, default=uuid.uuid4)" + }, + { + "name": "city_name", + "type": "Mapped[str]", + "default": "mapped_column(String(200))" + }, + { + "name": "state", + "type": "Mapped[str | None]", + "default": "mapped_column(String(2))" + }, + { + "name": "county", + "type": "Mapped[str | None]", + "default": "mapped_column(String(200))" + }, + { + "name": "population_band", + "type": "Mapped[str | None]", + "default": "mapped_column(String(50))" + }, + { + "name": "email_platform", + "type": "Mapped[str | None]", + "default": "mapped_column(String(50))" + }, + { + "name": "has_dedicated_it", + "type": "Mapped[bool | None]", + "default": "mapped_column(Boolean)" + }, + { + "name": "monthly_request_volume", + "type": "Mapped[str | None]", + "default": "mapped_column(String(20))" + }, + { + "name": "onboarding_status", + "type": "Mapped[str]", + "default": "mapped_column(String(20), default='not_started')" + }, + { + "name": "profile_data", + "type": "Mapped[dict]", + "default": "mapped_column(JSONB, default=dict)" + }, + { + "name": "gap_map", + "type": "Mapped[dict]", + "default": "mapped_column(JSONB, default=dict)" + }, + { + "name": "created_at", + "type": "Mapped[datetime]", + "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + }, + { + "name": "updated_at", + "type": "Mapped[datetime]", + "default": "mapped_column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())" + }, + { + "name": "updated_by", + "type": "Mapped[uuid.UUID | None]", + "default": "mapped_column(ForeignKey('users.id', ondelete='SET NULL'))" + } + ], + "line": 9, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/models/connectors.py", + "sha256": "bd21d54690bdd9298d218ac973f29a2f14e2a4e59898784208d8f714ed33b032", + "routes": [], + "models": [ + { + "name": "SystemCatalog", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[int]", + "default": "mapped_column(Integer, primary_key=True, autoincrement=True)" + }, + { + "name": "domain", + "type": "Mapped[str]", + "default": "mapped_column(String(100))" + }, + { + "name": "function", + "type": "Mapped[str]", + "default": "mapped_column(String(200))" + }, + { + "name": "vendor_name", + "type": "Mapped[str]", + "default": "mapped_column(String(200))" + }, + { + "name": "vendor_version", + "type": "Mapped[str | None]", + "default": "mapped_column(String(50))" + }, + { + "name": "access_protocol", + "type": "Mapped[str]", + "default": "mapped_column(String(50))" + }, + { + "name": "data_shape", + "type": "Mapped[str]", + "default": "mapped_column(String(50))" + }, + { + "name": "common_record_types", + "type": "Mapped[dict]", + "default": "mapped_column(JSONB, default=list)" + }, + { + "name": "redaction_tier", + "type": "Mapped[int]", + "default": "mapped_column(Integer, default=1)" + }, + { + "name": "discovery_hints", + "type": "Mapped[dict]", + "default": "mapped_column(JSONB, default=dict)" + }, + { + "name": "connector_template_id", + "type": "Mapped[int | None]", + "default": "mapped_column(Integer)" + }, + { + "name": "catalog_version", + "type": "Mapped[str]", + "default": "mapped_column(String(20))" + }, + { + "name": "created_at", + "type": "Mapped[datetime]", + "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + } + ], + "line": 8, + "doc": "" + }, + { + "name": "ConnectorTemplate", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[int]", + "default": "mapped_column(Integer, primary_key=True, autoincrement=True)" + }, + { + "name": "vendor_name", + "type": "Mapped[str]", + "default": "mapped_column(String(200))" + }, + { + "name": "protocol", + "type": "Mapped[str]", + "default": "mapped_column(String(50))" + }, + { + "name": "auth_method", + "type": "Mapped[str]", + "default": "mapped_column(String(50))" + }, + { + "name": "config_schema", + "type": "Mapped[dict]", + "default": "mapped_column(JSONB, default=dict)" + }, + { + "name": "default_sync_schedule", + "type": "Mapped[str | None]", + "default": "mapped_column(String(50))" + }, + { + "name": "default_rate_limit", + "type": "Mapped[int | None]", + "default": "mapped_column(Integer)" + }, + { + "name": "redaction_tier", + "type": "Mapped[int]", + "default": "mapped_column(Integer, default=1)" + }, + { + "name": "setup_instructions", + "type": "Mapped[str | None]", + "default": "mapped_column(Text)" + }, + { + "name": "created_at", + "type": "Mapped[datetime]", + "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + }, + { + "name": "catalog_version", + "type": "Mapped[str]", + "default": "mapped_column(String(20))" + } + ], + "line": 28, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/models/departments.py", + "sha256": "95df980295f111a89ec3197370eb7ebe5a67881871a9016ce9bee7a2741ed173", + "routes": [], + "models": [ + { + "name": "Department", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(primary_key=True, default=uuid.uuid4)" + }, + { + "name": "name", + "type": "Mapped[str]", + "default": "mapped_column(String(200))" + }, + { + "name": "code", + "type": "Mapped[str]", + "default": "mapped_column(String(20), unique=True)" + }, + { + "name": "contact_email", + "type": "Mapped[str | None]", + "default": "mapped_column(String(255))" + }, + { + "name": "created_at", + "type": "Mapped[datetime]", + "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + } + ], + "line": 8, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/models/document.py", + "sha256": "bcde5a7d50bc74ef2bb6d078e210366ca78b2c2ae9cc072ff72c6f727d9c78a7", + "routes": [], + "models": [ + { + "name": "DataSource", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)" + }, + { + "name": "name", + "type": "Mapped[str]", + "default": "mapped_column(String(255), unique=True)" + }, + { + "name": "source_type", + "type": "Mapped[SourceType]", + "default": "mapped_column(Enum(SourceType, name='source_type', create_type=False, values_callable=lambda e: [m.value for m in e]))" + }, + { + "name": "connection_config", + "type": "Mapped[dict]", + "default": "mapped_column(EncryptedJSONB, default=dict)" + }, + { + "name": "is_active", + "type": "Mapped[bool]", + "default": "mapped_column(Boolean, default=True)" + }, + { + "name": "created_by", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True), ForeignKey('users.id'))" + }, + { + "name": "created_at", + "type": "Mapped[datetime]", + "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + }, + { + "name": "last_ingestion_at", + "type": "Mapped[datetime | None]", + "default": "mapped_column(DateTime(timezone=True), nullable=True)" + }, + { + "name": "discovered_source_id", + "type": "Mapped[uuid.UUID | None]", + "default": "mapped_column(nullable=True)" + }, + { + "name": "connector_template_id", + "type": "Mapped[int | None]", + "default": "mapped_column(Integer, nullable=True)" + }, + { + "name": "sync_schedule", + "type": "Mapped[str | None]", + "default": "mapped_column(String(50), nullable=True)" + }, + { + "name": "schedule_enabled", + "type": "Mapped[bool]", + "default": "mapped_column(Boolean, default=True, server_default='true')" + }, + { + "name": "last_sync_at", + "type": "Mapped[datetime | None]", + "default": "mapped_column(DateTime(timezone=True), nullable=True)" + }, + { + "name": "last_sync_cursor", + "type": "Mapped[str | None]", + "default": "mapped_column(String, nullable=True)" + }, + { + "name": "last_sync_status", + "type": "Mapped[str | None]", + "default": "mapped_column(String(20), nullable=True)" + }, + { + "name": "consecutive_failure_count", + "type": "Mapped[int]", + "default": "mapped_column(Integer, default=0, server_default='0')" + }, + { + "name": "last_error_message", + "type": "Mapped[str | None]", + "default": "mapped_column(String(500), nullable=True)" + }, + { + "name": "last_error_at", + "type": "Mapped[datetime | None]", + "default": "mapped_column(DateTime(timezone=True), nullable=True)" + }, + { + "name": "sync_paused", + "type": "Mapped[bool]", + "default": "mapped_column(Boolean, default=False, server_default='false')" + }, + { + "name": "sync_paused_at", + "type": "Mapped[datetime | None]", + "default": "mapped_column(DateTime(timezone=True), nullable=True)" + }, + { + "name": "sync_paused_reason", + "type": "Mapped[str | None]", + "default": "mapped_column(String(200), nullable=True)" + }, + { + "name": "retry_batch_size", + "type": "Mapped[int | None]", + "default": "mapped_column(Integer, nullable=True)" + }, + { + "name": "retry_time_limit_seconds", + "type": "Mapped[int | None]", + "default": "mapped_column(Integer, nullable=True)" + }, + { + "name": "health_status", + "type": "Mapped[str | None]", + "default": "mapped_column(String(20), nullable=True)" + }, + { + "name": "schema_hash", + "type": "Mapped[str | None]", + "default": "mapped_column(String(64), nullable=True)" + } + ], + "line": 72, + "doc": "" + }, + { + "name": "Document", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)" + }, + { + "name": "source_id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True), ForeignKey('data_sources.id'), index=True)" + }, + { + "name": "source_path", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "filename", + "type": "Mapped[str]", + "default": "mapped_column(String(500))" + }, + { + "name": "file_type", + "type": "Mapped[str]", + "default": "mapped_column(String(50))" + }, + { + "name": "file_hash", + "type": "Mapped[str]", + "default": "mapped_column(String(64), index=True)" + }, + { + "name": "file_size", + "type": "Mapped[int]", + "default": "mapped_column(Integer, default=0)" + }, + { + "name": "ingestion_status", + "type": "Mapped[IngestionStatus]", + "default": "mapped_column(Enum(IngestionStatus, name='ingestion_status', create_type=False, values_callable=lambda e: [m.value for m in e]), default=IngestionStatus.PENDING)" + }, + { + "name": "ingestion_error", + "type": "Mapped[str | None]", + "default": "mapped_column(Text, nullable=True)" + }, + { + "name": "chunk_count", + "type": "Mapped[int]", + "default": "mapped_column(Integer, default=0)" + }, + { + "name": "ingested_at", + "type": "Mapped[datetime | None]", + "default": "mapped_column(DateTime(timezone=True), nullable=True)" + }, + { + "name": "metadata_", + "type": "Mapped[dict | None]", + "default": "mapped_column('metadata', JSONB, nullable=True)" + }, + { + "name": "connector_type", + "type": "Mapped[str | None]", + "default": "mapped_column(String(20), nullable=True)" + }, + { + "name": "updated_at", + "type": "Mapped[datetime | None]", + "default": "mapped_column(DateTime(timezone=True), nullable=True)" + }, + { + "name": "display_name", + "type": "Mapped[str | None]", + "default": "mapped_column(String(500), nullable=True)" + }, + { + "name": "department_id", + "type": "Mapped[uuid.UUID | None]", + "default": "mapped_column(nullable=True)" + }, + { + "name": "redaction_status", + "type": "Mapped[str]", + "default": "mapped_column(String(20), server_default='none')" + }, + { + "name": "derivative_path", + "type": "Mapped[str | None]", + "default": "mapped_column(String(1000), nullable=True)" + }, + { + "name": "original_locked", + "type": "Mapped[bool]", + "default": "mapped_column(Boolean, server_default='false')" + } + ], + "line": 110, + "doc": "" + }, + { + "name": "DocumentChunk", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)" + }, + { + "name": "document_id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True), ForeignKey('documents.id', ondelete='CASCADE'), index=True)" + }, + { + "name": "chunk_index", + "type": "Mapped[int]", + "default": "mapped_column(Integer)" + }, + { + "name": "content_text", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "embedding", + "type": "Mapped[list | None]", + "default": "mapped_column(Vector(768), nullable=True)" + }, + { + "name": "token_count", + "type": "Mapped[int]", + "default": "mapped_column(Integer, default=0)" + }, + { + "name": "page_number", + "type": "Mapped[int | None]", + "default": "mapped_column(Integer, nullable=True)" + } + ], + "line": 140, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/models/exemption.py", + "sha256": "19c6c9f126eb03fd77139619f1e2a6c6af89d67af7e90d2139644dc909e9f7e3", + "routes": [], + "models": [ + { + "name": "ExemptionRule", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)" + }, + { + "name": "state_code", + "type": "Mapped[str]", + "default": "mapped_column(String(2), index=True)" + }, + { + "name": "category", + "type": "Mapped[str]", + "default": "mapped_column(String(100), index=True)" + }, + { + "name": "rule_type", + "type": "Mapped[RuleType]", + "default": "mapped_column(Enum(RuleType, name='rule_type', create_type=False, values_callable=lambda e: [m.value for m in e]))" + }, + { + "name": "rule_definition", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "description", + "type": "Mapped[str | None]", + "default": "mapped_column(Text, nullable=True)" + }, + { + "name": "enabled", + "type": "Mapped[bool]", + "default": "mapped_column(Boolean, default=True)" + }, + { + "name": "version", + "type": "Mapped[int]", + "default": "mapped_column(Integer, default=1)" + }, + { + "name": "created_by", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True), ForeignKey('users.id'))" + }, + { + "name": "created_at", + "type": "Mapped[datetime]", + "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + } + ], + "line": 25, + "doc": "" + }, + { + "name": "ExemptionFlag", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)" + }, + { + "name": "chunk_id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True), ForeignKey('document_chunks.id'), index=True)" + }, + { + "name": "rule_id", + "type": "Mapped[uuid.UUID | None]", + "default": "mapped_column(UUID(as_uuid=True), ForeignKey('exemption_rules.id'), nullable=True, index=True)" + }, + { + "name": "request_id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True), ForeignKey('records_requests.id'), index=True)" + }, + { + "name": "category", + "type": "Mapped[str]", + "default": "mapped_column(String(100))" + }, + { + "name": "matched_text", + "type": "Mapped[str | None]", + "default": "mapped_column(Text, nullable=True)" + }, + { + "name": "confidence", + "type": "Mapped[float]", + "default": "mapped_column(Float, default=1.0)" + }, + { + "name": "status", + "type": "Mapped[FlagStatus]", + "default": "mapped_column(Enum(FlagStatus, name='flag_status', create_type=False, values_callable=lambda e: [m.value for m in e]), default=FlagStatus.FLAGGED)" + }, + { + "name": "reviewed_by", + "type": "Mapped[uuid.UUID | None]", + "default": "mapped_column(UUID(as_uuid=True), ForeignKey('users.id'), nullable=True)" + }, + { + "name": "reviewed_at", + "type": "Mapped[datetime | None]", + "default": "mapped_column(DateTime(timezone=True), nullable=True)" + }, + { + "name": "review_reason", + "type": "Mapped[str | None]", + "default": "mapped_column(Text, nullable=True)" + }, + { + "name": "created_at", + "type": "Mapped[datetime]", + "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + }, + { + "name": "review_note", + "type": "Mapped[str | None]", + "default": "mapped_column(Text, nullable=True)" + }, + { + "name": "detection_tier", + "type": "Mapped[int | None]", + "default": "mapped_column(Integer, nullable=True)" + }, + { + "name": "detection_method", + "type": "Mapped[str | None]", + "default": "mapped_column(String(50), nullable=True)" + }, + { + "name": "auto_detected", + "type": "Mapped[bool]", + "default": "mapped_column(Boolean, server_default='false')" + } + ], + "line": 42, + "doc": "" + }, + { + "name": "DisclosureTemplate", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)" + }, + { + "name": "template_type", + "type": "Mapped[str]", + "default": "mapped_column(String(100))" + }, + { + "name": "state_code", + "type": "Mapped[str | None]", + "default": "mapped_column(String(2), nullable=True)" + }, + { + "name": "content", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "version", + "type": "Mapped[int]", + "default": "mapped_column(Integer, default=1)" + }, + { + "name": "updated_by", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True), ForeignKey('users.id'))" + }, + { + "name": "updated_at", + "type": "Mapped[datetime]", + "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + } + ], + "line": 68, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/models/fees.py", + "sha256": "8b6cc691265769ccd53ba6376b96c584c0a9d2bb6e55fe79a276ea1265ed2a7d", + "routes": [], + "models": [ + { + "name": "FeeSchedule", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(primary_key=True, default=uuid.uuid4)" + }, + { + "name": "jurisdiction", + "type": "Mapped[str]", + "default": "mapped_column(String(100))" + }, + { + "name": "fee_type", + "type": "Mapped[str]", + "default": "mapped_column(String(50))" + }, + { + "name": "amount", + "type": "Mapped[float]", + "default": "mapped_column(Numeric(10, 2))" + }, + { + "name": "description", + "type": "Mapped[str | None]", + "default": "mapped_column(String(500))" + }, + { + "name": "effective_date", + "type": "Mapped[date]", + "default": "mapped_column(Date)" + }, + { + "name": "created_by", + "type": "Mapped[uuid.UUID | None]", + "default": "mapped_column(ForeignKey('users.id', ondelete='SET NULL'))" + }, + { + "name": "created_at", + "type": "Mapped[datetime]", + "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + } + ], + "line": 8, + "doc": "" + }, + { + "name": "FeeWaiver", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(primary_key=True, default=uuid.uuid4)" + }, + { + "name": "request_id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(ForeignKey('records_requests.id', ondelete='CASCADE'))" + }, + { + "name": "waiver_type", + "type": "Mapped[str]", + "default": "mapped_column(String(50))" + }, + { + "name": "reason", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "status", + "type": "Mapped[str]", + "default": "mapped_column(String(20), default='pending')" + }, + { + "name": "requested_by", + "type": "Mapped[uuid.UUID | None]", + "default": "mapped_column(ForeignKey('users.id', ondelete='SET NULL'))" + }, + { + "name": "reviewed_by", + "type": "Mapped[uuid.UUID | None]", + "default": "mapped_column(ForeignKey('users.id', ondelete='SET NULL'), nullable=True)" + }, + { + "name": "review_notes", + "type": "Mapped[str | None]", + "default": "mapped_column(String(2000), nullable=True)" + }, + { + "name": "created_at", + "type": "Mapped[datetime]", + "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + }, + { + "name": "reviewed_at", + "type": "Mapped[datetime | None]", + "default": "mapped_column(DateTime(timezone=True), nullable=True)" + } + ], + "line": 25, + "doc": "" + }, + { + "name": "FeeLineItem", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(primary_key=True, default=uuid.uuid4)" + }, + { + "name": "request_id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(ForeignKey('records_requests.id', ondelete='CASCADE'))" + }, + { + "name": "fee_schedule_id", + "type": "Mapped[uuid.UUID | None]", + "default": "mapped_column(ForeignKey('fee_schedules.id', ondelete='SET NULL'))" + }, + { + "name": "description", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "quantity", + "type": "Mapped[int]", + "default": "mapped_column(Integer, default=1)" + }, + { + "name": "unit_price", + "type": "Mapped[float]", + "default": "mapped_column(Numeric(21, 2))" + }, + { + "name": "total", + "type": "Mapped[float]", + "default": "mapped_column(Numeric(21, 2))" + }, + { + "name": "status", + "type": "Mapped[str]", + "default": "mapped_column(String(20), default='estimated')" + }, + { + "name": "created_at", + "type": "Mapped[datetime]", + "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + }, + { + "name": "legacy_id", + "type": "Mapped[str | None]", + "default": "mapped_column(Text)" + }, + { + "name": "position", + "type": "Mapped[int | None]", + "default": "mapped_column(Integer)" + }, + { + "name": "schedule_basis", + "type": "Mapped[str]", + "default": "mapped_column(Text, server_default='')" + } + ], + "line": 50, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/models/notifications.py", + "sha256": "f42e1facfadb8d4538b89f85a213142efc18e17be2bde95ac665b94d5704ad8c", + "routes": [], + "models": [ + { + "name": "NotificationTemplate", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(primary_key=True, default=uuid.uuid4)" + }, + { + "name": "event_type", + "type": "Mapped[str]", + "default": "mapped_column(String(50), unique=True)" + }, + { + "name": "channel", + "type": "Mapped[str]", + "default": "mapped_column(String(20))" + }, + { + "name": "subject_template", + "type": "Mapped[str]", + "default": "mapped_column(String(500))" + }, + { + "name": "body_template", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "is_active", + "type": "Mapped[bool]", + "default": "mapped_column(Boolean, default=True)" + }, + { + "name": "created_by", + "type": "Mapped[uuid.UUID | None]", + "default": "mapped_column(ForeignKey('users.id', ondelete='SET NULL'))" + }, + { + "name": "created_at", + "type": "Mapped[datetime]", + "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + } + ], + "line": 8, + "doc": "" + }, + { + "name": "NotificationLog", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(primary_key=True, default=uuid.uuid4)" + }, + { + "name": "template_id", + "type": "Mapped[uuid.UUID | None]", + "default": "mapped_column(ForeignKey('notification_templates.id', ondelete='SET NULL'))" + }, + { + "name": "recipient_email", + "type": "Mapped[str]", + "default": "mapped_column(String(255))" + }, + { + "name": "request_id", + "type": "Mapped[uuid.UUID | None]", + "default": "mapped_column(ForeignKey('records_requests.id', ondelete='SET NULL'))" + }, + { + "name": "channel", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "subject", + "type": "Mapped[str | None]", + "default": "mapped_column(Text, nullable=True)" + }, + { + "name": "body", + "type": "Mapped[str | None]", + "default": "mapped_column(Text, nullable=True)" + }, + { + "name": "status", + "type": "Mapped[str]", + "default": "mapped_column(String(20), default='queued')" + }, + { + "name": "sent_at", + "type": "Mapped[datetime | None]", + "default": "mapped_column(DateTime(timezone=True))" + }, + { + "name": "error_message", + "type": "Mapped[str | None]", + "default": "mapped_column(Text)" + }, + { + "name": "created_at", + "type": "Mapped[datetime]", + "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + }, + { + "name": "legacy_id", + "type": "Mapped[str | None]", + "default": "mapped_column(Text)" + }, + { + "name": "module_id", + "type": "Mapped[str | None]", + "default": "mapped_column(Text)" + }, + { + "name": "audience", + "type": "Mapped[str | None]", + "default": "mapped_column(Text)" + } + ], + "line": 25, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/models/records_artifacts.py", + "sha256": "bb3c7d9b5e796686c3731db8577009d00378a14feec56f8d46360bd8660d3130", + "routes": [], + "models": [ + { + "name": "RequestArtifact", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(primary_key=True, default=uuid.uuid4)" + }, + { + "name": "request_id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(ForeignKey('records_requests.id'), index=True)" + }, + { + "name": "legacy_id", + "type": "Mapped[str | None]", + "default": "mapped_column(Text)" + }, + { + "name": "position", + "type": "Mapped[int | None]", + "default": "mapped_column(Integer)" + }, + { + "name": "kind", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "content", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "sha256", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "response_sha256", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "export_path", + "type": "Mapped[str | None]", + "default": "mapped_column(Text, unique=True)" + }, + { + "name": "actor_id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(ForeignKey('users.id'))" + }, + { + "name": "document_count", + "type": "Mapped[int]", + "default": "mapped_column(Integer)" + }, + { + "name": "release_artifact_count", + "type": "Mapped[int]", + "default": "mapped_column(Integer)" + }, + { + "name": "search_session_count", + "type": "Mapped[int]", + "default": "mapped_column(Integer)" + }, + { + "name": "release_count", + "type": "Mapped[int]", + "default": "mapped_column(Integer)" + }, + { + "name": "redacted_count", + "type": "Mapped[int]", + "default": "mapped_column(Integer)" + }, + { + "name": "exempt_count", + "type": "Mapped[int]", + "default": "mapped_column(Integer)" + }, + { + "name": "created_at", + "type": "Mapped[datetime]", + "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + }, + { + "name": "completed_at", + "type": "Mapped[datetime | None]", + "default": "mapped_column(DateTime(timezone=True))" + } + ], + "line": 9, + "doc": "" + }, + { + "name": "RequestPublication", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(primary_key=True, default=uuid.uuid4)" + }, + { + "name": "request_id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(ForeignKey('records_requests.id'), index=True)" + }, + { + "name": "legacy_id", + "type": "Mapped[str | None]", + "default": "mapped_column(Text)" + }, + { + "name": "payload", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "payload_hash", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "actor_id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(ForeignKey('users.id'))" + }, + { + "name": "created_at", + "type": "Mapped[datetime]", + "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + } + ], + "line": 31, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/models/records_evidence.py", + "sha256": "acadc29d3b93a2432c2c752b05f9c61e649c7d94fe29948b8dab4c46ffd421dd", + "routes": [], + "models": [ + { + "name": "RequestEvidenceNote", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(primary_key=True, default=uuid.uuid4)" + }, + { + "name": "request_id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(ForeignKey('records_requests.id', ondelete='CASCADE'), index=True)" + }, + { + "name": "kind", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "position", + "type": "Mapped[int]", + "default": "mapped_column(Integer)" + }, + { + "name": "content", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "actor_id", + "type": "Mapped[uuid.UUID | None]", + "default": "mapped_column(ForeignKey('users.id', ondelete='SET NULL'))" + }, + { + "name": "created_at", + "type": "Mapped[datetime]", + "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + } + ], + "line": 16, + "doc": "" + }, + { + "name": "RequestExemptionDecision", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(primary_key=True, default=uuid.uuid4)" + }, + { + "name": "request_id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(ForeignKey('records_requests.id', ondelete='CASCADE'), index=True)" + }, + { + "name": "flag_id", + "type": "Mapped[uuid.UUID | None]", + "default": "mapped_column(ForeignKey('exemption_flags.id'))" + }, + { + "name": "legacy_id", + "type": "Mapped[str | None]", + "default": "mapped_column(Text)" + }, + { + "name": "position", + "type": "Mapped[int]", + "default": "mapped_column(Integer)" + }, + { + "name": "source", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "kind", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "finding", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "decision", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "basis", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "reviewer_label", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "actor_id", + "type": "Mapped[uuid.UUID | None]", + "default": "mapped_column(ForeignKey('users.id', ondelete='SET NULL'))" + }, + { + "name": "created_at", + "type": "Mapped[datetime]", + "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + } + ], + "line": 34, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/models/records_files.py", + "sha256": "8bceb23febbb492b13035ea12a9219d32741d397668d920a52b31f0e323b15f7", + "routes": [], + "models": [ + { + "name": "RequestFileEvidence", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(ForeignKey('request_documents.id'), primary_key=True)" + }, + { + "name": "request_id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(ForeignKey('records_requests.id'), index=True)" + }, + { + "name": "legacy_id", + "type": "Mapped[str | None]", + "default": "mapped_column(Text)" + }, + { + "name": "position", + "type": "Mapped[int]", + "default": "mapped_column(Integer)" + }, + { + "name": "title", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "original_path", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "citation", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "added_by", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "created_at", + "type": "Mapped[datetime]", + "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + } + ], + "line": 12, + "doc": "" + }, + { + "name": "RequestReleaseCopy", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(primary_key=True, default=uuid.uuid4)" + }, + { + "name": "request_id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(ForeignKey('records_requests.id'), index=True)" + }, + { + "name": "attachment_id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(ForeignKey('request_file_evidence.id'), index=True)" + }, + { + "name": "original_path", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "stored_path", + "type": "Mapped[str]", + "default": "mapped_column(Text, unique=True)" + }, + { + "name": "file_name", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "sha256", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "size_bytes", + "type": "Mapped[int]", + "default": "mapped_column(BigInteger)" + }, + { + "name": "status", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "note", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "added_by", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "actor_id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(ForeignKey('users.id'))" + }, + { + "name": "position", + "type": "Mapped[int]", + "default": "mapped_column(Integer)" + }, + { + "name": "created_at", + "type": "Mapped[datetime]", + "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + } + ], + "line": 26, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/models/request.py", + "sha256": "f88185889b139ac38de9a0d77449db246b22fef58f1743d25c7d2116c718ae76", + "routes": [], + "models": [ + { + "name": "RecordsRequest", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)" + }, + { + "name": "requester_name", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "requester_email", + "type": "Mapped[str | None]", + "default": "mapped_column(String(320), nullable=True)" + }, + { + "name": "date_received", + "type": "Mapped[datetime]", + "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + }, + { + "name": "statutory_deadline", + "type": "Mapped[datetime | None]", + "default": "mapped_column(DateTime(timezone=True), nullable=True)" + }, + { + "name": "description", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "status", + "type": "Mapped[RequestStatus]", + "default": "mapped_column(Enum(RequestStatus, name='request_status', create_type=False, values_callable=lambda e: [m.value for m in e]), default=RequestStatus.RECEIVED)" + }, + { + "name": "assigned_to", + "type": "Mapped[uuid.UUID | None]", + "default": "mapped_column(UUID(as_uuid=True), ForeignKey('users.id'), nullable=True)" + }, + { + "name": "created_by", + "type": "Mapped[uuid.UUID | None]", + "default": "mapped_column(UUID(as_uuid=True), ForeignKey('users.id'))" + }, + { + "name": "created_at", + "type": "Mapped[datetime]", + "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + }, + { + "name": "response_draft", + "type": "Mapped[str | None]", + "default": "mapped_column(Text, nullable=True)" + }, + { + "name": "review_notes", + "type": "Mapped[str | None]", + "default": "mapped_column(Text, nullable=True)" + }, + { + "name": "requester_phone", + "type": "Mapped[str | None]", + "default": "mapped_column(String(50), nullable=True)" + }, + { + "name": "requester_type", + "type": "Mapped[str | None]", + "default": "mapped_column(String(20), nullable=True)" + }, + { + "name": "scope_assessment", + "type": "Mapped[str | None]", + "default": "mapped_column(String(20), nullable=True)" + }, + { + "name": "department_id", + "type": "Mapped[uuid.UUID | None]", + "default": "mapped_column(nullable=True)" + }, + { + "name": "estimated_fee", + "type": "Mapped[float | None]", + "default": "mapped_column(Numeric(21, 2), nullable=True)" + }, + { + "name": "fee_status", + "type": "Mapped[str | None]", + "default": "mapped_column(String(20), nullable=True)" + }, + { + "name": "fee_waiver_requested", + "type": "Mapped[bool]", + "default": "mapped_column(Boolean, server_default='false')" + }, + { + "name": "priority", + "type": "Mapped[str]", + "default": "mapped_column(String(20), server_default='normal')" + }, + { + "name": "closed_at", + "type": "Mapped[datetime | None]", + "default": "mapped_column(DateTime(timezone=True), nullable=True)" + }, + { + "name": "closure_reason", + "type": "Mapped[str | None]", + "default": "mapped_column(String(500), nullable=True)" + }, + { + "name": "desktop_id", + "type": "Mapped[str | None]", + "default": "mapped_column(Text, unique=True, nullable=True)" + }, + { + "name": "public_tracking_number", + "type": "Mapped[str | None]", + "default": "mapped_column(Text, unique=True, nullable=True)" + }, + { + "name": "requester_contact", + "type": "Mapped[str]", + "default": "mapped_column(Text, server_default='')" + }, + { + "name": "submitted_via", + "type": "Mapped[str]", + "default": "mapped_column(Text, server_default='')" + }, + { + "name": "deadline_label", + "type": "Mapped[str]", + "default": "mapped_column(Text, server_default='')" + }, + { + "name": "deadline_basis", + "type": "Mapped[str]", + "default": "mapped_column(Text, server_default='')" + }, + { + "name": "deadline_reviewed_at", + "type": "Mapped[datetime | None]", + "default": "mapped_column(DateTime(timezone=True))" + }, + { + "name": "display_status", + "type": "Mapped[str | None]", + "default": "mapped_column(Text)" + }, + { + "name": "assigned_label", + "type": "Mapped[str]", + "default": "mapped_column(Text, server_default='')" + }, + { + "name": "fee_estimate_text", + "type": "Mapped[str]", + "default": "mapped_column(Text, server_default='')" + }, + { + "name": "fee_waiver_reason", + "type": "Mapped[str]", + "default": "mapped_column(Text, server_default='')" + }, + { + "name": "approved_at", + "type": "Mapped[datetime | None]", + "default": "mapped_column(DateTime(timezone=True))" + }, + { + "name": "approved_response_sha256", + "type": "Mapped[str | None]", + "default": "mapped_column(String(64))" + }, + { + "name": "fulfilled_at", + "type": "Mapped[datetime | None]", + "default": "mapped_column(DateTime(timezone=True))" + } + ], + "line": 31, + "doc": "" + }, + { + "name": "RequestDocument", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)" + }, + { + "name": "request_id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True), ForeignKey('records_requests.id'), index=True)" + }, + { + "name": "document_id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True), ForeignKey('documents.id'), index=True)" + }, + { + "name": "relevance_note", + "type": "Mapped[str | None]", + "default": "mapped_column(Text, nullable=True)" + }, + { + "name": "exemption_flags", + "type": "Mapped[dict | None]", + "default": "mapped_column(JSONB, nullable=True)" + }, + { + "name": "inclusion_status", + "type": "Mapped[InclusionStatus]", + "default": "mapped_column(Enum(InclusionStatus, name='inclusion_status', create_type=False, values_callable=lambda e: [m.value for m in e]), default=InclusionStatus.PENDING)" + }, + { + "name": "attached_at", + "type": "Mapped[datetime]", + "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + }, + { + "name": "attached_by", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True), ForeignKey('users.id'))" + } + ], + "line": 80, + "doc": "" + }, + { + "name": "DocumentCache", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)" + }, + { + "name": "document_id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True), ForeignKey('documents.id'), index=True)" + }, + { + "name": "request_id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True), ForeignKey('records_requests.id'), index=True)" + }, + { + "name": "cached_file_path", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "file_size", + "type": "Mapped[int]", + "default": "mapped_column(Integer, default=0)" + }, + { + "name": "cached_at", + "type": "Mapped[datetime]", + "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + } + ], + "line": 96, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/models/request_workflow.py", + "sha256": "cc297a448c7f2de9ef1e31d7d94d24494efeeac7165f1d466e94aecfb7807b64", + "routes": [], + "models": [ + { + "name": "RequestTimeline", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(primary_key=True, default=uuid.uuid4)" + }, + { + "name": "request_id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(ForeignKey('records_requests.id', ondelete='CASCADE'), index=True)" + }, + { + "name": "event_type", + "type": "Mapped[str]", + "default": "mapped_column(String(50))" + }, + { + "name": "actor_id", + "type": "Mapped[uuid.UUID | None]", + "default": "mapped_column(ForeignKey('users.id', ondelete='SET NULL'))" + }, + { + "name": "actor_role", + "type": "Mapped[str | None]", + "default": "mapped_column(String(50))" + }, + { + "name": "description", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "internal_note", + "type": "Mapped[str | None]", + "default": "mapped_column(Text)" + }, + { + "name": "created_at", + "type": "Mapped[datetime]", + "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + }, + { + "name": "legacy_id", + "type": "Mapped[str | None]", + "default": "mapped_column(Text)" + }, + { + "name": "actor_label", + "type": "Mapped[str | None]", + "default": "mapped_column(Text)" + }, + { + "name": "position", + "type": "Mapped[int | None]", + "default": "mapped_column(Integer)" + } + ], + "line": 8, + "doc": "" + }, + { + "name": "RequestPublicStatus", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(primary_key=True, default=uuid.uuid4)" + }, + { + "name": "request_id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(ForeignKey('records_requests.id', ondelete='CASCADE'), index=True)" + }, + { + "name": "legacy_id", + "type": "Mapped[str | None]", + "default": "mapped_column(Text)" + }, + { + "name": "label", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "summary", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "status", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "created_at", + "type": "Mapped[datetime]", + "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + }, + { + "name": "position", + "type": "Mapped[int | None]", + "default": "mapped_column(Integer)" + } + ], + "line": 34, + "doc": "" + }, + { + "name": "RequestMessage", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(primary_key=True, default=uuid.uuid4)" + }, + { + "name": "request_id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(ForeignKey('records_requests.id', ondelete='CASCADE'), index=True)" + }, + { + "name": "sender_type", + "type": "Mapped[str]", + "default": "mapped_column(String(20))" + }, + { + "name": "sender_id", + "type": "Mapped[uuid.UUID | None]", + "default": "mapped_column(ForeignKey('users.id', ondelete='SET NULL'))" + }, + { + "name": "message_text", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "is_internal", + "type": "Mapped[bool]", + "default": "mapped_column(Boolean, default=False)" + }, + { + "name": "created_at", + "type": "Mapped[datetime]", + "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + }, + { + "name": "legacy_id", + "type": "Mapped[str | None]", + "default": "mapped_column(Text)" + }, + { + "name": "sender_label", + "type": "Mapped[str | None]", + "default": "mapped_column(Text)" + }, + { + "name": "position", + "type": "Mapped[int | None]", + "default": "mapped_column(Integer)" + } + ], + "line": 51, + "doc": "" + }, + { + "name": "ResponseLetter", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(primary_key=True, default=uuid.uuid4)" + }, + { + "name": "request_id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(ForeignKey('records_requests.id', ondelete='CASCADE'), index=True)" + }, + { + "name": "template_id", + "type": "Mapped[uuid.UUID | None]", + "default": "mapped_column(ForeignKey('disclosure_templates.id', ondelete='SET NULL'))" + }, + { + "name": "generated_content", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "edited_content", + "type": "Mapped[str | None]", + "default": "mapped_column(Text)" + }, + { + "name": "status", + "type": "Mapped[str]", + "default": "mapped_column(String(20), default='draft')" + }, + { + "name": "generated_by", + "type": "Mapped[uuid.UUID | None]", + "default": "mapped_column(ForeignKey('users.id', ondelete='SET NULL'))" + }, + { + "name": "approved_by", + "type": "Mapped[uuid.UUID | None]", + "default": "mapped_column(ForeignKey('users.id', ondelete='SET NULL'))" + }, + { + "name": "sent_at", + "type": "Mapped[datetime | None]", + "default": "mapped_column(DateTime(timezone=True))" + }, + { + "name": "created_at", + "type": "Mapped[datetime]", + "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + } + ], + "line": 72, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/models/search.py", + "sha256": "e1f7499d2042fcae621e817878b1cf12bd53e5b55ebbaae33d8c24e29de275c9", + "routes": [], + "models": [ + { + "name": "SearchSession", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)" + }, + { + "name": "user_id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True), ForeignKey('users.id'), index=True)" + }, + { + "name": "created_at", + "type": "Mapped[datetime]", + "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + } + ], + "line": 11, + "doc": "" + }, + { + "name": "SearchQuery", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)" + }, + { + "name": "session_id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True), ForeignKey('search_sessions.id'), index=True)" + }, + { + "name": "query_text", + "type": "Mapped[str]", + "default": "mapped_column(Text)" + }, + { + "name": "filters", + "type": "Mapped[dict | None]", + "default": "mapped_column(JSONB, nullable=True)" + }, + { + "name": "results_count", + "type": "Mapped[int]", + "default": "mapped_column(Integer, default=0)" + }, + { + "name": "synthesized_answer", + "type": "Mapped[str | None]", + "default": "mapped_column(Text, nullable=True)" + }, + { + "name": "created_at", + "type": "Mapped[datetime]", + "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + }, + { + "name": "request_id", + "type": "Mapped[uuid.UUID | None]", + "default": "mapped_column(UUID(as_uuid=True), ForeignKey('records_requests.id'), index=True)" + }, + { + "name": "legacy_id", + "type": "Mapped[str | None]", + "default": "mapped_column(Text)" + }, + { + "name": "position", + "type": "Mapped[int | None]", + "default": "mapped_column(Integer)" + }, + { + "name": "locations", + "type": "Mapped[str | None]", + "default": "mapped_column(Text)" + }, + { + "name": "reviewer_label", + "type": "Mapped[str | None]", + "default": "mapped_column(Text)" + } + ], + "line": 19, + "doc": "" + }, + { + "name": "SearchResult", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)" + }, + { + "name": "query_id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True), ForeignKey('search_queries.id'), index=True)" + }, + { + "name": "chunk_id", + "type": "Mapped[uuid.UUID | None]", + "default": "mapped_column(UUID(as_uuid=True), ForeignKey('document_chunks.id'), index=True)" + }, + { + "name": "similarity_score", + "type": "Mapped[float | None]", + "default": "mapped_column(Float)" + }, + { + "name": "rank", + "type": "Mapped[int]", + "default": "mapped_column(Integer)" + }, + { + "name": "normalized_score", + "type": "Mapped[int | None]", + "default": "mapped_column(Integer, nullable=True)" + }, + { + "name": "legacy_id", + "type": "Mapped[str | None]", + "default": "mapped_column(Text)" + }, + { + "name": "title", + "type": "Mapped[str | None]", + "default": "mapped_column(Text)" + }, + { + "name": "citation", + "type": "Mapped[str | None]", + "default": "mapped_column(Text)" + }, + { + "name": "summary", + "type": "Mapped[str | None]", + "default": "mapped_column(Text)" + }, + { + "name": "review_status", + "type": "Mapped[str | None]", + "default": "mapped_column(Text)" + } + ], + "line": 38, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/models/service_account.py", + "sha256": "594cbd1dfeea0bf026341f1a427f4e96a362f75c11a7cc0df7fb7e3a8363a311", + "routes": [], + "models": [ + { + "name": "ServiceAccount", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)" + }, + { + "name": "name", + "type": "Mapped[str]", + "default": "mapped_column(String(255), unique=True)" + }, + { + "name": "api_key_hash", + "type": "Mapped[str]", + "default": "mapped_column(String(255))" + }, + { + "name": "role", + "type": "Mapped[UserRole]", + "default": "mapped_column(Enum(UserRole, name='user_role', create_type=False, values_callable=lambda e: [m.value for m in e]), default=UserRole.READ_ONLY)" + }, + { + "name": "created_by", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True), ForeignKey('users.id'))" + }, + { + "name": "created_at", + "type": "Mapped[datetime]", + "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + }, + { + "name": "is_active", + "type": "Mapped[bool]", + "default": "mapped_column(default=True)" + } + ], + "line": 11, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/models/sync_failure.py", + "sha256": "d31b87435c855f632b9b6d746eeec477d4f3811a95017401d0b1c3db4d506eb0", + "routes": [], + "models": [ + { + "name": "SyncFailure", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)" + }, + { + "name": "source_id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True), ForeignKey('data_sources.id', ondelete='CASCADE'), nullable=False)" + }, + { + "name": "source_path", + "type": "Mapped[str]", + "default": "mapped_column(Text, nullable=False)" + }, + { + "name": "error_message", + "type": "Mapped[str | None]", + "default": "mapped_column(Text, nullable=True)" + }, + { + "name": "error_class", + "type": "Mapped[str | None]", + "default": "mapped_column(String(200), nullable=True)" + }, + { + "name": "http_status_code", + "type": "Mapped[int | None]", + "default": "mapped_column(Integer, nullable=True)" + }, + { + "name": "retry_count", + "type": "Mapped[int]", + "default": "mapped_column(Integer, default=0, nullable=False)" + }, + { + "name": "status", + "type": "Mapped[str]", + "default": "mapped_column(String(20), nullable=False, default='retrying')" + }, + { + "name": "first_failed_at", + "type": "Mapped[datetime]", + "default": "mapped_column(DateTime(timezone=True), nullable=False, server_default=func.now())" + }, + { + "name": "last_retried_at", + "type": "Mapped[datetime | None]", + "default": "mapped_column(DateTime(timezone=True), nullable=True)" + }, + { + "name": "resolved_at", + "type": "Mapped[datetime | None]", + "default": "mapped_column(DateTime(timezone=True), nullable=True)" + }, + { + "name": "dismissed_at", + "type": "Mapped[datetime | None]", + "default": "mapped_column(DateTime(timezone=True), nullable=True)" + }, + { + "name": "dismissed_by", + "type": "Mapped[uuid.UUID | None]", + "default": "mapped_column(UUID(as_uuid=True), ForeignKey('users.id'), nullable=True)" + } + ], + "line": 15, + "doc": "" + }, + { + "name": "SyncRunLog", + "bases": [ + "Base" + ], + "fields": [ + { + "name": "id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)" + }, + { + "name": "source_id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True), ForeignKey('data_sources.id', ondelete='CASCADE'), nullable=False)" + }, + { + "name": "started_at", + "type": "Mapped[datetime]", + "default": "mapped_column(DateTime(timezone=True), nullable=False, server_default=func.now())" + }, + { + "name": "finished_at", + "type": "Mapped[datetime | None]", + "default": "mapped_column(DateTime(timezone=True), nullable=True)" + }, + { + "name": "status", + "type": "Mapped[str | None]", + "default": "mapped_column(String(20), nullable=True)" + }, + { + "name": "records_attempted", + "type": "Mapped[int]", + "default": "mapped_column(Integer, default=0)" + }, + { + "name": "records_succeeded", + "type": "Mapped[int]", + "default": "mapped_column(Integer, default=0)" + }, + { + "name": "records_failed", + "type": "Mapped[int]", + "default": "mapped_column(Integer, default=0)" + }, + { + "name": "error_summary", + "type": "Mapped[str | None]", + "default": "mapped_column(Text, nullable=True)" + } + ], + "line": 47, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/models/user.py", + "sha256": "39603bc8063007391d478b52165d2ae8d4bf0c5f1a1d7f716b78ff94754b2c82", + "routes": [], + "models": [ + { + "name": "User", + "bases": [ + "SQLAlchemyBaseUserTableUUID", + "Base" + ], + "fields": [ + { + "name": "full_name", + "type": "Mapped[str]", + "default": "mapped_column(default='')" + }, + { + "name": "role", + "type": "Mapped[UserRole]", + "default": "mapped_column(Enum(UserRole, name='user_role', create_type=False, values_callable=lambda e: [m.value for m in e]), default=UserRole.STAFF)" + }, + { + "name": "created_at", + "type": "Mapped[datetime]", + "default": "mapped_column(DateTime(timezone=True), server_default=func.now())" + }, + { + "name": "last_login", + "type": "Mapped[datetime | None]", + "default": "mapped_column(DateTime(timezone=True), nullable=True)" + }, + { + "name": "must_change_password", + "type": "Mapped[bool]", + "default": "mapped_column(Boolean, nullable=False, default=False, server_default='false')" + }, + { + "name": "department_id", + "type": "Mapped[uuid.UUID | None]", + "default": "mapped_column(ForeignKey('departments.id'), nullable=True)" + } + ], + "line": 23, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/notifications/__init__.py", + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/notifications/router.py", + "sha256": "ac77bd461ee941a84117eb93935464dc2c908ba96c3e2c613d80bd28088d5009", + "routes": [ + { + "method": "GET", + "path": "/notifications/templates", + "router": "router", + "prefix_resolved": false, + "name": "list_templates", + "signature": "session: AsyncSession=Depends(get_async_session), user=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 22, + "doc": "List all notification templates.", + "decorator": "router.get('/notifications/templates', response_model=list[NotificationTemplateRead])", + "errors": [] + }, + { + "method": "POST", + "path": "/notifications/templates", + "router": "router", + "prefix_resolved": false, + "name": "create_template", + "signature": "payload: NotificationTemplateCreate, session: AsyncSession=Depends(get_async_session), user=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 38, + "doc": "Create a new notification template (admin only).", + "decorator": "router.post('/notifications/templates', response_model=NotificationTemplateRead, status_code=201)", + "errors": [ + "HTTPException(status_code=409, detail=f\"Template for event_type '{payload.event_type}' already exists\")" + ] + }, + { + "method": "PATCH", + "path": "/notifications/templates/{template_id}", + "router": "router", + "prefix_resolved": false, + "name": "update_template", + "signature": "template_id: uuid.UUID, payload: NotificationTemplateUpdate, session: AsyncSession=Depends(get_async_session), user=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 83, + "doc": "Update a notification template (admin only).", + "decorator": "router.patch('/notifications/templates/{template_id}', response_model=NotificationTemplateRead)", + "errors": [ + "HTTPException(status_code=404, detail='Template not found')", + "HTTPException(status_code=400, detail='No fields to update')" + ] + }, + { + "method": "GET", + "path": "/notifications/log", + "router": "router", + "prefix_resolved": false, + "name": "list_notification_log", + "signature": "limit: int=Query(default=50, le=200), request_id: uuid.UUID | None=Query(default=None), session: AsyncSession=Depends(get_async_session), user=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 116, + "doc": "List recent notification log entries.", + "decorator": "router.get('/notifications/log', response_model=list[NotificationLogRead])", + "errors": [] + } + ], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/notifications/service.py", + "sha256": "0672a6a7a60bc09c4b1bfe29d7046f93fef36ea48b09a2ff3b898bdf66ad0965", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/notifications/smtp_delivery.py", + "sha256": "4dc26331949c01537173b6bb5c91d5f4d23419e73e46d1600fe289053904e544", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/notifications/sync_notifications.py", + "sha256": "8dee67dcfacd3182afbba6a1ed874e7029a0f2a7aef5a619fcec353dc569b778", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/onboarding/__init__.py", + "sha256": "410f27365a45a5cad7e8a8b23a63e6312fcc6ba18b9f3cfb8ecf782940f7fc49", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/onboarding/router.py", + "sha256": "fd107d538b24379eb31a08e39927eec2486df5d383c20b6f23af9adbb3299ff4", + "routes": [ + { + "method": "POST", + "path": "/onboarding/interview", + "router": "router", + "prefix_resolved": true, + "name": "get_next_question", + "signature": "body: InterviewRequest, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 113, + "doc": "Generate the next onboarding question and persist the last answer.", + "decorator": "router.post('/interview', response_model=InterviewResponse)", + "errors": [] + } + ], + "models": [ + { + "name": "InterviewRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "last_answer", + "type": "str | None", + "default": "None" + }, + { + "name": "last_field", + "type": "str | None", + "default": "None" + }, + { + "name": "skipped_fields", + "type": "list[str] | None", + "default": "None" + } + ], + "line": 63, + "doc": "" + }, + { + "name": "InterviewResponse", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "question", + "type": "str", + "default": "" + }, + { + "name": "target_field", + "type": "str | None", + "default": "" + }, + { + "name": "all_complete", + "type": "bool", + "default": "" + }, + { + "name": "completed_fields", + "type": "list[str]", + "default": "" + }, + { + "name": "onboarding_status", + "type": "str", + "default": "" + }, + { + "name": "skipped_fields", + "type": "list[str]", + "default": "" + } + ], + "line": 73, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/public/__init__.py", + "sha256": "9b2399a19ebba72002567e091d5d5bc56a158640e121328fa89365823d0607f9", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/public/router.py", + "sha256": "1b688edd6b2ed2334bd6c113c4c30e47748ce98bc12c6c70e716f81b8acc23ea", + "routes": [ + { + "method": "POST", + "path": "/requests", + "router": "router", + "prefix_resolved": false, + "name": "submit_public_request", + "signature": "body: PublicRequestSubmitBody, user: User=Depends(_require_public_role), session: AsyncSession=Depends(get_async_session)", + "returns": "PublicRequestSubmitResponse", + "line": 115, + "doc": "Create a records request on behalf of the signed-in PUBLIC user.\n\nThe request lands in :class:`RequestStatus.RECEIVED` with\n``created_by`` = the authenticated resident's id. ``requester_name``\nand ``requester_email`` are copied from the user record so staff\nreviewers see the submitter's registered identity verbatim. An audit\nlog entry is written with ``action=\"public.requests.create\"`` for\nfull traceability.", + "decorator": "router.post('/requests', response_model=PublicRequestSubmitResponse, status_code=status.HTTP_201_CREATED, summary='Submit a records request as an authenticated resident.')", + "errors": [] + } + ], + "models": [ + { + "name": "PublicRequestSubmitBody", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "description", + "type": "str", + "default": "Field(min_length=10, max_length=10000, description='Plain-language description of the records being requested. At least 10 characters; the staff reviewer reads this verbatim.')" + }, + { + "name": "phone", + "type": "str | None", + "default": "Field(default=None, max_length=50, description='Optional contact phone number.')" + } + ], + "line": 47, + "doc": "Minimal public submission payload.\n\nThe authenticated ``UserRole.PUBLIC`` user's ``full_name`` and ``email``\nare reused for ``requester_name`` / ``requester_email`` (they already\nown that identity via self-registration). Only the free-form\ndescription and optional phone are collected here." + }, + { + "name": "PublicRequestSubmitResponse", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "request_id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "status", + "type": "RequestStatus", + "default": "" + }, + { + "name": "submitted_at", + "type": "datetime", + "default": "" + }, + { + "name": "message", + "type": "str", + "default": "" + } + ], + "line": 71, + "doc": "What the resident sees after submitting.\n\nThe tracking id is the database UUID of the request \u2014 the resident\ncan reference it when contacting the records office. Expanded\ntrack-my-request functionality (status page, timeline view,\ndownloads) is explicitly out of T5D scope." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/requests/__init__.py", + "sha256": "10f4a38349943e0adc86d6b60e935616b29948f77c0a1c4ea7c3ccf94b70f2e3", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/requests/artifacts.py", + "sha256": "e557ecc8cfd265bfcb76b4b06de38fcaf6eb75ed3dbba6d21fe65f481bbbf8a1", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/requests/deadline_check.py", + "sha256": "d5d734204bf8ef783d8d619b07df8884ab3cf2987bffcf57daa6d55a3431eb5a", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/requests/files.py", + "sha256": "f5c2703a70c076b963f1116a0779d354479c65cb734bc921a4197c72694c8eec", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/requests/meeting_sources.py", + "sha256": "5694a2e0b345cf684261ef54cc205e5ec1aaeb0125c2c77c0c4a1cf2899feb79", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/requests/native_public.py", + "sha256": "0f9995ccc14fd61e49f51474fc2fcbcc52696b9102c1bd65b227fe135ea5e6cc", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/requests/planning_sources.py", + "sha256": "b62831d83e129a974bec04ee10fd71cfd15c8940f5c5c4dd11794b8f51cbd8d8", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/requests/router.py", + "sha256": "f29526862e9e3adae5cb288a59644fa9d10f0e62fdb0e41602286d715c529199", + "routes": [ + { + "method": "POST", + "path": "/requests/", + "router": "router", + "prefix_resolved": true, + "name": "create_request", + "signature": "data: RequestCreate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 85, + "doc": "", + "decorator": "router.post('/', response_model=RequestRead, status_code=201)", + "errors": [] + }, + { + "method": "GET", + "path": "/requests/", + "router": "router", + "prefix_resolved": true, + "name": "list_requests", + "signature": "status: RequestStatus | None=None, assigned_to: uuid.UUID | None=None, limit: int=50, offset: int=0, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.LIAISON))", + "returns": "", + "line": 104, + "doc": "", + "decorator": "router.get('/', response_model=list[RequestRead])", + "errors": [] + }, + { + "method": "GET", + "path": "/requests/stats", + "router": "router", + "prefix_resolved": true, + "name": "request_stats", + "signature": "session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.LIAISON))", + "returns": "", + "line": 136, + "doc": "", + "decorator": "router.get('/stats', response_model=RequestStats)", + "errors": [] + }, + { + "method": "GET", + "path": "/requests/{request_id}", + "router": "router", + "prefix_resolved": true, + "name": "get_request", + "signature": "request_id: uuid.UUID, request: Request, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.LIAISON))", + "returns": "", + "line": 189, + "doc": "", + "decorator": "router.get('/{request_id}', response_model=RequestRead)", + "errors": [ + "HTTPException(status_code=404, detail='Request not found')" + ] + }, + { + "method": "PATCH", + "path": "/requests/{request_id}", + "router": "router", + "prefix_resolved": true, + "name": "update_request", + "signature": "request_id: uuid.UUID, data: RequestUpdate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 211, + "doc": "", + "decorator": "router.patch('/{request_id}', response_model=RequestRead)", + "errors": [ + "HTTPException(status_code=404, detail='Request not found')", + "HTTPException(status_code=400, detail=f'Cannot transition from {req.status.value} to {data.status.value}')" + ] + }, + { + "method": "POST", + "path": "/requests/{request_id}/documents", + "router": "router", + "prefix_resolved": true, + "name": "attach_document", + "signature": "request_id: uuid.UUID, data: RequestDocumentAdd, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 275, + "doc": "", + "decorator": "router.post('/{request_id}/documents', response_model=RequestDocumentRead, status_code=201)", + "errors": [ + "HTTPException(status_code=404, detail='Request not found')", + "HTTPException(status_code=404, detail='Document not found')", + "HTTPException(status_code=409, detail='Document already attached')" + ] + }, + { + "method": "GET", + "path": "/requests/{request_id}/documents", + "router": "router", + "prefix_resolved": true, + "name": "list_attached_documents", + "signature": "request_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 342, + "doc": "", + "decorator": "router.get('/{request_id}/documents', response_model=list[RequestDocumentRead])", + "errors": [ + "HTTPException(status_code=404, detail='Request not found')" + ] + }, + { + "method": "DELETE", + "path": "/requests/{request_id}/documents/{doc_id}", + "router": "router", + "prefix_resolved": true, + "name": "remove_document", + "signature": "request_id: uuid.UUID, doc_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 363, + "doc": "", + "decorator": "router.delete('/{request_id}/documents/{doc_id}', status_code=204)", + "errors": [ + "HTTPException(status_code=404, detail='Request not found')", + "HTTPException(status_code=404, detail='Attachment not found')" + ] + }, + { + "method": "POST", + "path": "/requests/{request_id}/submit-review", + "router": "router", + "prefix_resolved": true, + "name": "submit_for_review", + "signature": "request_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 395, + "doc": "", + "decorator": "router.post('/{request_id}/submit-review', response_model=RequestRead)", + "errors": [ + "HTTPException(status_code=404, detail='Request not found')", + "HTTPException(status_code=400, detail=f'Cannot submit for review from status {req.status.value}')" + ] + }, + { + "method": "POST", + "path": "/requests/{request_id}/ready-for-release", + "router": "router", + "prefix_resolved": true, + "name": "mark_ready_for_release", + "signature": "request_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.REVIEWER))", + "returns": "", + "line": 437, + "doc": "", + "decorator": "router.post('/{request_id}/ready-for-release', response_model=RequestRead)", + "errors": [ + "HTTPException(status_code=404, detail='Request not found')", + "HTTPException(status_code=400, detail=f\"Can only mark ready for release from 'in_review' status, current: {req.status.value}\")" + ] + }, + { + "method": "POST", + "path": "/requests/{request_id}/approve", + "router": "router", + "prefix_resolved": true, + "name": "approve_request", + "signature": "request_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.REVIEWER))", + "returns": "", + "line": 481, + "doc": "", + "decorator": "router.post('/{request_id}/approve', response_model=RequestRead)", + "errors": [ + "HTTPException(status_code=404, detail='Request not found')", + "HTTPException(status_code=400, detail=f\"Can only approve from 'drafted' or 'ready_for_release' status, current: {req.status.value}\")" + ] + }, + { + "method": "POST", + "path": "/requests/{request_id}/reject", + "router": "router", + "prefix_resolved": true, + "name": "reject_request", + "signature": "request_id: uuid.UUID, reason: str='', session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.REVIEWER))", + "returns": "", + "line": 525, + "doc": "", + "decorator": "router.post('/{request_id}/reject', response_model=RequestRead)", + "errors": [ + "HTTPException(status_code=404, detail='Request not found')", + "HTTPException(status_code=400, detail=\"Can only reject from 'in_review' status\")" + ] + }, + { + "method": "GET", + "path": "/requests/{request_id}/timeline", + "router": "router", + "prefix_resolved": true, + "name": "get_timeline", + "signature": "request_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 571, + "doc": "", + "decorator": "router.get('/{request_id}/timeline', response_model=list[TimelineEventRead])", + "errors": [ + "HTTPException(status_code=404, detail='Request not found')" + ] + }, + { + "method": "POST", + "path": "/requests/{request_id}/timeline", + "router": "router", + "prefix_resolved": true, + "name": "add_timeline_event", + "signature": "request_id: uuid.UUID, event: TimelineEventCreate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 590, + "doc": "", + "decorator": "router.post('/{request_id}/timeline', response_model=TimelineEventRead, status_code=201)", + "errors": [ + "HTTPException(status_code=404, detail='Request not found')" + ] + }, + { + "method": "GET", + "path": "/requests/{request_id}/messages", + "router": "router", + "prefix_resolved": true, + "name": "get_messages", + "signature": "request_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 622, + "doc": "", + "decorator": "router.get('/{request_id}/messages', response_model=list[MessageRead])", + "errors": [ + "HTTPException(status_code=404, detail='Request not found')" + ] + }, + { + "method": "POST", + "path": "/requests/{request_id}/messages", + "router": "router", + "prefix_resolved": true, + "name": "add_message", + "signature": "request_id: uuid.UUID, msg: MessageCreate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 641, + "doc": "", + "decorator": "router.post('/{request_id}/messages', response_model=MessageRead, status_code=201)", + "errors": [ + "HTTPException(status_code=404, detail='Request not found')" + ] + }, + { + "method": "GET", + "path": "/requests/{request_id}/fees", + "router": "router", + "prefix_resolved": true, + "name": "get_fees", + "signature": "request_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 672, + "doc": "", + "decorator": "router.get('/{request_id}/fees', response_model=list[FeeLineItemRead])", + "errors": [ + "HTTPException(status_code=404, detail='Request not found')" + ] + }, + { + "method": "POST", + "path": "/requests/{request_id}/fees", + "router": "router", + "prefix_resolved": true, + "name": "add_fee", + "signature": "request_id: uuid.UUID, fee: FeeLineItemCreate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 692, + "doc": "", + "decorator": "router.post('/{request_id}/fees', response_model=FeeLineItemRead, status_code=201)", + "errors": [ + "HTTPException(status_code=404, detail='Request not found')" + ] + }, + { + "method": "POST", + "path": "/requests/{request_id}/estimate-fees", + "router": "router", + "prefix_resolved": true, + "name": "estimate_fees", + "signature": "request_id: uuid.UUID, body: FeeEstimateRequest, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 748, + "doc": "Estimate fees based on staff-entered page count and fee schedule.\n\nPage count is a manual staff estimate \u2014 not inferred from ingested docs.", + "decorator": "router.post('/{request_id}/estimate-fees', response_model=FeeEstimateResponse)", + "errors": [ + "HTTPException(status_code=404, detail='Request not found')", + "HTTPException(status_code=404, detail='Fee schedule not found')" + ] + }, + { + "method": "POST", + "path": "/requests/{request_id}/fee-waiver", + "router": "router", + "prefix_resolved": true, + "name": "create_fee_waiver", + "signature": "request_id: uuid.UUID, body: FeeWaiverCreateRequest, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 803, + "doc": "Request a fee waiver for this records request.", + "decorator": "router.post('/{request_id}/fee-waiver', response_model=FeeWaiverReadResponse, status_code=201)", + "errors": [ + "HTTPException(status_code=404, detail='Request not found')", + "HTTPException(status_code=422, detail=f'Invalid waiver_type: {body.waiver_type}')" + ] + }, + { + "method": "PATCH", + "path": "/requests/{request_id}/fee-waiver/{waiver_id}", + "router": "router", + "prefix_resolved": true, + "name": "review_fee_waiver", + "signature": "request_id: uuid.UUID, waiver_id: uuid.UUID, body: FeeWaiverReviewRequest, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.REVIEWER))", + "returns": "", + "line": 848, + "doc": "Approve or deny a fee waiver. Reviewer/Admin only.", + "decorator": "router.patch('/{request_id}/fee-waiver/{waiver_id}', response_model=FeeWaiverReadResponse)", + "errors": [ + "HTTPException(status_code=404, detail='Request not found')", + "HTTPException(status_code=404, detail='Fee waiver not found')", + "HTTPException(status_code=422, detail=\"Status must be 'approved' or 'denied'\")" + ] + }, + { + "method": "POST", + "path": "/requests/{request_id}/response-letter", + "router": "router", + "prefix_resolved": true, + "name": "generate_response_letter", + "signature": "request_id: uuid.UUID, data: ResponseLetterCreate | None=None, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 1138, + "doc": "Generate a draft response letter for a records request.\n\nAttempts LLM generation via Ollama first; falls back to a structured\ntemplate if the LLM is unavailable.", + "decorator": "router.post('/{request_id}/response-letter', response_model=ResponseLetterRead, status_code=201)", + "errors": [ + "HTTPException(status_code=404, detail='Request not found')" + ] + }, + { + "method": "GET", + "path": "/requests/{request_id}/response-letter", + "router": "router", + "prefix_resolved": true, + "name": "get_response_letter", + "signature": "request_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 1203, + "doc": "Get the latest response letter for a request.", + "decorator": "router.get('/{request_id}/response-letter', response_model=ResponseLetterRead)", + "errors": [ + "HTTPException(status_code=404, detail='Request not found')", + "HTTPException(status_code=404, detail='No response letter found for this request')" + ] + }, + { + "method": "PATCH", + "path": "/requests/{request_id}/response-letter/{letter_id}", + "router": "router", + "prefix_resolved": true, + "name": "update_response_letter", + "signature": "request_id: uuid.UUID, letter_id: uuid.UUID, data: ResponseLetterUpdate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 1232, + "doc": "Update a response letter's edited content or status.\n\nStatus changes to 'approved' require REVIEWER role.", + "decorator": "router.patch('/{request_id}/response-letter/{letter_id}', response_model=ResponseLetterRead)", + "errors": [ + "HTTPException(status_code=404, detail='Request not found')", + "HTTPException(status_code=404, detail='Response letter not found')", + "HTTPException(status_code=400, detail='Invalid status. Must be draft, approved, or sent')", + "HTTPException(status_code=403, detail='Only reviewers or admins can approve response letters')" + ] + } + ], + "models": [ + { + "name": "FeeEstimateRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "page_count", + "type": "int", + "default": "" + }, + { + "name": "fee_schedule_id", + "type": "uuid.UUID", + "default": "" + } + ], + "line": 734, + "doc": "" + }, + { + "name": "FeeEstimateResponse", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "page_count", + "type": "int", + "default": "" + }, + { + "name": "unit_price", + "type": "float", + "default": "" + }, + { + "name": "total", + "type": "float", + "default": "" + }, + { + "name": "fee_type", + "type": "str", + "default": "" + }, + { + "name": "description", + "type": "str", + "default": "" + } + ], + "line": 739, + "doc": "" + }, + { + "name": "FeeWaiverCreateRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "waiver_type", + "type": "str", + "default": "" + }, + { + "name": "reason", + "type": "str", + "default": "" + } + ], + "line": 780, + "doc": "" + }, + { + "name": "FeeWaiverReadResponse", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "request_id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "waiver_type", + "type": "str", + "default": "" + }, + { + "name": "reason", + "type": "str", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "review_notes", + "type": "str | None", + "default": "None" + }, + { + "name": "created_at", + "type": "str", + "default": "" + } + ], + "line": 785, + "doc": "" + }, + { + "name": "FeeWaiverReviewRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "review_notes", + "type": "str | None", + "default": "None" + } + ], + "line": 797, + "doc": "" + } + ], + "configuration": [ + { + "variable": "LLM_MODEL", + "default": "", + "line": 992 + } + ] + }, + { + "source": "installed-owned-source/app/requests/service.py", + "sha256": "117aa98e60d09824799b2696dfce65d9ade7d60b58a35df3e8664add3cccca66", + "routes": [], + "models": [ + { + "name": "RequestIntake", + "bases": [], + "fields": [ + { + "name": "requester_name", + "type": "str", + "default": "" + }, + { + "name": "description", + "type": "str", + "default": "" + }, + { + "name": "requester_email", + "type": "str | None", + "default": "None" + }, + { + "name": "requester_phone", + "type": "str | None", + "default": "None" + }, + { + "name": "requester_type", + "type": "str | None", + "default": "None" + }, + { + "name": "statutory_deadline", + "type": "datetime | None", + "default": "None" + }, + { + "name": "priority", + "type": "str", + "default": "'normal'" + }, + { + "name": "scope_assessment", + "type": "str | None", + "default": "None" + }, + { + "name": "department_id", + "type": "uuid.UUID | None", + "default": "None" + } + ], + "line": 19, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/requests/workflow.py", + "sha256": "3d0ec7c9e4dd987beab5c1ca89f7b4c8e45f0a24075b64ce7694be50a901a72b", + "routes": [], + "models": [ + { + "name": "RecordsActor", + "bases": [], + "fields": [ + { + "name": "user", + "type": "User", + "default": "" + }, + { + "name": "role", + "type": "str", + "default": "" + } + ], + "line": 25, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/schemas/__init__.py", + "sha256": "7cd5688441a82abcca61eda136c29d767a8043bb0a3f7d9f0696a6443f675372", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/schemas/analytics.py", + "sha256": "1b2f2d7507f1057d010c203ec7c7fa6037d7adfd1e5be4b7323402dca5693a69", + "routes": [], + "models": [ + { + "name": "OperationalMetrics", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "average_response_time_days", + "type": "float | None", + "default": "" + }, + { + "name": "median_response_time_days", + "type": "float | None", + "default": "" + }, + { + "name": "requests_by_status", + "type": "dict[str, int]", + "default": "" + }, + { + "name": "requests_by_department", + "type": "dict[str, int]", + "default": "" + }, + { + "name": "deadline_compliance_rate", + "type": "float", + "default": "" + }, + { + "name": "total_open", + "type": "int", + "default": "" + }, + { + "name": "total_closed", + "type": "int", + "default": "" + }, + { + "name": "total_overdue", + "type": "int", + "default": "" + }, + { + "name": "clarification_frequency", + "type": "float", + "default": "" + }, + { + "name": "top_request_topics", + "type": "list[str]", + "default": "" + } + ], + "line": 4, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/schemas/audit.py", + "sha256": "95b0e336b85ffdb37079359ab68aa04b9ed974e964dc9a943cbef132f99e327d", + "routes": [], + "models": [ + { + "name": "AuditLogRead", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "id", + "type": "int", + "default": "" + }, + { + "name": "prev_hash", + "type": "str", + "default": "" + }, + { + "name": "entry_hash", + "type": "str", + "default": "" + }, + { + "name": "timestamp", + "type": "datetime", + "default": "" + }, + { + "name": "user_id", + "type": "uuid.UUID | None", + "default": "" + }, + { + "name": "action", + "type": "str", + "default": "" + }, + { + "name": "resource_type", + "type": "str", + "default": "" + }, + { + "name": "resource_id", + "type": "str | None", + "default": "" + }, + { + "name": "details", + "type": "dict | None", + "default": "" + }, + { + "name": "ai_generated", + "type": "bool", + "default": "" + } + ], + "line": 7, + "doc": "" + }, + { + "name": "AuditLogQuery", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "action", + "type": "str | None", + "default": "None" + }, + { + "name": "resource_type", + "type": "str | None", + "default": "None" + }, + { + "name": "user_id", + "type": "uuid.UUID | None", + "default": "None" + }, + { + "name": "start_date", + "type": "datetime | None", + "default": "None" + }, + { + "name": "end_date", + "type": "datetime | None", + "default": "None" + }, + { + "name": "limit", + "type": "int", + "default": "Field(default=50, le=200)" + }, + { + "name": "offset", + "type": "int", + "default": "0" + } + ], + "line": 22, + "doc": "" + }, + { + "name": "AuditChainVerification", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "is_valid", + "type": "bool", + "default": "" + }, + { + "name": "entries_checked", + "type": "int", + "default": "" + }, + { + "name": "error_message", + "type": "str", + "default": "" + } + ], + "line": 32, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/schemas/city_profile.py", + "sha256": "b3187fb30ee67b36d4eb2794c2e36b31a49f01b9ad53b0db1a0d9bf87b2c2b2d", + "routes": [], + "models": [ + { + "name": "CityProfileCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "city_name", + "type": "str", + "default": "" + }, + { + "name": "state", + "type": "str | None", + "default": "None" + }, + { + "name": "county", + "type": "str | None", + "default": "None" + }, + { + "name": "population_band", + "type": "str | None", + "default": "None" + }, + { + "name": "email_platform", + "type": "str | None", + "default": "None" + }, + { + "name": "has_dedicated_it", + "type": "bool | None", + "default": "None" + }, + { + "name": "monthly_request_volume", + "type": "str | None", + "default": "None" + }, + { + "name": "profile_data", + "type": "dict", + "default": "{}" + }, + { + "name": "gap_map", + "type": "dict", + "default": "{}" + } + ], + "line": 7, + "doc": "" + }, + { + "name": "CityProfileRead", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "city_name", + "type": "str", + "default": "" + }, + { + "name": "state", + "type": "str | None", + "default": "" + }, + { + "name": "county", + "type": "str | None", + "default": "" + }, + { + "name": "population_band", + "type": "str | None", + "default": "" + }, + { + "name": "email_platform", + "type": "str | None", + "default": "" + }, + { + "name": "has_dedicated_it", + "type": "bool | None", + "default": "" + }, + { + "name": "monthly_request_volume", + "type": "str | None", + "default": "" + }, + { + "name": "onboarding_status", + "type": "str", + "default": "" + }, + { + "name": "profile_data", + "type": "dict", + "default": "" + }, + { + "name": "gap_map", + "type": "dict", + "default": "" + }, + { + "name": "created_at", + "type": "datetime", + "default": "" + }, + { + "name": "updated_at", + "type": "datetime", + "default": "" + } + ], + "line": 23, + "doc": "" + }, + { + "name": "CityProfileUpdate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "city_name", + "type": "str | None", + "default": "None" + }, + { + "name": "state", + "type": "str | None", + "default": "None" + }, + { + "name": "county", + "type": "str | None", + "default": "None" + }, + { + "name": "population_band", + "type": "str | None", + "default": "None" + }, + { + "name": "email_platform", + "type": "str | None", + "default": "None" + }, + { + "name": "has_dedicated_it", + "type": "bool | None", + "default": "None" + }, + { + "name": "monthly_request_volume", + "type": "str | None", + "default": "None" + }, + { + "name": "onboarding_status", + "type": "str | None", + "default": "None" + }, + { + "name": "profile_data", + "type": "dict | None", + "default": "None" + }, + { + "name": "gap_map", + "type": "dict | None", + "default": "None" + } + ], + "line": 42, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/schemas/connectors/__init__.py", + "sha256": "bc0d25288808206c0bad0ff842e9e68f6aa298f194cec977e540cc20438d79ec", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/schemas/connectors/odbc.py", + "sha256": "d21cc39b1dc8567b6615bf14c3ff1a44c43cbedd851ce27acfe52e92015ede65", + "routes": [], + "models": [ + { + "name": "ODBCConfig", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "connector_type", + "type": "Literal['odbc']", + "default": "'odbc'" + }, + { + "name": "connection_string", + "type": "str", + "default": "" + }, + { + "name": "table_name", + "type": "str", + "default": "" + }, + { + "name": "pk_column", + "type": "str", + "default": "" + }, + { + "name": "modified_column", + "type": "Optional[str]", + "default": "None" + }, + { + "name": "columns", + "type": "Optional[list[str]]", + "default": "None" + }, + { + "name": "batch_size", + "type": "int", + "default": "Field(default=500, ge=1, le=10000)" + }, + { + "name": "max_row_bytes", + "type": "int", + "default": "Field(default=10485760, ge=1)" + } + ], + "line": 17, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/schemas/connectors/rest_api.py", + "sha256": "a14767ee188a3ff4ca34b54f73f5c6059a146628d559de016402e3b3cf04793b", + "routes": [], + "models": [ + { + "name": "RestApiConfig", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "connector_type", + "type": "Literal['rest_api']", + "default": "'rest_api'" + }, + { + "name": "base_url", + "type": "AnyHttpUrl", + "default": "" + }, + { + "name": "endpoint_path", + "type": "str", + "default": "Field(default='/', description='Path appended to base_url')" + }, + { + "name": "auth_method", + "type": "Literal['none', 'api_key', 'bearer', 'oauth2', 'basic']", + "default": "" + }, + { + "name": "api_key", + "type": "Optional[str]", + "default": "None" + }, + { + "name": "key_location", + "type": "Literal['header', 'query']", + "default": "'header'" + }, + { + "name": "key_header", + "type": "str", + "default": "'X-API-Key'" + }, + { + "name": "token", + "type": "Optional[str]", + "default": "None" + }, + { + "name": "client_id", + "type": "Optional[str]", + "default": "None" + }, + { + "name": "client_secret", + "type": "Optional[str]", + "default": "None" + }, + { + "name": "token_url", + "type": "Optional[AnyHttpUrl]", + "default": "None" + }, + { + "name": "username", + "type": "Optional[str]", + "default": "None" + }, + { + "name": "password", + "type": "Optional[str]", + "default": "None" + }, + { + "name": "pagination_style", + "type": "Literal['none', 'page', 'offset', 'cursor']", + "default": "'none'" + }, + { + "name": "page_param", + "type": "str", + "default": "'page'" + }, + { + "name": "offset_param", + "type": "str", + "default": "'offset'" + }, + { + "name": "limit_param", + "type": "str", + "default": "'limit'" + }, + { + "name": "page_size", + "type": "int", + "default": "Field(default=100, ge=1, le=10000)" + }, + { + "name": "cursor_field", + "type": "str", + "default": "'next'" + }, + { + "name": "response_format", + "type": "Literal['json', 'xml', 'csv']", + "default": "'json'" + }, + { + "name": "results_field", + "type": "Optional[str]", + "default": "None" + }, + { + "name": "data_key", + "type": "Optional[str]", + "default": "None" + }, + { + "name": "id_field", + "type": "str", + "default": "'id'" + }, + { + "name": "envelope_excludes", + "type": "list[str]", + "default": "[]" + }, + { + "name": "since_field", + "type": "Optional[str]", + "default": "None" + }, + { + "name": "since_format", + "type": "str", + "default": "'%Y-%m-%dT%H:%M:%SZ'" + }, + { + "name": "max_records", + "type": "int", + "default": "Field(default=10000, ge=1)" + }, + { + "name": "max_response_bytes", + "type": "int", + "default": "Field(default=52428800, ge=1)" + } + ], + "line": 5, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/schemas/department.py", + "sha256": "5e45ab7a46abbb6a40e6c7d22b928aa65bdc0fabab5a424ee988fd31ec672c30", + "routes": [], + "models": [ + { + "name": "DepartmentCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "name", + "type": "str", + "default": "" + }, + { + "name": "code", + "type": "str", + "default": "" + }, + { + "name": "contact_email", + "type": "str | None", + "default": "None" + } + ], + "line": 6, + "doc": "" + }, + { + "name": "DepartmentRead", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "name", + "type": "str", + "default": "" + }, + { + "name": "code", + "type": "str", + "default": "" + }, + { + "name": "contact_email", + "type": "str | None", + "default": "" + }, + { + "name": "created_at", + "type": "datetime", + "default": "" + } + ], + "line": 12, + "doc": "" + }, + { + "name": "DepartmentUpdate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "name", + "type": "str | None", + "default": "None" + }, + { + "name": "code", + "type": "str | None", + "default": "None" + }, + { + "name": "contact_email", + "type": "str | None", + "default": "None" + } + ], + "line": 21, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/schemas/document.py", + "sha256": "139e5160eac328e5d5499c935a2ee4bbc8a7eee5a24cfe1fc7e08b1aca0fbc8a", + "routes": [], + "models": [ + { + "name": "DataSourceCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "name", + "type": "str", + "default": "" + }, + { + "name": "source_type", + "type": "SourceType", + "default": "" + }, + { + "name": "connection_config", + "type": "dict", + "default": "{}" + }, + { + "name": "sync_schedule", + "type": "str | None", + "default": "None" + }, + { + "name": "schedule_enabled", + "type": "bool", + "default": "True" + } + ], + "line": 7, + "doc": "" + }, + { + "name": "DataSourceRead", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "name", + "type": "str", + "default": "" + }, + { + "name": "source_type", + "type": "SourceType", + "default": "" + }, + { + "name": "sync_schedule", + "type": "str | None", + "default": "None" + }, + { + "name": "schedule_enabled", + "type": "bool", + "default": "True" + }, + { + "name": "next_sync_at", + "type": "datetime | None", + "default": "None" + }, + { + "name": "is_active", + "type": "bool", + "default": "" + }, + { + "name": "created_by", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "created_at", + "type": "datetime", + "default": "" + }, + { + "name": "last_ingestion_at", + "type": "datetime | None", + "default": "" + }, + { + "name": "last_sync_at", + "type": "datetime | None", + "default": "None" + }, + { + "name": "last_sync_status", + "type": "str | None", + "default": "None" + }, + { + "name": "last_error_message", + "type": "str | None", + "default": "None" + }, + { + "name": "consecutive_failure_count", + "type": "int", + "default": "0" + }, + { + "name": "sync_paused", + "type": "bool", + "default": "False" + }, + { + "name": "health_status", + "type": "str", + "default": "'healthy'" + }, + { + "name": "active_failure_count", + "type": "int", + "default": "0" + }, + { + "name": "connector_type", + "type": "str | None", + "default": "None" + }, + { + "name": "updated_at", + "type": "datetime | None", + "default": "None" + } + ], + "line": 23, + "doc": "Redacted datasource shape \u2014 safe for non-admin roles. connection_config omitted." + }, + { + "name": "DataSourceAdminRead", + "bases": [ + "DataSourceRead" + ], + "fields": [ + { + "name": "connection_config", + "type": "dict", + "default": "" + } + ], + "line": 52, + "doc": "Full datasource shape including connection_config. Returned only by admin-gated endpoints." + }, + { + "name": "DataSourceUpdate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "name", + "type": "str | None", + "default": "None" + }, + { + "name": "connection_config", + "type": "dict | None", + "default": "None" + }, + { + "name": "sync_schedule", + "type": "str | None", + "default": "None" + }, + { + "name": "schedule_enabled", + "type": "bool | None", + "default": "None" + }, + { + "name": "is_active", + "type": "bool | None", + "default": "None" + } + ], + "line": 57, + "doc": "" + }, + { + "name": "DocumentRead", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "source_id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "source_path", + "type": "str", + "default": "" + }, + { + "name": "filename", + "type": "str", + "default": "" + }, + { + "name": "file_type", + "type": "str", + "default": "" + }, + { + "name": "file_hash", + "type": "str", + "default": "" + }, + { + "name": "file_size", + "type": "int", + "default": "" + }, + { + "name": "ingestion_status", + "type": "IngestionStatus", + "default": "" + }, + { + "name": "ingestion_error", + "type": "str | None", + "default": "" + }, + { + "name": "chunk_count", + "type": "int", + "default": "" + }, + { + "name": "ingested_at", + "type": "datetime | None", + "default": "" + }, + { + "name": "connector_type", + "type": "str | None", + "default": "None" + }, + { + "name": "updated_at", + "type": "datetime | None", + "default": "None" + } + ], + "line": 73, + "doc": "" + }, + { + "name": "DocumentChunkRead", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "document_id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "chunk_index", + "type": "int", + "default": "" + }, + { + "name": "content_text", + "type": "str", + "default": "" + }, + { + "name": "token_count", + "type": "int", + "default": "" + }, + { + "name": "page_number", + "type": "int | None", + "default": "" + } + ], + "line": 90, + "doc": "" + }, + { + "name": "IngestionStats", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "total_sources", + "type": "int", + "default": "" + }, + { + "name": "active_sources", + "type": "int", + "default": "" + }, + { + "name": "total_documents", + "type": "int", + "default": "" + }, + { + "name": "documents_by_status", + "type": "dict[str, int]", + "default": "" + }, + { + "name": "total_chunks", + "type": "int", + "default": "" + } + ], + "line": 100, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/schemas/exemption.py", + "sha256": "7cd5c0e1d1c2eaca8dace50b570ac06832765cbb3c3df148b84d3a12188f4664", + "routes": [], + "models": [ + { + "name": "ExemptionRuleCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "state_code", + "type": "str", + "default": "" + }, + { + "name": "category", + "type": "str", + "default": "" + }, + { + "name": "rule_type", + "type": "RuleType", + "default": "" + }, + { + "name": "rule_definition", + "type": "str", + "default": "" + }, + { + "name": "description", + "type": "str | None", + "default": "None" + }, + { + "name": "enabled", + "type": "bool", + "default": "True" + } + ], + "line": 8, + "doc": "" + }, + { + "name": "ExemptionRuleRead", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "state_code", + "type": "str", + "default": "" + }, + { + "name": "category", + "type": "str", + "default": "" + }, + { + "name": "rule_type", + "type": "RuleType", + "default": "" + }, + { + "name": "rule_definition", + "type": "str", + "default": "" + }, + { + "name": "description", + "type": "str | None", + "default": "" + }, + { + "name": "enabled", + "type": "bool", + "default": "" + }, + { + "name": "version", + "type": "int", + "default": "1" + }, + { + "name": "created_by", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "created_at", + "type": "datetime", + "default": "" + } + ], + "line": 17, + "doc": "" + }, + { + "name": "ExemptionRuleUpdate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "rule_definition", + "type": "str | None", + "default": "None" + }, + { + "name": "description", + "type": "str | None", + "default": "None" + }, + { + "name": "enabled", + "type": "bool | None", + "default": "None" + } + ], + "line": 31, + "doc": "" + }, + { + "name": "ExemptionFlagRead", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "chunk_id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "rule_id", + "type": "uuid.UUID | None", + "default": "" + }, + { + "name": "request_id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "category", + "type": "str", + "default": "" + }, + { + "name": "matched_text", + "type": "str | None", + "default": "" + }, + { + "name": "confidence", + "type": "float", + "default": "" + }, + { + "name": "status", + "type": "FlagStatus", + "default": "" + }, + { + "name": "reviewed_by", + "type": "uuid.UUID | None", + "default": "" + }, + { + "name": "reviewed_at", + "type": "datetime | None", + "default": "" + }, + { + "name": "review_reason", + "type": "str | None", + "default": "" + }, + { + "name": "created_at", + "type": "datetime", + "default": "" + } + ], + "line": 37, + "doc": "" + }, + { + "name": "ExemptionFlagReview", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "status", + "type": "FlagStatus", + "default": "" + }, + { + "name": "review_reason", + "type": "str | None", + "default": "None" + } + ], + "line": 53, + "doc": "" + }, + { + "name": "DisclosureTemplateCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "template_type", + "type": "str", + "default": "" + }, + { + "name": "state_code", + "type": "str | None", + "default": "None" + }, + { + "name": "content", + "type": "str", + "default": "" + } + ], + "line": 58, + "doc": "" + }, + { + "name": "DisclosureTemplateRead", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "template_type", + "type": "str", + "default": "" + }, + { + "name": "state_code", + "type": "str | None", + "default": "" + }, + { + "name": "content", + "type": "str", + "default": "" + }, + { + "name": "version", + "type": "int", + "default": "" + }, + { + "name": "updated_by", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "updated_at", + "type": "datetime", + "default": "" + } + ], + "line": 64, + "doc": "" + }, + { + "name": "ExemptionDashboard", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "total_flags", + "type": "int", + "default": "" + }, + { + "name": "by_status", + "type": "dict[str, int]", + "default": "" + }, + { + "name": "by_category", + "type": "dict[str, int]", + "default": "" + }, + { + "name": "acceptance_rate", + "type": "float", + "default": "" + }, + { + "name": "total_rules", + "type": "int", + "default": "" + }, + { + "name": "active_rules", + "type": "int", + "default": "" + } + ], + "line": 75, + "doc": "" + }, + { + "name": "ExemptionAccuracyReport", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "category", + "type": "str", + "default": "" + }, + { + "name": "total_flags", + "type": "int", + "default": "" + }, + { + "name": "accepted", + "type": "int", + "default": "" + }, + { + "name": "rejected", + "type": "int", + "default": "" + }, + { + "name": "pending", + "type": "int", + "default": "" + }, + { + "name": "acceptance_rate", + "type": "float", + "default": "" + } + ], + "line": 84, + "doc": "" + }, + { + "name": "DisclosureTemplateRendered", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "template_type", + "type": "str", + "default": "" + }, + { + "name": "rendered_content", + "type": "str", + "default": "" + }, + { + "name": "has_unresolved_variables", + "type": "bool", + "default": "" + } + ], + "line": 93, + "doc": "" + }, + { + "name": "DisclosureTemplateUpdate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "content", + "type": "str | None", + "default": "None" + }, + { + "name": "state_code", + "type": "str | None", + "default": "None" + } + ], + "line": 100, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/schemas/fee_schedule.py", + "sha256": "132fca7b2f2484f924464e8c01bec43674d8a6fc579202849cf73e43630adf70", + "routes": [], + "models": [ + { + "name": "FeeScheduleCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "jurisdiction", + "type": "str", + "default": "" + }, + { + "name": "fee_type", + "type": "str", + "default": "" + }, + { + "name": "amount", + "type": "float", + "default": "" + }, + { + "name": "description", + "type": "str | None", + "default": "None" + }, + { + "name": "effective_date", + "type": "date | None", + "default": "None" + } + ], + "line": 6, + "doc": "" + }, + { + "name": "FeeScheduleRead", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "jurisdiction", + "type": "str", + "default": "" + }, + { + "name": "fee_type", + "type": "str", + "default": "" + }, + { + "name": "amount", + "type": "float", + "default": "" + }, + { + "name": "description", + "type": "str | None", + "default": "" + }, + { + "name": "effective_date", + "type": "date | None", + "default": "" + }, + { + "name": "created_by", + "type": "uuid.UUID | None", + "default": "" + }, + { + "name": "created_at", + "type": "datetime", + "default": "" + } + ], + "line": 14, + "doc": "" + }, + { + "name": "FeeScheduleUpdate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "fee_type", + "type": "str | None", + "default": "None" + }, + { + "name": "amount", + "type": "float | None", + "default": "None" + }, + { + "name": "description", + "type": "str | None", + "default": "None" + }, + { + "name": "effective_date", + "type": "date | None", + "default": "None" + } + ], + "line": 26, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/schemas/notifications.py", + "sha256": "61d74c4b0977679c0739a374997ae5d49792d47f0f469baf6c422b77fd993fa3", + "routes": [], + "models": [ + { + "name": "NotificationTemplateCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "event_type", + "type": "str", + "default": "" + }, + { + "name": "channel", + "type": "str", + "default": "'email'" + }, + { + "name": "subject_template", + "type": "str", + "default": "" + }, + { + "name": "body_template", + "type": "str", + "default": "" + } + ], + "line": 7, + "doc": "" + }, + { + "name": "NotificationTemplateRead", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "event_type", + "type": "str", + "default": "" + }, + { + "name": "channel", + "type": "str", + "default": "" + }, + { + "name": "subject_template", + "type": "str", + "default": "" + }, + { + "name": "body_template", + "type": "str", + "default": "" + }, + { + "name": "is_active", + "type": "bool", + "default": "" + }, + { + "name": "created_at", + "type": "datetime", + "default": "" + } + ], + "line": 14, + "doc": "" + }, + { + "name": "NotificationTemplateUpdate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "subject_template", + "type": "str | None", + "default": "None" + }, + { + "name": "body_template", + "type": "str | None", + "default": "None" + }, + { + "name": "is_active", + "type": "bool | None", + "default": "None" + } + ], + "line": 26, + "doc": "" + }, + { + "name": "NotificationLogRead", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "template_id", + "type": "uuid.UUID | None", + "default": "" + }, + { + "name": "recipient_email", + "type": "str", + "default": "" + }, + { + "name": "request_id", + "type": "uuid.UUID | None", + "default": "" + }, + { + "name": "channel", + "type": "str", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "sent_at", + "type": "datetime | None", + "default": "" + }, + { + "name": "error_message", + "type": "str | None", + "default": "" + }, + { + "name": "created_at", + "type": "datetime", + "default": "" + } + ], + "line": 32, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/schemas/request.py", + "sha256": "7c632f8eaaa7198a74edf0860e25fcf2ef3fa8c8a5eb15fd55f633089787b8cd", + "routes": [], + "models": [ + { + "name": "RequestCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "requester_name", + "type": "str", + "default": "Field(..., max_length=255)" + }, + { + "name": "requester_email", + "type": "str | None", + "default": "Field(None, max_length=255)" + }, + { + "name": "requester_phone", + "type": "str | None", + "default": "Field(None, max_length=50)" + }, + { + "name": "requester_type", + "type": "str | None", + "default": "Field(None, max_length=100)" + }, + { + "name": "description", + "type": "str", + "default": "Field(..., max_length=10000)" + }, + { + "name": "statutory_deadline", + "type": "datetime | None", + "default": "None" + }, + { + "name": "priority", + "type": "str", + "default": "'normal'" + }, + { + "name": "scope_assessment", + "type": "str | None", + "default": "Field(None, pattern='^(narrow|moderate|broad)$')" + }, + { + "name": "department_id", + "type": "uuid.UUID | None", + "default": "None" + } + ], + "line": 8, + "doc": "" + }, + { + "name": "RequestRead", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "requester_name", + "type": "str", + "default": "" + }, + { + "name": "requester_email", + "type": "str | None", + "default": "" + }, + { + "name": "requester_phone", + "type": "str | None", + "default": "None" + }, + { + "name": "requester_type", + "type": "str | None", + "default": "None" + }, + { + "name": "date_received", + "type": "datetime", + "default": "" + }, + { + "name": "statutory_deadline", + "type": "datetime | None", + "default": "" + }, + { + "name": "description", + "type": "str", + "default": "" + }, + { + "name": "status", + "type": "RequestStatus", + "default": "" + }, + { + "name": "assigned_to", + "type": "uuid.UUID | None", + "default": "" + }, + { + "name": "created_by", + "type": "uuid.UUID | None", + "default": "" + }, + { + "name": "created_at", + "type": "datetime", + "default": "" + }, + { + "name": "response_draft", + "type": "str | None", + "default": "" + }, + { + "name": "review_notes", + "type": "str | None", + "default": "" + }, + { + "name": "department_id", + "type": "uuid.UUID | None", + "default": "None" + }, + { + "name": "estimated_fee", + "type": "float | None", + "default": "None" + }, + { + "name": "fee_status", + "type": "str | None", + "default": "None" + }, + { + "name": "fee_waiver_requested", + "type": "bool", + "default": "False" + }, + { + "name": "priority", + "type": "str", + "default": "'normal'" + }, + { + "name": "scope_assessment", + "type": "str | None", + "default": "None" + }, + { + "name": "closed_at", + "type": "datetime | None", + "default": "None" + }, + { + "name": "closure_reason", + "type": "str | None", + "default": "None" + } + ], + "line": 20, + "doc": "" + }, + { + "name": "RequestUpdate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "description", + "type": "str | None", + "default": "None" + }, + { + "name": "status", + "type": "RequestStatus | None", + "default": "None" + }, + { + "name": "assigned_to", + "type": "uuid.UUID | None", + "default": "None" + }, + { + "name": "response_draft", + "type": "str | None", + "default": "None" + }, + { + "name": "statutory_deadline", + "type": "datetime | None", + "default": "None" + }, + { + "name": "scope_assessment", + "type": "str | None", + "default": "None" + } + ], + "line": 47, + "doc": "" + }, + { + "name": "RequestDocumentAdd", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "document_id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "relevance_note", + "type": "str | None", + "default": "None" + } + ], + "line": 56, + "doc": "" + }, + { + "name": "RequestDocumentRead", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "request_id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "document_id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "relevance_note", + "type": "str | None", + "default": "" + }, + { + "name": "exemption_flags", + "type": "dict | None", + "default": "" + }, + { + "name": "inclusion_status", + "type": "InclusionStatus", + "default": "" + }, + { + "name": "attached_at", + "type": "datetime", + "default": "" + }, + { + "name": "attached_by", + "type": "uuid.UUID", + "default": "" + } + ], + "line": 61, + "doc": "" + }, + { + "name": "RequestStats", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "total_requests", + "type": "int", + "default": "" + }, + { + "name": "by_status", + "type": "dict[str, int]", + "default": "" + }, + { + "name": "approaching_deadline", + "type": "int", + "default": "" + }, + { + "name": "overdue", + "type": "int", + "default": "" + } + ], + "line": 74, + "doc": "" + }, + { + "name": "TimelineEventCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "event_type", + "type": "str", + "default": "" + }, + { + "name": "description", + "type": "str", + "default": "" + }, + { + "name": "internal_note", + "type": "str | None", + "default": "None" + } + ], + "line": 81, + "doc": "" + }, + { + "name": "TimelineEventRead", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "request_id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "event_type", + "type": "str", + "default": "" + }, + { + "name": "actor_id", + "type": "uuid.UUID | None", + "default": "" + }, + { + "name": "actor_role", + "type": "str | None", + "default": "" + }, + { + "name": "description", + "type": "str", + "default": "" + }, + { + "name": "internal_note", + "type": "str | None", + "default": "" + }, + { + "name": "created_at", + "type": "datetime", + "default": "" + } + ], + "line": 87, + "doc": "" + }, + { + "name": "MessageCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "message_text", + "type": "str", + "default": "" + }, + { + "name": "is_internal", + "type": "bool", + "default": "False" + } + ], + "line": 99, + "doc": "" + }, + { + "name": "MessageRead", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "request_id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "sender_type", + "type": "str", + "default": "" + }, + { + "name": "sender_id", + "type": "uuid.UUID | None", + "default": "" + }, + { + "name": "message_text", + "type": "str", + "default": "" + }, + { + "name": "is_internal", + "type": "bool", + "default": "" + }, + { + "name": "created_at", + "type": "datetime", + "default": "" + } + ], + "line": 104, + "doc": "" + }, + { + "name": "FeeLineItemCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "description", + "type": "str", + "default": "" + }, + { + "name": "quantity", + "type": "int", + "default": "1" + }, + { + "name": "unit_price", + "type": "float", + "default": "" + }, + { + "name": "fee_schedule_id", + "type": "uuid.UUID | None", + "default": "None" + } + ], + "line": 115, + "doc": "" + }, + { + "name": "FeeLineItemRead", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "request_id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "fee_schedule_id", + "type": "uuid.UUID | None", + "default": "" + }, + { + "name": "description", + "type": "str", + "default": "" + }, + { + "name": "quantity", + "type": "int", + "default": "" + }, + { + "name": "unit_price", + "type": "float", + "default": "" + }, + { + "name": "total", + "type": "float", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "created_at", + "type": "datetime", + "default": "" + } + ], + "line": 122, + "doc": "" + }, + { + "name": "ResponseLetterCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "template_id", + "type": "uuid.UUID | None", + "default": "None" + } + ], + "line": 138, + "doc": "" + }, + { + "name": "ResponseLetterRead", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "request_id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "template_id", + "type": "uuid.UUID | None", + "default": "" + }, + { + "name": "generated_content", + "type": "str", + "default": "" + }, + { + "name": "edited_content", + "type": "str | None", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "generated_by", + "type": "uuid.UUID | None", + "default": "" + }, + { + "name": "approved_by", + "type": "uuid.UUID | None", + "default": "" + }, + { + "name": "sent_at", + "type": "datetime | None", + "default": "" + }, + { + "name": "created_at", + "type": "datetime", + "default": "" + } + ], + "line": 142, + "doc": "" + }, + { + "name": "ResponseLetterUpdate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "edited_content", + "type": "str | None", + "default": "None" + }, + { + "name": "status", + "type": "str | None", + "default": "None" + } + ], + "line": 156, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/schemas/search.py", + "sha256": "13a5c1913290f2d1b4c9447c3b3d4d1046038e146c2b11a97a03e1bb895b3015", + "routes": [], + "models": [ + { + "name": "SearchRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "query", + "type": "str", + "default": "" + }, + { + "name": "session_id", + "type": "uuid.UUID | None", + "default": "None" + }, + { + "name": "filters", + "type": "dict | None", + "default": "None" + }, + { + "name": "limit", + "type": "int", + "default": "Field(default=10, le=50)" + }, + { + "name": "synthesize", + "type": "bool", + "default": "False" + } + ], + "line": 6, + "doc": "" + }, + { + "name": "SearchResultItem", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "chunk_id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "document_id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "filename", + "type": "str", + "default": "" + }, + { + "name": "file_type", + "type": "str", + "default": "" + }, + { + "name": "source_path", + "type": "str", + "default": "" + }, + { + "name": "page_number", + "type": "int | None", + "default": "" + }, + { + "name": "content_text", + "type": "str", + "default": "" + }, + { + "name": "similarity_score", + "type": "float", + "default": "" + }, + { + "name": "rank", + "type": "int", + "default": "" + } + ], + "line": 14, + "doc": "" + }, + { + "name": "SearchResponse", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "query_id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "session_id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "query_text", + "type": "str", + "default": "" + }, + { + "name": "results", + "type": "list[SearchResultItem]", + "default": "" + }, + { + "name": "results_count", + "type": "int", + "default": "" + }, + { + "name": "synthesized_answer", + "type": "str | None", + "default": "None" + }, + { + "name": "ai_generated", + "type": "bool", + "default": "False" + } + ], + "line": 28, + "doc": "" + }, + { + "name": "SearchSessionRead", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "user_id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "created_at", + "type": "datetime", + "default": "" + }, + { + "name": "queries", + "type": "list[dict]", + "default": "[]" + } + ], + "line": 38, + "doc": "" + }, + { + "name": "SearchFilterOptions", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "file_types", + "type": "list[str]", + "default": "" + }, + { + "name": "source_names", + "type": "list[str]", + "default": "" + }, + { + "name": "departments", + "type": "list[dict]", + "default": "[]" + }, + { + "name": "date_range", + "type": "dict | None", + "default": "None" + } + ], + "line": 47, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/schemas/service_account.py", + "sha256": "998b5de7ba31a8800d2feb6379c5eaa00747bccd23c05ce99863a42b0951a37f", + "routes": [], + "models": [ + { + "name": "ServiceAccountCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "name", + "type": "str", + "default": "" + }, + { + "name": "role", + "type": "UserRole", + "default": "UserRole.READ_ONLY" + } + ], + "line": 9, + "doc": "" + }, + { + "name": "ServiceAccountRead", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "name", + "type": "str", + "default": "" + }, + { + "name": "role", + "type": "UserRole", + "default": "" + }, + { + "name": "created_by", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "created_at", + "type": "datetime", + "default": "" + }, + { + "name": "is_active", + "type": "bool", + "default": "" + } + ], + "line": 14, + "doc": "" + }, + { + "name": "ServiceAccountCreated", + "bases": [ + "ServiceAccountRead" + ], + "fields": [ + { + "name": "api_key", + "type": "str", + "default": "" + } + ], + "line": 25, + "doc": "Returned only on creation \u2014 includes the plaintext API key (shown once)." + }, + { + "name": "ServiceAccountUpdate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "role", + "type": "UserRole | None", + "default": "None" + }, + { + "name": "is_active", + "type": "bool | None", + "default": "None" + } + ], + "line": 30, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/schemas/sync_failure.py", + "sha256": "7d0f1052aba113868dc3439ef78b85b8d9941cf243eb7224ca12e1d9019f9971", + "routes": [], + "models": [ + { + "name": "SyncFailureRead", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "source_id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "source_path", + "type": "str", + "default": "" + }, + { + "name": "error_message", + "type": "str | None", + "default": "" + }, + { + "name": "error_class", + "type": "str | None", + "default": "" + }, + { + "name": "http_status_code", + "type": "int | None", + "default": "" + }, + { + "name": "retry_count", + "type": "int", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "first_failed_at", + "type": "datetime", + "default": "" + }, + { + "name": "last_retried_at", + "type": "datetime | None", + "default": "" + }, + { + "name": "dismissed_at", + "type": "datetime | None", + "default": "" + }, + { + "name": "dismissed_by", + "type": "uuid.UUID | None", + "default": "" + } + ], + "line": 8, + "doc": "" + }, + { + "name": "SyncRunLogRead", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "source_id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "started_at", + "type": "datetime", + "default": "" + }, + { + "name": "finished_at", + "type": "datetime | None", + "default": "" + }, + { + "name": "status", + "type": "str | None", + "default": "" + }, + { + "name": "records_attempted", + "type": "int", + "default": "" + }, + { + "name": "records_succeeded", + "type": "int", + "default": "" + }, + { + "name": "records_failed", + "type": "int", + "default": "" + }, + { + "name": "error_summary", + "type": "str | None", + "default": "" + } + ], + "line": 24, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/schemas/user.py", + "sha256": "95cee0fce572e5c68f21453c6d2ae145f4a44a7aa9e3b7a3e1d6393eebf5bf06", + "routes": [], + "models": [ + { + "name": "UserRead", + "bases": [ + "schemas.BaseUser[uuid.UUID]" + ], + "fields": [ + { + "name": "full_name", + "type": "str", + "default": "" + }, + { + "name": "role", + "type": "UserRole", + "default": "" + }, + { + "name": "created_at", + "type": "datetime", + "default": "" + }, + { + "name": "last_login", + "type": "datetime | None", + "default": "" + }, + { + "name": "must_change_password", + "type": "bool", + "default": "False" + }, + { + "name": "department_id", + "type": "uuid.UUID | None", + "default": "None" + } + ], + "line": 10, + "doc": "" + }, + { + "name": "UserCreate", + "bases": [ + "schemas.BaseUserCreate" + ], + "fields": [ + { + "name": "full_name", + "type": "str", + "default": "''" + }, + { + "name": "role", + "type": "UserRole", + "default": "UserRole.PUBLIC" + } + ], + "line": 19, + "doc": "Self-registration schema for the public ``/auth/register`` endpoint.\n\nRole is forced server-side, never honored from the request payload:\n* In ``PORTAL_MODE=public``: role \u2192 ``UserRole.PUBLIC`` (residents who\n register via the public surface get the minimal public role, never\n STAFF).\n* In ``PORTAL_MODE=private``: ``/auth/register`` is not mounted at all,\n so this schema is unreachable in private mode. The fallback value here\n matches the private-mode non-assignability posture (PUBLIC, not STAFF)\n \u2014 which also corrects a pre-existing bug where self-register was\n silently forced to STAFF regardless of caller intent.\n\nAdmin-driven user creation (including explicit STAFF/REVIEWER/LIAISON/\nREAD_ONLY assignments) goes through ``/admin/users`` via\n:class:`AdminUserCreate`." + }, + { + "name": "AdminUserCreate", + "bases": [ + "schemas.BaseUserCreate" + ], + "fields": [ + { + "name": "full_name", + "type": "str", + "default": "''" + }, + { + "name": "role", + "type": "UserRole", + "default": "UserRole.STAFF" + }, + { + "name": "department_id", + "type": "uuid.UUID | None", + "default": "None" + } + ], + "line": 54, + "doc": "Schema for admin-only user creation endpoint. Role IS caller-supplied." + }, + { + "name": "UserUpdate", + "bases": [ + "schemas.BaseUserUpdate" + ], + "fields": [ + { + "name": "full_name", + "type": "str | None", + "default": "None" + }, + { + "name": "role", + "type": "UserRole | None", + "default": "None" + } + ], + "line": 61, + "doc": "" + }, + { + "name": "UserSelfUpdate", + "bases": [ + "schemas.BaseUserUpdate" + ], + "fields": [ + { + "name": "full_name", + "type": "str | None", + "default": "None" + } + ], + "line": 66, + "doc": "Schema for user self-update via PATCH /users/me.\n\nExcludes role and department_id. Any payload containing those fields is\nrejected at parse time (HTTP 422). Role and department changes require\nadmin privileges via /admin/users/{id}." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/search/__init__.py", + "sha256": "6d5a53e92963972bce100511001cfc78b65a347390a47b4273c0c62f7a88ccc9", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/search/engine.py", + "sha256": "ff3c9ca2fba3293400ed1d5f4056e5a47a8673f443061b703abdace1e309d454", + "routes": [], + "models": [ + { + "name": "SearchHit", + "bases": [], + "fields": [ + { + "name": "chunk_id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "document_id", + "type": "uuid.UUID", + "default": "" + }, + { + "name": "filename", + "type": "str", + "default": "" + }, + { + "name": "file_type", + "type": "str", + "default": "" + }, + { + "name": "source_path", + "type": "str", + "default": "" + }, + { + "name": "page_number", + "type": "int | None", + "default": "" + }, + { + "name": "content_text", + "type": "str", + "default": "" + }, + { + "name": "similarity_score", + "type": "float", + "default": "" + }, + { + "name": "rank", + "type": "int", + "default": "" + } + ], + "line": 13, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/search/router.py", + "sha256": "904441f2323a86199c42d647e5935c4f78bbb973c5c20a9b35e1bcc929691891", + "routes": [ + { + "method": "POST", + "path": "/search/query", + "router": "router", + "prefix_resolved": true, + "name": "execute_search", + "signature": "req: SearchRequest, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.LIAISON))", + "returns": "", + "line": 28, + "doc": "Execute a hybrid search query. Optionally synthesize an LLM answer.", + "decorator": "router.post('/query', response_model=SearchResponse)", + "errors": [ + "HTTPException(status_code=404, detail='Search session not found')" + ] + }, + { + "method": "GET", + "path": "/search/sessions", + "router": "router", + "prefix_resolved": true, + "name": "list_sessions", + "signature": "limit: int=20, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 141, + "doc": "List the current user's search sessions.", + "decorator": "router.get('/sessions', response_model=list[SearchSessionRead])", + "errors": [] + }, + { + "method": "GET", + "path": "/search/sessions/{session_id}", + "router": "router", + "prefix_resolved": true, + "name": "get_session", + "signature": "session_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 191, + "doc": "Get a search session with its query history.", + "decorator": "router.get('/sessions/{session_id}', response_model=SearchSessionRead)", + "errors": [ + "HTTPException(status_code=404, detail='Search session not found')" + ] + }, + { + "method": "GET", + "path": "/search/filters", + "router": "router", + "prefix_resolved": true, + "name": "get_filter_options", + "signature": "session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 226, + "doc": "Get available filter values for search.", + "decorator": "router.get('/filters', response_model=SearchFilterOptions)", + "errors": [] + }, + { + "method": "GET", + "path": "/search/export", + "router": "router", + "prefix_resolved": true, + "name": "export_search_results", + "signature": "query: str, format: str='csv', department_id: str | None=None, file_type: str | None=None, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.STAFF))", + "returns": "", + "line": 270, + "doc": "Export search results as CSV. Runs a search and streams the results.", + "decorator": "router.get('/export')", + "errors": [] + } + ], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/search/synthesizer.py", + "sha256": "427e73f0cf9752fb347f7769751e7e14a522fcc6bebeb1b785440ad0f5b7e254", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/security/__init__.py", + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/security/at_rest.py", + "sha256": "ae75ffc5d633a6d99180bb61e0d01f2084af917565f67cfc5a5ab1d0a055b554", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/security/host_validator.py", + "sha256": "2890b06c3440118166ca36640d0d7d06b81224eb3e540e021721712fe3c967a8", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/seed/__init__.py", + "sha256": "94373caf66af4bff649d9b77dee25b4a9f03f57ba8cc507c02f889baa1d48575", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/seed/first_boot.py", + "sha256": "88b0f011853f6f60f7d488bfebe0dde96209a8d3243a08b731e4a6f682bab40b", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/service_accounts/__init__.py", + "sha256": "724c131242497b5d06cb96ed27573bdd2de4f098babe79129e6f1e20d9a5b76b", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/service_accounts/router.py", + "sha256": "c6632fc265846154c9a537070390de2c47c3d2d92c78e6fb8fb352f32ad3bf30", + "routes": [ + { + "method": "POST", + "path": "/service-accounts/", + "router": "router", + "prefix_resolved": true, + "name": "create_service_account", + "signature": "data: ServiceAccountCreate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 29, + "doc": "", + "decorator": "router.post('/', response_model=ServiceAccountCreated, status_code=201)", + "errors": [ + "HTTPException(status_code=409, detail='Name already taken')" + ] + }, + { + "method": "GET", + "path": "/service-accounts/", + "router": "router", + "prefix_resolved": true, + "name": "list_service_accounts", + "signature": "session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 72, + "doc": "", + "decorator": "router.get('/', response_model=list[ServiceAccountRead])", + "errors": [] + }, + { + "method": "PATCH", + "path": "/service-accounts/{account_id}", + "router": "router", + "prefix_resolved": true, + "name": "update_service_account", + "signature": "account_id: uuid.UUID, data: ServiceAccountUpdate, session: AsyncSession=Depends(get_async_session), user: User=Depends(require_role(UserRole.ADMIN))", + "returns": "", + "line": 81, + "doc": "", + "decorator": "router.patch('/{account_id}', response_model=ServiceAccountRead)", + "errors": [ + "HTTPException(status_code=404, detail='Service account not found')" + ] + } + ], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/worker.py", + "sha256": "6b33f496ba32184cc049e6cc5c6398c2e42f1b30c51bea52ae67e768da880829", + "routes": [], + "models": [], + "configuration": [] + } + ], + "bridge": [ + { + "source": "installed-owned-source/app/desktop_bridge/__init__.py", + "sha256": "707138dfa41f7f4e91957a523e3c3394ce52803778c5b278b3cc77d4a5b1c30f", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/desktop_bridge/projection.py", + "sha256": "5267b17ae6be18258ea0e225ffb0d53c56aeaf674d9426856b8db804f801008c", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/desktop_bridge/records.py", + "sha256": "407b2ca9974caa761c00daee3b585ca915c2fe649a69a0dd58f42342b39821d1", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/app/desktop_bridge/router.py", + "sha256": "7c02e0a222c36aecb84b105a918309a811f40249c3f55756d87cfa2646c4ef1b", + "routes": [ + { + "method": "GET", + "path": "/desktop/v1/public/records-state", + "router": "router", + "prefix_resolved": true, + "name": "public_records_state", + "signature": "request: Request, session: AsyncSession=Depends(get_async_session)", + "returns": "", + "line": 134, + "doc": "", + "decorator": "router.get('/public/records-state', dependencies=[Depends(native_public_shell)], response_model=RecordsStateRead)", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/public/requests", + "router": "router", + "prefix_resolved": true, + "name": "public_records_intake", + "signature": "data: PublicIntake, request: Request, session: AsyncSession=Depends(get_async_session)", + "returns": "", + "line": 144, + "doc": "", + "decorator": "router.post('/public/requests', dependencies=[Depends(native_public_shell)])", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/public/lookup", + "router": "router", + "prefix_resolved": true, + "name": "public_records_lookup", + "signature": "data: PublicLookup, request: Request, session: AsyncSession=Depends(get_async_session)", + "returns": "", + "line": 153, + "doc": "", + "decorator": "router.post('/public/lookup', dependencies=[Depends(native_public_shell)])", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/public/messages", + "router": "router", + "prefix_resolved": true, + "name": "public_records_message", + "signature": "data: PublicMessage, request: Request, session: AsyncSession=Depends(get_async_session)", + "returns": "", + "line": 160, + "doc": "", + "decorator": "router.post('/public/messages', dependencies=[Depends(native_public_shell)])", + "errors": [ + "HTTPException(400, str(error))" + ] + }, + { + "method": "POST", + "path": "/desktop/v1/permitting-sources/search", + "router": "router", + "prefix_resolved": true, + "name": "search_permitting_sources", + "signature": "data: MeetingsSearch, request: Request, actor: User=Depends(native_records_user)", + "returns": "", + "line": 204, + "doc": "", + "decorator": "router.post('/permitting-sources/search')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/requests/{request_id}/permitting-sources", + "router": "router", + "prefix_resolved": true, + "name": "attach_permitting_source", + "signature": "request_id: uuid.UUID, data: MeetingsSourceSelection, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", + "returns": "", + "line": 213, + "doc": "", + "decorator": "router.post('/requests/{request_id}/permitting-sources', response_model=RecordsOperationRead)", + "errors": [ + "HTTPException(404, 'Records request not found.')", + "HTTPException(404, 'Reviewed Permitting copy not found or no longer permitted.')", + "HTTPException(409, 'Permitting source changed; search again before attaching.')", + "HTTPException(422, 'Source attachment not confirmed; existing evidence retained.')" + ] + }, + { + "method": "POST", + "path": "/desktop/v1/inspections-sources/search", + "router": "router", + "prefix_resolved": true, + "name": "search_inspections_sources", + "signature": "data: MeetingsSearch, request: Request, actor: User=Depends(native_records_user)", + "returns": "", + "line": 239, + "doc": "", + "decorator": "router.post('/inspections-sources/search')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/requests/{request_id}/inspections-sources", + "router": "router", + "prefix_resolved": true, + "name": "attach_inspections_source", + "signature": "request_id: uuid.UUID, data: MeetingsSourceSelection, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", + "returns": "", + "line": 248, + "doc": "", + "decorator": "router.post('/requests/{request_id}/inspections-sources', response_model=RecordsOperationRead)", + "errors": [ + "HTTPException(404, 'Records request not found.')", + "HTTPException(404, 'Reviewed Inspections copy not found or no longer permitted.')", + "HTTPException(409, 'Inspections source changed; search again before attaching.')", + "HTTPException(422, 'Source attachment not confirmed; existing evidence retained.')" + ] + }, + { + "method": "POST", + "path": "/desktop/v1/planning-sources/search", + "router": "router", + "prefix_resolved": true, + "name": "search_planning_sources", + "signature": "data: MeetingsSearch, request: Request, actor: User=Depends(native_records_user)", + "returns": "", + "line": 274, + "doc": "", + "decorator": "router.post('/planning-sources/search')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/requests/{request_id}/planning-sources", + "router": "router", + "prefix_resolved": true, + "name": "attach_planning_source", + "signature": "request_id: uuid.UUID, data: MeetingsSourceSelection, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", + "returns": "", + "line": 283, + "doc": "", + "decorator": "router.post('/requests/{request_id}/planning-sources', response_model=RecordsOperationRead)", + "errors": [ + "HTTPException(404, 'Records request not found.')", + "HTTPException(404, 'Permitted Planning source not found.')", + "HTTPException(409, 'Planning source changed; search again before attaching.')", + "HTTPException(422, 'Source attachment not confirmed; existing evidence retained.')" + ] + }, + { + "method": "POST", + "path": "/desktop/v1/zoning-sources/search", + "router": "router", + "prefix_resolved": true, + "name": "search_zoning_sources", + "signature": "data: MeetingsSearch, request: Request, actor: User=Depends(native_records_user)", + "returns": "", + "line": 310, + "doc": "", + "decorator": "router.post('/zoning-sources/search')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/requests/{request_id}/zoning-sources", + "router": "router", + "prefix_resolved": true, + "name": "attach_zoning_source", + "signature": "request_id: uuid.UUID, data: MeetingsSourceSelection, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", + "returns": "", + "line": 319, + "doc": "", + "decorator": "router.post('/requests/{request_id}/zoning-sources', response_model=RecordsOperationRead)", + "errors": [ + "HTTPException(404, 'Records request not found.')", + "HTTPException(404, 'Permitted Zoning source not found.')", + "HTTPException(409, 'Zoning source changed; search again before attaching.')", + "HTTPException(422, 'Source attachment not confirmed; existing evidence retained.')" + ] + }, + { + "method": "GET", + "path": "/desktop/v1/records-state", + "router": "router", + "prefix_resolved": true, + "name": "get_native_records_state", + "signature": "session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", + "returns": "", + "line": 346, + "doc": "", + "decorator": "router.get('/records-state', response_model=RecordsStateRead)", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/meetings-sources/search", + "router": "router", + "prefix_resolved": true, + "name": "search_meetings_sources", + "signature": "data: MeetingsSearch, request: Request, actor: User=Depends(native_records_user)", + "returns": "", + "line": 355, + "doc": "", + "decorator": "router.post('/meetings-sources/search')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/requests/{request_id}/meetings-sources", + "router": "router", + "prefix_resolved": true, + "name": "attach_meetings_source", + "signature": "request_id: uuid.UUID, data: MeetingsSourceSelection, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", + "returns": "", + "line": 364, + "doc": "", + "decorator": "router.post('/requests/{request_id}/meetings-sources', response_model=RecordsOperationRead)", + "errors": [ + "HTTPException(404, 'Records request not found.')", + "HTTPException(404, 'Permitted Meetings source not found.')", + "HTTPException(409, 'Meetings source changed; search again before attaching.')", + "HTTPException(422, 'Source attachment not confirmed; existing evidence retained.')" + ] + }, + { + "method": "POST", + "path": "/desktop/v1/code-sources/search", + "router": "router", + "prefix_resolved": true, + "name": "search_code_sources", + "signature": "data: CodeSearch, request: Request, actor: User=Depends(native_records_user)", + "returns": "", + "line": 389, + "doc": "", + "decorator": "router.post('/code-sources/search')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/requests/{request_id}/code-sources", + "router": "router", + "prefix_resolved": true, + "name": "attach_code_source", + "signature": "request_id: uuid.UUID, data: CodeSourceSelection, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", + "returns": "", + "line": 398, + "doc": "", + "decorator": "router.post('/requests/{request_id}/code-sources', response_model=RecordsOperationRead)", + "errors": [ + "HTTPException(404, 'Records request not found.')", + "HTTPException(404, 'Permitted Code source not found.')", + "HTTPException(409, 'Code source changed; search again before attaching.')", + "HTTPException(422, 'Source attachment not confirmed; existing evidence retained.')" + ] + }, + { + "method": "POST", + "path": "/desktop/v1/notifications/{notification_id}/sent", + "router": "router", + "prefix_resolved": true, + "name": "mark_native_notification_sent", + "signature": "notification_id: uuid.UUID, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", + "returns": "", + "line": 423, + "doc": "", + "decorator": "router.post('/notifications/{notification_id}/sent', response_model=RecordsStateRead)", + "errors": [ + "HTTPException(404, 'Records notification not found.')", + "HTTPException(400, 'This local notification is already marked sent.')" + ] + }, + { + "method": "POST", + "path": "/desktop/v1/requests/{request_id}/documents", + "router": "router", + "prefix_resolved": true, + "name": "attach_native_document", + "signature": "request_id: uuid.UUID, data: AttachDocument, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", + "returns": "", + "line": 443, + "doc": "", + "decorator": "router.post('/requests/{request_id}/documents', response_model=RecordsOperationRead)", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/requests/{request_id}/documents/{attachment_id}/release-copy", + "router": "router", + "prefix_resolved": true, + "name": "attach_native_release_copy", + "signature": "request_id: uuid.UUID, attachment_id: uuid.UUID, data: AttachReleaseCopy, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", + "returns": "", + "line": 453, + "doc": "", + "decorator": "router.post('/requests/{request_id}/documents/{attachment_id}/release-copy', response_model=RecordsOperationRead)", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/requests/{request_id}/artifacts", + "router": "router", + "prefix_resolved": true, + "name": "prepare_native_artifact", + "signature": "request_id: uuid.UUID, data: PrepareArtifact, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", + "returns": "", + "line": 463, + "doc": "", + "decorator": "router.post('/requests/{request_id}/artifacts', response_model=ArtifactPlan)", + "errors": [ + "HTTPException(404, 'Records request not found.')", + "HTTPException(400, str(error))" + ] + }, + { + "method": "POST", + "path": "/desktop/v1/requests/{request_id}/artifacts/{artifact_id}/complete", + "router": "router", + "prefix_resolved": true, + "name": "complete_native_artifact", + "signature": "request_id: uuid.UUID, artifact_id: uuid.UUID, data: CompleteArtifact, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", + "returns": "", + "line": 481, + "doc": "", + "decorator": "router.post('/requests/{request_id}/artifacts/{artifact_id}/complete', response_model=RecordsOperationRead)", + "errors": [ + "HTTPException(404, 'Records request not found.')", + "HTTPException(400, str(error))" + ] + }, + { + "method": "POST", + "path": "/desktop/v1/requests", + "router": "router", + "prefix_resolved": true, + "name": "create_native_request", + "signature": "data: StaffRecordsIntake, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", + "returns": "", + "line": 500, + "doc": "", + "decorator": "router.post('/requests', response_model=NativeRequestRead, status_code=201)", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/requests/{request_id}", + "router": "router", + "prefix_resolved": true, + "name": "get_native_request", + "signature": "request_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", + "returns": "", + "line": 521, + "doc": "", + "decorator": "router.get('/requests/{request_id}', response_model=NativeRequestRead)", + "errors": [ + "HTTPException(404, 'Records request not found.')" + ] + }, + { + "method": "GET", + "path": "/desktop/v1/requests/{request_id}/view", + "router": "router", + "prefix_resolved": true, + "name": "get_native_request_view", + "signature": "request_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", + "returns": "", + "line": 537, + "doc": "", + "decorator": "router.get('/requests/{request_id}/view', response_model=RecordsView)", + "errors": [ + "HTTPException(404, 'Records request not found.')" + ] + }, + { + "method": "GET", + "path": "/desktop/v1/requests/{request_id}/draft-context", + "router": "router", + "prefix_resolved": true, + "name": "native_draft_context", + "signature": "request_id: uuid.UUID, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", + "returns": "", + "line": 549, + "doc": "", + "decorator": "router.get('/requests/{request_id}/draft-context')", + "errors": [ + "HTTPException(404, 'Records request not found.')", + "HTTPException(400, str(error))" + ] + }, + { + "method": "POST", + "path": "/desktop/v1/requests/{request_id}/generated-draft", + "router": "router", + "prefix_resolved": true, + "name": "native_generated_draft", + "signature": "request_id: uuid.UUID, data: GeneratedDraft, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", + "returns": "", + "line": 575, + "doc": "", + "decorator": "router.post('/requests/{request_id}/generated-draft', response_model=RecordsOperationRead)", + "errors": [ + "HTTPException(404, 'Records request not found.')", + "HTTPException(409, 'The draft changed during generation. Refresh before generating again.')", + "HTTPException(400, str(error))" + ] + }, + { + "method": "POST", + "path": "/desktop/v1/requests/{request_id}/actions", + "router": "router", + "prefix_resolved": true, + "name": "native_request_operation", + "signature": "request_id: uuid.UUID, command: RecordsCommand, request: Request, session: AsyncSession=Depends(get_async_session), actor: User=Depends(native_records_user)", + "returns": "", + "line": 605, + "doc": "", + "decorator": "router.post('/requests/{request_id}/actions', response_model=RecordsOperationRead)", + "errors": [ + "HTTPException(404, 'Records request not found.')", + "HTTPException(400, str(error))" + ] + } + ], + "models": [ + { + "name": "MeetingsSearch", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "query", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + } + ], + "line": 38, + "doc": "" + }, + { + "name": "MeetingsSourceSelection", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "source_id", + "type": "str", + "default": "Field(min_length=1, max_length=200)" + }, + { + "name": "expected_sha256", + "type": "str", + "default": "Field(pattern='^[0-9a-f]{64}$')" + } + ], + "line": 43, + "doc": "" + }, + { + "name": "CodeSearch", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "query", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + }, + { + "name": "as_of", + "type": "date | None", + "default": "None" + } + ], + "line": 49, + "doc": "" + }, + { + "name": "CodeSourceSelection", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "source_id", + "type": "str", + "default": "Field(min_length=1, max_length=200)" + }, + { + "name": "expected_sha256", + "type": "str", + "default": "Field(pattern='^[0-9a-f]{64}$')" + }, + { + "name": "as_of", + "type": "date | None", + "default": "None" + } + ], + "line": 55, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/desktop_bridge/schemas.py", + "sha256": "753dd5474d532912bc50118fe9add74613cbc3b17a062dd93681309ac590926d", + "routes": [], + "models": [ + { + "name": "StaffRecordsIntake", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "requester", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "summary", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "deadline", + "type": "str", + "default": "" + }, + { + "name": "deadlineBasis", + "type": "str", + "default": "''" + } + ], + "line": 10, + "doc": "Existing native create-records-request input; no caller-supplied actor." + }, + { + "name": "NativeRequestRead", + "bases": [ + "RequestRead" + ], + "fields": [ + { + "name": "desktop_id", + "type": "str | None", + "default": "" + }, + { + "name": "public_tracking_number", + "type": "str | None", + "default": "" + }, + { + "name": "submitted_via", + "type": "str", + "default": "" + }, + { + "name": "deadline_label", + "type": "str", + "default": "" + }, + { + "name": "deadline_basis", + "type": "str", + "default": "" + }, + { + "name": "deadline_reviewed_at", + "type": "datetime | None", + "default": "" + } + ], + "line": 28, + "doc": "" + }, + { + "name": "AssignmentPayload", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "assignedTo", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 41, + "doc": "" + }, + { + "name": "DeadlinePayload", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "deadline", + "type": "str", + "default": "" + }, + { + "name": "deadlineBasis", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 45, + "doc": "" + }, + { + "name": "CalculateDeadlinePayload", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "deadlineReceivedDate", + "type": "str", + "default": "" + }, + { + "name": "deadlineRuleName", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "deadlineDayCount", + "type": "str", + "default": "" + }, + { + "name": "deadlineDayType", + "type": "str", + "default": "" + }, + { + "name": "deadlineBasis", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 52, + "doc": "" + }, + { + "name": "ClarificationPayload", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "clarificationNote", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 77, + "doc": "" + }, + { + "name": "MessagePayload", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "requestMessageBody", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 81, + "doc": "" + }, + { + "name": "SearchNotePayload", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "sourceNote", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "citation", + "type": "str", + "default": "''" + } + ], + "line": 85, + "doc": "" + }, + { + "name": "SearchReceiptPayload", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "searchQuery", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "searchLocations", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "searchResultTitle", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "searchResultCitation", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "searchResultSummary", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "searchResultStatus", + "type": "str", + "default": "''" + }, + { + "name": "searchReviewer", + "type": "str", + "default": "''" + } + ], + "line": 90, + "doc": "" + }, + { + "name": "ExemptionNotePayload", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "exemptionNote", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 100, + "doc": "" + }, + { + "name": "ExemptionDecisionPayload", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "exemptionSource", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "exemptionKind", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "exemptionFinding", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "exemptionDecision", + "type": "Literal['release', 'redact', 'exempt']", + "default": "" + }, + { + "name": "exemptionBasis", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "exemptionReviewer", + "type": "str", + "default": "''" + } + ], + "line": 104, + "doc": "" + }, + { + "name": "FeeEstimatePayload", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "feeEstimate", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 118, + "doc": "" + }, + { + "name": "FeeLinePayload", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "feeLineDescription", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "feeScheduleBasis", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "feeLineAmount", + "type": "str", + "default": "" + } + ], + "line": 122, + "doc": "" + }, + { + "name": "FeeWaiverPayload", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "feeWaiverReason", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 140, + "doc": "" + }, + { + "name": "DraftPayload", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "responseDraft", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "citation", + "type": "str", + "default": "''" + } + ], + "line": 144, + "doc": "" + }, + { + "name": "ApprovalPayload", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "approvalNote", + "type": "str", + "default": "''" + } + ], + "line": 149, + "doc": "" + }, + { + "name": "AssignCommand", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "action", + "type": "Literal['assign-records-request']", + "default": "" + }, + { + "name": "payload", + "type": "AssignmentPayload", + "default": "" + } + ], + "line": 153, + "doc": "" + }, + { + "name": "DeadlineCommand", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "action", + "type": "Literal['set-records-deadline']", + "default": "" + }, + { + "name": "payload", + "type": "DeadlinePayload", + "default": "" + } + ], + "line": 158, + "doc": "" + }, + { + "name": "CalculateDeadlineCommand", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "action", + "type": "Literal['calculate-records-deadline']", + "default": "" + }, + { + "name": "payload", + "type": "CalculateDeadlinePayload", + "default": "" + } + ], + "line": 163, + "doc": "" + }, + { + "name": "ClarificationCommand", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "action", + "type": "Literal['request-records-clarification']", + "default": "" + }, + { + "name": "payload", + "type": "ClarificationPayload", + "default": "" + } + ], + "line": 168, + "doc": "" + }, + { + "name": "MessageCommand", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "action", + "type": "Literal['add-records-message']", + "default": "" + }, + { + "name": "payload", + "type": "MessagePayload", + "default": "" + } + ], + "line": 173, + "doc": "" + }, + { + "name": "SearchNoteCommand", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "action", + "type": "Literal['record-records-search']", + "default": "" + }, + { + "name": "payload", + "type": "SearchNotePayload", + "default": "" + } + ], + "line": 178, + "doc": "" + }, + { + "name": "SearchReceiptCommand", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "action", + "type": "Literal['record-records-search-session']", + "default": "" + }, + { + "name": "payload", + "type": "SearchReceiptPayload", + "default": "" + } + ], + "line": 183, + "doc": "" + }, + { + "name": "ExemptionNoteCommand", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "action", + "type": "Literal['add-records-exemption-review']", + "default": "" + }, + { + "name": "payload", + "type": "ExemptionNotePayload", + "default": "" + } + ], + "line": 188, + "doc": "" + }, + { + "name": "ExemptionDecisionCommand", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "action", + "type": "Literal['add-records-exemption-decision']", + "default": "" + }, + { + "name": "payload", + "type": "ExemptionDecisionPayload", + "default": "" + } + ], + "line": 193, + "doc": "" + }, + { + "name": "FeeEstimateCommand", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "action", + "type": "Literal['estimate-records-fee']", + "default": "" + }, + { + "name": "payload", + "type": "FeeEstimatePayload", + "default": "" + } + ], + "line": 198, + "doc": "" + }, + { + "name": "FeeLineCommand", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "action", + "type": "Literal['add-records-fee-line']", + "default": "" + }, + { + "name": "payload", + "type": "FeeLinePayload", + "default": "" + } + ], + "line": 203, + "doc": "" + }, + { + "name": "FeeWaiverCommand", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "action", + "type": "Literal['waive-records-fee']", + "default": "" + }, + { + "name": "payload", + "type": "FeeWaiverPayload", + "default": "" + } + ], + "line": 208, + "doc": "" + }, + { + "name": "DraftCommand", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "action", + "type": "Literal['draft-records-response']", + "default": "" + }, + { + "name": "payload", + "type": "DraftPayload", + "default": "" + } + ], + "line": 213, + "doc": "" + }, + { + "name": "ApprovalCommand", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "action", + "type": "Literal['approve-records-response']", + "default": "" + }, + { + "name": "payload", + "type": "ApprovalPayload", + "default": "Field(default_factory=ApprovalPayload)" + } + ], + "line": 218, + "doc": "" + }, + { + "name": "FinishCommand", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "action", + "type": "Literal['fulfill-records-request', 'close-records-request']", + "default": "" + }, + { + "name": "payload", + "type": "NativePayload", + "default": "Field(default_factory=NativePayload)" + } + ], + "line": 223, + "doc": "" + }, + { + "name": "TimelineView", + "bases": [ + "NativeView" + ], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "action", + "type": "str", + "default": "" + }, + { + "name": "actor", + "type": "str", + "default": "" + }, + { + "name": "note", + "type": "str", + "default": "" + }, + { + "name": "created_at_unix_seconds", + "type": "int", + "default": "" + } + ], + "line": 241, + "doc": "" + }, + { + "name": "PublicStatusView", + "bases": [ + "NativeView" + ], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "label", + "type": "str", + "default": "" + }, + { + "name": "summary", + "type": "str", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "created_at_unix_seconds", + "type": "int", + "default": "" + } + ], + "line": 249, + "doc": "" + }, + { + "name": "MessageView", + "bases": [ + "NativeView" + ], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "author", + "type": "str", + "default": "" + }, + { + "name": "author_role", + "type": "str", + "default": "" + }, + { + "name": "body", + "type": "str", + "default": "" + }, + { + "name": "visibility", + "type": "str", + "default": "" + }, + { + "name": "created_at_unix_seconds", + "type": "int", + "default": "" + } + ], + "line": 257, + "doc": "" + }, + { + "name": "FeeLineView", + "bases": [ + "NativeView" + ], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "description", + "type": "str", + "default": "" + }, + { + "name": "schedule_basis", + "type": "str", + "default": "" + }, + { + "name": "amount_cents", + "type": "int", + "default": "" + }, + { + "name": "created_at_unix_seconds", + "type": "int", + "default": "" + } + ], + "line": 266, + "doc": "" + }, + { + "name": "ExemptionDecisionView", + "bases": [ + "NativeView" + ], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "source", + "type": "str", + "default": "" + }, + { + "name": "kind", + "type": "str", + "default": "" + }, + { + "name": "finding", + "type": "str", + "default": "" + }, + { + "name": "decision", + "type": "Literal['release', 'redact', 'exempt']", + "default": "" + }, + { + "name": "basis", + "type": "str", + "default": "" + }, + { + "name": "reviewer", + "type": "str", + "default": "" + }, + { + "name": "created_at_unix_seconds", + "type": "int", + "default": "" + } + ], + "line": 274, + "doc": "" + }, + { + "name": "SearchResultView", + "bases": [ + "NativeView" + ], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "title", + "type": "str", + "default": "" + }, + { + "name": "citation", + "type": "str", + "default": "" + }, + { + "name": "summary", + "type": "str", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "" + } + ], + "line": 285, + "doc": "" + }, + { + "name": "SearchReceiptView", + "bases": [ + "NativeView" + ], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "query", + "type": "str", + "default": "" + }, + { + "name": "locations", + "type": "str", + "default": "" + }, + { + "name": "reviewer", + "type": "str", + "default": "" + }, + { + "name": "results", + "type": "list[SearchResultView]", + "default": "" + }, + { + "name": "created_at_unix_seconds", + "type": "int", + "default": "" + } + ], + "line": 293, + "doc": "" + }, + { + "name": "RecordsView", + "bases": [ + "NativeView" + ], + "fields": [ + { + "name": "request_id", + "type": "str", + "default": "" + }, + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "public_tracking_number", + "type": "str", + "default": "" + }, + { + "name": "requester", + "type": "str", + "default": "" + }, + { + "name": "requester_contact", + "type": "str", + "default": "" + }, + { + "name": "submitted_via", + "type": "str", + "default": "" + }, + { + "name": "summary", + "type": "str", + "default": "" + }, + { + "name": "deadline", + "type": "str", + "default": "" + }, + { + "name": "deadline_basis", + "type": "str", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "assigned_to", + "type": "str", + "default": "" + }, + { + "name": "clarification_notes", + "type": "list[str]", + "default": "" + }, + { + "name": "search_notes", + "type": "list[str]", + "default": "" + }, + { + "name": "search_sessions", + "type": "list[SearchReceiptView]", + "default": "" + }, + { + "name": "exemption_reviews", + "type": "list[str]", + "default": "" + }, + { + "name": "exemption_decisions", + "type": "list[ExemptionDecisionView]", + "default": "" + }, + { + "name": "fee_estimate", + "type": "str", + "default": "" + }, + { + "name": "fee_line_items", + "type": "list[FeeLineView]", + "default": "" + }, + { + "name": "fee_waiver_reason", + "type": "str", + "default": "" + }, + { + "name": "citations", + "type": "list[str]", + "default": "" + }, + { + "name": "response_draft", + "type": "str", + "default": "" + }, + { + "name": "approval_notes", + "type": "list[str]", + "default": "" + }, + { + "name": "exports", + "type": "list[str]", + "default": "" + }, + { + "name": "documents", + "type": "list['RecordsDocumentView']", + "default": "Field(default_factory=list)" + }, + { + "name": "release_packages", + "type": "list['ReleasePackageView']", + "default": "Field(default_factory=list)" + }, + { + "name": "timeline", + "type": "list[TimelineView]", + "default": "" + }, + { + "name": "public_status_events", + "type": "list[PublicStatusView]", + "default": "" + }, + { + "name": "messages", + "type": "list[MessageView]", + "default": "" + }, + { + "name": "deadline_reviewed_at_unix_seconds", + "type": "int | None", + "default": "" + }, + { + "name": "approved_at_unix_seconds", + "type": "int | None", + "default": "" + }, + { + "name": "fulfilled_at_unix_seconds", + "type": "int | None", + "default": "" + }, + { + "name": "closed_at_unix_seconds", + "type": "int | None", + "default": "" + }, + { + "name": "created_at_unix_seconds", + "type": "int", + "default": "" + } + ], + "line": 302, + "doc": "" + }, + { + "name": "RecordsOperationRead", + "bases": [ + "NativeView" + ], + "fields": [ + { + "name": "action", + "type": "str", + "default": "" + }, + { + "name": "message", + "type": "str", + "default": "" + }, + { + "name": "request", + "type": "RecordsView", + "default": "" + } + ], + "line": 339, + "doc": "" + }, + { + "name": "RecordsStateRead", + "bases": [ + "NativeView" + ], + "fields": [ + { + "name": "demo_fixture", + "type": "dict | None", + "default": "None" + }, + { + "name": "records_requests", + "type": "list[RecordsView]", + "default": "" + }, + { + "name": "notification_events", + "type": "list['NotificationView']", + "default": "Field(default_factory=list)" + }, + { + "name": "publication_events", + "type": "list['PublicationView']", + "default": "Field(default_factory=list)" + }, + { + "name": "audit_entries", + "type": "list['AuditView']", + "default": "Field(default_factory=list)" + } + ], + "line": 345, + "doc": "" + }, + { + "name": "ManagedFileReceipt", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "original_path", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "stored_path", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "file_name", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + }, + { + "name": "sha256", + "type": "str", + "default": "Field(pattern='^[0-9a-f]{64}$')" + }, + { + "name": "size_bytes", + "type": "int", + "default": "Field(ge=0, le=2147483647, strict=True)" + } + ], + "line": 353, + "doc": "" + }, + { + "name": "AttachDocument", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "title", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "citation", + "type": "str", + "default": "''" + }, + { + "name": "file", + "type": "ManagedFileReceipt", + "default": "" + } + ], + "line": 361, + "doc": "" + }, + { + "name": "AttachReleaseCopy", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "status", + "type": "Literal['release-ready copy', 'redacted copy']", + "default": "" + }, + { + "name": "note", + "type": "str", + "default": "''" + }, + { + "name": "added_by", + "type": "str", + "default": "''" + }, + { + "name": "file", + "type": "ManagedFileReceipt", + "default": "" + } + ], + "line": 367, + "doc": "" + }, + { + "name": "RecordsDocumentView", + "bases": [ + "NativeView" + ], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "attachment_id", + "type": "str", + "default": "" + }, + { + "name": "title", + "type": "str", + "default": "" + }, + { + "name": "original_path", + "type": "str", + "default": "" + }, + { + "name": "stored_path", + "type": "str", + "default": "" + }, + { + "name": "citation", + "type": "str", + "default": "" + }, + { + "name": "sha256", + "type": "str", + "default": "" + }, + { + "name": "size_bytes", + "type": "int", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "added_by", + "type": "str", + "default": "" + }, + { + "name": "created_at_unix_seconds", + "type": "int", + "default": "" + }, + { + "name": "release_original_path", + "type": "str", + "default": "''" + }, + { + "name": "release_stored_path", + "type": "str", + "default": "''" + }, + { + "name": "release_file_name", + "type": "str", + "default": "''" + }, + { + "name": "release_sha256", + "type": "str", + "default": "''" + }, + { + "name": "release_size_bytes", + "type": "int", + "default": "0" + }, + { + "name": "release_status", + "type": "str", + "default": "''" + }, + { + "name": "release_note", + "type": "str", + "default": "''" + }, + { + "name": "release_added_by", + "type": "str", + "default": "''" + }, + { + "name": "release_added_at_unix_seconds", + "type": "int | None", + "default": "None" + } + ], + "line": 374, + "doc": "" + }, + { + "name": "ReleasePackageView", + "bases": [ + "NativeView" + ], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "export_path", + "type": "str", + "default": "" + }, + { + "name": "package_hash", + "type": "str", + "default": "" + }, + { + "name": "document_count", + "type": "int", + "default": "" + }, + { + "name": "release_artifact_count", + "type": "int", + "default": "" + }, + { + "name": "search_session_count", + "type": "int", + "default": "" + }, + { + "name": "release_count", + "type": "int", + "default": "" + }, + { + "name": "redacted_count", + "type": "int", + "default": "" + }, + { + "name": "exempt_count", + "type": "int", + "default": "" + }, + { + "name": "created_at_unix_seconds", + "type": "int", + "default": "" + } + ], + "line": 397, + "doc": "" + }, + { + "name": "PrepareArtifact", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "kind", + "type": "Literal['response', 'release-package']", + "default": "" + } + ], + "line": 410, + "doc": "" + }, + { + "name": "ArtifactPlan", + "bases": [ + "NativeView" + ], + "fields": [ + { + "name": "artifact_id", + "type": "str", + "default": "" + }, + { + "name": "file_name", + "type": "str", + "default": "" + }, + { + "name": "content", + "type": "str", + "default": "" + }, + { + "name": "sha256", + "type": "str", + "default": "" + }, + { + "name": "created_at_unix_seconds", + "type": "int", + "default": "" + } + ], + "line": 414, + "doc": "" + }, + { + "name": "CompleteArtifact", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "export_path", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 422, + "doc": "" + }, + { + "name": "PublicIntake", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "requester", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "requesterContact", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "summary", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "deadline", + "type": "str", + "default": "''" + } + ], + "line": 426, + "doc": "" + }, + { + "name": "PublicLookup", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "trackingNumber", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "requesterContact", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 433, + "doc": "" + }, + { + "name": "PublicMessage", + "bases": [ + "PublicLookup" + ], + "fields": [ + { + "name": "publicRequestMessage", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 438, + "doc": "" + }, + { + "name": "GeneratedDraft", + "bases": [ + "NativePayload" + ], + "fields": [ + { + "name": "text", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "model", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "previous_response_sha256", + "type": "str", + "default": "Field(pattern='^[0-9a-f]{64}$')" + } + ], + "line": 442, + "doc": "" + }, + { + "name": "NotificationView", + "bases": [ + "NativeView" + ], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "notification_id", + "type": "str", + "default": "" + }, + { + "name": "module_id", + "type": "str", + "default": "" + }, + { + "name": "record_id", + "type": "str", + "default": "" + }, + { + "name": "audience", + "type": "str", + "default": "" + }, + { + "name": "channel", + "type": "str", + "default": "" + }, + { + "name": "subject", + "type": "str", + "default": "" + }, + { + "name": "body", + "type": "str", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "created_at_unix_seconds", + "type": "int", + "default": "" + }, + { + "name": "sent_at_unix_seconds", + "type": "int | None", + "default": "" + } + ], + "line": 448, + "doc": "" + }, + { + "name": "PublicationView", + "bases": [ + "NativeView" + ], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "source_module", + "type": "str", + "default": "" + }, + { + "name": "source_record_id", + "type": "str", + "default": "" + }, + { + "name": "record_type", + "type": "str", + "default": "" + }, + { + "name": "public_payload", + "type": "str", + "default": "" + }, + { + "name": "payload_hash", + "type": "str", + "default": "" + }, + { + "name": "published_at_unix_seconds", + "type": "int", + "default": "" + }, + { + "name": "retracted_at_unix_seconds", + "type": "int | None", + "default": "None" + }, + { + "name": "retracted_by", + "type": "str", + "default": "''" + } + ], + "line": 462, + "doc": "" + }, + { + "name": "AuditView", + "bases": [ + "NativeView" + ], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "module_id", + "type": "str", + "default": "" + }, + { + "name": "action", + "type": "str", + "default": "" + }, + { + "name": "summary", + "type": "str", + "default": "" + }, + { + "name": "created_at_unix_seconds", + "type": "int", + "default": "" + }, + { + "name": "previous_hash", + "type": "str", + "default": "" + }, + { + "name": "entry_hash", + "type": "str", + "default": "" + } + ], + "line": 474, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/app/desktop_bridge/station.py", + "sha256": "2f53398b6a897f804419ea5025895bb7dc468d8891dc553b20bb14cb5d0a8084", + "routes": [ + { + "method": "GET", + "path": "/station/context", + "router": "router", + "prefix_resolved": false, + "name": "context", + "signature": "request: Request, capability: Literal['capture', 'read'], proof: str | None=Header(default=None, alias='X-Townlight-Session'), session: AsyncSession=Depends(get_async_session)", + "returns": "", + "line": 43, + "doc": "", + "decorator": "router.get('/station/context')", + "errors": [ + "HTTPException(403, 'This staff role cannot perform this Station operation')", + "HTTPException(401, str(exc))" + ] + }, + { + "method": "POST", + "path": "/requests/{request_id}/station-recordings", + "router": "router", + "prefix_resolved": false, + "name": "attach", + "signature": "request_id: UUID, data: Selection, request: Request, actor=Depends(station_actor), session: AsyncSession=Depends(get_async_session)", + "returns": "", + "line": 79, + "doc": "", + "decorator": "router.post('/requests/{request_id}/station-recordings', response_model=RecordsOperationRead)", + "errors": [ + "HTTPException(404, 'Records request not found')", + "HTTPException(409, str(exc))", + "HTTPException(422, 'Station evidence not attached; existing evidence preserved')", + "HTTPException(response.status_code, 'Station denied this recording')", + "HTTPException(409, 'Station recording is incomplete or changed; refresh selection')" + ] + } + ], + "models": [ + { + "name": "Selection", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "recording_id", + "type": "UUID", + "default": "" + }, + { + "name": "expected_sha256", + "type": "str", + "default": "Field(pattern='^[0-9a-f]{64}$')" + } + ], + "line": 61, + "doc": "" + } + ], + "configuration": [ + { + "variable": "TOWNLIGHT_STATION_URL", + "default": "''", + "line": 33 + } + ] + } + ] + }, + "meetings": { + "package": "townlight_meetings", + "source": [ + { + "source": "installed-owned-source/townlight_meetings/__init__.py", + "sha256": "e8c6f4d348bc657f507a748a9f941317ea223f13facbc6f71d5777872d472564", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/agenda_intake.py", + "sha256": "efe504bf430447fdd19ee39fbeace4c03365c6bd5f967f29bba40bd3dd48cfd2", + "routes": [], + "models": [ + { + "name": "AgendaIntakeItem", + "bases": [], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "title", + "type": "str", + "default": "" + }, + { + "name": "department_name", + "type": "str", + "default": "" + }, + { + "name": "submitted_by", + "type": "str", + "default": "" + }, + { + "name": "summary", + "type": "str", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "readiness_status", + "type": "str", + "default": "" + }, + { + "name": "source_references", + "type": "list[dict]", + "default": "" + }, + { + "name": "reviewer", + "type": "str | None", + "default": "" + }, + { + "name": "review_notes", + "type": "str | None", + "default": "" + }, + { + "name": "promoted_agenda_item_id", + "type": "str | None", + "default": "" + }, + { + "name": "promoted_at", + "type": "datetime | None", + "default": "" + }, + { + "name": "promotion_audit_hash", + "type": "str | None", + "default": "" + }, + { + "name": "last_audit_hash", + "type": "str", + "default": "" + }, + { + "name": "created_at", + "type": "datetime", + "default": "" + }, + { + "name": "updated_at", + "type": "datetime", + "default": "" + } + ], + "line": 51, + "doc": "Department-submitted item waiting for staff readiness review." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/agenda_lifecycle.py", + "sha256": "e1e3fb531ca432cbc94bb258454776b8f97112077c5bbcd7d015a6f82f751a14", + "routes": [], + "models": [ + { + "name": "TransitionResult", + "bases": [], + "fields": [ + { + "name": "allowed", + "type": "bool", + "default": "" + }, + { + "name": "http_status", + "type": "int", + "default": "" + }, + { + "name": "message", + "type": "str", + "default": "" + }, + { + "name": "fix", + "type": "str", + "default": "" + }, + { + "name": "audit_entry", + "type": "dict[str, object]", + "default": "" + } + ], + "line": 39, + "doc": "" + }, + { + "name": "AgendaItemRecord", + "bases": [], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "title", + "type": "str", + "default": "" + }, + { + "name": "department_name", + "type": "str", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "'DRAFTED'" + }, + { + "name": "audit_entries", + "type": "list[dict[str, object]]", + "default": "field(default_factory=list)" + }, + { + "name": "meeting_id", + "type": "str | None", + "default": "None" + } + ], + "line": 48, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/cc7_completeness.py", + "sha256": "683d4ba8f4bf4a047e0e3d87725497f30da5210c4496e4586eecc20b1784a468", + "routes": [], + "models": [ + { + "name": "ApiCategory", + "bases": [], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "label", + "type": "str", + "default": "" + }, + { + "name": "paths", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "protected", + "type": "bool", + "default": "" + }, + { + "name": "auth_scope", + "type": "str", + "default": "'staff-only'" + } + ], + "line": 12, + "doc": "" + }, + { + "name": "FrontendPage", + "bases": [], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "label", + "type": "str", + "default": "" + }, + { + "name": "surface", + "type": "str", + "default": "" + }, + { + "name": "evidence_states", + "type": "tuple[str, ...]", + "default": "REQUIRED_VIEW_STATES" + } + ], + "line": 21, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/connector_import_sync.py", + "sha256": "1d30954f15c9b6d8a9afb5ef9392b4a7475bfd7d926b040707380a7005b8f96e", + "routes": [], + "models": [ + { + "name": "ImportAttempt", + "bases": [], + "fields": [ + { + "name": "connector", + "type": "str", + "default": "" + }, + { + "name": "payload_path", + "type": "Path", + "default": "" + }, + { + "name": "ok", + "type": "bool", + "default": "" + }, + { + "name": "message", + "type": "str", + "default": "" + }, + { + "name": "fix", + "type": "str", + "default": "" + }, + { + "name": "normalized", + "type": "dict[str, Any] | None", + "default": "None" + } + ], + "line": 14, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/connectors.py", + "sha256": "31c19cd11f63ae32db9b51f0da57ac5cc8b637a63a16c6b1287c10a7d5afda9d", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/demo_seed.py", + "sha256": "d983fb6b80310ce84a0c703f55b5b35e5ecb73f8b5f0c407bab1f9edf27f5cbb", + "routes": [], + "models": [ + { + "name": "DemoSeedSummary", + "bases": [ + "TypedDict" + ], + "fields": [ + { + "name": "city", + "type": "str", + "default": "" + }, + { + "name": "meeting_body_count", + "type": "int", + "default": "" + }, + { + "name": "meeting_count", + "type": "int", + "default": "" + }, + { + "name": "agenda_intake_count", + "type": "int", + "default": "" + }, + { + "name": "packet_count", + "type": "int", + "default": "" + }, + { + "name": "notice_count", + "type": "int", + "default": "" + }, + { + "name": "motion_count", + "type": "int", + "default": "" + }, + { + "name": "minutes_draft_count", + "type": "int", + "default": "" + }, + { + "name": "public_record_count", + "type": "int", + "default": "" + }, + { + "name": "primary_meeting_id", + "type": "str", + "default": "" + } + ], + "line": 35, + "doc": "Counts and representative ids produced by the demo seed." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/desktop_delivery.py", + "sha256": "cbb7f44aee90b9ea16c60c1f64efffa8bb7204765d49a5ce80fe52e2670d384e", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/integration_contracts.py", + "sha256": "3899a7aad3af2464ab35d15fee07b952e130cb207a36d1a07dfb6986c67bd805", + "routes": [], + "models": [ + { + "name": "IntegrationCheck", + "bases": [], + "fields": [ + { + "name": "contract_id", + "type": "str", + "default": "" + }, + { + "name": "scenario", + "type": "str", + "default": "" + }, + { + "name": "ok", + "type": "bool", + "default": "" + }, + { + "name": "message", + "type": "str", + "default": "" + }, + { + "name": "fix", + "type": "str", + "default": "" + } + ], + "line": 17, + "doc": "A no-network adversarial check for one integration contract." + }, + { + "name": "IntegrationContract", + "bases": [], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "label", + "type": "str", + "default": "" + }, + { + "name": "status", + "type": "IntegrationStatus", + "default": "" + }, + { + "name": "mode", + "type": "str", + "default": "" + }, + { + "name": "proof_model", + "type": "Literal['live_wire_validation', 'in_process_boundary_validation']", + "default": "" + }, + { + "name": "dependent_module_required", + "type": "bool", + "default": "" + }, + { + "name": "network_calls", + "type": "bool", + "default": "" + }, + { + "name": "contract_artifact", + "type": "str", + "default": "" + }, + { + "name": "supported_operations", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "absent_dependency_behavior", + "type": "str", + "default": "" + }, + { + "name": "operator_fix", + "type": "str", + "default": "" + }, + { + "name": "adversarial_scenarios", + "type": "tuple[str, ...]", + "default": "" + } + ], + "line": 37, + "doc": "Operator-facing contract for an integration that may not exist yet." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/main.py", + "sha256": "d224d17b9869739b6faaddcd7213e202f8b710f72cda402479c0c6a84e737285", + "routes": [ + { + "method": "GET", + "path": "/", + "router": "app", + "prefix_resolved": true, + "name": "root", + "signature": "", + "returns": "dict[str, str]", + "line": 492, + "doc": "Describe what the runtime foundation currently provides.", + "decorator": "app.get('/')", + "errors": [] + }, + { + "method": "GET", + "path": "/health", + "router": "app", + "prefix_resolved": true, + "name": "health", + "signature": "", + "returns": "dict[str, str]", + "line": 550, + "doc": "Provide a simple operational health check for IT staff.", + "decorator": "app.get('/health')", + "errors": [] + }, + { + "method": "GET", + "path": "/favicon.ico", + "router": "app", + "prefix_resolved": true, + "name": "favicon", + "signature": "", + "returns": "Response", + "line": 561, + "doc": "Return an empty public favicon response so browser QA stays console-clean.", + "decorator": "app.get('/favicon.ico', response_class=Response)", + "errors": [] + }, + { + "method": "GET", + "path": "/staff", + "router": "app", + "prefix_resolved": true, + "name": "staff_dashboard", + "signature": "", + "returns": "str", + "line": 567, + "doc": "Render the staff-facing workflow foundation.", + "decorator": "app.get('/staff', response_class=HTMLResponse)", + "errors": [] + }, + { + "method": "GET", + "path": "/public", + "router": "app", + "prefix_resolved": true, + "name": "public_portal", + "signature": "", + "returns": "str", + "line": 617, + "doc": "Render the resident-facing public portal shell.", + "decorator": "app.get('/public', response_class=HTMLResponse)", + "errors": [] + }, + { + "method": "GET", + "path": "/staff/session", + "router": "app", + "prefix_resolved": true, + "name": "staff_session", + "signature": "request: Request", + "returns": "dict[str, object]", + "line": 623, + "doc": "Describe the current staff access mode for the browser workflow shell.", + "decorator": "app.get('/staff/session')", + "errors": [ + "HTTPException(status_code=401, detail={'message': 'Staff authentication is required.', 'fix': f'The default {STAFF_AUTH_MODE_ENV_VAR}={STAFF_PROTECTED_MODE} denies anonymous staff writes. Configure bearer, trusted-header, or OIDC staff auth, or explicitly set {STAFF_AUTH_MODE_ENV_VAR}={STAFF_OPEN_MODE} only for local rehearsal.'}, headers={'WWW-Authenticate': 'Bearer'})", + "HTTPException(status_code=500, detail={'message': 'Staff session principal is missing.', 'fix': 'Retry the request with a configured bearer token or review staff auth middleware setup.'})" + ] + }, + { + "method": "GET", + "path": "/staff/login", + "router": "app", + "prefix_resolved": true, + "name": "staff_login", + "signature": "request: Request", + "returns": "RedirectResponse", + "line": 705, + "doc": "Start the municipal OIDC browser sign-in flow for staff users.", + "decorator": "app.get('/staff/login')", + "errors": [ + "HTTPException(status_code=400, detail={'message': 'OIDC browser sign-in is available only when staff auth mode is oidc.', 'fix': f'Set {STAFF_AUTH_MODE_ENV_VAR}={STAFF_OIDC_MODE} before using /staff/login.'})", + "HTTPException(status_code=503, detail={'message': 'OIDC browser sign-in is not fully configured.', 'fix': _oidc_browser_login_fix(missing)})" + ] + }, + { + "method": "GET", + "path": "/staff/oidc/callback", + "router": "app", + "prefix_resolved": true, + "name": "staff_oidc_callback", + "signature": "request: Request", + "returns": "RedirectResponse", + "line": 763, + "doc": "Complete the OIDC authorization-code callback and issue a staff session cookie.", + "decorator": "app.get('/staff/oidc/callback')", + "errors": [ + "HTTPException(status_code=400, detail={'message': 'OIDC callback received while staff auth mode is not oidc.', 'fix': f'Set {STAFF_AUTH_MODE_ENV_VAR}={STAFF_OIDC_MODE}, then restart sign-in from /staff/login.'})", + "HTTPException(status_code=400, detail={'message': 'OIDC provider returned a sign-in error.', 'fix': f\"Review the provider response '{callback_error}', then restart sign-in from /staff/login.\"})", + "HTTPException(status_code=400, detail={'message': 'OIDC sign-in state did not match.', 'fix': 'Restart sign-in from /staff/login. If this repeats, confirm cookies are allowed for the CivicMeetings host.'})", + "HTTPException(status_code=400, detail={'message': 'OIDC sign-in PKCE verifier is missing.', 'fix': 'Restart sign-in from /staff/login. If this repeats, confirm cookies are allowed for the CivicMeetings host.'})", + "HTTPException(status_code=400, detail={'message': 'OIDC callback did not include an authorization code.', 'fix': 'Restart sign-in from /staff/login and confirm the provider uses authorization-code flow.'})", + "HTTPException(status_code=503, detail={'message': 'OIDC browser sign-in is not fully configured.', 'fix': _oidc_browser_login_fix(missing)})", + "HTTPException(status_code=502, detail={'message': 'OIDC token response did not include an ID token or access token.', 'fix': 'Confirm the provider app registration issues an ID token or API access token for CivicMeetings.'})" + ] + }, + { + "method": "GET", + "path": "/staff/logout", + "router": "app", + "prefix_resolved": true, + "name": "staff_logout", + "signature": "request: Request", + "returns": "RedirectResponse", + "line": 861, + "doc": "Clear the local CivicMeetings staff browser session.", + "decorator": "app.get('/staff/logout')", + "errors": [] + }, + { + "method": "POST", + "path": "/staff/logout", + "router": "app", + "prefix_resolved": true, + "name": "staff_logout", + "signature": "request: Request", + "returns": "RedirectResponse", + "line": 861, + "doc": "Clear the local CivicMeetings staff browser session.", + "decorator": "app.post('/staff/logout')", + "errors": [] + }, + { + "method": "GET", + "path": "/staff/auth-readiness", + "router": "app", + "prefix_resolved": true, + "name": "staff_auth_readiness", + "signature": "", + "returns": "dict[str, object]", + "line": 873, + "doc": "Report whether the current staff auth mode is configured for safe use.", + "decorator": "app.get('/staff/auth-readiness')", + "errors": [] + }, + { + "method": "GET", + "path": "/admin/config", + "router": "app", + "prefix_resolved": true, + "name": "admin_config", + "signature": "", + "returns": "dict[str, object]", + "line": 935, + "doc": "Describe CC-7 runtime coverage and staff-auth configuration posture.", + "decorator": "app.get('/admin/config')", + "errors": [] + }, + { + "method": "GET", + "path": "/integrations/readiness", + "router": "app", + "prefix_resolved": true, + "name": "integrations_readiness", + "signature": "", + "returns": "dict[str, object]", + "line": 968, + "doc": "Report live or in-process integration boundary contracts.", + "decorator": "app.get('/integrations/readiness')", + "errors": [] + }, + { + "method": "GET", + "path": "/admin/prompts", + "router": "app", + "prefix_resolved": true, + "name": "admin_prompts", + "signature": "", + "returns": "dict[str, object]", + "line": 975, + "doc": "List prompt-library definitions and public approval gates for admins.", + "decorator": "app.get('/admin/prompts')", + "errors": [] + }, + { + "method": "POST", + "path": "/agenda-items", + "router": "app", + "prefix_resolved": true, + "name": "create_agenda_item", + "signature": "payload: AgendaItemCreate", + "returns": "dict[str, str]", + "line": 1009, + "doc": "Create a draft agenda item for lifecycle enforcement.", + "decorator": "app.post('/agenda-items', status_code=201)", + "errors": [] + }, + { + "method": "GET", + "path": "/agenda-items/{item_id}", + "router": "app", + "prefix_resolved": true, + "name": "get_agenda_item", + "signature": "item_id: str", + "returns": "dict[str, str]", + "line": 1018, + "doc": "Return the current agenda item state.", + "decorator": "app.get('/agenda-items/{item_id}')", + "errors": [ + "HTTPException(status_code=404, detail='Agenda item not found.')" + ] + }, + { + "method": "POST", + "path": "/agenda-items/{item_id}/transitions", + "router": "app", + "prefix_resolved": true, + "name": "transition_agenda_item", + "signature": "item_id: str, payload: AgendaItemTransitionRequest", + "returns": "dict[str, str]", + "line": 1027, + "doc": "Apply a canonical agenda item lifecycle transition.", + "decorator": "app.post('/agenda-items/{item_id}/transitions')", + "errors": [ + "HTTPException(status_code=404, detail='Agenda item not found.')", + "HTTPException(status_code=result.http_status, detail={'message': result.message, 'fix': result.fix, 'current_status': item.status, 'requested_status': payload.to_status})" + ] + }, + { + "method": "GET", + "path": "/agenda-items/{item_id}/audit", + "router": "app", + "prefix_resolved": true, + "name": "get_agenda_item_audit", + "signature": "item_id: str", + "returns": "dict[str, list[dict[str, object]]]", + "line": 1058, + "doc": "Return lifecycle audit entries for an agenda item.", + "decorator": "app.get('/agenda-items/{item_id}/audit')", + "errors": [ + "HTTPException(status_code=404, detail='Agenda item not found.')" + ] + }, + { + "method": "POST", + "path": "/agenda-intake", + "router": "app", + "prefix_resolved": true, + "name": "submit_agenda_intake_item", + "signature": "payload: AgendaIntakeCreate", + "returns": "dict", + "line": 1067, + "doc": "Submit a department agenda item into the database-backed staff queue.", + "decorator": "app.post('/agenda-intake', status_code=201)", + "errors": [] + }, + { + "method": "GET", + "path": "/agenda-intake", + "router": "app", + "prefix_resolved": true, + "name": "list_agenda_intake_items", + "signature": "readiness_status: str | None=None", + "returns": "dict[str, list[dict]]", + "line": 1080, + "doc": "List department-submitted agenda intake items awaiting staff review.", + "decorator": "app.get('/agenda-intake')", + "errors": [] + }, + { + "method": "POST", + "path": "/agenda-intake/{item_id}/review", + "router": "app", + "prefix_resolved": true, + "name": "review_agenda_intake_item", + "signature": "item_id: str, payload: AgendaIntakeReviewRequest", + "returns": "dict", + "line": 1093, + "doc": "Record clerk readiness review for an intake queue item.", + "decorator": "app.post('/agenda-intake/{item_id}/review')", + "errors": [ + "HTTPException(status_code=404, detail={'message': 'Agenda intake item not found.', 'fix': 'Submit the agenda item into the intake queue before review.'})" + ] + }, + { + "method": "POST", + "path": "/agenda-intake/{item_id}/promote", + "router": "app", + "prefix_resolved": true, + "name": "promote_agenda_intake_item", + "signature": "item_id: str, payload: AgendaIntakePromoteRequest, response: Response", + "returns": "dict", + "line": 1116, + "doc": "Promote a clerk-ready intake item into the canonical agenda lifecycle.", + "decorator": "app.post('/agenda-intake/{item_id}/promote', status_code=201)", + "errors": [ + "HTTPException(status_code=404, detail={'message': 'Agenda intake item not found.', 'fix': 'Submit the agenda item into intake, then complete clerk review before promotion.'})", + "HTTPException(status_code=409, detail={'message': 'Agenda intake item is not ready for agenda promotion.', 'current_readiness_status': intake_item.readiness_status, 'fix': 'Mark the item ready in the clerk review queue, then promote it to agenda work.'})", + "HTTPException(status_code=404, detail={'message': 'Agenda intake item disappeared during promotion.', 'fix': 'Reload the intake queue and retry promotion from the current record.'})", + "HTTPException(status_code=500, detail={'message': 'Agenda item promotion could not complete its lifecycle transitions.', 'fix': 'Retry promotion after confirming the agenda lifecycle service is available.'})" + ] + }, + { + "method": "POST", + "path": "/meetings/{meeting_id}/staff-reports", + "router": "app", + "prefix_resolved": true, + "name": "create_staff_report", + "signature": "meeting_id: str, payload: StaffReportCreate", + "returns": "dict[str, object]", + "line": 1193, + "doc": "Normalize a staff report into the clerk-visible agenda intake trail.", + "decorator": "app.post('/meetings/{meeting_id}/staff-reports', status_code=201)", + "errors": [] + }, + { + "method": "GET", + "path": "/meetings/{meeting_id}/staff-reports", + "router": "app", + "prefix_resolved": true, + "name": "list_staff_reports", + "signature": "meeting_id: str", + "returns": "dict[str, object]", + "line": 1222, + "doc": "List staff report records linked to a meeting.", + "decorator": "app.get('/meetings/{meeting_id}/staff-reports')", + "errors": [] + }, + { + "method": "POST", + "path": "/meeting-bodies", + "router": "app", + "prefix_resolved": true, + "name": "create_meeting_body", + "signature": "payload: MeetingBodyCreate", + "returns": "dict[str, str | bool]", + "line": 1246, + "doc": "Create a municipal meeting body for staff calendar workflows.", + "decorator": "app.post('/meeting-bodies', status_code=201)", + "errors": [] + }, + { + "method": "GET", + "path": "/meeting-bodies", + "router": "app", + "prefix_resolved": true, + "name": "list_meeting_bodies", + "signature": "active_only: bool=False", + "returns": "dict[str, int | list[dict[str, str | bool]]]", + "line": 1257, + "doc": "List municipal meeting bodies for staff setup and scheduling clients.", + "decorator": "app.get('/meeting-bodies')", + "errors": [] + }, + { + "method": "GET", + "path": "/meeting-bodies/{body_id}", + "router": "app", + "prefix_resolved": true, + "name": "get_meeting_body", + "signature": "body_id: str", + "returns": "dict[str, str | bool]", + "line": 1268, + "doc": "Return one municipal meeting body.", + "decorator": "app.get('/meeting-bodies/{body_id}')", + "errors": [ + "HTTPException(status_code=404, detail='Meeting body not found.')" + ] + }, + { + "method": "PATCH", + "path": "/meeting-bodies/{body_id}", + "router": "app", + "prefix_resolved": true, + "name": "update_meeting_body", + "signature": "body_id: str, payload: MeetingBodyUpdate", + "returns": "dict[str, str | bool]", + "line": 1278, + "doc": "Update a municipal meeting body without losing its record identity.", + "decorator": "app.patch('/meeting-bodies/{body_id}')", + "errors": [ + "HTTPException(status_code=404, detail='Meeting body not found.')" + ] + }, + { + "method": "DELETE", + "path": "/meeting-bodies/{body_id}", + "router": "app", + "prefix_resolved": true, + "name": "deactivate_meeting_body", + "signature": "body_id: str", + "returns": "dict[str, str | bool]", + "line": 1296, + "doc": "Deactivate a meeting body instead of hard-deleting legal history.", + "decorator": "app.delete('/meeting-bodies/{body_id}')", + "errors": [ + "HTTPException(status_code=404, detail='Meeting body not found.')" + ] + }, + { + "method": "POST", + "path": "/meetings", + "router": "app", + "prefix_resolved": true, + "name": "create_meeting", + "signature": "payload: MeetingCreate", + "returns": "dict[str, str]", + "line": 1306, + "doc": "Create a scheduled meeting for lifecycle enforcement.", + "decorator": "app.post('/meetings', status_code=201)", + "errors": [] + }, + { + "method": "GET", + "path": "/meetings", + "router": "app", + "prefix_resolved": true, + "name": "list_meetings", + "signature": "", + "returns": "dict[str, int | list[dict[str, str | None]]]", + "line": 1322, + "doc": "List meetings for staff calendar and dashboard clients.", + "decorator": "app.get('/meetings')", + "errors": [] + }, + { + "method": "GET", + "path": "/meetings/{meeting_id}", + "router": "app", + "prefix_resolved": true, + "name": "get_meeting", + "signature": "meeting_id: str", + "returns": "dict[str, str]", + "line": 1329, + "doc": "Return the current meeting state.", + "decorator": "app.get('/meetings/{meeting_id}')", + "errors": [ + "HTTPException(status_code=404, detail='Meeting not found.')" + ] + }, + { + "method": "PATCH", + "path": "/meetings/{meeting_id}", + "router": "app", + "prefix_resolved": true, + "name": "update_meeting_schedule", + "signature": "meeting_id: str, payload: MeetingUpdate", + "returns": "dict[str, str]", + "line": 1338, + "doc": "Edit staff scheduling fields before the public meeting is locked.", + "decorator": "app.patch('/meetings/{meeting_id}')", + "errors": [ + "HTTPException(status_code=422, detail={'message': 'Meeting update did not include any schedule fields.', 'fix': 'Send at least one of title, meeting_type, scheduled_start, meeting_body_id, or location.'})", + "HTTPException(status_code=404, detail='Meeting not found.')", + "HTTPException(status_code=409, detail={'message': exc.message, 'fix': exc.fix})" + ] + }, + { + "method": "POST", + "path": "/meetings/{meeting_id}/transitions", + "router": "app", + "prefix_resolved": true, + "name": "transition_meeting", + "signature": "meeting_id: str, payload: MeetingTransitionRequest", + "returns": "dict[str, str]", + "line": 1391, + "doc": "Apply a canonical meeting lifecycle transition.", + "decorator": "app.post('/meetings/{meeting_id}/transitions')", + "errors": [ + "HTTPException(status_code=404, detail='Meeting not found.')", + "HTTPException(status_code=result.http_status, detail={'message': result.message, 'fix': result.fix, 'current_status': meeting.status, 'requested_status': payload.to_status})" + ] + }, + { + "method": "GET", + "path": "/meetings/{meeting_id}/audit", + "router": "app", + "prefix_resolved": true, + "name": "get_meeting_audit", + "signature": "meeting_id: str", + "returns": "dict[str, list[dict[str, object]]]", + "line": 1424, + "doc": "Return lifecycle audit entries for a meeting.", + "decorator": "app.get('/meetings/{meeting_id}/audit')", + "errors": [ + "HTTPException(status_code=404, detail='Meeting not found.')" + ] + }, + { + "method": "POST", + "path": "/meetings/{meeting_id}/packet-snapshots", + "router": "app", + "prefix_resolved": true, + "name": "create_packet_snapshot", + "signature": "meeting_id: str, payload: PacketSnapshotCreate", + "returns": "dict", + "line": 1433, + "doc": "Create an immutable packet snapshot version for a meeting.", + "decorator": "app.post('/meetings/{meeting_id}/packet-snapshots', status_code=201)", + "errors": [ + "HTTPException(status_code=404, detail='Meeting not found.')" + ] + }, + { + "method": "GET", + "path": "/meetings/{meeting_id}/packet-snapshots", + "router": "app", + "prefix_resolved": true, + "name": "list_packet_snapshots", + "signature": "meeting_id: str", + "returns": "dict[str, list[dict]]", + "line": 1449, + "doc": "Return packet snapshot versions for a meeting.", + "decorator": "app.get('/meetings/{meeting_id}/packet-snapshots')", + "errors": [ + "HTTPException(status_code=404, detail='Meeting not found.')" + ] + }, + { + "method": "POST", + "path": "/meetings/{meeting_id}/packet-assemblies", + "router": "app", + "prefix_resolved": true, + "name": "create_packet_assembly_record", + "signature": "meeting_id: str, payload: PacketAssemblyCreate", + "returns": "dict", + "line": 1463, + "doc": "Create a persisted packet assembly record tied to a packet snapshot.", + "decorator": "app.post('/meetings/{meeting_id}/packet-assemblies', status_code=201)", + "errors": [ + "HTTPException(status_code=404, detail='Meeting not found.')" + ] + }, + { + "method": "GET", + "path": "/meetings/{meeting_id}/packet-assemblies", + "router": "app", + "prefix_resolved": true, + "name": "list_packet_assembly_records", + "signature": "meeting_id: str", + "returns": "dict[str, list[dict]]", + "line": 1489, + "doc": "List persisted packet assembly records for a meeting.", + "decorator": "app.get('/meetings/{meeting_id}/packet-assemblies')", + "errors": [ + "HTTPException(status_code=404, detail='Meeting not found.')" + ] + }, + { + "method": "POST", + "path": "/packet-assemblies/{record_id}/finalize", + "router": "app", + "prefix_resolved": true, + "name": "finalize_packet_assembly_record", + "signature": "record_id: str, payload: PacketAssemblyFinalizeRequest", + "returns": "dict", + "line": 1503, + "doc": "Finalize a persisted packet assembly record.", + "decorator": "app.post('/packet-assemblies/{record_id}/finalize')", + "errors": [ + "HTTPException(status_code=404, detail={'message': 'Packet assembly record not found.', 'fix': 'Create the packet assembly record before finalizing it.'})" + ] + }, + { + "method": "POST", + "path": "/meetings/{meeting_id}/export-bundle", + "router": "app", + "prefix_resolved": true, + "name": "create_packet_export_bundle", + "signature": "meeting_id: str, payload: PacketExportCreate", + "returns": "dict", + "line": 1524, + "doc": "Create a records-ready packet export bundle with manifest, checksums, and audit.", + "decorator": "app.post('/meetings/{meeting_id}/export-bundle', status_code=201)", + "errors": [ + "HTTPException(status_code=404, detail='Meeting not found.')", + "HTTPException(status_code=error.http_status, detail=error.public_dict())" + ] + }, + { + "method": "POST", + "path": "/meetings/{meeting_id}/notices/check", + "router": "app", + "prefix_resolved": true, + "name": "check_notice_compliance", + "signature": "meeting_id: str, payload: NoticeComplianceRequest", + "returns": "dict", + "line": 1559, + "doc": "Check public notice compliance without posting.", + "decorator": "app.post('/meetings/{meeting_id}/notices/check')", + "errors": [ + "HTTPException(status_code=result.http_status, detail={'message': 'Notice is not ready for public posting. Review the warnings and fix each item.', 'warnings': result.warnings})" + ] + }, + { + "method": "POST", + "path": "/meetings/{meeting_id}/notice-checklists", + "router": "app", + "prefix_resolved": true, + "name": "create_notice_checklist_record", + "signature": "meeting_id: str, payload: NoticeChecklistCreate", + "returns": "dict", + "line": 1577, + "doc": "Persist a notice compliance checklist record for staff review.", + "decorator": "app.post('/meetings/{meeting_id}/notice-checklists', status_code=201)", + "errors": [] + }, + { + "method": "GET", + "path": "/meetings/{meeting_id}/notice-checklists", + "router": "app", + "prefix_resolved": true, + "name": "list_notice_checklist_records", + "signature": "meeting_id: str", + "returns": "dict[str, list[dict]]", + "line": 1599, + "doc": "List persisted notice checklist records for a meeting.", + "decorator": "app.get('/meetings/{meeting_id}/notice-checklists')", + "errors": [ + "HTTPException(status_code=404, detail='Meeting not found.')" + ] + }, + { + "method": "POST", + "path": "/notice-checklists/{record_id}/posting-proof", + "router": "app", + "prefix_resolved": true, + "name": "attach_notice_posting_proof", + "signature": "record_id: str, payload: NoticePostingProofCreate", + "returns": "dict", + "line": 1613, + "doc": "Attach posting proof metadata to a persisted notice checklist record.", + "decorator": "app.post('/notice-checklists/{record_id}/posting-proof')", + "errors": [ + "HTTPException(status_code=404, detail={'message': 'Notice checklist record not found.', 'fix': 'Create the notice checklist record before attaching posting proof.'})" + ] + }, + { + "method": "POST", + "path": "/meetings/{meeting_id}/notices/post", + "router": "app", + "prefix_resolved": true, + "name": "post_notice", + "signature": "meeting_id: str, payload: NoticeComplianceRequest", + "returns": "dict", + "line": 1635, + "doc": "Post a public notice after deadline and human-approval checks pass.", + "decorator": "app.post('/meetings/{meeting_id}/notices/post', status_code=201)", + "errors": [ + "HTTPException(status_code=result.http_status, detail={'message': 'Notice cannot be posted publicly. Review the warnings and fix each item.', 'warnings': result.warnings})" + ] + }, + { + "method": "POST", + "path": "/meetings/{meeting_id}/motions", + "router": "app", + "prefix_resolved": true, + "name": "capture_motion", + "signature": "meeting_id: str, payload: MotionCreate", + "returns": "dict", + "line": 1653, + "doc": "Capture an immutable motion for a meeting.", + "decorator": "app.post('/meetings/{meeting_id}/motions', status_code=201)", + "errors": [ + "HTTPException(status_code=404, detail='Meeting not found.')" + ] + }, + { + "method": "GET", + "path": "/meetings/{meeting_id}/motions", + "router": "app", + "prefix_resolved": true, + "name": "list_motions", + "signature": "meeting_id: str", + "returns": "dict[str, list[dict]]", + "line": 1668, + "doc": "List captured motions and correction records for a meeting.", + "decorator": "app.get('/meetings/{meeting_id}/motions')", + "errors": [ + "HTTPException(status_code=404, detail='Meeting not found.')" + ] + }, + { + "method": "PUT", + "path": "/motions/{motion_id}", + "router": "app", + "prefix_resolved": true, + "name": "reject_motion_mutation", + "signature": "motion_id: str", + "returns": "None", + "line": 1683, + "doc": "Reject edits to captured motions; corrections must be append-only.", + "decorator": "app.put('/motions/{motion_id}')", + "errors": [ + "HTTPException(status_code=409, detail={'message': 'Captured motions are immutable.', 'fix': 'Use POST /motions/{motion_id}/corrections to add a correction record that references the original motion.'})", + "HTTPException(status_code=404, detail='Motion not found.')" + ] + }, + { + "method": "PATCH", + "path": "/motions/{motion_id}", + "router": "app", + "prefix_resolved": true, + "name": "reject_motion_mutation", + "signature": "motion_id: str", + "returns": "None", + "line": 1683, + "doc": "Reject edits to captured motions; corrections must be append-only.", + "decorator": "app.patch('/motions/{motion_id}')", + "errors": [ + "HTTPException(status_code=409, detail={'message': 'Captured motions are immutable.', 'fix': 'Use POST /motions/{motion_id}/corrections to add a correction record that references the original motion.'})", + "HTTPException(status_code=404, detail='Motion not found.')" + ] + }, + { + "method": "POST", + "path": "/motions/{motion_id}/corrections", + "router": "app", + "prefix_resolved": true, + "name": "correct_motion", + "signature": "motion_id: str, payload: MotionCorrectionCreate", + "returns": "dict", + "line": 1697, + "doc": "Create an append-only correction record for a captured motion.", + "decorator": "app.post('/motions/{motion_id}/corrections', status_code=201)", + "errors": [ + "HTTPException(status_code=404, detail='Motion not found.')" + ] + }, + { + "method": "POST", + "path": "/motions/{motion_id}/votes", + "router": "app", + "prefix_resolved": true, + "name": "capture_vote", + "signature": "motion_id: str, payload: VoteCreate", + "returns": "dict", + "line": 1711, + "doc": "Capture an immutable vote for a motion.", + "decorator": "app.post('/motions/{motion_id}/votes', status_code=201)", + "errors": [ + "HTTPException(status_code=404, detail='Motion not found.')" + ] + }, + { + "method": "GET", + "path": "/motions/{motion_id}/votes", + "router": "app", + "prefix_resolved": true, + "name": "list_votes", + "signature": "motion_id: str", + "returns": "dict[str, list[dict]]", + "line": 1728, + "doc": "List captured votes and correction records for a motion.", + "decorator": "app.get('/motions/{motion_id}/votes')", + "errors": [ + "HTTPException(status_code=404, detail='Motion not found.')" + ] + }, + { + "method": "PUT", + "path": "/votes/{vote_id}", + "router": "app", + "prefix_resolved": true, + "name": "reject_vote_mutation", + "signature": "vote_id: str", + "returns": "None", + "line": 1743, + "doc": "Reject edits to captured votes; corrections must be append-only.", + "decorator": "app.put('/votes/{vote_id}')", + "errors": [ + "HTTPException(status_code=409, detail={'message': 'Captured votes are immutable.', 'fix': 'Use POST /votes/{vote_id}/corrections to add a correction record that references the original vote.'})", + "HTTPException(status_code=404, detail='Vote not found.')" + ] + }, + { + "method": "PATCH", + "path": "/votes/{vote_id}", + "router": "app", + "prefix_resolved": true, + "name": "reject_vote_mutation", + "signature": "vote_id: str", + "returns": "None", + "line": 1743, + "doc": "Reject edits to captured votes; corrections must be append-only.", + "decorator": "app.patch('/votes/{vote_id}')", + "errors": [ + "HTTPException(status_code=409, detail={'message': 'Captured votes are immutable.', 'fix': 'Use POST /votes/{vote_id}/corrections to add a correction record that references the original vote.'})", + "HTTPException(status_code=404, detail='Vote not found.')" + ] + }, + { + "method": "POST", + "path": "/votes/{vote_id}/corrections", + "router": "app", + "prefix_resolved": true, + "name": "correct_vote", + "signature": "vote_id: str, payload: VoteCorrectionCreate", + "returns": "dict", + "line": 1757, + "doc": "Create an append-only correction record for a captured vote.", + "decorator": "app.post('/votes/{vote_id}/corrections', status_code=201)", + "errors": [ + "HTTPException(status_code=404, detail='Vote not found.')" + ] + }, + { + "method": "POST", + "path": "/meetings/{meeting_id}/action-items", + "router": "app", + "prefix_resolved": true, + "name": "create_action_item", + "signature": "meeting_id: str, payload: ActionItemCreate", + "returns": "dict", + "line": 1771, + "doc": "Create an action item linked to a meeting outcome.", + "decorator": "app.post('/meetings/{meeting_id}/action-items', status_code=201)", + "errors": [ + "HTTPException(status_code=404, detail='Meeting not found.')", + "HTTPException(status_code=422, detail={'message': 'Action items must reference a captured meeting outcome.', 'fix': 'Capture the related motion first, then send its id as source_motion_id.'})", + "HTTPException(status_code=404, detail='Source motion not found.')", + "HTTPException(status_code=422, detail={'message': 'Action item source motion belongs to a different meeting.', 'fix': 'Use a motion captured for this meeting as source_motion_id.'})" + ] + }, + { + "method": "GET", + "path": "/meetings/{meeting_id}/action-items", + "router": "app", + "prefix_resolved": true, + "name": "list_action_items", + "signature": "meeting_id: str", + "returns": "dict[str, list[dict]]", + "line": 1809, + "doc": "List action items linked to a meeting.", + "decorator": "app.get('/meetings/{meeting_id}/action-items')", + "errors": [ + "HTTPException(status_code=404, detail='Meeting not found.')" + ] + }, + { + "method": "POST", + "path": "/meetings/{meeting_id}/ordinance-resolution-handoff", + "router": "app", + "prefix_resolved": true, + "name": "create_ordinance_resolution_handoff", + "signature": "meeting_id: str, payload: OrdinanceResolutionHandoffCreate", + "returns": "dict[str, object]", + "line": 2063, + "doc": "Create a code-drafting handoff from adopted meeting action.", + "decorator": "app.post('/meetings/{meeting_id}/ordinance-resolution-handoff', status_code=201)", + "errors": [ + "HTTPException(status_code=404, detail='Source motion not found.')", + "HTTPException(status_code=422, detail={'message': 'Ordinance or resolution source motion belongs to a different meeting.', 'fix': 'Use a motion captured for this meeting, then retry the handoff.'})" + ] + }, + { + "method": "GET", + "path": "/meetings/{meeting_id}/ordinance-resolution-handoff", + "router": "app", + "prefix_resolved": true, + "name": "list_ordinance_resolution_handoffs", + "signature": "meeting_id: str", + "returns": "dict[str, object]", + "line": 2112, + "doc": "List ordinance and resolution handoffs for a meeting.", + "decorator": "app.get('/meetings/{meeting_id}/ordinance-resolution-handoff')", + "errors": [] + }, + { + "method": "POST", + "path": "/meetings/{meeting_id}/ordinance-resolution-handoff/retry", + "router": "app", + "prefix_resolved": true, + "name": "retry_ordinance_resolution_handoff", + "signature": "meeting_id: str, payload: OrdinanceResolutionHandoffRetry | None=None", + "returns": "dict[str, object]", + "line": 2125, + "doc": "Retry TownlightCode emission for failed or unconfigured ordinance handoffs.", + "decorator": "app.post('/meetings/{meeting_id}/ordinance-resolution-handoff/retry')", + "errors": [ + "HTTPException(status_code=404, detail='Handoff not found.')" + ] + }, + { + "method": "POST", + "path": "/meetings/{meeting_id}/minutes/drafts", + "router": "app", + "prefix_resolved": true, + "name": "create_minutes_draft", + "signature": "meeting_id: str, payload: MinutesDraftCreate", + "returns": "dict", + "line": 2159, + "doc": "Create a cited minutes draft from staff-provided sentence text.", + "decorator": "app.post('/meetings/{meeting_id}/minutes/drafts', status_code=201)", + "errors": [ + "HTTPException(status_code=404, detail='Meeting not found.')", + "HTTPException(status_code=422, detail={'message': result.message, 'fix': result.fix})" + ] + }, + { + "method": "POST", + "path": "/meetings/{meeting_id}/minutes/ai-assist", + "router": "app", + "prefix_resolved": true, + "name": "create_minutes_ai_assist", + "signature": "meeting_id: str, payload: MinutesAiAssistCreate", + "returns": "dict", + "line": 2197, + "doc": "Generate an optional Ollama-assisted cited minutes draft.", + "decorator": "app.post('/meetings/{meeting_id}/minutes/ai-assist', status_code=201)", + "errors": [ + "HTTPException(status_code=404, detail='Meeting not found.')", + "HTTPException(status_code=422, detail={'message': result.message, 'fix': result.fix})", + "HTTPException(status_code=503, detail=_minutes_ai_unavailable_detail(str(exc)))" + ] + }, + { + "method": "GET", + "path": "/meetings/{meeting_id}/minutes/drafts", + "router": "app", + "prefix_resolved": true, + "name": "list_minutes_drafts", + "signature": "meeting_id: str", + "returns": "dict[str, list[dict]]", + "line": 2243, + "doc": "List citation-gated minutes drafts for a meeting.", + "decorator": "app.get('/meetings/{meeting_id}/minutes/drafts')", + "errors": [ + "HTTPException(status_code=404, detail='Meeting not found.')" + ] + }, + { + "method": "POST", + "path": "/minutes/{minute_id}/post", + "router": "app", + "prefix_resolved": true, + "name": "reject_automatic_minutes_posting", + "signature": "minute_id: str", + "returns": "None", + "line": 2257, + "doc": "Reject automatic public posting of AI-drafted minutes.", + "decorator": "app.post('/minutes/{minute_id}/post')", + "errors": [ + "HTTPException(status_code=409, detail={'message': 'AI-drafted minutes cannot be posted automatically.', 'fix': 'Review, cite-check, and adopt minutes through a human approval workflow before public posting.'})", + "HTTPException(status_code=404, detail='Minutes draft not found.')" + ] + }, + { + "method": "POST", + "path": "/meetings/{meeting_id}/transcripts", + "router": "app", + "prefix_resolved": true, + "name": "create_transcript_record", + "signature": "meeting_id: str, payload: TranscriptCreate", + "returns": "dict[str, object]", + "line": 2271, + "doc": "Capture transcript material for clerk review before public release.", + "decorator": "app.post('/meetings/{meeting_id}/transcripts', status_code=201)", + "errors": [] + }, + { + "method": "GET", + "path": "/meetings/{meeting_id}/transcripts", + "router": "app", + "prefix_resolved": true, + "name": "list_transcript_records", + "signature": "meeting_id: str", + "returns": "dict[str, object]", + "line": 2295, + "doc": "List transcript records queued for a meeting.", + "decorator": "app.get('/meetings/{meeting_id}/transcripts')", + "errors": [] + }, + { + "method": "POST", + "path": "/meetings/{meeting_id}/public-record", + "router": "app", + "prefix_resolved": true, + "name": "publish_public_record", + "signature": "meeting_id: str, payload: PublicMeetingRecordCreate", + "returns": "dict", + "line": 2309, + "doc": "Create a public or restricted archive record for a meeting.", + "decorator": "app.post('/meetings/{meeting_id}/public-record', status_code=201)", + "errors": [ + "HTTPException(status_code=404, detail='Meeting not found.')", + "HTTPException(status_code=404, detail={'message': 'Meeting not found in the public archive database.', 'fix': 'Point TOWNLIGHT_MEETINGS_PUBLIC_ARCHIVE_DB_URL at the same database as TOWNLIGHT_MEETINGS_MEETING_DB_URL so published records reference real meetings.'})" + ] + }, + { + "method": "POST", + "path": "/imports/{connector_name}/meetings", + "router": "app", + "prefix_resolved": true, + "name": "import_connector_meeting", + "signature": "connector_name: str, payload: dict", + "returns": "dict", + "line": 2347, + "doc": "Import a local connector export payload without outbound network calls.", + "decorator": "app.post('/imports/{connector_name}/meetings', status_code=201)", + "errors": [ + "HTTPException(status_code=status_code, detail=error.public_dict())" + ] + }, + { + "method": "POST", + "path": "/vendor-live-sync/sources", + "router": "app", + "prefix_resolved": true, + "name": "create_vendor_live_sync_source", + "signature": "payload: VendorSyncSourceCreate", + "returns": "dict", + "line": 2365, + "doc": "Create a durable vendor live-sync source record without contacting the vendor.", + "decorator": "app.post('/vendor-live-sync/sources', status_code=201)", + "errors": [ + "HTTPException(status_code=422, detail=error.public_dict())" + ] + }, + { + "method": "GET", + "path": "/vendor-live-sync/sources", + "router": "app", + "prefix_resolved": true, + "name": "list_vendor_live_sync_sources", + "signature": "", + "returns": "dict[str, object]", + "line": 2386, + "doc": "List persisted vendor live-sync source health without contacting vendors.", + "decorator": "app.get('/vendor-live-sync/sources')", + "errors": [] + }, + { + "method": "POST", + "path": "/vendor-live-sync/sources/{source_id}/cursor-reset", + "router": "app", + "prefix_resolved": true, + "name": "reset_vendor_live_sync_cursor", + "signature": "source_id: str, payload: VendorSyncCursorReset", + "returns": "dict[str, object]", + "line": 2398, + "doc": "Clear or move a vendor delta cursor without contacting the vendor network.", + "decorator": "app.post('/vendor-live-sync/sources/{source_id}/cursor-reset')", + "errors": [ + "HTTPException(status_code=404, detail={'message': 'Vendor live-sync source not found.', 'fix': 'Create the source with POST /vendor-live-sync/sources before resetting its cursor.'})" + ] + }, + { + "method": "POST", + "path": "/vendor-live-sync/sources/{source_id}/run-log", + "router": "app", + "prefix_resolved": true, + "name": "record_vendor_live_sync_run", + "signature": "source_id: str, payload: VendorSyncRunRecordCreate", + "returns": "dict", + "line": 2431, + "doc": "Record one vendor sync run outcome without starting a vendor pull.", + "decorator": "app.post('/vendor-live-sync/sources/{source_id}/run-log', status_code=201)", + "errors": [ + "HTTPException(status_code=404, detail={'message': 'Vendor live-sync source not found.', 'fix': 'Create the source with POST /vendor-live-sync/sources before recording a run outcome.'})" + ] + }, + { + "method": "GET", + "path": "/vendor-live-sync/sources/{source_id}/run-log", + "router": "app", + "prefix_resolved": true, + "name": "list_vendor_live_sync_runs", + "signature": "source_id: str", + "returns": "dict[str, object]", + "line": 2463, + "doc": "Return persisted run history for one vendor source without contacting vendors.", + "decorator": "app.get('/vendor-live-sync/sources/{source_id}/run-log')", + "errors": [ + "HTTPException(status_code=404, detail={'message': 'Vendor live-sync source not found.', 'fix': 'Create the source with POST /vendor-live-sync/sources before viewing run history.'})" + ] + }, + { + "method": "GET", + "path": "/public/meetings", + "router": "app", + "prefix_resolved": true, + "name": "public_meetings", + "signature": "", + "returns": "dict[str, int | list[dict]]", + "line": 2484, + "doc": "Return public meeting calendar records only.", + "decorator": "app.get('/public/meetings')", + "errors": [] + }, + { + "method": "GET", + "path": "/public/meetings/{record_id}", + "router": "app", + "prefix_resolved": true, + "name": "public_meeting_detail", + "signature": "record_id: str", + "returns": "dict", + "line": 2494, + "doc": "Return one public meeting record without revealing restricted records.", + "decorator": "app.get('/public/meetings/{record_id}')", + "errors": [ + "HTTPException(status_code=404, detail='Public meeting record not found.')" + ] + }, + { + "method": "GET", + "path": "/public/meetings/{record_id}/{document_kind}.txt", + "router": "app", + "prefix_resolved": true, + "name": "public_meeting_download", + "signature": "record_id: str, document_kind: str", + "returns": "Response", + "line": 2503, + "doc": "Download one public-safe agenda, packet, or adopted-minutes text file.", + "decorator": "app.get('/public/meetings/{record_id}/{document_kind}.txt')", + "errors": [ + "HTTPException(status_code=404, detail='Public meeting record not found.')", + "HTTPException(status_code=404, detail={'message': 'Public meeting document not found.', 'fix': 'Use agenda.txt, packet.txt, or minutes.txt from the public meeting detail response.'})" + ] + }, + { + "method": "POST", + "path": "/public/meetings/{record_id}/comments", + "router": "app", + "prefix_resolved": true, + "name": "submit_public_comment", + "signature": "record_id: str, payload: PublicCommentCreate", + "returns": "dict", + "line": 2530, + "doc": "Accept a resident comment only for public records with comment intake enabled.", + "decorator": "app.post('/public/meetings/{record_id}/comments', status_code=201)", + "errors": [ + "HTTPException(status_code=404, detail='Public meeting record not found.')", + "HTTPException(status_code=409, detail={'message': 'Public comment intake is closed for this meeting record.', 'fix': 'Contact the clerk for the official comment method or check the posted agenda for comment instructions.'})" + ] + }, + { + "method": "GET", + "path": "/public/meetings/{record_id}/comments", + "router": "app", + "prefix_resolved": true, + "name": "list_public_comments", + "signature": "record_id: str", + "returns": "dict[str, int | list[dict]]", + "line": 2557, + "doc": "List resident comments collected for a public record.", + "decorator": "app.get('/public/meetings/{record_id}/comments')", + "errors": [ + "HTTPException(status_code=404, detail='Public meeting record not found.')" + ] + }, + { + "method": "GET", + "path": "/public-comments/review-queue", + "router": "app", + "prefix_resolved": true, + "name": "list_public_comment_review_queue", + "signature": "", + "returns": "dict[str, object]", + "line": 2567, + "doc": "List resident comments awaiting staff review across public records.", + "decorator": "app.get('/public-comments/review-queue')", + "errors": [] + }, + { + "method": "GET", + "path": "/public/archive/search", + "router": "app", + "prefix_resolved": true, + "name": "public_archive_search", + "signature": "q: str, credentials: HTTPAuthorizationCredentials | None=Depends(_archive_search_bearer)", + "returns": "dict[str, int | list[dict]]", + "line": 2580, + "doc": "Search public archives with permission-aware closed-session filtering.", + "decorator": "app.get('/public/archive/search')", + "errors": [] + } + ], + "models": [ + { + "name": "AgendaItemCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "title", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "department_name", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 238, + "doc": "" + }, + { + "name": "AgendaItemTransitionRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "to_status", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "actor", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 243, + "doc": "" + }, + { + "name": "AgendaIntakeCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "title", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "department_name", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "submitted_by", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "summary", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "source_references", + "type": "list[dict]", + "default": "Field(min_length=1)" + } + ], + "line": 248, + "doc": "" + }, + { + "name": "AgendaIntakeReviewRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "reviewer", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "ready", + "type": "bool", + "default": "" + }, + { + "name": "notes", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 256, + "doc": "" + }, + { + "name": "AgendaIntakePromoteRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "reviewer", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "notes", + "type": "str", + "default": "Field(default='Promoted to agenda lifecycle.', min_length=1)" + } + ], + "line": 262, + "doc": "" + }, + { + "name": "StaffReportCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "title", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "department_name", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "author", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "summary", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "source_references", + "type": "list[dict]", + "default": "Field(min_length=1)" + }, + { + "name": "agenda_item_id", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + }, + { + "name": "legal_reviewer", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + } + ], + "line": 267, + "doc": "" + }, + { + "name": "MeetingCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "title", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "meeting_type", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "scheduled_start", + "type": "str | None", + "default": "None" + }, + { + "name": "meeting_body_id", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + }, + { + "name": "location", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + } + ], + "line": 277, + "doc": "" + }, + { + "name": "MeetingUpdate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "title", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + }, + { + "name": "meeting_type", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + }, + { + "name": "scheduled_start", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + }, + { + "name": "meeting_body_id", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + }, + { + "name": "location", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + }, + { + "name": "actor", + "type": "str", + "default": "Field(default='clerk@example.gov', min_length=1)" + } + ], + "line": 285, + "doc": "" + }, + { + "name": "MeetingBodyCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "name", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "body_type", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "is_active", + "type": "bool", + "default": "True" + } + ], + "line": 294, + "doc": "" + }, + { + "name": "MeetingBodyUpdate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "name", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + }, + { + "name": "body_type", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + }, + { + "name": "is_active", + "type": "bool | None", + "default": "None" + } + ], + "line": 300, + "doc": "" + }, + { + "name": "MeetingTransitionRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "to_status", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "actor", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "statutory_basis", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + } + ], + "line": 306, + "doc": "" + }, + { + "name": "PacketSnapshotCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "agenda_item_ids", + "type": "list[str]", + "default": "Field(min_length=1)" + }, + { + "name": "actor", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 312, + "doc": "" + }, + { + "name": "PacketAssemblyCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "title", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "agenda_item_ids", + "type": "list[str]", + "default": "Field(min_length=1)" + }, + { + "name": "actor", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "source_references", + "type": "list[dict]", + "default": "Field(min_length=1)" + }, + { + "name": "citations", + "type": "list[dict]", + "default": "Field(min_length=1)" + } + ], + "line": 317, + "doc": "" + }, + { + "name": "PacketAssemblyFinalizeRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "actor", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 325, + "doc": "" + }, + { + "name": "PacketSourceCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "source_id", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "title", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "kind", + "type": "str", + "default": "Field(default='document', min_length=1)" + }, + { + "name": "source_system", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + }, + { + "name": "source_path", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + }, + { + "name": "checksum", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + }, + { + "name": "sensitivity_label", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + }, + { + "name": "citation_label", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + } + ], + "line": 329, + "doc": "" + }, + { + "name": "PacketExportCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "bundle_name", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "actor", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "sources", + "type": "list[PacketSourceCreate]", + "default": "Field(min_length=1)" + }, + { + "name": "public_bundle", + "type": "bool", + "default": "True" + } + ], + "line": 340, + "doc": "" + }, + { + "name": "NoticeComplianceRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "notice_type", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "posted_at", + "type": "datetime", + "default": "" + }, + { + "name": "minimum_notice_hours", + "type": "int", + "default": "Field(gt=0)" + }, + { + "name": "statutory_basis", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + }, + { + "name": "approved_by", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + } + ], + "line": 347, + "doc": "" + }, + { + "name": "NoticeChecklistCreate", + "bases": [ + "NoticeComplianceRequest" + ], + "fields": [ + { + "name": "actor", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 355, + "doc": "" + }, + { + "name": "NoticePostingProofCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "actor", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "posting_proof", + "type": "dict", + "default": "Field(min_length=1)" + } + ], + "line": 359, + "doc": "" + }, + { + "name": "MotionCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "text", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "actor", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "agenda_item_id", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + }, + { + "name": "seconded_by", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + } + ], + "line": 364, + "doc": "" + }, + { + "name": "MotionCorrectionCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "text", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "actor", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "reason", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 371, + "doc": "" + }, + { + "name": "VoteCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "voter_name", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "vote", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "actor", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 377, + "doc": "" + }, + { + "name": "VoteCorrectionCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "vote", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "actor", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "reason", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 383, + "doc": "" + }, + { + "name": "ActionItemCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "description", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "actor", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "assigned_to", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + }, + { + "name": "source_motion_id", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + } + ], + "line": 389, + "doc": "" + }, + { + "name": "SourceMaterialCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "source_id", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "label", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "text", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 396, + "doc": "" + }, + { + "name": "MinutesSentenceCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "text", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "citations", + "type": "list[str]", + "default": "Field(default_factory=list)" + } + ], + "line": 402, + "doc": "" + }, + { + "name": "MinutesDraftCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "model", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "prompt_version", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "human_approver", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "source_materials", + "type": "list[SourceMaterialCreate]", + "default": "Field(min_length=1)" + }, + { + "name": "sentences", + "type": "list[MinutesSentenceCreate]", + "default": "Field(min_length=1)" + } + ], + "line": 407, + "doc": "" + }, + { + "name": "MinutesAiAssistCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "model", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "prompt_version", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "human_approver", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "source_materials", + "type": "list[SourceMaterialCreate]", + "default": "Field(min_length=1)" + }, + { + "name": "instruction", + "type": "str", + "default": "Field(default='Draft concise meeting minutes from the cited source material.', min_length=1)" + } + ], + "line": 415, + "doc": "" + }, + { + "name": "TranscriptCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "actor", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "source_label", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "transcript_text", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "public_release_requested", + "type": "bool", + "default": "False" + }, + { + "name": "closed_session", + "type": "bool", + "default": "False" + } + ], + "line": 426, + "doc": "" + }, + { + "name": "OrdinanceResolutionHandoffCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "item_type", + "type": "str", + "default": "Field(pattern='^(ordinance|resolution)$')" + }, + { + "name": "title", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "actor", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "legal_reviewer", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "text", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "source_motion_id", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + }, + { + "name": "ordinance_number", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + }, + { + "name": "resolution_number", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + }, + { + "name": "source_references", + "type": "list[dict]", + "default": "Field(default_factory=list)" + }, + { + "name": "affected_sections", + "type": "list[str]", + "default": "Field(default_factory=list)" + }, + { + "name": "source_document_url", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + }, + { + "name": "source_document_hash", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + } + ], + "line": 434, + "doc": "" + }, + { + "name": "OrdinanceResolutionHandoffRetry", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "handoff_id", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + } + ], + "line": 449, + "doc": "" + }, + { + "name": "PublicMeetingRecordCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "title", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "visibility", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "posted_agenda", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "posted_packet", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "approved_minutes", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "public_comment_enabled", + "type": "bool", + "default": "False" + }, + { + "name": "plain_language_summary", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + }, + { + "name": "minutes_adopted_at", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + }, + { + "name": "minutes_signed_by", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + }, + { + "name": "closed_session_notes", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + } + ], + "line": 453, + "doc": "" + }, + { + "name": "PublicCommentCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "commenter_name", + "type": "str", + "default": "Field(min_length=1, max_length=255)" + }, + { + "name": "comment", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 466, + "doc": "" + }, + { + "name": "VendorSyncSourceCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "connector", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "source_name", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "source_url", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "auth_method", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 471, + "doc": "" + }, + { + "name": "VendorSyncRunRecordCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "records_discovered", + "type": "int", + "default": "Field(ge=0)" + }, + { + "name": "records_succeeded", + "type": "int", + "default": "Field(ge=0)" + }, + { + "name": "records_failed", + "type": "int", + "default": "Field(ge=0)" + }, + { + "name": "retries_attempted", + "type": "int", + "default": "Field(default=0, ge=0)" + }, + { + "name": "error_summary", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + } + ], + "line": 478, + "doc": "" + }, + { + "name": "VendorSyncCursorReset", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "cursor_at", + "type": "datetime | None", + "default": "None" + }, + { + "name": "reason", + "type": "str", + "default": "Field(min_length=8, max_length=500)" + } + ], + "line": 486, + "doc": "" + } + ], + "configuration": [ + { + "variable": "TOWNLIGHT_MEETINGS_EXPORT_ROOT", + "default": "'exports'", + "line": 3457 + }, + { + "variable": "TOWNLIGHT_MEETINGS_AGENDA_INTAKE_DB_URL", + "default": "", + "line": 3463 + }, + { + "variable": "TOWNLIGHT_MEETINGS_AGENDA_ITEM_DB_URL", + "default": "", + "line": 3472 + }, + { + "variable": "TOWNLIGHT_MEETINGS_PACKET_ASSEMBLY_DB_URL", + "default": "", + "line": 3483 + }, + { + "variable": "TOWNLIGHT_MEETINGS_NOTICE_CHECKLIST_DB_URL", + "default": "", + "line": 3492 + }, + { + "variable": "TOWNLIGHT_MEETINGS_MEETING_BODY_DB_URL", + "default": "", + "line": 3501 + }, + { + "variable": "TOWNLIGHT_MEETINGS_MEETING_DB_URL", + "default": "", + "line": 3510 + }, + { + "variable": "TOWNLIGHT_MEETINGS_VENDOR_SYNC_DB_URL", + "default": "", + "line": 3521 + }, + { + "variable": "TOWNLIGHT_MEETINGS_MOTION_VOTE_DB_URL", + "default": "", + "line": 3530 + }, + { + "variable": "TOWNLIGHT_MEETINGS_MINUTES_DB_URL", + "default": "", + "line": 3541 + }, + { + "variable": "TOWNLIGHT_MEETINGS_PUBLIC_ARCHIVE_DB_URL", + "default": "", + "line": 3552 + }, + { + "variable": "TOWNLIGHT_MEETINGS_PUBLIC_ARCHIVE_DB_URL", + "default": "", + "line": 3563 + } + ] + }, + { + "source": "installed-owned-source/townlight_meetings/meeting_body.py", + "sha256": "21085a87b167afb85ddd1e20f561695f580f1e20e8259bc8586e29f5f40cc079", + "routes": [], + "models": [ + { + "name": "MeetingBodyRecord", + "bases": [], + "fields": [ + { + "name": "id", + "type": "UUID", + "default": "" + }, + { + "name": "name", + "type": "str", + "default": "" + }, + { + "name": "body_type", + "type": "str", + "default": "" + }, + { + "name": "is_active", + "type": "bool", + "default": "" + }, + { + "name": "created_at", + "type": "datetime", + "default": "" + }, + { + "name": "updated_at", + "type": "datetime", + "default": "" + } + ], + "line": 29, + "doc": "One municipal body that can own public meetings." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/meeting_lifecycle.py", + "sha256": "3eb5fdb3d1a259a6841280fca6ce1c1c56317ff8f79de39022e8b5e35fd9115e", + "routes": [], + "models": [ + { + "name": "TransitionResult", + "bases": [], + "fields": [ + { + "name": "allowed", + "type": "bool", + "default": "" + }, + { + "name": "http_status", + "type": "int", + "default": "" + }, + { + "name": "message", + "type": "str", + "default": "" + }, + { + "name": "fix", + "type": "str", + "default": "" + }, + { + "name": "audit_entry", + "type": "dict[str, object]", + "default": "" + } + ], + "line": 74, + "doc": "" + }, + { + "name": "MeetingRecord", + "bases": [], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "title", + "type": "str", + "default": "" + }, + { + "name": "meeting_type", + "type": "str", + "default": "" + }, + { + "name": "scheduled_start", + "type": "datetime | None", + "default": "None" + }, + { + "name": "meeting_body_id", + "type": "str | None", + "default": "None" + }, + { + "name": "location", + "type": "str | None", + "default": "None" + }, + { + "name": "status", + "type": "str", + "default": "'SCHEDULED'" + }, + { + "name": "audit_entries", + "type": "list[dict[str, object]]", + "default": "field(default_factory=list)" + } + ], + "line": 83, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/migrations/__init__.py", + "sha256": "dd0a9b788de59eae83bec1152f0508532d3921e8bec7f175ba85f7caa5acc64f", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/migrations/env.py", + "sha256": "9b3b3726c41218c534b726516d30de7dce83cc3d8b2f5d02f561ae3460807d5f", + "routes": [], + "models": [], + "configuration": [ + { + "variable": "DATABASE_URL", + "default": "", + "line": 24 + } + ] + }, + { + "source": "installed-owned-source/townlight_meetings/migrations/guards.py", + "sha256": "5dfcd955681e2467f4ae52ebfe04cf3b5892c9aa68adeae3cb5a999c15ceb69e", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/migrations/versions/__init__.py", + "sha256": "e08e35c06b073f92af22b7b5bb564ea2b9caaf2295b68e9c6c5ec175605dcc96", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0001_schema.py", + "sha256": "21441c137f2570d037447bb832d9a8223dcba7ee16e4e7cd7a974d81f1824028", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0002_agenda_intake_queue.py", + "sha256": "e23ff5cf9360ab9657e183970c1e36d67111ebf57d5ab1025f9c820eb81f51b3", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0003_packet_assembly_records.py", + "sha256": "28b2b1adc000bbbfd1d537df7abfed94c1a3120f9755542718c05478e96968cc", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0004_notice_checklist_records.py", + "sha256": "a9759ee9a869cbae969e7f371800a296c53f2787ff6654dcb347c18117ce5fcf", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0005_meeting_records.py", + "sha256": "48d3c089a65d4733c164215ec9a18c153b20226f11d9cf06db0ec19d578ec4ea", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0006_agenda_item_lifecycle_records.py", + "sha256": "b030e37ee25d963ada7b51f907c28dbdd77949f2d9882dedf27ea5dc2cfdf32a", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0007_meeting_schedule_fields.py", + "sha256": "e19e655c7fdbf347a85c22be379b2a537e8075a53748facd55f0856bf93ab598", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0008_agenda_intake_promotion.py", + "sha256": "56d0019f2c413c731a09c8dae9150c4d2cd4ccf7b3911786d6e833b9d965dcc0", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0009_vendor_sync_persistence.py", + "sha256": "83df336d1ba176f5e5ef4c01485b013dd5686e5cbb1c8ca935dd5bb1336b641d", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0010_vendor_sync_cursor.py", + "sha256": "860c440f1696e8094d466c8b634b330416a7e0c0616a660820a1463542f6931b", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0011_data_model_completion.py", + "sha256": "ee830e52b4fd24d37f234ad928b4beda378ef5267a35542739477a46e7b6a93e", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0012_action_item_actor.py", + "sha256": "d7a9b4c893b3387ff7557015213cdc6dda893881998071e74b82cf15be2a986c", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0013_minutes_model_posted.py", + "sha256": "908d75f2a666d4a2837823ff48b94cdc0394227d91b48c46deb6efcc9a69e962", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0014_public_meeting_records.py", + "sha256": "f92409988f5893fcc0da7dcaa5fa083e20b7c42056681c54e9ae8152b6bf1331", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0015_capture_seq.py", + "sha256": "092e93ad53ec9ee047bf4d0d634933f5d735c2b3fa46a1de1e13f1dc11408ff1", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0016_archive_indexes.py", + "sha256": "3d91062951e78685411983f45ea206ab436b6fadb20627a79624880def896742", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0017_meeting_authority.py", + "sha256": "73c6266df0dd33b74223133a2a00d045112a1996ffc38025d3aa8ba7831f1082", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0018_agenda_authority.py", + "sha256": "7dc3993bf51db8239270fd53a651b98ebbff0dbfce56ccbb73414ac9bbac2464", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0019_minutes_decisions.py", + "sha256": "5f088e0026bef9f492cac6a4c4a6c16ee81409d6447b1ab1ee19c037cd56d9cc", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0020_delivery_history.py", + "sha256": "92a6779b59cb3228b3bbd963a9c4cef921163cbd07473381f015dbf474ba4005", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/migrations/versions/townlight_meetings_0021_sources_archive.py", + "sha256": "3220a0e7992d865b5a1f5a9bb71cb85722336f276fc974c13939d81fbfc1b29c", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/minutes.py", + "sha256": "d4d890d0c9faaa3fdd51643a156e5f6a29274f436eba858db63746ad0ebb1ea3", + "routes": [], + "models": [ + { + "name": "MinutesProvenance", + "bases": [], + "fields": [ + { + "name": "model", + "type": "str", + "default": "" + }, + { + "name": "prompt_version", + "type": "str", + "default": "" + }, + { + "name": "data_sources", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "human_approver", + "type": "str", + "default": "" + } + ], + "line": 26, + "doc": "" + }, + { + "name": "MinutesDraft", + "bases": [], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "meeting_id", + "type": "str", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "sentences", + "type": "tuple[MinutesSentence, ...]", + "default": "" + }, + { + "name": "source_materials", + "type": "tuple[SourceMaterial, ...]", + "default": "" + }, + { + "name": "provenance", + "type": "MinutesProvenance", + "default": "" + }, + { + "name": "adopted", + "type": "bool", + "default": "False" + }, + { + "name": "posted", + "type": "bool", + "default": "False" + }, + { + "name": "signed_by", + "type": "str | None", + "default": "None" + }, + { + "name": "decision_history", + "type": "tuple[dict, ...]", + "default": "()" + } + ], + "line": 42, + "doc": "" + }, + { + "name": "MinutesValidationError", + "bases": [], + "fields": [ + { + "name": "message", + "type": "str", + "default": "" + }, + { + "name": "fix", + "type": "str", + "default": "" + } + ], + "line": 71, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/mock_city_environment.py", + "sha256": "6df0969766b42257f372e2babf23675b50aead141a1c91e3e9b95237074f084f", + "routes": [], + "models": [ + { + "name": "MockCityHostileFixture", + "bases": [], + "fields": [ + { + "name": "area", + "type": "HostileArea", + "default": "" + }, + { + "name": "scenario", + "type": "str", + "default": "" + }, + { + "name": "target", + "type": "str", + "default": "" + }, + { + "name": "trigger", + "type": "str", + "default": "" + }, + { + "name": "expected_behavior", + "type": "str", + "default": "" + }, + { + "name": "fix", + "type": "str", + "default": "" + }, + { + "name": "sample", + "type": "dict[str, Any]", + "default": "" + } + ], + "line": 47, + "doc": "Secret-free adversarial fixture for the mock-city hostile-mode toggle." + }, + { + "name": "MockCityHostileCheck", + "bases": [], + "fields": [ + { + "name": "area", + "type": "HostileArea", + "default": "" + }, + { + "name": "scenario", + "type": "str", + "default": "" + }, + { + "name": "target", + "type": "str", + "default": "" + }, + { + "name": "ok", + "type": "bool", + "default": "" + }, + { + "name": "message", + "type": "str", + "default": "" + }, + { + "name": "fix", + "type": "str", + "default": "" + } + ], + "line": 71, + "doc": "Conformance result for a hostile-mode mock-city fixture." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/models.py", + "sha256": "ffc262c2381523ee111259d53bc402938781de926624ca2c791f2ca23bb8072c", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/motion_vote.py", + "sha256": "8bc167f9e1ab291f7ee8a616f54786bf4baa686849deac1db33884d5a6d5eaef", + "routes": [], + "models": [ + { + "name": "MotionRecord", + "bases": [], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "meeting_id", + "type": "str", + "default": "" + }, + { + "name": "text", + "type": "str", + "default": "" + }, + { + "name": "actor", + "type": "str", + "default": "" + }, + { + "name": "agenda_item_id", + "type": "str | None", + "default": "None" + }, + { + "name": "seconded_by", + "type": "str | None", + "default": "None" + }, + { + "name": "correction_of_id", + "type": "str | None", + "default": "None" + }, + { + "name": "correction_reason", + "type": "str | None", + "default": "None" + }, + { + "name": "captured", + "type": "bool", + "default": "True" + } + ], + "line": 17, + "doc": "" + }, + { + "name": "VoteRecord", + "bases": [], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "motion_id", + "type": "str", + "default": "" + }, + { + "name": "voter_name", + "type": "str", + "default": "" + }, + { + "name": "vote", + "type": "str", + "default": "" + }, + { + "name": "actor", + "type": "str", + "default": "" + }, + { + "name": "correction_of_id", + "type": "str | None", + "default": "None" + }, + { + "name": "correction_reason", + "type": "str | None", + "default": "None" + }, + { + "name": "captured", + "type": "bool", + "default": "True" + } + ], + "line": 43, + "doc": "" + }, + { + "name": "ActionItemRecord", + "bases": [], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "meeting_id", + "type": "str", + "default": "" + }, + { + "name": "description", + "type": "str", + "default": "" + }, + { + "name": "actor", + "type": "str", + "default": "" + }, + { + "name": "assigned_to", + "type": "str | None", + "default": "None" + }, + { + "name": "source_motion_id", + "type": "str | None", + "default": "None" + }, + { + "name": "status", + "type": "str", + "default": "'OPEN'" + } + ], + "line": 67, + "doc": "" + }, + { + "name": "MeetingOutcomeSummary", + "bases": [], + "fields": [ + { + "name": "meeting_id", + "type": "str", + "default": "" + }, + { + "name": "motion_id", + "type": "str", + "default": "" + }, + { + "name": "text", + "type": "str", + "default": "" + }, + { + "name": "actor", + "type": "str", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "vote_count", + "type": "int", + "default": "" + }, + { + "name": "action_item_count", + "type": "int", + "default": "" + } + ], + "line": 89, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/notice_checklist.py", + "sha256": "093031a3501ad47e35075e5350f20a3cf5ad8f7d29aa9298ea654edcbd253f71", + "routes": [], + "models": [ + { + "name": "NoticeChecklistRecord", + "bases": [], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "meeting_id", + "type": "str", + "default": "" + }, + { + "name": "notice_type", + "type": "str", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "compliant", + "type": "bool", + "default": "" + }, + { + "name": "http_status", + "type": "int", + "default": "" + }, + { + "name": "warnings", + "type": "list[dict]", + "default": "" + }, + { + "name": "deadline_at", + "type": "datetime", + "default": "" + }, + { + "name": "posted_at", + "type": "datetime", + "default": "" + }, + { + "name": "minimum_notice_hours", + "type": "int", + "default": "" + }, + { + "name": "statutory_basis", + "type": "str | None", + "default": "" + }, + { + "name": "approved_by", + "type": "str | None", + "default": "" + }, + { + "name": "posting_proof", + "type": "dict | None", + "default": "" + }, + { + "name": "last_audit_hash", + "type": "str", + "default": "" + }, + { + "name": "created_at", + "type": "datetime", + "default": "" + }, + { + "name": "updated_at", + "type": "datetime", + "default": "" + }, + { + "name": "audit_entries", + "type": "list[dict]", + "default": "" + } + ], + "line": 50, + "doc": "Persisted notice compliance check and optional posting proof." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/oidc_auth.py", + "sha256": "3c9ae9b5d1f664d4372048c6e708cc77589cceb071d3e15cab8b90cf76926120", + "routes": [], + "models": [ + { + "name": "OidcStaffAuthConfig", + "bases": [], + "fields": [ + { + "name": "provider", + "type": "str", + "default": "" + }, + { + "name": "issuer", + "type": "str", + "default": "" + }, + { + "name": "audience", + "type": "str", + "default": "" + }, + { + "name": "jwks_url", + "type": "str | None", + "default": "" + }, + { + "name": "jwks_json", + "type": "str | None", + "default": "" + }, + { + "name": "role_claims", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "algorithms", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "authorization_url", + "type": "str | None", + "default": "" + }, + { + "name": "token_url", + "type": "str | None", + "default": "" + }, + { + "name": "client_id", + "type": "str | None", + "default": "" + }, + { + "name": "client_secret", + "type": "str | None", + "default": "" + }, + { + "name": "redirect_uri", + "type": "str | None", + "default": "" + }, + { + "name": "session_cookie_secret", + "type": "str | None", + "default": "" + } + ], + "line": 21, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/packet_assembly.py", + "sha256": "5edc8d3316a5eb4965b8bcbd94468fb70ef5050ed75811facccc560cec6a4791", + "routes": [], + "models": [ + { + "name": "PacketAssemblyRecord", + "bases": [], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "meeting_id", + "type": "str", + "default": "" + }, + { + "name": "packet_snapshot_id", + "type": "str", + "default": "" + }, + { + "name": "packet_version", + "type": "int", + "default": "" + }, + { + "name": "title", + "type": "str", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "actor", + "type": "str", + "default": "" + }, + { + "name": "agenda_item_ids", + "type": "list[str]", + "default": "" + }, + { + "name": "source_references", + "type": "list[dict]", + "default": "" + }, + { + "name": "citations", + "type": "list[dict]", + "default": "" + }, + { + "name": "finalized_by", + "type": "str | None", + "default": "" + }, + { + "name": "finalized_at", + "type": "datetime | None", + "default": "" + }, + { + "name": "last_audit_hash", + "type": "str", + "default": "" + }, + { + "name": "created_at", + "type": "datetime", + "default": "" + }, + { + "name": "updated_at", + "type": "datetime", + "default": "" + }, + { + "name": "snapshot_content", + "type": "list[dict]", + "default": "" + }, + { + "name": "delivery_history", + "type": "list[dict]", + "default": "" + }, + { + "name": "audit_entries", + "type": "list[dict]", + "default": "" + } + ], + "line": 51, + "doc": "One persisted packet assembly draft or finalized packet record." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/packet_notice.py", + "sha256": "826b46e12dc114c10b25838bd68bc2d668dc5bdfa2e74bfafc841b6fddff3ffc", + "routes": [], + "models": [ + { + "name": "PacketSource", + "bases": [], + "fields": [ + { + "name": "source_id", + "type": "str", + "default": "" + }, + { + "name": "title", + "type": "str", + "default": "" + }, + { + "name": "kind", + "type": "str", + "default": "'document'" + }, + { + "name": "source_system", + "type": "str | None", + "default": "None" + }, + { + "name": "source_path", + "type": "str | None", + "default": "None" + }, + { + "name": "checksum", + "type": "str | None", + "default": "None" + }, + { + "name": "sensitivity_label", + "type": "str | None", + "default": "None" + }, + { + "name": "citation_label", + "type": "str | None", + "default": "None" + } + ], + "line": 58, + "doc": "Source material included in an exported packet bundle." + }, + { + "name": "PacketSnapshot", + "bases": [], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "meeting_id", + "type": "str", + "default": "" + }, + { + "name": "version", + "type": "int", + "default": "" + }, + { + "name": "agenda_item_ids", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "actor", + "type": "str", + "default": "" + }, + { + "name": "created_at", + "type": "datetime", + "default": "field(default_factory=lambda: datetime.now(UTC))" + } + ], + "line": 92, + "doc": "" + }, + { + "name": "PacketExportResult", + "bases": [], + "fields": [ + { + "name": "meeting_id", + "type": "str", + "default": "" + }, + { + "name": "bundle_path", + "type": "str", + "default": "" + }, + { + "name": "manifest_path", + "type": "str", + "default": "" + }, + { + "name": "checksums_path", + "type": "str", + "default": "" + }, + { + "name": "townlight_core_version", + "type": "str", + "default": "" + }, + { + "name": "packet_version", + "type": "int", + "default": "" + }, + { + "name": "audit_hash", + "type": "str", + "default": "" + }, + { + "name": "generated_files", + "type": "tuple[str, ...]", + "default": "" + } + ], + "line": 112, + "doc": "Result of creating a records-ready packet export bundle." + }, + { + "name": "NoticeComplianceResult", + "bases": [], + "fields": [ + { + "name": "meeting_id", + "type": "str", + "default": "" + }, + { + "name": "notice_type", + "type": "str", + "default": "" + }, + { + "name": "scheduled_start", + "type": "datetime", + "default": "" + }, + { + "name": "posted_at", + "type": "datetime", + "default": "" + }, + { + "name": "minimum_notice_hours", + "type": "int", + "default": "" + }, + { + "name": "deadline_at", + "type": "datetime", + "default": "" + }, + { + "name": "statutory_basis", + "type": "str | None", + "default": "" + }, + { + "name": "approved_by", + "type": "str | None", + "default": "" + }, + { + "name": "compliant", + "type": "bool", + "default": "" + }, + { + "name": "http_status", + "type": "int", + "default": "" + }, + { + "name": "warnings", + "type": "list[dict[str, str]]", + "default": "" + } + ], + "line": 343, + "doc": "" + }, + { + "name": "PostedNotice", + "bases": [], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "result", + "type": "NoticeComplianceResult", + "default": "" + } + ], + "line": 372, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/prompt_evals.py", + "sha256": "0c47c06b36500ae63a0ad9dda52edd4baadd8688010714701b6228d6ccca21bd", + "routes": [], + "models": [ + { + "name": "PromptEvalResult", + "bases": [], + "fields": [ + { + "name": "prompt_reference", + "type": "str", + "default": "" + }, + { + "name": "provider", + "type": "str", + "default": "" + }, + { + "name": "offline", + "type": "bool", + "default": "" + }, + { + "name": "passed", + "type": "bool", + "default": "" + }, + { + "name": "message", + "type": "str", + "default": "" + } + ], + "line": 17, + "doc": "" + } + ], + "configuration": [ + { + "variable": "TOWNLIGHT_CORE_LLM_PROVIDER", + "default": "''", + "line": 128 + }, + { + "variable": "TOWNLIGHT_MEETINGS_EVAL_OFFLINE", + "default": "", + "line": 129 + } + ] + }, + { + "source": "installed-owned-source/townlight_meetings/prompt_library.py", + "sha256": "433e349bb9c768d37359bae0a68c89715337da8f363ddaec5a62f37bddd563d9", + "routes": [], + "models": [ + { + "name": "PromptEvaluation", + "bases": [], + "fields": [ + { + "name": "name", + "type": "str", + "default": "" + }, + { + "name": "required_phrases", + "type": "tuple[str, ...]", + "default": "" + } + ], + "line": 34, + "doc": "" + }, + { + "name": "PromptDefinition", + "bases": [], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "version", + "type": "str", + "default": "" + }, + { + "name": "provider", + "type": "str", + "default": "" + }, + { + "name": "purpose", + "type": "str", + "default": "" + }, + { + "name": "required_variables", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "system_prompt", + "type": "str", + "default": "" + }, + { + "name": "template", + "type": "str", + "default": "" + }, + { + "name": "evaluations", + "type": "tuple[PromptEvaluation, ...]", + "default": "" + }, + { + "name": "public_facing", + "type": "bool", + "default": "False" + }, + { + "name": "approval_required", + "type": "str | None", + "default": "None" + } + ], + "line": 40, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/public_archive.py", + "sha256": "389d714ee91ef1c4b0cbf49d960894bba49787232a29537ddaebcb9eecbe06b9", + "routes": [], + "models": [ + { + "name": "PublicMeetingRecord", + "bases": [], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "meeting_id", + "type": "str", + "default": "" + }, + { + "name": "title", + "type": "str", + "default": "" + }, + { + "name": "visibility", + "type": "str", + "default": "" + }, + { + "name": "posted_agenda", + "type": "str", + "default": "" + }, + { + "name": "posted_packet", + "type": "str", + "default": "" + }, + { + "name": "approved_minutes", + "type": "str", + "default": "" + }, + { + "name": "public_comment_enabled", + "type": "bool", + "default": "False" + }, + { + "name": "plain_language_summary", + "type": "str | None", + "default": "None" + }, + { + "name": "agenda_download_url", + "type": "str | None", + "default": "None" + }, + { + "name": "packet_download_url", + "type": "str | None", + "default": "None" + }, + { + "name": "minutes_download_url", + "type": "str | None", + "default": "None" + }, + { + "name": "minutes_adopted_at", + "type": "str | None", + "default": "None" + }, + { + "name": "minutes_signed_by", + "type": "str | None", + "default": "None" + }, + { + "name": "closed_session_notes", + "type": "str | None", + "default": "None" + }, + { + "name": "audit_entries", + "type": "list[dict]", + "default": "field(default_factory=list)" + } + ], + "line": 27, + "doc": "" + }, + { + "name": "PublicCommentRecord", + "bases": [], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "public_record_id", + "type": "str", + "default": "" + }, + { + "name": "commenter_name", + "type": "str", + "default": "" + }, + { + "name": "comment", + "type": "str", + "default": "" + }, + { + "name": "submitted_at", + "type": "str", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "'RECEIVED'" + } + ], + "line": 69, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/public_ui.py", + "sha256": "4359447b52c4499727fa1d62f385e778154a4243af716cd2fb828e30af6f5db0", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/records_sources.py", + "sha256": "843b4808e4a335ab05a7801a33a3a5750dc49ce84d7e71961841e91e7532598f", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/staff_ui.py", + "sha256": "158329afdeafeb52619ae70bb78cdc731a1cc65f21b31494e3cafd2884b5bdb3", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/suite_session_compat.py", + "sha256": "6b7cfc7719b722eb7da68fa137c3996d64f237d313ef925ba340f6c39d74474e", + "routes": [], + "models": [ + { + "name": "SuiteSessionPrincipal", + "bases": [], + "fields": [ + { + "name": "subject", + "type": "str", + "default": "" + }, + { + "name": "roles", + "type": "frozenset[str]", + "default": "" + }, + { + "name": "session_id", + "type": "str", + "default": "" + } + ], + "line": 28, + "doc": "Validated TownlightCore suite session principal." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/transcripts.py", + "sha256": "33d5b6f97ce58b6f645e0c236a53a855c358d01db06ee048ec9c90100474bc98", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/vendor_delta.py", + "sha256": "cebd1ffb95726fd5beb874fbfd9726555681e6c35be7957b97dda26a69898cd3", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/vendor_live_sync.py", + "sha256": "0a5048436302ad12e21d822952705ae754ed0ca7a76a7ea9080b292cc2489ab5", + "routes": [], + "models": [ + { + "name": "LiveSyncCheck", + "bases": [], + "fields": [ + { + "name": "status", + "type": "Literal['PASS', 'FAIL']", + "default": "" + }, + { + "name": "name", + "type": "str", + "default": "" + }, + { + "name": "message", + "type": "str", + "default": "" + }, + { + "name": "fix", + "type": "str", + "default": "" + } + ], + "line": 49, + "doc": "" + }, + { + "name": "VendorLiveSyncConfig", + "bases": [], + "fields": [ + { + "name": "connector", + "type": "str", + "default": "" + }, + { + "name": "source_url", + "type": "str", + "default": "" + }, + { + "name": "auth_method", + "type": "AuthMethod", + "default": "" + } + ], + "line": 57, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/vendor_network_sync.py", + "sha256": "cf3a9c14de83f76b8deb87aabfaeb43e93bca98f26a65183f1dd4001a3df91e1", + "routes": [], + "models": [ + { + "name": "VendorNetworkSyncAttempt", + "bases": [], + "fields": [ + { + "name": "ok", + "type": "bool", + "default": "" + }, + { + "name": "message", + "type": "str", + "default": "" + }, + { + "name": "fix", + "type": "str", + "default": "" + }, + { + "name": "external_meeting_id", + "type": "str | None", + "default": "None" + }, + { + "name": "error_class", + "type": "str | None", + "default": "None" + } + ], + "line": 31, + "doc": "" + }, + { + "name": "VendorNetworkSyncReport", + "bases": [], + "fields": [ + { + "name": "source_id", + "type": "str", + "default": "" + }, + { + "name": "connector", + "type": "str", + "default": "" + }, + { + "name": "network_calls", + "type": "bool", + "default": "" + }, + { + "name": "records_discovered", + "type": "int", + "default": "" + }, + { + "name": "records_succeeded", + "type": "int", + "default": "" + }, + { + "name": "records_failed", + "type": "int", + "default": "" + }, + { + "name": "run_status", + "type": "str | None", + "default": "" + }, + { + "name": "source_health_status", + "type": "str | None", + "default": "" + }, + { + "name": "delta_request_url", + "type": "str | None", + "default": "" + }, + { + "name": "cursor_param", + "type": "str | None", + "default": "" + }, + { + "name": "cursor_value", + "type": "str | None", + "default": "" + }, + { + "name": "cursor_advanced_at", + "type": "str | None", + "default": "" + }, + { + "name": "message", + "type": "str", + "default": "" + }, + { + "name": "fix", + "type": "str", + "default": "" + }, + { + "name": "attempts", + "type": "list[VendorNetworkSyncAttempt]", + "default": "" + } + ], + "line": 40, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/vendor_sync_persistence.py", + "sha256": "f719849f9cd2e1c667bc61f501dc281bf0efe26646e230b0b5b786afcb082d9b", + "routes": [], + "models": [ + { + "name": "VendorSyncSourceRecord", + "bases": [], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "connector", + "type": "str", + "default": "" + }, + { + "name": "source_name", + "type": "str", + "default": "" + }, + { + "name": "source_url", + "type": "str", + "default": "" + }, + { + "name": "auth_method", + "type": "str", + "default": "" + }, + { + "name": "consecutive_failure_count", + "type": "int", + "default": "" + }, + { + "name": "active_failure_count", + "type": "int", + "default": "" + }, + { + "name": "sync_paused", + "type": "bool", + "default": "" + }, + { + "name": "sync_paused_at", + "type": "datetime | None", + "default": "" + }, + { + "name": "sync_paused_reason", + "type": "str | None", + "default": "" + }, + { + "name": "last_sync_status", + "type": "str | None", + "default": "" + }, + { + "name": "last_error_at", + "type": "datetime | None", + "default": "" + }, + { + "name": "last_success_cursor_at", + "type": "datetime | None", + "default": "" + }, + { + "name": "created_at", + "type": "datetime", + "default": "" + }, + { + "name": "updated_at", + "type": "datetime", + "default": "" + } + ], + "line": 81, + "doc": "" + }, + { + "name": "VendorSyncRunRecord", + "bases": [], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "source_id", + "type": "str", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "records_discovered", + "type": "int", + "default": "" + }, + { + "name": "records_succeeded", + "type": "int", + "default": "" + }, + { + "name": "records_failed", + "type": "int", + "default": "" + }, + { + "name": "retries_attempted", + "type": "int", + "default": "" + }, + { + "name": "error_summary", + "type": "str | None", + "default": "" + }, + { + "name": "started_at", + "type": "datetime", + "default": "" + }, + { + "name": "finished_at", + "type": "datetime", + "default": "" + } + ], + "line": 140, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_meetings/worker.py", + "sha256": "6e0aa475591252a06401a613e85d402c8981bdaaf23b460f30b442efbdd43a9b", + "routes": [], + "models": [], + "configuration": [ + { + "variable": "TOWNLIGHT_MEETINGS_REDIS_URL", + "default": "'redis://redis:6379/0'", + "line": 46 + } + ] + } + ], + "bridge": [ + { + "source": "installed-owned-source/townlight_runtime/meetings_bridge.py", + "sha256": "37ea43e633b55e9428e928143e5da0d41a7a5906673b8cc54b40fa4d1748fa52", + "routes": [ + { + "method": "POST", + "path": "/desktop/v1/meetings/meetings/{meeting_id}/stages", + "router": "router", + "prefix_resolved": true, + "name": "record_meeting_stage", + "signature": "meeting_id: UUID, data: MeetingStageInput, actor_id: str=Depends(actor)", + "returns": "", + "line": 106, + "doc": "", + "decorator": "router.post('/meetings/{meeting_id}/stages')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/meetings/meetings", + "router": "router", + "prefix_resolved": true, + "name": "create_meeting", + "signature": "data: MeetingInput, actor_id: str=Depends(actor)", + "returns": "", + "line": 128, + "doc": "", + "decorator": "router.post('/meetings', status_code=201)", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/meetings/meetings/{meeting_id}", + "router": "router", + "prefix_resolved": true, + "name": "get_meeting", + "signature": "meeting_id: UUID, actor_id: str=Depends(actor)", + "returns": "", + "line": 136, + "doc": "", + "decorator": "router.get('/meetings/{meeting_id}')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/meetings/agenda-items", + "router": "router", + "prefix_resolved": true, + "name": "create_agenda_item", + "signature": "data: AgendaInput, actor_id: str=Depends(actor)", + "returns": "", + "line": 141, + "doc": "", + "decorator": "router.post('/agenda-items', status_code=201)", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/meetings/agenda-items/{item_id}", + "router": "router", + "prefix_resolved": true, + "name": "get_agenda_item", + "signature": "item_id: UUID, actor_id: str=Depends(actor)", + "returns": "", + "line": 148, + "doc": "", + "decorator": "router.get('/agenda-items/{item_id}')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/meetings/agenda-items/{item_id}/reviews", + "router": "router", + "prefix_resolved": true, + "name": "record_agenda_review", + "signature": "item_id: UUID, data: AgendaReviewInput, actor_id: str=Depends(actor)", + "returns": "", + "line": 164, + "doc": "", + "decorator": "router.post('/agenda-items/{item_id}/reviews')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/meetings/agenda-items/{item_id}/meeting", + "router": "router", + "prefix_resolved": true, + "name": "assign_agenda", + "signature": "item_id: UUID, data: AgendaAssignment, actor_id: str=Depends(actor)", + "returns": "", + "line": 170, + "doc": "", + "decorator": "router.post('/agenda-items/{item_id}/meeting')", + "errors": [ + "HTTPException(409, str(error))" + ] + }, + { + "method": "GET", + "path": "/desktop/v1/meetings/notices/{notice_id}/template", + "router": "router", + "prefix_resolved": true, + "name": "notice_template", + "signature": "notice_id: UUID, actor_id: str=Depends(actor)", + "returns": "", + "line": 249, + "doc": "", + "decorator": "router.get('/notices/{notice_id}/template')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/meetings/notices/{notice_id}/document", + "router": "router", + "prefix_resolved": true, + "name": "notice_document", + "signature": "notice_id: UUID, data: NoticeDocumentInput, actor_id: str=Depends(actor)", + "returns": "", + "line": 264, + "doc": "", + "decorator": "router.post('/notices/{notice_id}/document')", + "errors": [ + "HTTPException(404, 'Notice not found.')", + "HTTPException(422, 'Notice delivery not confirmed; existing documents were retained.')", + "HTTPException(503, 'Notice history write not confirmed; read saved work before retrying.')" + ] + }, + { + "method": "POST", + "path": "/desktop/v1/meetings/meetings/{meeting_id}/notice-checks", + "router": "router", + "prefix_resolved": true, + "name": "check_notice", + "signature": "meeting_id: UUID, data: NoticeInput, actor_id: str=Depends(actor)", + "returns": "", + "line": 278, + "doc": "", + "decorator": "router.post('/meetings/{meeting_id}/notice-checks', status_code=201)", + "errors": [ + "HTTPException(422, 'A scheduled start is needed to calculate a notice deadline.')" + ] + }, + { + "method": "POST", + "path": "/desktop/v1/meetings/notices/{notice_id}/proof", + "router": "router", + "prefix_resolved": true, + "name": "record_notice_proof", + "signature": "notice_id: UUID, data: NoticeProofInput, actor_id: str=Depends(actor)", + "returns": "", + "line": 295, + "doc": "", + "decorator": "router.post('/notices/{notice_id}/proof')", + "errors": [ + "HTTPException(422, str(error))" + ] + }, + { + "method": "POST", + "path": "/desktop/v1/meetings/meetings/{meeting_id}/transcripts", + "router": "router", + "prefix_resolved": true, + "name": "capture_transcript", + "signature": "meeting_id: UUID, data: TranscriptInput, actor_id: str=Depends(actor)", + "returns": "", + "line": 332, + "doc": "", + "decorator": "router.post('/meetings/{meeting_id}/transcripts', status_code=201)", + "errors": [ + "HTTPException(422, str(error))" + ] + }, + { + "method": "POST", + "path": "/desktop/v1/meetings/meetings/{meeting_id}/action-items", + "router": "router", + "prefix_resolved": true, + "name": "capture_action_item", + "signature": "meeting_id: UUID, data: ActionItemInput, actor_id: str=Depends(actor)", + "returns": "", + "line": 344, + "doc": "", + "decorator": "router.post('/meetings/{meeting_id}/action-items', status_code=201)", + "errors": [ + "HTTPException(422, 'Motion belongs to another meeting.')" + ] + }, + { + "method": "POST", + "path": "/desktop/v1/meetings/meetings/{meeting_id}/archive", + "router": "router", + "prefix_resolved": true, + "name": "archive_meeting", + "signature": "meeting_id: UUID, data: ArchiveInput, actor_id: str=Depends(actor)", + "returns": "", + "line": 356, + "doc": "", + "decorator": "router.post('/meetings/{meeting_id}/archive', status_code=201)", + "errors": [ + "HTTPException(422, 'Packet belongs to another meeting.')", + "HTTPException(422, 'Minutes belong to another meeting.')" + ] + }, + { + "method": "GET", + "path": "/public/meetings", + "router": "public_router", + "prefix_resolved": true, + "name": "public_archive_index", + "signature": "q: str=''", + "returns": "", + "line": 399, + "doc": "", + "decorator": "public_router.get('', response_class=HTMLResponse, dependencies=[Depends(public_active)])", + "errors": [] + }, + { + "method": "GET", + "path": "/public/meetings/{record_id}", + "router": "public_router", + "prefix_resolved": true, + "name": "public_archive_detail", + "signature": "record_id: UUID", + "returns": "", + "line": 407, + "doc": "", + "decorator": "public_router.get('/{record_id}', response_class=HTMLResponse, dependencies=[Depends(public_active)])", + "errors": [] + }, + { + "method": "GET", + "path": "/public/meetings/{record_id}/{kind}.txt", + "router": "public_router", + "prefix_resolved": true, + "name": "public_archive_download", + "signature": "record_id: UUID, kind: Literal['agenda', 'packet', 'minutes']", + "returns": "", + "line": 417, + "doc": "", + "decorator": "public_router.get('/{record_id}/{kind}.txt', dependencies=[Depends(public_active)])", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/meetings/meetings/{meeting_id}/packet-snapshots", + "router": "router", + "prefix_resolved": true, + "name": "capture_packet", + "signature": "meeting_id: UUID, data: PacketInput, actor_id: str=Depends(actor)", + "returns": "", + "line": 441, + "doc": "", + "decorator": "router.post('/meetings/{meeting_id}/packet-snapshots', status_code=201)", + "errors": [ + "HTTPException(422, str(error))" + ] + }, + { + "method": "POST", + "path": "/desktop/v1/meetings/packets/{packet_id}/deliver", + "router": "router", + "prefix_resolved": true, + "name": "export_packet", + "signature": "packet_id: UUID, actor_id: str=Depends(actor)", + "returns": "", + "line": 462, + "doc": "", + "decorator": "router.post('/packets/{packet_id}/deliver')", + "errors": [ + "HTTPException(404, 'Packet not found.')", + "HTTPException(422, str(error))", + "HTTPException(503, 'Packet delivery not confirmed. Inspect saved work before retrying.')" + ] + }, + { + "method": "POST", + "path": "/desktop/v1/meetings/minutes/{draft_id}/decisions", + "router": "router", + "prefix_resolved": true, + "name": "decide_minutes", + "signature": "draft_id: UUID, data: MinutesDecision, actor_id: str=Depends(actor)", + "returns": "", + "line": 475, + "doc": "", + "decorator": "router.post('/minutes/{draft_id}/decisions')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/meetings/meetings/{meeting_id}/motions", + "router": "router", + "prefix_resolved": true, + "name": "capture_motion", + "signature": "meeting_id: UUID, data: MotionInput, actor_id: str=Depends(actor)", + "returns": "", + "line": 498, + "doc": "", + "decorator": "router.post('/meetings/{meeting_id}/motions', status_code=201)", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/meetings/motions/{motion_id}/corrections", + "router": "router", + "prefix_resolved": true, + "name": "correct_motion", + "signature": "motion_id: UUID, data: MotionCorrection, actor_id: str=Depends(actor)", + "returns": "", + "line": 505, + "doc": "", + "decorator": "router.post('/motions/{motion_id}/corrections', status_code=201)", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/meetings/motions/{motion_id}/votes", + "router": "router", + "prefix_resolved": true, + "name": "capture_vote", + "signature": "motion_id: UUID, data: VoteInput, actor_id: str=Depends(actor)", + "returns": "", + "line": 511, + "doc": "", + "decorator": "router.post('/motions/{motion_id}/votes', status_code=201)", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/meetings/votes/{vote_id}/corrections", + "router": "router", + "prefix_resolved": true, + "name": "correct_vote", + "signature": "vote_id: UUID, data: VoteCorrection, actor_id: str=Depends(actor)", + "returns": "", + "line": 517, + "doc": "", + "decorator": "router.post('/votes/{vote_id}/corrections', status_code=201)", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/meetings/meetings/{meeting_id}/minutes/drafts", + "router": "router", + "prefix_resolved": true, + "name": "create_minutes", + "signature": "meeting_id: UUID, data: DraftInput, actor_id: str=Depends(actor)", + "returns": "", + "line": 523, + "doc": "", + "decorator": "router.post('/meetings/{meeting_id}/minutes/drafts', status_code=201)", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/meetings/meetings/{meeting_id}/proceedings", + "router": "router", + "prefix_resolved": true, + "name": "proceedings", + "signature": "meeting_id: UUID, actor_id: str=Depends(actor)", + "returns": "", + "line": 532, + "doc": "", + "decorator": "router.get('/meetings/{meeting_id}/proceedings')", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/meetings/station/catalog", + "router": "router", + "prefix_resolved": true, + "name": "station_catalog", + "signature": "actor_id: str=Depends(actor)", + "returns": "", + "line": 552, + "doc": "Authorized name-based operator selection from canonical Meetings data.", + "decorator": "router.get('/station/catalog')", + "errors": [] + } + ], + "models": [ + { + "name": "MeetingInput", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "title", + "type": "str", + "default": "Field(min_length=1, max_length=255)" + }, + { + "name": "scheduled_start", + "type": "AwareDatetime", + "default": "" + }, + { + "name": "location", + "type": "str", + "default": "Field(min_length=1, max_length=255)" + }, + { + "name": "meeting_type", + "type": "Literal['regular', 'special', 'emergency', 'closed_session', 'executive']", + "default": "'regular'" + } + ], + "line": 83, + "doc": "" + }, + { + "name": "AgendaInput", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "title", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + }, + { + "name": "department_name", + "type": "str", + "default": "Field(min_length=1, max_length=255)" + } + ], + "line": 91, + "doc": "" + }, + { + "name": "MeetingStageInput", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "to_status", + "type": "Literal['SCHEDULED', 'NOTICED', 'PACKET_POSTED', 'IN_PROGRESS', 'RECESSED', 'ADJOURNED', 'TRANSCRIPT_READY', 'MINUTES_DRAFTED', 'MINUTES_POSTED', 'MINUTES_ADOPTED', 'MINUTES_SIGNED', 'ARCHIVED', 'CANCELLED']", + "default": "" + }, + { + "name": "statutory_basis", + "type": "str | None", + "default": "None" + } + ], + "line": 97, + "doc": "" + }, + { + "name": "AgendaReviewInput", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "to_status", + "type": "Literal['DRAFTED', 'SUBMITTED', 'DEPT_APPROVED', 'LEGAL_REVIEWED', 'CLERK_ACCEPTED', 'ON_AGENDA', 'IN_PACKET', 'POSTED', 'HEARD', 'DISPOSED', 'ARCHIVED']", + "default": "" + } + ], + "line": 152, + "doc": "" + }, + { + "name": "AgendaAssignment", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "meeting_id", + "type": "UUID", + "default": "" + } + ], + "line": 158, + "doc": "" + }, + { + "name": "MotionInput", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "text", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "seconded_by", + "type": "str | None", + "default": "Field(default=None, min_length=1)" + } + ], + "line": 178, + "doc": "" + }, + { + "name": "MotionCorrection", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "text", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "reason", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 184, + "doc": "" + }, + { + "name": "VoteInput", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "voter_name", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "vote", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 190, + "doc": "" + }, + { + "name": "VoteCorrection", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "vote", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "reason", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 196, + "doc": "" + }, + { + "name": "SourceInput", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "source_id", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "label", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "text", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 202, + "doc": "" + }, + { + "name": "SentenceInput", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "text", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "citations", + "type": "list[str]", + "default": "Field(default_factory=list)" + } + ], + "line": 209, + "doc": "" + }, + { + "name": "DraftInput", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "source_materials", + "type": "list[SourceInput]", + "default": "Field(default_factory=list)" + }, + { + "name": "sentences", + "type": "list[SentenceInput]", + "default": "Field(min_length=1)" + } + ], + "line": 215, + "doc": "" + }, + { + "name": "MinutesDecision", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "action", + "type": "Literal['post', 'adopt', 'sign']", + "default": "" + }, + { + "name": "note", + "type": "str", + "default": "''" + } + ], + "line": 221, + "doc": "" + }, + { + "name": "NoticeInput", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "notice_type", + "type": "Literal['regular', 'special', 'emergency', 'closed_session', 'executive']", + "default": "" + }, + { + "name": "posted_at", + "type": "AwareDatetime", + "default": "" + }, + { + "name": "minimum_notice_hours", + "type": "int", + "default": "Field(ge=0)" + }, + { + "name": "statutory_basis", + "type": "str | None", + "default": "None" + }, + { + "name": "approved_by", + "type": "str | None", + "default": "None" + } + ], + "line": 227, + "doc": "" + }, + { + "name": "NoticeProofInput", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "location", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "note", + "type": "str", + "default": "''" + }, + { + "name": "document_delivery_id", + "type": "str | None", + "default": "None" + } + ], + "line": 236, + "doc": "" + }, + { + "name": "NoticeDocumentInput", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "text", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 243, + "doc": "" + }, + { + "name": "PacketInput", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "agenda_item_ids", + "type": "list[UUID]", + "default": "" + }, + { + "name": "source_files", + "type": "list['ManagedSource']", + "default": "Field(default_factory=list)" + } + ], + "line": 303, + "doc": "" + }, + { + "name": "TranscriptInput", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "source_label", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "transcript_text", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "correction_of_id", + "type": "UUID | None", + "default": "None" + } + ], + "line": 309, + "doc": "" + }, + { + "name": "ActionItemInput", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "description", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "assigned_to", + "type": "str | None", + "default": "None" + }, + { + "name": "source_motion_id", + "type": "UUID | None", + "default": "None" + } + ], + "line": 316, + "doc": "" + }, + { + "name": "ArchiveInput", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "visibility", + "type": "Literal['public', 'closed_session']", + "default": "" + }, + { + "name": "packet_id", + "type": "UUID | None", + "default": "None" + }, + { + "name": "minutes_id", + "type": "UUID | None", + "default": "None" + }, + { + "name": "plain_language_summary", + "type": "str", + "default": "''" + } + ], + "line": 323, + "doc": "" + }, + { + "name": "ManagedSource", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "original_path", + "type": "str", + "default": "" + }, + { + "name": "stored_path", + "type": "str", + "default": "" + }, + { + "name": "file_name", + "type": "str", + "default": "" + }, + { + "name": "sha256", + "type": "str", + "default": "Field(pattern='^[0-9a-f]{64}$')" + }, + { + "name": "size_bytes", + "type": "int", + "default": "Field(ge=0)" + } + ], + "line": 424, + "doc": "" + } + ], + "configuration": [ + { + "variable": "DATABASE_URL", + "default": "''", + "line": 38 + }, + { + "variable": "TOWNLIGHT_PROFILE_ROOT", + "default": "", + "line": 434 + } + ] + } + ] + }, + "code": { + "package": "townlight_code", + "source": [ + { + "source": "installed-owned-source/townlight_code/__init__.py", + "sha256": "22abb4eaa2a94737461591a5b6f494bf7c4ad481b476fc3cf020fa090c97bcd8", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_code/ai_answer.py", + "sha256": "0d82f0c105e1b8102e0b640b97de85f95f79695cc6903008d56245ed79e6568d", + "routes": [], + "models": [ + { + "name": "LocalLLMConfig", + "bases": [], + "fields": [ + { + "name": "provider", + "type": "str", + "default": "" + }, + { + "name": "base_url", + "type": "str", + "default": "" + }, + { + "name": "model", + "type": "str", + "default": "" + }, + { + "name": "timeout_seconds", + "type": "float", + "default": "" + } + ], + "line": 18, + "doc": "" + } + ], + "configuration": [ + { + "variable": "TOWNLIGHT_CODE_OLLAMA_URL", + "default": "''", + "line": 28 + }, + { + "variable": "TOWNLIGHT_CODE_OLLAMA_TIMEOUT_SECONDS", + "default": "'20'", + "line": 35 + }, + { + "variable": "TOWNLIGHT_CODE_AI_MODE", + "default": "''", + "line": 27 + }, + { + "variable": "TOWNLIGHT_CODE_OLLAMA_MODEL", + "default": "'gemma4:e4b'", + "line": 34 + } + ] + }, + { + "source": "installed-owned-source/townlight_code/citation_contract.py", + "sha256": "58e2cc3b8e05987a801a94c174ad34a8a7af18f684d367b08f097ab420ff3e37", + "routes": [], + "models": [ + { + "name": "CitationRefusal", + "bases": [], + "fields": [ + { + "name": "reason", + "type": "str", + "default": "" + }, + { + "name": "fix", + "type": "str", + "default": "" + }, + { + "name": "refusal_type", + "type": "str", + "default": "" + } + ], + "line": 10, + "doc": "Structured refusal object for unsafe citation requests." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_code/codifier_sync.py", + "sha256": "9c8b9635a2534eaccd3f80cc0b2a9b5c4751830a9d99796bb125e773778bd57f", + "routes": [], + "models": [ + { + "name": "CodifierDeltaPlan", + "bases": [], + "fields": [ + { + "name": "connector", + "type": "str", + "default": "" + }, + { + "name": "request_url", + "type": "str", + "default": "" + }, + { + "name": "delta_enabled", + "type": "bool", + "default": "" + }, + { + "name": "cursor_param", + "type": "str | None", + "default": "" + }, + { + "name": "cursor_value", + "type": "str | None", + "default": "" + }, + { + "name": "message", + "type": "str", + "default": "" + }, + { + "name": "fix", + "type": "str", + "default": "" + } + ], + "line": 56, + "doc": "Operator-visible planned codifier request." + }, + { + "name": "CodifierSyncSource", + "bases": [], + "fields": [ + { + "name": "source_id", + "type": "str", + "default": "" + }, + { + "name": "connector", + "type": "str", + "default": "" + }, + { + "name": "source_name", + "type": "str", + "default": "" + }, + { + "name": "source_url", + "type": "str", + "default": "" + }, + { + "name": "sync_schedule", + "type": "str", + "default": "" + }, + { + "name": "allowlisted_hosts", + "type": "tuple[str, ...]", + "default": "()" + }, + { + "name": "last_successful_sync_at", + "type": "datetime | None", + "default": "None" + }, + { + "name": "last_attempted_sync_at", + "type": "datetime | None", + "default": "None" + }, + { + "name": "last_import_job_id", + "type": "str | None", + "default": "None" + }, + { + "name": "next_sync_at_recorded", + "type": "datetime | None", + "default": "None" + }, + { + "name": "host_validation", + "type": "dict[str, Any]", + "default": "field(default_factory=dict)" + }, + { + "name": "delta_plan_history", + "type": "list[dict[str, Any]]", + "default": "field(default_factory=list)" + }, + { + "name": "state", + "type": "SyncCircuitState", + "default": "field(default_factory=lambda: SyncCircuitState(connector='codifier'))" + } + ], + "line": 80, + "doc": "Configured codifier sync source backed by a registered TownlightCode source." + }, + { + "name": "CodifierSyncRun", + "bases": [], + "fields": [ + { + "name": "source", + "type": "CodifierSyncSource", + "default": "" + }, + { + "name": "job_payload", + "type": "dict[str, Any]", + "default": "" + }, + { + "name": "delta_plan", + "type": "CodifierDeltaPlan", + "default": "" + } + ], + "line": 103, + "doc": "Result of one local codifier sync run." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_code/import_connectors.py", + "sha256": "bf4013448af2bd851642baefdbd1abcd212dd7b5b3c0e91d5811414c85e792f0", + "routes": [], + "models": [ + { + "name": "ImportJob", + "bases": [], + "fields": [ + { + "name": "job_id", + "type": "str", + "default": "" + }, + { + "name": "connector_type", + "type": "str", + "default": "" + }, + { + "name": "actor", + "type": "str", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "'pending'" + }, + { + "name": "retry_of", + "type": "str | None", + "default": "None" + }, + { + "name": "counts", + "type": "dict[str, int]", + "default": "field(default_factory=dict)" + }, + { + "name": "provenance", + "type": "dict[str, Any]", + "default": "field(default_factory=dict)" + }, + { + "name": "failure", + "type": "dict[str, str] | None", + "default": "None" + }, + { + "name": "source_id", + "type": "str | None", + "default": "None" + }, + { + "name": "created_at", + "type": "datetime", + "default": "field(default_factory=lambda: datetime.now(UTC))" + }, + { + "name": "completed_at", + "type": "datetime | None", + "default": "None" + } + ], + "line": 54, + "doc": "Auditable local import job record." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_code/main.py", + "sha256": "930e05298b82f10ec0338040770d8af83aa56a9d43016908931ab8f796e63f48", + "routes": [ + { + "method": "GET", + "path": "/", + "router": "app", + "prefix_resolved": true, + "name": "root", + "signature": "", + "returns": "dict[str, str]", + "line": 786, + "doc": "Describe the current shipped runtime boundary.", + "decorator": "app.get('/')", + "errors": [] + }, + { + "method": "GET", + "path": "/townlight_code", + "router": "app", + "prefix_resolved": true, + "name": "public_lookup_home", + "signature": "", + "returns": "str", + "line": 834, + "doc": "Render the resident-facing public code lookup home page.", + "decorator": "app.get('/townlight_code', response_class=HTMLResponse)", + "errors": [] + }, + { + "method": "GET", + "path": "/townlight_code/app", + "router": "app", + "prefix_resolved": true, + "name": "townlight_code_frontend_app", + "signature": "", + "returns": "Response", + "line": 845, + "doc": "Serve the React/Vite TownlightCode frontend when built.", + "decorator": "app.get('/townlight_code/app')", + "errors": [] + }, + { + "method": "GET", + "path": "/townlight_code/app/", + "router": "app", + "prefix_resolved": true, + "name": "townlight_code_frontend_app", + "signature": "", + "returns": "Response", + "line": 845, + "doc": "Serve the React/Vite TownlightCode frontend when built.", + "decorator": "app.get('/townlight_code/app/')", + "errors": [] + }, + { + "method": "GET", + "path": "/townlight_code/search", + "router": "app", + "prefix_resolved": true, + "name": "public_lookup_search", + "signature": "q: str=''", + "returns": "str", + "line": 858, + "doc": "Render public search results, empty states, or refusal states.", + "decorator": "app.get('/townlight_code/search', response_class=HTMLResponse)", + "errors": [] + }, + { + "method": "GET", + "path": "/townlight_code/answer", + "router": "app", + "prefix_resolved": true, + "name": "public_lookup_answer", + "signature": "q: str='', section_number: str | None=None, as_of: date | None=None", + "returns": "str", + "line": 878, + "doc": "Render a resident-facing cited answer for one adopted section.", + "decorator": "app.get('/townlight_code/answer', response_class=HTMLResponse)", + "errors": [] + }, + { + "method": "GET", + "path": "/townlight_code/sections/{section_ref}", + "router": "app", + "prefix_resolved": true, + "name": "public_section_detail", + "signature": "section_ref: str, as_of: date | None=None", + "returns": "str", + "line": 901, + "doc": "Render a public section detail page with citation and warning context.", + "decorator": "app.get('/townlight_code/sections/{section_ref}', response_class=HTMLResponse)", + "errors": [] + }, + { + "method": "GET", + "path": "/townlight_code/sections/{section_ref}/export", + "router": "app", + "prefix_resolved": true, + "name": "public_section_export", + "signature": "section_ref: str, as_of: date | None=None", + "returns": "str", + "line": 937, + "doc": "Render an accessible records-ready export page for a section.", + "decorator": "app.get('/townlight_code/sections/{section_ref}/export', response_class=HTMLResponse)", + "errors": [] + }, + { + "method": "GET", + "path": "/staff/sources", + "router": "app", + "prefix_resolved": true, + "name": "staff_source_workspace", + "signature": "x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", + "returns": "HTMLResponse", + "line": 953, + "doc": "Render the staff source registry workspace.", + "decorator": "app.get('/staff/sources', response_class=HTMLResponse)", + "errors": [] + }, + { + "method": "GET", + "path": "/staff/code", + "router": "app", + "prefix_resolved": true, + "name": "staff_code_workspace", + "signature": "x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", + "returns": "HTMLResponse", + "line": 970, + "doc": "Render the staff code lifecycle workspace.", + "decorator": "app.get('/staff/code', response_class=HTMLResponse)", + "errors": [] + }, + { + "method": "GET", + "path": "/staff/sync", + "router": "app", + "prefix_resolved": true, + "name": "staff_sync_workspace", + "signature": "x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", + "returns": "HTMLResponse", + "line": 983, + "doc": "Render the staff codifier sync health workspace.", + "decorator": "app.get('/staff/sync', response_class=HTMLResponse)", + "errors": [] + }, + { + "method": "GET", + "path": "/staff/imports", + "router": "app", + "prefix_resolved": true, + "name": "staff_import_ledger", + "signature": "x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", + "returns": "HTMLResponse", + "line": 1000, + "doc": "Render the staff import job and provenance ledger.", + "decorator": "app.get('/staff/imports', response_class=HTMLResponse)", + "errors": [] + }, + { + "method": "GET", + "path": "/health", + "router": "app", + "prefix_resolved": true, + "name": "health", + "signature": "", + "returns": "dict[str, str]", + "line": 1013, + "doc": "Provide a simple operational health check for IT staff.", + "decorator": "app.get('/health')", + "errors": [] + }, + { + "method": "GET", + "path": "/api/v1/townlight_code/staff/operational-state", + "router": "app", + "prefix_resolved": true, + "name": "get_staff_operational_state", + "signature": "x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", + "returns": "dict[str, Any]", + "line": 1024, + "doc": "Return current operational readiness state for staff operators.", + "decorator": "app.get('/api/v1/townlight_code/staff/operational-state')", + "errors": [] + }, + { + "method": "GET", + "path": "/api/v1/townlight_code/sources/catalog", + "router": "app", + "prefix_resolved": true, + "name": "source_registry_catalog", + "signature": "", + "returns": "dict[str, Any]", + "line": 1036, + "doc": "Expose allowed source registry vocabulary for staff integration clients.", + "decorator": "app.get('/api/v1/townlight_code/sources/catalog')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_code/sources", + "router": "app", + "prefix_resolved": true, + "name": "create_source", + "signature": "request: SourceCreate, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", + "returns": "dict[str, Any]", + "line": 1050, + "doc": "Register a municipal code source without importing its contents yet.", + "decorator": "app.post('/api/v1/townlight_code/sources', status_code=201)", + "errors": [] + }, + { + "method": "GET", + "path": "/api/v1/townlight_code/sources", + "router": "app", + "prefix_resolved": true, + "name": "list_public_sources", + "signature": "", + "returns": "dict[str, Any]", + "line": 1068, + "doc": "List public-visible sources without exposing staff-only notes.", + "decorator": "app.get('/api/v1/townlight_code/sources')", + "errors": [] + }, + { + "method": "GET", + "path": "/api/v1/townlight_code/sources/{source_id}", + "router": "app", + "prefix_resolved": true, + "name": "get_public_source", + "signature": "source_id: str", + "returns": "dict[str, Any]", + "line": 1079, + "doc": "Read a public source record without leaking staff-only notes.", + "decorator": "app.get('/api/v1/townlight_code/sources/{source_id}')", + "errors": [ + "HTTPException(status_code=404, detail={'message': f\"Source '{source_id}' is not public-visible.\", 'fix': 'Use the staff source endpoint if you are authorized to view it.'})" + ] + }, + { + "method": "GET", + "path": "/api/v1/townlight_code/staff/sources", + "router": "app", + "prefix_resolved": true, + "name": "list_staff_sources", + "signature": "x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", + "returns": "dict[str, Any]", + "line": 1097, + "doc": "List all registered sources for staff workflows.", + "decorator": "app.get('/api/v1/townlight_code/staff/sources')", + "errors": [] + }, + { + "method": "GET", + "path": "/api/v1/townlight_code/staff/sources/{source_id}", + "router": "app", + "prefix_resolved": true, + "name": "get_staff_source", + "signature": "source_id: str, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", + "returns": "dict[str, Any]", + "line": 1112, + "doc": "Read a staff source record including staff-only notes.", + "decorator": "app.get('/api/v1/townlight_code/staff/sources/{source_id}')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_code/sources/{source_id}/transitions", + "router": "app", + "prefix_resolved": true, + "name": "transition_source", + "signature": "source_id: str, request: SourceTransitionRequest, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", + "returns": "dict[str, Any]", + "line": 1127, + "doc": "Transition a source through the official registry lifecycle.", + "decorator": "app.post('/api/v1/townlight_code/sources/{source_id}/transitions')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_code/titles", + "router": "app", + "prefix_resolved": true, + "name": "create_title", + "signature": "request: TitleCreate, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", + "returns": "dict[str, Any]", + "line": 1148, + "doc": "Create a municipal code title container.", + "decorator": "app.post('/api/v1/townlight_code/titles', status_code=201)", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_code/chapters", + "router": "app", + "prefix_resolved": true, + "name": "create_chapter", + "signature": "request: ChapterCreate, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", + "returns": "dict[str, Any]", + "line": 1163, + "doc": "Create a municipal code chapter under a title.", + "decorator": "app.post('/api/v1/townlight_code/chapters', status_code=201)", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_code/sections", + "router": "app", + "prefix_resolved": true, + "name": "create_section", + "signature": "request: SectionCreate, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", + "returns": "dict[str, Any]", + "line": 1178, + "doc": "Create a code section or subsection without generating answers.", + "decorator": "app.post('/api/v1/townlight_code/sections', status_code=201)", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_code/sections/{section_id}/versions", + "router": "app", + "prefix_resolved": true, + "name": "create_section_version", + "signature": "section_id: str, request: SectionVersionCreate, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", + "returns": "dict[str, Any]", + "line": 1193, + "doc": "Create an immutable section version for adopted, pending, or retired text.", + "decorator": "app.post('/api/v1/townlight_code/sections/{section_id}/versions', status_code=201)", + "errors": [ + "HTTPException(status_code=422, detail={'message': 'Path section_id must match request body section_id.', 'fix': 'Use the same section_id in the URL and JSON body.'})", + "HTTPException(status_code=409, detail={'message': f\"Source '{source.source_id}' is {source.status} and cannot back section text.\", 'fix': 'Use an active source or refresh the source registry record first.'})", + "HTTPException(status_code=409, detail={'message': 'Adopted section versions require an active public-visible source.', 'fix': 'Activate an official source in the registry before marking text as adopted law.'})", + "HTTPException(status_code=404, detail={'message': f\"Source '{data['source_id']}' was not found for this section version.\", 'fix': 'Register the source before adding section text from it.'})" + ] + }, + { + "method": "GET", + "path": "/api/v1/townlight_code/sections/lookup", + "router": "app", + "prefix_resolved": true, + "name": "lookup_section", + "signature": "section_number: str, as_of: date | None=None", + "returns": "dict[str, Any]", + "line": 1244, + "doc": "Lookup adopted section text by current flag or effective date.", + "decorator": "app.get('/api/v1/townlight_code/sections/lookup')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_code/sections/resolve", + "router": "app", + "prefix_resolved": true, + "name": "resolve_section", + "signature": "request: SectionResolveRequest", + "returns": "dict[str, Any]", + "line": 1255, + "doc": "Resolve adopted code context for downstream Townlight module clients.", + "decorator": "app.post('/api/v1/townlight_code/sections/resolve')", + "errors": [] + }, + { + "method": "GET", + "path": "/api/v1/townlight_code/sections/{section_id}/history", + "router": "app", + "prefix_resolved": true, + "name": "section_history", + "signature": "section_id: str", + "returns": "dict[str, Any]", + "line": 1354, + "doc": "Return immutable amendment/version history for a section.", + "decorator": "app.get('/api/v1/townlight_code/sections/{section_id}/history')", + "errors": [] + }, + { + "method": "GET", + "path": "/api/v1/townlight_code/sections/{section_id}/permalink", + "router": "app", + "prefix_resolved": true, + "name": "section_permalink", + "signature": "section_id: str", + "returns": "dict[str, Any]", + "line": 1363, + "doc": "Return the stable public-facing permalink for a section.", + "decorator": "app.get('/api/v1/townlight_code/sections/{section_id}/permalink')", + "errors": [] + }, + { + "method": "GET", + "path": "/api/v1/townlight_code/search", + "router": "app", + "prefix_resolved": true, + "name": "search_sections", + "signature": "q: str", + "returns": "dict[str, Any]", + "line": 1372, + "doc": "Search public-visible code sections and related public materials.", + "decorator": "app.get('/api/v1/townlight_code/search')", + "errors": [] + }, + { + "method": "GET", + "path": "/api/v1/townlight_code/popular-questions", + "router": "app", + "prefix_resolved": true, + "name": "list_popular_questions", + "signature": "", + "returns": "dict[str, Any]", + "line": 1381, + "doc": "List staff-approved public popular questions as navigation aids.", + "decorator": "app.get('/api/v1/townlight_code/popular-questions')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_code/staff/popular-questions", + "router": "app", + "prefix_resolved": true, + "name": "create_popular_question", + "signature": "request: PopularQuestionCreate, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", + "returns": "dict[str, Any]", + "line": 1403, + "doc": "Create a staff-approved public popular question tied to cited adopted code.", + "decorator": "app.post('/api/v1/townlight_code/staff/popular-questions', status_code=201)", + "errors": [ + "HTTPException(status_code=422, detail={'message': 'Popular questions cannot ask TownlightCode for a legal determination.', 'fix': \"Rewrite the question as a navigation prompt, such as 'Where do I read the backyard chicken permit rule?'\"})", + "HTTPException(status_code=409, detail={'message': citation_payload.get('reason', 'Citation could not be built.'), 'fix': citation_payload.get('fix', 'Attach the question to cited adopted code.')})" + ] + }, + { + "method": "GET", + "path": "/api/v1/townlight_code/sections/{section_number}/related", + "router": "app", + "prefix_resolved": true, + "name": "related_materials", + "signature": "section_number: str", + "returns": "dict[str, Any]", + "line": 1453, + "doc": "List explicit public related materials for one adopted section.", + "decorator": "app.get('/api/v1/townlight_code/sections/{section_number}/related')", + "errors": [] + }, + { + "method": "GET", + "path": "/api/v1/townlight_code/citations/build", + "router": "app", + "prefix_resolved": true, + "name": "build_citation", + "signature": "section_number: str, as_of: date | None=None", + "returns": "dict[str, Any]", + "line": 1466, + "doc": "Build a deterministic citation object or a structured refusal.", + "decorator": "app.get('/api/v1/townlight_code/citations/build')", + "errors": [] + }, + { + "method": "GET", + "path": "/api/v1/townlight_code/sections/{section_ref}/export", + "router": "app", + "prefix_resolved": true, + "name": "export_section", + "signature": "section_ref: str, as_of: date | None=None", + "returns": "dict[str, Any]", + "line": 1472, + "doc": "Return a records-ready section export with citation and source provenance.", + "decorator": "app.get('/api/v1/townlight_code/sections/{section_ref}/export')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_code/questions/answer", + "router": "app", + "prefix_resolved": true, + "name": "answer_question", + "signature": "request: QuestionAnswerRequest", + "returns": "dict[str, Any]", + "line": 1478, + "doc": "Answer code questions only when an adopted section citation grounds them.", + "decorator": "app.post('/api/v1/townlight_code/questions/answer')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_code/staff/sections/{section_id}/notes", + "router": "app", + "prefix_resolved": true, + "name": "create_interpretation_note", + "signature": "section_id: str, request: InterpretationNoteCreate, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", + "returns": "dict[str, Any]", + "line": 1494, + "doc": "Create a staff-only interpretation note without exposing it publicly.", + "decorator": "app.post('/api/v1/townlight_code/staff/sections/{section_id}/notes', status_code=201)", + "errors": [] + }, + { + "method": "GET", + "path": "/api/v1/townlight_code/staff/sections/{section_id}/notes", + "router": "app", + "prefix_resolved": true, + "name": "list_interpretation_notes", + "signature": "section_id: str, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", + "returns": "dict[str, Any]", + "line": 1517, + "doc": "List staff-only interpretation notes for authorized staff clients.", + "decorator": "app.get('/api/v1/townlight_code/staff/sections/{section_id}/notes')", + "errors": [] + }, + { + "method": "GET", + "path": "/api/v1/townlight_code/staff/audit-events", + "router": "app", + "prefix_resolved": true, + "name": "list_staff_audit_events", + "signature": "x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", + "returns": "dict[str, Any]", + "line": 1532, + "doc": "List staff workbench audit events for authorized staff clients.", + "decorator": "app.get('/api/v1/townlight_code/staff/audit-events')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_code/staff/imports/local-bundle", + "router": "app", + "prefix_resolved": true, + "name": "create_local_import_job", + "signature": "request: ImportBundleCreate, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", + "returns": "dict[str, Any]", + "line": 1548, + "doc": "Import a local codifier/file-drop fixture without outbound network calls.", + "decorator": "app.post('/api/v1/townlight_code/staff/imports/local-bundle', status_code=201)", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_code/staff/imports/shared-pdf", + "router": "app", + "prefix_resolved": true, + "name": "create_shared_pdf_import_job", + "signature": "request: SharedPdfImportCreate, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", + "returns": "dict[str, Any]", + "line": 1560, + "doc": "Ingest a municipal code PDF through TownlightCore, then structure it for TownlightCode.", + "decorator": "app.post('/api/v1/townlight_code/staff/imports/shared-pdf', status_code=201)", + "errors": [ + "HTTPException(status_code=409, detail={'message': 'Shared PDF ingestion requires a durable PostgreSQL runtime.', 'fix': 'Set TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL or DATABASE_URL to the TownlightCode PostgreSQL DSN.'})" + ] + }, + { + "method": "GET", + "path": "/api/v1/townlight_code/staff/imports", + "router": "app", + "prefix_resolved": true, + "name": "list_import_jobs", + "signature": "x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", + "returns": "dict[str, Any]", + "line": 1594, + "doc": "List local import jobs and their visible success/failure states.", + "decorator": "app.get('/api/v1/townlight_code/staff/imports')", + "errors": [] + }, + { + "method": "GET", + "path": "/api/v1/townlight_code/staff/imports/{job_id}", + "router": "app", + "prefix_resolved": true, + "name": "get_import_job", + "signature": "job_id: str, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", + "returns": "dict[str, Any]", + "line": 1604, + "doc": "Read a local import job, including actionable failure details.", + "decorator": "app.get('/api/v1/townlight_code/staff/imports/{job_id}')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_code/staff/imports/{job_id}/retry", + "router": "app", + "prefix_resolved": true, + "name": "retry_import_job", + "signature": "job_id: str, request: ImportBundleCreate, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", + "returns": "dict[str, Any]", + "line": 1619, + "doc": "Retry a failed import job with a corrected local bundle.", + "decorator": "app.post('/api/v1/townlight_code/staff/imports/{job_id}/retry', status_code=201)", + "errors": [] + }, + { + "method": "GET", + "path": "/api/v1/townlight_code/staff/imports/{job_id}/provenance", + "router": "app", + "prefix_resolved": true, + "name": "get_import_provenance", + "signature": "job_id: str, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", + "returns": "dict[str, Any]", + "line": 1635, + "doc": "Return a provenance report for a local import job.", + "decorator": "app.get('/api/v1/townlight_code/staff/imports/{job_id}/provenance')", + "errors": [] + }, + { + "method": "GET", + "path": "/api/v1/townlight_code/staff/imports/{job_id}/tree", + "router": "app", + "prefix_resolved": true, + "name": "get_imported_tree", + "signature": "job_id: str, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", + "returns": "dict[str, Any]", + "line": 1650, + "doc": "Show imported title/chapter/section/version tree for staff verification.", + "decorator": "app.get('/api/v1/townlight_code/staff/imports/{job_id}/tree')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_code/staff/sync/codifier-sources", + "router": "app", + "prefix_resolved": true, + "name": "configure_codifier_sync_source", + "signature": "request: CodifierSyncConfigureRequest, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", + "returns": "dict[str, Any]", + "line": 1673, + "doc": "Enable staff-controlled codifier sync readiness for an official source.", + "decorator": "app.post('/api/v1/townlight_code/staff/sync/codifier-sources', status_code=201)", + "errors": [] + }, + { + "method": "GET", + "path": "/api/v1/townlight_code/staff/sync/codifier-sources", + "router": "app", + "prefix_resolved": true, + "name": "list_codifier_sync_sources", + "signature": "x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", + "returns": "dict[str, Any]", + "line": 1694, + "doc": "List codifier sync readiness and circuit health for staff.", + "decorator": "app.get('/api/v1/townlight_code/staff/sync/codifier-sources')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_code/staff/sync/codifier-sources/{source_id}/run", + "router": "app", + "prefix_resolved": true, + "name": "run_codifier_sync_source", + "signature": "source_id: str, request: CodifierSyncRunRequest, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", + "returns": "dict[str, Any]", + "line": 1709, + "doc": "Run one staff-controlled codifier sync using an already fetched local payload.", + "decorator": "app.post('/api/v1/townlight_code/staff/sync/codifier-sources/{source_id}/run', status_code=201)", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_code/staff/townlight_meetings/ordinance-events", + "router": "app", + "prefix_resolved": true, + "name": "create_townlight_meetings_ordinance_event", + "signature": "request: TownlightMeetingsOrdinanceEventCreate, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None), x_townlight_code_intake_auth: str | None=Header(default=None, alias=TOWNLIGHT_CODE_INTAKE_AUTH_HEADER), authorization: str | None=Header(default=None)", + "returns": "dict[str, Any]", + "line": 1730, + "doc": "Receive TownlightMeetings ordinance/adoption events without codifying them.", + "decorator": "app.post('/api/v1/townlight_code/staff/townlight_meetings/ordinance-events', status_code=201)", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_code/staff/townlight_meetings/ordinance-events/{event_id}/resolve", + "router": "app", + "prefix_resolved": true, + "name": "resolve_townlight_meetings_ordinance_event", + "signature": "event_id: str, request: TownlightMeetingsOrdinanceEventResolve, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None), x_townlight_code_intake_auth: str | None=Header(default=None, alias=TOWNLIGHT_CODE_INTAKE_AUTH_HEADER), authorization: str | None=Header(default=None)", + "returns": "dict[str, Any]", + "line": 1756, + "doc": "Mark a TownlightMeetings handoff codified after staff creates the adopted code version.", + "decorator": "app.post('/api/v1/townlight_code/staff/townlight_meetings/ordinance-events/{event_id}/resolve')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_code/staff/sections/{section_id}/summaries", + "router": "app", + "prefix_resolved": true, + "name": "create_plain_language_summary", + "signature": "section_id: str, request: PlainLanguageSummaryCreate, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", + "returns": "dict[str, Any]", + "line": 1806, + "doc": "Create a staff-drafted plain-language summary tied to adopted code text.", + "decorator": "app.post('/api/v1/townlight_code/staff/sections/{section_id}/summaries', status_code=201)", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_code/staff/summaries/{summary_id}/approve", + "router": "app", + "prefix_resolved": true, + "name": "approve_plain_language_summary", + "signature": "summary_id: str, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", + "returns": "dict[str, Any]", + "line": 1841, + "doc": "Approve a plain-language summary for public display after staff review.", + "decorator": "app.post('/api/v1/townlight_code/staff/summaries/{summary_id}/approve')", + "errors": [] + }, + { + "method": "GET", + "path": "/api/v1/townlight_code/sections/{section_id}/summaries", + "router": "app", + "prefix_resolved": true, + "name": "list_public_plain_language_summaries", + "signature": "section_id: str", + "returns": "dict[str, Any]", + "line": 1866, + "doc": "List public approved summaries while keeping authoritative code visible.", + "decorator": "app.get('/api/v1/townlight_code/sections/{section_id}/summaries')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_code/staff/questions/answer", + "router": "app", + "prefix_resolved": true, + "name": "answer_staff_question", + "signature": "request: QuestionAnswerRequest, x_townlight_code_role: str | None=Header(default=None), x_townlight_code_actor: str | None=Header(default=None)", + "returns": "dict[str, Any]", + "line": 1895, + "doc": "Answer staff questions with staff-only notes kept out of public responses.", + "decorator": "app.post('/api/v1/townlight_code/staff/questions/answer')", + "errors": [] + } + ], + "models": [ + { + "name": "SourceCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "source_id", + "type": "str | None", + "default": "None" + }, + { + "name": "name", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "publisher", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "source_type", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "source_category", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "source_url", + "type": "str | None", + "default": "None" + }, + { + "name": "file_reference", + "type": "str | None", + "default": "None" + }, + { + "name": "retrieved_at", + "type": "datetime | None", + "default": "None" + }, + { + "name": "retrieval_method", + "type": "str | None", + "default": "None" + }, + { + "name": "checksum", + "type": "str | None", + "default": "None" + }, + { + "name": "source_owner", + "type": "str | None", + "default": "None" + }, + { + "name": "is_official", + "type": "bool", + "default": "True" + }, + { + "name": "official_status_note", + "type": "str | None", + "default": "None" + }, + { + "name": "status", + "type": "str", + "default": "'draft'" + }, + { + "name": "staff_notes", + "type": "str | None", + "default": "None" + } + ], + "line": 286, + "doc": "Request body for registering an official or explicitly labeled source." + }, + { + "name": "SourceTransitionRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "to_status", + "type": "str", + "default": "" + }, + { + "name": "actor", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "reason", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 308, + "doc": "Request body for source-state changes." + }, + { + "name": "TitleCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "title_id", + "type": "str | None", + "default": "None" + }, + { + "name": "title_number", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "title_name", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "sort_order", + "type": "int", + "default": "0" + } + ], + "line": 318, + "doc": "Request body for creating a code title." + }, + { + "name": "ChapterCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "chapter_id", + "type": "str | None", + "default": "None" + }, + { + "name": "title_id", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "chapter_number", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "chapter_name", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "sort_order", + "type": "int", + "default": "0" + } + ], + "line": 329, + "doc": "Request body for creating a code chapter." + }, + { + "name": "SectionCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "section_id", + "type": "str | None", + "default": "None" + }, + { + "name": "chapter_id", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "section_number", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "section_heading", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "parent_section_id", + "type": "str | None", + "default": "None" + }, + { + "name": "sort_order", + "type": "int", + "default": "0" + }, + { + "name": "administrative_regulation_refs", + "type": "list[str]", + "default": "Field(default_factory=list)" + }, + { + "name": "resolution_refs", + "type": "list[str]", + "default": "Field(default_factory=list)" + }, + { + "name": "policy_refs", + "type": "list[str]", + "default": "Field(default_factory=list)" + }, + { + "name": "approved_summary_refs", + "type": "list[str]", + "default": "Field(default_factory=list)" + } + ], + "line": 341, + "doc": "Request body for creating a code section or subsection." + }, + { + "name": "SectionVersionCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "version_id", + "type": "str | None", + "default": "None" + }, + { + "name": "section_id", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "source_id", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "version_label", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "body", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "effective_start", + "type": "date", + "default": "" + }, + { + "name": "effective_end", + "type": "date | None", + "default": "None" + }, + { + "name": "status", + "type": "str", + "default": "'draft'" + }, + { + "name": "is_current", + "type": "bool", + "default": "False" + }, + { + "name": "adoption_event_id", + "type": "str | None", + "default": "None" + }, + { + "name": "amendment_event_id", + "type": "str | None", + "default": "None" + }, + { + "name": "amendment_summary", + "type": "str | None", + "default": "None" + }, + { + "name": "prior_version_id", + "type": "str | None", + "default": "None" + } + ], + "line": 358, + "doc": "Request body for adding an immutable section version." + }, + { + "name": "QuestionAnswerRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "question", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "section_number", + "type": "str | None", + "default": "None" + }, + { + "name": "as_of", + "type": "date | None", + "default": "None" + } + ], + "line": 378, + "doc": "Request body for citation-grounded code Q&A." + }, + { + "name": "SectionResolveRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "consumer_module", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "section_number", + "type": "str | None", + "default": "None" + }, + { + "name": "query", + "type": "str | None", + "default": "None" + }, + { + "name": "as_of", + "type": "date | None", + "default": "None" + } + ], + "line": 388, + "doc": "Request body for downstream module section-resolution clients." + }, + { + "name": "PopularQuestionCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "question_id", + "type": "str | None", + "default": "None" + }, + { + "name": "question_text", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "section_number", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "answer_excerpt", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "audience", + "type": "str", + "default": "'public'" + }, + { + "name": "status", + "type": "str", + "default": "'approved'" + }, + { + "name": "is_popular", + "type": "bool", + "default": "True" + } + ], + "line": 399, + "doc": "Request body for a staff-approved public popular-question navigation aid." + }, + { + "name": "InterpretationNoteCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "note_id", + "type": "str | None", + "default": "None" + }, + { + "name": "note_text", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "status", + "type": "str", + "default": "'draft'" + } + ], + "line": 413, + "doc": "Request body for staff-only interpretation notes." + }, + { + "name": "PlainLanguageSummaryCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "summary_id", + "type": "str | None", + "default": "None" + }, + { + "name": "section_version_id", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "summary_text", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "language_code", + "type": "str", + "default": "'en'" + }, + { + "name": "status", + "type": "str", + "default": "'draft'" + } + ], + "line": 423, + "doc": "Request body for staff-drafted plain-language summaries." + }, + { + "name": "TownlightMeetingsOrdinanceEventCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "event_id", + "type": "str | None", + "default": "None" + }, + { + "name": "external_event_id", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "townlight_meetings_meeting_id", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "townlight_meetings_agenda_item_id", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "ordinance_number", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "title", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "status", + "type": "str", + "default": "'pending'" + }, + { + "name": "affected_sections", + "type": "list[str]", + "default": "Field(default_factory=list)" + }, + { + "name": "source_document_url", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "source_document_hash", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "ordinance_text", + "type": "str", + "default": "''" + }, + { + "name": "adopted_at", + "type": "datetime | None", + "default": "None" + }, + { + "name": "failure_reason", + "type": "str | None", + "default": "None" + } + ], + "line": 435, + "doc": "Request body for TownlightMeetings ordinance/adoption handoff intake." + }, + { + "name": "TownlightMeetingsOrdinanceEventResolve", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "section_version_id", + "type": "str", + "default": "Field(min_length=1)" + } + ], + "line": 455, + "doc": "Request body for resolving a handoff after staff codifies the amendment." + }, + { + "name": "ImportBundleCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "job_id", + "type": "str | None", + "default": "None" + }, + { + "name": "connector_type", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "source", + "type": "SourceCreate", + "default": "" + }, + { + "name": "sources", + "type": "list[SourceCreate]", + "default": "Field(default_factory=list)" + }, + { + "name": "titles", + "type": "list[TitleCreate]", + "default": "Field(default_factory=list)" + }, + { + "name": "chapters", + "type": "list[ChapterCreate]", + "default": "Field(default_factory=list)" + }, + { + "name": "sections", + "type": "list[SectionCreate]", + "default": "Field(default_factory=list)" + }, + { + "name": "versions", + "type": "list[SectionVersionCreate]", + "default": "Field(default_factory=list)" + }, + { + "name": "provenance", + "type": "dict[str, Any]", + "default": "Field(default_factory=dict)" + } + ], + "line": 463, + "doc": "Request body for local fixture/file-drop import jobs." + }, + { + "name": "SharedPdfImportCreate", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "pdf_path", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "force_reingest", + "type": "bool", + "default": "False" + } + ], + "line": 479, + "doc": "Request body for TownlightCore shared PDF ingestion into TownlightCode." + }, + { + "name": "CodifierSyncConfigureRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "source_id", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "sync_schedule", + "type": "str", + "default": "Field(min_length=1)" + }, + { + "name": "allowlisted_hosts", + "type": "list[str]", + "default": "Field(default_factory=list)" + } + ], + "line": 488, + "doc": "Request body for enabling staff-controlled codifier sync readiness." + }, + { + "name": "CodifierSyncRunRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "payload", + "type": "ImportBundleCreate", + "default": "" + }, + { + "name": "changed_since", + "type": "datetime | None", + "default": "None" + } + ], + "line": 498, + "doc": "Request body for a local codifier sync run." + } + ], + "configuration": [ + { + "variable": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", + "default": "", + "line": 1988 + }, + { + "variable": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", + "default": "", + "line": 1999 + }, + { + "variable": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", + "default": "", + "line": 2010 + }, + { + "variable": "TOWNLIGHT_CODE_DEMO_ACTOR", + "default": "'demo-seed@portland.example.gov'", + "line": 2062 + }, + { + "variable": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", + "default": "", + "line": 173 + }, + { + "variable": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", + "default": "", + "line": 201 + }, + { + "variable": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", + "default": "", + "line": 224 + }, + { + "variable": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", + "default": "", + "line": 252 + }, + { + "variable": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", + "default": "", + "line": 1567 + }, + { + "variable": "DATABASE_URL", + "default": "", + "line": 1567 + }, + { + "variable": "TOWNLIGHT_CODE_SOURCE_REGISTRY_DB_URL", + "default": "", + "line": 2020 + }, + { + "variable": "TOWNLIGHT_CODE_DEMO_SEED", + "default": "''", + "line": 2056 + } + ] + }, + { + "source": "installed-owned-source/townlight_code/migrations/__init__.py", + "sha256": "4c8b91a2b40fe7951bf11bd74070344c9967b0feb5170a68d490305dc8333b8e", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_code/migrations/env.py", + "sha256": "5526b8ac01c1bc652c77861bb77209503668127d5c9a8d810dda351dff7a158e", + "routes": [], + "models": [], + "configuration": [ + { + "variable": "DATABASE_URL", + "default": "", + "line": 24 + } + ] + }, + { + "source": "installed-owned-source/townlight_code/migrations/guards.py", + "sha256": "110cca437db7e2507374b9e0d9d32739dbdbaf57c664ac89d8a4c56472c05d7f", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_code/migrations/versions/__init__.py", + "sha256": "74446fe86c7d899c1e4942b131ef47880cbb716011970d702ac78799902cc7ac", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_code/migrations/versions/townlight_code_0001_schema.py", + "sha256": "3361408fb75b2330c3dffa4c343bffa39ec96cb41b25d7c3e980f3efea69a950", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_code/migrations/versions/townlight_code_0002_source_registry_records.py", + "sha256": "a237d274d614a260242b2eee1661845fa96476445a8496c1fc2e8ff773fcc85c", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_code/migrations/versions/townlight_code_0003_popular_question_records.py", + "sha256": "d973ad1e13a5b84cc4bcc19d9977d9532d09388451c3872549180fa02ecfe609", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_code/migrations/versions/townlight_code_0004_section_lifecycle_records.py", + "sha256": "e11d0b3c4d08f32c00e513bbf336bf9f3ee2459c929aca0fed7c2158b688299f", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_code/migrations/versions/townlight_code_0005_staff_summary_records.py", + "sha256": "04d9a42402dbf503f9988dc07c4fe264390470d798d8e2d51983a1d7b8a5e601", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_code/migrations/versions/townlight_code_0006_ordinance_handoff_records.py", + "sha256": "bd2c85f222a0d4946298bdb580a36af174be378fbb3bdf62641457b87d5499fa", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_code/migrations/versions/townlight_code_0007_import_job_records.py", + "sha256": "d965ccf019d4059fe56ffd234955f45193d51d52a38b20fa1ba66e809493cb67", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_code/migrations/versions/townlight_code_0008_codifier_sync.py", + "sha256": "10b417a95e25d79ea3cc48fb3feedec0eea878f9580eba0b3c9e0b9413886366", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_code/migrations/versions/townlight_code_0009_operational_state.py", + "sha256": "5ff5a28d099a69b55c121fbf6ff9336cb8dee51e385966900510aba5df9a7540", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_code/migrations/versions/townlight_code_0010_handoff_resolution.py", + "sha256": "ed20579ff39863de49bd01a97a47b77d84b380f54f0aba7473c1aad360b11b4a", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_code/migrations/versions/townlight_code_0011_semantic_search.py", + "sha256": "4bf32028058db6ff90c19e2cf891886fef6d4e958ed7e72165e9a224ebd1b19d", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_code/migrations/versions/townlight_code_0012_drop_local_search.py", + "sha256": "6ac60feecb72efbe78a788066ac58d790f6e6c460f4a71eea6ecf6cf30a6570d", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_code/mock_city_environment.py", + "sha256": "91c1e1089e2956417fd520725847950c544166f0a93f2a0a63b7c1a9859c1189", + "routes": [], + "models": [ + { + "name": "MockCityCodifierContract", + "bases": [], + "fields": [ + { + "name": "connector", + "type": "str", + "default": "" + }, + { + "name": "publisher", + "type": "str", + "default": "" + }, + { + "name": "source_type", + "type": "str", + "default": "" + }, + { + "name": "interface_status", + "type": "str", + "default": "" + }, + { + "name": "source_url", + "type": "str", + "default": "" + }, + { + "name": "retrieval_method", + "type": "str", + "default": "" + }, + { + "name": "auth_method", + "type": "str", + "default": "" + }, + { + "name": "delta_query_param", + "type": "str", + "default": "" + }, + { + "name": "sample_file", + "type": "str", + "default": "" + }, + { + "name": "source_owner", + "type": "str", + "default": "'City Clerk'" + } + ], + "line": 31, + "doc": "A public, secret-free contract for one municipal-code source interface." + }, + { + "name": "MockCityCodeCheck", + "bases": [], + "fields": [ + { + "name": "connector", + "type": "str", + "default": "" + }, + { + "name": "ok", + "type": "bool", + "default": "" + }, + { + "name": "message", + "type": "str", + "default": "" + }, + { + "name": "fix", + "type": "str", + "default": "" + }, + { + "name": "source_id", + "type": "str | None", + "default": "None" + }, + { + "name": "import_job_id", + "type": "str | None", + "default": "None" + }, + { + "name": "delta_request_url", + "type": "str | None", + "default": "None" + }, + { + "name": "checked_sections", + "type": "tuple[str, ...]", + "default": "()" + } + ], + "line": 66, + "doc": "Result for one mock-city codifier contract check." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_code/models.py", + "sha256": "15f328be4b05481401d8ccd296110136ef98e98634fe59af1c2aa729340e8e4f", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_code/operational_readiness.py", + "sha256": "002130b66583a7645218e271d515ca6b9295f7a8fe19ee9e85e6e52adacc07a9", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_code/operational_state.py", + "sha256": "6d73c3201fc449de9bf6678d129184533323960f82ccb0a5c0f6dcb147421b0f", + "routes": [], + "models": [ + { + "name": "OperationalStateRecord", + "bases": [], + "fields": [ + { + "name": "record_id", + "type": "str", + "default": "" + }, + { + "name": "lane", + "type": "str", + "default": "" + }, + { + "name": "record_type", + "type": "str", + "default": "" + }, + { + "name": "subject_id", + "type": "str", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "actor", + "type": "str", + "default": "'system'" + }, + { + "name": "attempt_count", + "type": "int", + "default": "0" + }, + { + "name": "next_attempt_at", + "type": "datetime | None", + "default": "None" + }, + { + "name": "cursor_key", + "type": "str | None", + "default": "None" + }, + { + "name": "cursor_value", + "type": "str | None", + "default": "None" + }, + { + "name": "replay_of", + "type": "str | None", + "default": "None" + }, + { + "name": "payload_hash", + "type": "str | None", + "default": "None" + }, + { + "name": "details", + "type": "dict[str, Any]", + "default": "field(default_factory=dict)" + }, + { + "name": "failure", + "type": "dict[str, Any] | None", + "default": "None" + }, + { + "name": "created_at", + "type": "datetime", + "default": "field(default_factory=lambda: datetime.now(UTC))" + }, + { + "name": "updated_at", + "type": "datetime", + "default": "field(default_factory=lambda: datetime.now(UTC))" + } + ], + "line": 20, + "doc": "One operator-visible operational state record." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_code/ordinance_handoff.py", + "sha256": "5e98eefc3e510efaf0d5973927aa3506f8b652d319320f745a831bef0cb5897b", + "routes": [], + "models": [ + { + "name": "OrdinanceEvent", + "bases": [], + "fields": [ + { + "name": "event_id", + "type": "str", + "default": "" + }, + { + "name": "external_event_id", + "type": "str", + "default": "" + }, + { + "name": "townlight_meetings_meeting_id", + "type": "str", + "default": "" + }, + { + "name": "townlight_meetings_agenda_item_id", + "type": "str", + "default": "" + }, + { + "name": "ordinance_number", + "type": "str", + "default": "" + }, + { + "name": "title", + "type": "str", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "affected_sections", + "type": "list[str]", + "default": "" + }, + { + "name": "source_document_url", + "type": "str", + "default": "" + }, + { + "name": "source_document_hash", + "type": "str", + "default": "" + }, + { + "name": "ordinance_text", + "type": "str", + "default": "''" + }, + { + "name": "adopted_at", + "type": "datetime | None", + "default": "None" + }, + { + "name": "failure_reason", + "type": "str | None", + "default": "None" + }, + { + "name": "resolved_section_version_id", + "type": "str | None", + "default": "None" + }, + { + "name": "resolved_by", + "type": "str | None", + "default": "None" + }, + { + "name": "resolved_at", + "type": "datetime | None", + "default": "None" + }, + { + "name": "created_by", + "type": "str", + "default": "'unknown'" + }, + { + "name": "created_at", + "type": "datetime", + "default": "field(default_factory=lambda: datetime.now(UTC))" + } + ], + "line": 39, + "doc": "" + }, + { + "name": "HandoffAuditEvent", + "bases": [], + "fields": [ + { + "name": "event_id", + "type": "str", + "default": "" + }, + { + "name": "event_type", + "type": "str", + "default": "" + }, + { + "name": "actor", + "type": "str", + "default": "" + }, + { + "name": "target_id", + "type": "str", + "default": "" + }, + { + "name": "created_at", + "type": "datetime", + "default": "field(default_factory=lambda: datetime.now(UTC))" + } + ], + "line": 69, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_code/plain_language.py", + "sha256": "074b7aae42a3c4ee7ae5e64726a5fbbe151039cb51467f89f47b977e93e9b2bd", + "routes": [], + "models": [ + { + "name": "PlainLanguageSummary", + "bases": [], + "fields": [ + { + "name": "summary_id", + "type": "str", + "default": "" + }, + { + "name": "section_id", + "type": "str", + "default": "" + }, + { + "name": "section_version_id", + "type": "str", + "default": "" + }, + { + "name": "summary_text", + "type": "str", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "language_code", + "type": "str", + "default": "'en'" + }, + { + "name": "created_by", + "type": "str", + "default": "'unknown'" + }, + { + "name": "approved_by", + "type": "str | None", + "default": "None" + }, + { + "name": "approved_at", + "type": "datetime | None", + "default": "None" + }, + { + "name": "created_at", + "type": "datetime", + "default": "field(default_factory=lambda: datetime.now(UTC))" + } + ], + "line": 31, + "doc": "" + }, + { + "name": "SummaryAuditEvent", + "bases": [], + "fields": [ + { + "name": "event_id", + "type": "str", + "default": "" + }, + { + "name": "event_type", + "type": "str", + "default": "" + }, + { + "name": "actor", + "type": "str", + "default": "" + }, + { + "name": "section_id", + "type": "str", + "default": "" + }, + { + "name": "target_id", + "type": "str", + "default": "" + }, + { + "name": "created_at", + "type": "datetime", + "default": "field(default_factory=lambda: datetime.now(UTC))" + } + ], + "line": 49, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_code/public_discovery.py", + "sha256": "f87497befbd3f75db94c4db0f36fb04fc1a34af8eba73a425ff49edb8dfc20ae", + "routes": [], + "models": [ + { + "name": "PopularQuestion", + "bases": [], + "fields": [ + { + "name": "question_id", + "type": "str", + "default": "" + }, + { + "name": "question_text", + "type": "str", + "default": "" + }, + { + "name": "section_id", + "type": "str", + "default": "" + }, + { + "name": "section_number", + "type": "str", + "default": "" + }, + { + "name": "section_heading", + "type": "str", + "default": "" + }, + { + "name": "answer_excerpt", + "type": "str", + "default": "" + }, + { + "name": "citation_payload", + "type": "dict[str, Any]", + "default": "" + }, + { + "name": "audience", + "type": "str", + "default": "'public'" + }, + { + "name": "status", + "type": "str", + "default": "'draft'" + }, + { + "name": "is_popular", + "type": "bool", + "default": "True" + }, + { + "name": "approved_by", + "type": "str | None", + "default": "None" + }, + { + "name": "approved_at", + "type": "datetime | None", + "default": "None" + }, + { + "name": "created_at", + "type": "datetime", + "default": "field(default_factory=lambda: datetime.now(UTC))" + } + ], + "line": 34, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_code/public_exports.py", + "sha256": "2d413d312f8baf1e790bb4205ad93ac25928f1afefa3aca1898d91092085bcc4", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_code/public_lookup.py", + "sha256": "a3c62b6aaa3de1ef98ac824fd5806e61bd444ae61241e2a19f0f7dff3a3cca79", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_code/qa_harness.py", + "sha256": "bc040cb0c4ff124f13a63e10fbcb26d478a06da5364e7fa18d177b40af269797", + "routes": [], + "models": [ + { + "name": "QuestionRequestContext", + "bases": [], + "fields": [ + { + "name": "question", + "type": "str", + "default": "" + }, + { + "name": "section_number", + "type": "str | None", + "default": "None" + }, + { + "name": "as_of", + "type": "date | None", + "default": "None" + } + ], + "line": 37, + "doc": "Normalized input for deterministic question answering." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_code/real_municipal_fixtures.py", + "sha256": "a88b400d5b5bb8d6a74ec8a29d793c3e51ab94226e0f0b8abbde7030f667280a", + "routes": [], + "models": [ + { + "name": "PortlandSectionFixture", + "bases": [], + "fields": [ + { + "name": "section_id", + "type": "str", + "default": "" + }, + { + "name": "section_number", + "type": "str", + "default": "" + }, + { + "name": "heading", + "type": "str", + "default": "" + }, + { + "name": "source_id", + "type": "str", + "default": "" + }, + { + "name": "source_url", + "type": "str", + "default": "" + }, + { + "name": "file_reference", + "type": "str", + "default": "" + }, + { + "name": "body", + "type": "str", + "default": "" + }, + { + "name": "effective_start", + "type": "str", + "default": "" + }, + { + "name": "adoption_event_id", + "type": "str | None", + "default": "None" + } + ], + "line": 22, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_code/section_lifecycle.py", + "sha256": "34096b4ca4fa8f65628d33761609044f29a03bf0d89a5da09085440e56d149f2", + "routes": [], + "models": [ + { + "name": "CodeTitle", + "bases": [], + "fields": [ + { + "name": "title_id", + "type": "str", + "default": "" + }, + { + "name": "title_number", + "type": "str", + "default": "" + }, + { + "name": "title_name", + "type": "str", + "default": "" + }, + { + "name": "sort_order", + "type": "int", + "default": "0" + }, + { + "name": "created_at", + "type": "datetime", + "default": "field(default_factory=lambda: datetime.now(UTC))" + } + ], + "line": 42, + "doc": "" + }, + { + "name": "CodeChapter", + "bases": [], + "fields": [ + { + "name": "chapter_id", + "type": "str", + "default": "" + }, + { + "name": "title_id", + "type": "str", + "default": "" + }, + { + "name": "chapter_number", + "type": "str", + "default": "" + }, + { + "name": "chapter_name", + "type": "str", + "default": "" + }, + { + "name": "sort_order", + "type": "int", + "default": "0" + }, + { + "name": "created_at", + "type": "datetime", + "default": "field(default_factory=lambda: datetime.now(UTC))" + } + ], + "line": 51, + "doc": "" + }, + { + "name": "CodeSection", + "bases": [], + "fields": [ + { + "name": "section_id", + "type": "str", + "default": "" + }, + { + "name": "chapter_id", + "type": "str", + "default": "" + }, + { + "name": "section_number", + "type": "str", + "default": "" + }, + { + "name": "section_heading", + "type": "str", + "default": "" + }, + { + "name": "parent_section_id", + "type": "str | None", + "default": "None" + }, + { + "name": "sort_order", + "type": "int", + "default": "0" + }, + { + "name": "administrative_regulation_refs", + "type": "list[str]", + "default": "field(default_factory=list)" + }, + { + "name": "resolution_refs", + "type": "list[str]", + "default": "field(default_factory=list)" + }, + { + "name": "policy_refs", + "type": "list[str]", + "default": "field(default_factory=list)" + }, + { + "name": "approved_summary_refs", + "type": "list[str]", + "default": "field(default_factory=list)" + }, + { + "name": "created_at", + "type": "datetime", + "default": "field(default_factory=lambda: datetime.now(UTC))" + } + ], + "line": 61, + "doc": "" + }, + { + "name": "SectionVersion", + "bases": [], + "fields": [ + { + "name": "version_id", + "type": "str", + "default": "" + }, + { + "name": "section_id", + "type": "str", + "default": "" + }, + { + "name": "source_id", + "type": "str", + "default": "" + }, + { + "name": "version_label", + "type": "str", + "default": "" + }, + { + "name": "body", + "type": "str", + "default": "" + }, + { + "name": "effective_start", + "type": "date", + "default": "" + }, + { + "name": "effective_end", + "type": "date | None", + "default": "None" + }, + { + "name": "status", + "type": "str", + "default": "'draft'" + }, + { + "name": "is_current", + "type": "bool", + "default": "False" + }, + { + "name": "adoption_event_id", + "type": "str | None", + "default": "None" + }, + { + "name": "amendment_event_id", + "type": "str | None", + "default": "None" + }, + { + "name": "amendment_summary", + "type": "str | None", + "default": "None" + }, + { + "name": "prior_version_id", + "type": "str | None", + "default": "None" + }, + { + "name": "created_at", + "type": "datetime", + "default": "field(default_factory=lambda: datetime.now(UTC))" + } + ], + "line": 76, + "doc": "" + } + ], + "configuration": [ + { + "variable": "TOWNLIGHT_CODE_SEMANTIC_SCORE_FLOOR", + "default": "", + "line": 929 + } + ] + }, + { + "source": "installed-owned-source/townlight_code/semantic_search.py", + "sha256": "85de9cb0b861a7551a701bd4082ec3343728831c8bf20e45d90719db60f8b78c", + "routes": [], + "models": [ + { + "name": "SemanticDocument", + "bases": [], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "version_id", + "type": "str", + "default": "" + }, + { + "name": "text", + "type": "str", + "default": "" + } + ], + "line": 24, + "doc": "" + }, + { + "name": "EmbeddingConfig", + "bases": [], + "fields": [ + { + "name": "mode", + "type": "str", + "default": "" + }, + { + "name": "base_url", + "type": "str", + "default": "" + }, + { + "name": "model", + "type": "str", + "default": "" + }, + { + "name": "timeout_seconds", + "type": "float", + "default": "" + } + ], + "line": 31, + "doc": "" + } + ], + "configuration": [ + { + "variable": "TOWNLIGHT_CODE_OLLAMA_EMBEDDING_MODEL", + "default": "DEFAULT_EMBEDDING_MODEL", + "line": 49 + }, + { + "variable": "TOWNLIGHT_CODE_OLLAMA_EMBEDDING_URL", + "default": "", + "line": 45 + }, + { + "variable": "TOWNLIGHT_CODE_OLLAMA_URL", + "default": "", + "line": 46 + }, + { + "variable": "OLLAMA_BASE_URL", + "default": "", + "line": 47 + }, + { + "variable": "TOWNLIGHT_CODE_OLLAMA_EMBEDDING_TIMEOUT_SECONDS", + "default": "'30'", + "line": 50 + }, + { + "variable": "TOWNLIGHT_CODE_EMBEDDING_MODE", + "default": "''", + "line": 40 + } + ] + }, + { + "source": "installed-owned-source/townlight_code/shared_ingestion.py", + "sha256": "caf8ec1c4d1da5a485ec96d0ae04e800e29f02fe1a71809cbebe0718c574f987", + "routes": [], + "models": [ + { + "name": "SharedIngestionImport", + "bases": [], + "fields": [ + { + "name": "payload", + "type": "dict[str, Any]", + "default": "" + }, + { + "name": "proof", + "type": "dict[str, Any]", + "default": "" + } + ], + "line": 65, + "doc": "A TownlightCore-ingested document plus a TownlightCode local-bundle payload." + } + ], + "configuration": [ + { + "variable": "DATABASE_URL", + "default": "", + "line": 172 + }, + { + "variable": "TOWNLIGHT_CODE_SHARED_INGEST_CHUNK_SIZE", + "default": "'500'", + "line": 88 + }, + { + "variable": "TOWNLIGHT_CODE_SHARED_INGEST_CHUNK_OVERLAP", + "default": "'50'", + "line": 89 + }, + { + "variable": "TOWNLIGHT_CODE_SHARED_INGEST_ALLOWED_DIRS", + "default": "", + "line": 252 + }, + { + "variable": "TOWNLIGHT_CODE_SHARED_INGEST_ALLOWED_DIR", + "default": "", + "line": 252 + } + ] + }, + { + "source": "installed-owned-source/townlight_code/source_registry.py", + "sha256": "292e2286802f36458a7468b749f81ff82277cc5f404fbf7b0ac7dd88f5d79651", + "routes": [], + "models": [ + { + "name": "CodeSource", + "bases": [], + "fields": [ + { + "name": "source_id", + "type": "str", + "default": "" + }, + { + "name": "name", + "type": "str", + "default": "" + }, + { + "name": "publisher", + "type": "str", + "default": "" + }, + { + "name": "source_type", + "type": "str", + "default": "" + }, + { + "name": "source_category", + "type": "str", + "default": "" + }, + { + "name": "source_url", + "type": "str | None", + "default": "None" + }, + { + "name": "file_reference", + "type": "str | None", + "default": "None" + }, + { + "name": "retrieved_at", + "type": "datetime | None", + "default": "None" + }, + { + "name": "retrieval_method", + "type": "str | None", + "default": "None" + }, + { + "name": "checksum", + "type": "str | None", + "default": "None" + }, + { + "name": "source_owner", + "type": "str | None", + "default": "None" + }, + { + "name": "is_official", + "type": "bool", + "default": "True" + }, + { + "name": "official_status_note", + "type": "str | None", + "default": "None" + }, + { + "name": "status", + "type": "str", + "default": "'draft'" + }, + { + "name": "staff_notes", + "type": "str | None", + "default": "None" + }, + { + "name": "created_at", + "type": "datetime", + "default": "field(default_factory=lambda: datetime.now(UTC))" + }, + { + "name": "updated_at", + "type": "datetime", + "default": "field(default_factory=lambda: datetime.now(UTC))" + } + ], + "line": 74, + "doc": "Runtime representation of an official or explicitly non-official source." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_code/staff_code.py", + "sha256": "90b3d8ac3c6eb0c65831b47d8f6fa63ce3ac3d2350442c0913e15f7a768e317d", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_code/staff_imports.py", + "sha256": "f5ccf4e1d8d24bd23b62f922013f0f8eb2a8b633737b0a1134002ea0ea51e8df", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_code/staff_sources.py", + "sha256": "b7d00f3e051f131fde7142426b911e4484076987e4711685d18cf85dcee15412", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_code/staff_sync.py", + "sha256": "92361f57357bd12e22dff589a6f2353de3602947ed739b8738d8479e2462791d", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_code/staff_workbench.py", + "sha256": "13893408816cb0794c266c78d78e30e8182171b92830e757353001afea4f79fd", + "routes": [], + "models": [ + { + "name": "InterpretationNote", + "bases": [], + "fields": [ + { + "name": "note_id", + "type": "str", + "default": "" + }, + { + "name": "section_id", + "type": "str", + "default": "" + }, + { + "name": "note_text", + "type": "str", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "visibility", + "type": "str", + "default": "'staff_only'" + }, + { + "name": "created_by", + "type": "str", + "default": "'unknown'" + }, + { + "name": "created_at", + "type": "datetime", + "default": "field(default_factory=lambda: datetime.now(UTC))" + } + ], + "line": 31, + "doc": "" + }, + { + "name": "AuditEvent", + "bases": [], + "fields": [ + { + "name": "event_id", + "type": "str", + "default": "" + }, + { + "name": "event_type", + "type": "str", + "default": "" + }, + { + "name": "actor", + "type": "str", + "default": "" + }, + { + "name": "section_id", + "type": "str | None", + "default": "None" + }, + { + "name": "target_id", + "type": "str | None", + "default": "None" + }, + { + "name": "created_at", + "type": "datetime", + "default": "field(default_factory=lambda: datetime.now(UTC))" + } + ], + "line": 42, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_code/suite_session_auth.py", + "sha256": "b30a449b95838c04098d33373f3b6b030539b7a8ea2a998210333b314f9f4582", + "routes": [], + "models": [ + { + "name": "SuiteSessionPrincipal", + "bases": [], + "fields": [ + { + "name": "subject", + "type": "str", + "default": "" + }, + { + "name": "roles", + "type": "frozenset[str]", + "default": "" + }, + { + "name": "session_id", + "type": "str", + "default": "" + } + ], + "line": 32, + "doc": "Validated TownlightCore suite-session identity." + } + ], + "configuration": [] + } + ], + "bridge": [ + { + "source": "installed-owned-source/townlight_runtime/code_bridge.py", + "sha256": "901f1473aa6f4db4b089925a2fec17e963cef7a27c6bf885099a362df1fe15e9", + "routes": [ + { + "method": "POST", + "path": "/desktop/v1/code/imports", + "router": "router", + "prefix_resolved": true, + "name": "imports", + "signature": "data: code.ImportBundleCreate, actor_id: str=Depends(actor)", + "returns": "", + "line": 46, + "doc": "", + "decorator": "router.post('/imports')", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/code/sources", + "router": "router", + "prefix_resolved": true, + "name": "sources", + "signature": "actor_id: str=Depends(actor)", + "returns": "", + "line": 55, + "doc": "", + "decorator": "router.get('/sources')", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/code/workspace", + "router": "router", + "prefix_resolved": true, + "name": "workspace", + "signature": "actor_id: str=Depends(actor)", + "returns": "", + "line": 60, + "doc": "", + "decorator": "router.get('/workspace')", + "errors": [ + "HTTPException(503, 'Townlight Code persistence unavailable.')" + ] + }, + { + "method": "GET", + "path": "/desktop/v1/code/lookup", + "router": "router", + "prefix_resolved": true, + "name": "lookup", + "signature": "section_number: str, as_of: date | None=None, actor_id: str=Depends(actor)", + "returns": "", + "line": 68, + "doc": "", + "decorator": "router.get('/lookup')", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/code/sections/{section_id}/history", + "router": "router", + "prefix_resolved": true, + "name": "section_history", + "signature": "section_id: str, actor_id: str=Depends(actor)", + "returns": "", + "line": 77, + "doc": "", + "decorator": "router.get('/sections/{section_id}/history')", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/code/citation", + "router": "router", + "prefix_resolved": true, + "name": "citation", + "signature": "section_number: str, as_of: date | None=None, actor_id: str=Depends(actor)", + "returns": "", + "line": 82, + "doc": "", + "decorator": "router.get('/citation')", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/code/search", + "router": "router", + "prefix_resolved": true, + "name": "search", + "signature": "q: str, actor_id: str=Depends(actor)", + "returns": "", + "line": 89, + "doc": "", + "decorator": "router.get('/search')", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/code/imports", + "router": "router", + "prefix_resolved": true, + "name": "list_imports", + "signature": "actor_id: str=Depends(actor)", + "returns": "", + "line": 100, + "doc": "", + "decorator": "router.get('/imports')", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/code/imports/{job_id}/tree", + "router": "router", + "prefix_resolved": true, + "name": "import_tree", + "signature": "job_id: str, actor_id: str=Depends(actor)", + "returns": "", + "line": 105, + "doc": "", + "decorator": "router.get('/imports/{job_id}/tree')", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/code/imports/{job_id}/provenance", + "router": "router", + "prefix_resolved": true, + "name": "import_provenance", + "signature": "job_id: str, actor_id: str=Depends(actor)", + "returns": "", + "line": 110, + "doc": "", + "decorator": "router.get('/imports/{job_id}/provenance')", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/code/export", + "router": "router", + "prefix_resolved": true, + "name": "export_section", + "signature": "section_ref: str, as_of: date | None=None, actor_id: str=Depends(actor)", + "returns": "", + "line": 115, + "doc": "", + "decorator": "router.get('/export')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/code/questions", + "router": "router", + "prefix_resolved": true, + "name": "questions", + "signature": "data: code.QuestionAnswerRequest, actor_id: str=Depends(actor)", + "returns": "", + "line": 120, + "doc": "", + "decorator": "router.post('/questions')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/code/sections/{section_id}/notes", + "router": "router", + "prefix_resolved": true, + "name": "create_note", + "signature": "section_id: str, data: code.InterpretationNoteCreate, actor_id: str=Depends(actor)", + "returns": "", + "line": 125, + "doc": "", + "decorator": "router.post('/sections/{section_id}/notes')", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/code/sections/{section_id}/notes", + "router": "router", + "prefix_resolved": true, + "name": "list_notes", + "signature": "section_id: str, actor_id: str=Depends(actor)", + "returns": "", + "line": 130, + "doc": "", + "decorator": "router.get('/sections/{section_id}/notes')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/code/sections/{section_id}/summaries", + "router": "router", + "prefix_resolved": true, + "name": "create_summary", + "signature": "section_id: str, data: code.PlainLanguageSummaryCreate, actor_id: str=Depends(actor)", + "returns": "", + "line": 135, + "doc": "", + "decorator": "router.post('/sections/{section_id}/summaries')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/code/summaries/{summary_id}/approve", + "router": "router", + "prefix_resolved": true, + "name": "approve_summary", + "signature": "summary_id: str, actor_id: str=Depends(actor)", + "returns": "", + "line": 140, + "doc": "", + "decorator": "router.post('/summaries/{summary_id}/approve')", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/code/sections/{section_id}/summaries", + "router": "router", + "prefix_resolved": true, + "name": "list_summaries", + "signature": "section_id: str, actor_id: str=Depends(actor)", + "returns": "", + "line": 145, + "doc": "", + "decorator": "router.get('/sections/{section_id}/summaries')", + "errors": [] + } + ], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_runtime/code_public.py", + "sha256": "0fe956329a96e54e138b669d4ab4f69ab0d6f489b647a115cfd126cfa58742a5", + "routes": [ + { + "method": "GET", + "path": "/townlight_code", + "router": "router", + "prefix_resolved": true, + "name": "home", + "signature": "", + "returns": "", + "line": 66, + "doc": "", + "decorator": "router.get('', response_class=HTMLResponse)", + "errors": [] + }, + { + "method": "GET", + "path": "/townlight_code/search", + "router": "router", + "prefix_resolved": true, + "name": "search", + "signature": "q: str=''", + "returns": "", + "line": 71, + "doc": "", + "decorator": "router.get('/search', response_class=HTMLResponse)", + "errors": [] + }, + { + "method": "GET", + "path": "/townlight_code/answer", + "router": "router", + "prefix_resolved": true, + "name": "answer", + "signature": "q: str='', section_number: str | None=None, as_of: date | None=None", + "returns": "", + "line": 80, + "doc": "", + "decorator": "router.get('/answer', response_class=HTMLResponse)", + "errors": [] + }, + { + "method": "GET", + "path": "/townlight_code/sections/{section_ref}", + "router": "router", + "prefix_resolved": true, + "name": "detail", + "signature": "section_ref: str, as_of: date | None=None", + "returns": "HTMLResponse", + "line": 91, + "doc": "", + "decorator": "router.get('/sections/{section_ref}', response_class=HTMLResponse)", + "errors": [ + "HTTPException(503, 'Service unavailable')" + ] + }, + { + "method": "GET", + "path": "/townlight_code/sections/{section_ref}/export", + "router": "router", + "prefix_resolved": true, + "name": "export", + "signature": "section_ref: str, as_of: date | None=None", + "returns": "HTMLResponse", + "line": 109, + "doc": "", + "decorator": "router.get('/sections/{section_ref}/export', response_class=HTMLResponse)", + "errors": [ + "HTTPException(503, 'Service unavailable')" + ] + } + ], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_runtime/code_meetings_bridge.py", + "sha256": "831045dc48508e866472a9ff6d9d837e8eed0a46c91c8f93b41eec526650c7c5", + "routes": [ + { + "method": "GET", + "path": "/desktop/v1/code/connections", + "router": "code_router", + "prefix_resolved": true, + "name": "list_connections", + "signature": "actor=Depends(code_actor)", + "returns": "", + "line": 87, + "doc": "", + "decorator": "code_router.get('/connections')", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/code/connections/{connection_id}", + "router": "code_router", + "prefix_resolved": true, + "name": "get_connection", + "signature": "connection_id: Key, actor=Depends(code_actor)", + "returns": "", + "line": 92, + "doc": "", + "decorator": "code_router.get('/connections/{connection_id}')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/code/connections", + "router": "code_router", + "prefix_resolved": true, + "name": "create_connection", + "signature": "payload: Proposal, actor=Depends(code_actor)", + "returns": "", + "line": 97, + "doc": "", + "decorator": "code_router.post('/connections')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/code/connections/{connection_id}/closeout", + "router": "code_router", + "prefix_resolved": true, + "name": "closeout_connection", + "signature": "connection_id: Key, payload: Closeout, actor=Depends(code_actor)", + "returns": "", + "line": 104, + "doc": "", + "decorator": "code_router.post('/connections/{connection_id}/closeout')", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/meetings/code-connections", + "router": "meetings_router", + "prefix_resolved": true, + "name": "list_code_connections", + "signature": "actor=Depends(meeting_actor)", + "returns": "", + "line": 111, + "doc": "", + "decorator": "meetings_router.get('/code-connections')", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/meetings/code-connections/{connection_id}", + "router": "meetings_router", + "prefix_resolved": true, + "name": "get_code_connection", + "signature": "connection_id: Key, actor=Depends(meeting_actor)", + "returns": "", + "line": 116, + "doc": "", + "decorator": "meetings_router.get('/code-connections/{connection_id}')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/meetings/code-connections/{connection_id}/decisions", + "router": "meetings_router", + "prefix_resolved": true, + "name": "record_decision", + "signature": "connection_id: Key, payload: Decision, actor=Depends(meeting_actor)", + "returns": "", + "line": 121, + "doc": "", + "decorator": "meetings_router.post('/code-connections/{connection_id}/decisions')", + "errors": [] + } + ], + "models": [ + { + "name": "Proposal", + "bases": [ + "_Strict" + ], + "fields": [ + { + "name": "id", + "type": "Key", + "default": "" + }, + { + "name": "version_id", + "type": "str", + "default": "Field(min_length=1, max_length=255)" + }, + { + "name": "meeting_id", + "type": "UUID", + "default": "" + }, + { + "name": "title", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + }, + { + "name": "ordinance_number", + "type": "str", + "default": "Field(min_length=1, max_length=120)" + }, + { + "name": "proposed_text", + "type": "str", + "default": "Field(min_length=1, max_length=1000000)" + }, + { + "name": "supersedes_id", + "type": "Key | None", + "default": "None" + }, + { + "name": "reconciliation_note", + "type": "str | None", + "default": "None" + } + ], + "line": 26, + "doc": "" + }, + { + "name": "Decision", + "bases": [ + "_Strict" + ], + "fields": [ + { + "name": "id", + "type": "Key", + "default": "" + }, + { + "name": "outcome", + "type": "Literal['adopted', 'not_adopted', 'deferred', 'withdrawn']", + "default": "" + }, + { + "name": "decided_at", + "type": "AwareDatetime | None", + "default": "None" + }, + { + "name": "decision_text", + "type": "str", + "default": "Field(min_length=1, max_length=1000000)" + }, + { + "name": "supporting_references", + "type": "list[str]", + "default": "Field(default_factory=list)" + }, + { + "name": "supersedes_decision_id", + "type": "Key | None", + "default": "None" + }, + { + "name": "reconciliation_note", + "type": "str | None", + "default": "None" + } + ], + "line": 37, + "doc": "" + }, + { + "name": "Closeout", + "bases": [ + "_Strict" + ], + "fields": [ + { + "name": "decision_id", + "type": "Key", + "default": "" + }, + { + "name": "version_id", + "type": "str", + "default": "Field(min_length=1, max_length=255)" + }, + { + "name": "source_id", + "type": "str", + "default": "Field(min_length=1, max_length=255)" + }, + { + "name": "version_label", + "type": "str", + "default": "Field(min_length=1, max_length=255)" + }, + { + "name": "body", + "type": "str", + "default": "Field(min_length=1, max_length=1000000)" + }, + { + "name": "effective_start", + "type": "date", + "default": "" + }, + { + "name": "effective_end", + "type": "date | None", + "default": "None" + }, + { + "name": "is_current", + "type": "bool", + "default": "" + }, + { + "name": "reconciliation_note", + "type": "str | None", + "default": "None" + } + ], + "line": 47, + "doc": "" + } + ], + "configuration": [] + } + ] + }, + "zoning": { + "package": "townlight_zoning", + "source": [ + { + "source": "installed-owned-source/townlight_zoning/__init__.py", + "sha256": "528eaa60c6814c1cf2b3ceb5a510c059380c37670f48928c27a02d765a2d4d15", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_zoning/cited_questions.py", + "sha256": "7a154dd540eae464090b4c12e6e0c1ca263670525df6a7328d317b0dd1e79a43", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_zoning/cited_rules.py", + "sha256": "4fb421ff3cd9e27be7689de75711bba8d1cd3ede304547868c204cf7a0daa43a", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_zoning/connected_sources.py", + "sha256": "68ad55c71b897eca689a6d028f4aee115dc5ca4b5ef005613385f9588387715b", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_zoning/discretionary.py", + "sha256": "919a5a573109fc76840290b4656e8fc63be91cdd10a6b3ff21fd106b52218ca5", + "routes": [], + "models": [ + { + "name": "Unavailable", + "bases": [], + "fields": [ + { + "name": "reason", + "type": "str", + "default": "" + }, + { + "name": "fix", + "type": "str", + "default": "" + }, + { + "name": "review_required", + "type": "bool", + "default": "True" + }, + { + "name": "disclaimer", + "type": "str", + "default": "DISCLAIMER" + } + ], + "line": 45, + "doc": "An explicit refusal: the sources do not support an answer." + }, + { + "name": "NonconformityFlag", + "bases": [], + "fields": [ + { + "name": "observed", + "type": "str", + "default": "" + }, + { + "name": "standard", + "type": "str", + "default": "" + }, + { + "name": "citation", + "type": "str", + "default": "" + }, + { + "name": "basis", + "type": "str", + "default": "" + }, + { + "name": "review_required", + "type": "bool", + "default": "True" + }, + { + "name": "determination_made", + "type": "bool", + "default": "False" + }, + { + "name": "disclaimer", + "type": "str", + "default": "DISCLAIMER" + } + ], + "line": 55, + "doc": "A REVIEW flag raised from existing parcel/rule data. Never a finding." + }, + { + "name": "ProcessExplanation", + "bases": [], + "fields": [ + { + "name": "process", + "type": "str", + "default": "" + }, + { + "name": "label", + "type": "str", + "default": "" + }, + { + "name": "what", + "type": "str", + "default": "" + }, + { + "name": "standard_citation", + "type": "str", + "default": "" + }, + { + "name": "needs", + "type": "list", + "default": "" + }, + { + "name": "review", + "type": "list", + "default": "" + }, + { + "name": "source_citation", + "type": "dict", + "default": "field(default_factory=dict)" + }, + { + "name": "standards", + "type": "list", + "default": "field(default_factory=list)" + }, + { + "name": "flags", + "type": "list", + "default": "field(default_factory=list)" + }, + { + "name": "review_required", + "type": "bool", + "default": "True" + }, + { + "name": "determination_made", + "type": "bool", + "default": "False" + }, + { + "name": "disclaimer", + "type": "str", + "default": "DISCLAIMER" + }, + { + "name": "as_of", + "type": "str | None", + "default": "None" + } + ], + "line": 68, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_zoning/geo_import.py", + "sha256": "e49824301593f8c06dd6bc64832542721d7b1763d745deb7ba531f7b894cc4a0", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_zoning/geo_spatial.py", + "sha256": "dfe4c88a940a20825c5c493babacb0cb0a96a70cb31a831c3ff1ecb4b77ebc13", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_zoning/geo_validate.py", + "sha256": "65b4a2b84722be8c25decfaeb80c6177ff30588259379927e853f7727d767178", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_zoning/integration_mocks.py", + "sha256": "ed14fba1a58020377ebee28c20ef042f5b50126ca2351efb73e46d7a2d80982c", + "routes": [], + "models": [ + { + "name": "IntegrationError", + "bases": [], + "fields": [ + { + "name": "provider", + "type": "str", + "default": "" + }, + { + "name": "message", + "type": "str", + "default": "" + }, + { + "name": "fix", + "type": "str", + "default": "" + }, + { + "name": "code", + "type": "str", + "default": "" + } + ], + "line": 27, + "doc": "" + }, + { + "name": "IntegrationResult", + "bases": [], + "fields": [ + { + "name": "provider", + "type": "str", + "default": "" + }, + { + "name": "records", + "type": "tuple[dict[str, Any], ...]", + "default": "" + }, + { + "name": "source", + "type": "str", + "default": "" + }, + { + "name": "warnings", + "type": "tuple[str, ...]", + "default": "()" + }, + { + "name": "stale", + "type": "bool", + "default": "False" + } + ], + "line": 35, + "doc": "" + }, + { + "name": "LocalIntegrationAdapter", + "bases": [], + "fields": [ + { + "name": "provider", + "type": "str", + "default": "" + }, + { + "name": "dependency", + "type": "str | None", + "default": "None" + } + ], + "line": 43, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_zoning/main.py", + "sha256": "cdbc4bd6f20650c08ca4a81c7e9d2fc7c85e0896bbd3d1c4e982dfe178c7bb93", + "routes": [ + { + "method": "GET", + "path": "/", + "router": "app", + "prefix_resolved": true, + "name": "root", + "signature": "", + "returns": "dict[str, str]", + "line": 74, + "doc": "Return current product state without overstating unshipped behavior.", + "decorator": "app.get('/')", + "errors": [] + }, + { + "method": "GET", + "path": "/health", + "router": "app", + "prefix_resolved": true, + "name": "health", + "signature": "", + "returns": "dict[str, str]", + "line": 92, + "doc": "Return dependency/version health for deployment smoke checks.", + "decorator": "app.get('/health')", + "errors": [] + }, + { + "method": "GET", + "path": "/townlight_zoning", + "router": "app", + "prefix_resolved": true, + "name": "public_townlight_zoning_page", + "signature": "", + "returns": "str", + "line": 104, + "doc": "Return the accessible public sample UI.", + "decorator": "app.get('/townlight_zoning', response_class=HTMLResponse)", + "errors": [] + }, + { + "method": "GET", + "path": "/townlight_zoning/staff", + "router": "app", + "prefix_resolved": true, + "name": "staff_townlight_zoning_page", + "signature": "", + "returns": "str", + "line": 111, + "doc": "Return the staff workflow shell without exposing staff data in HTML.", + "decorator": "app.get('/townlight_zoning/staff', response_class=HTMLResponse)", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_zoning/parcels/lookup", + "router": "app", + "prefix_resolved": true, + "name": "parcel_lookup", + "signature": "request: ParcelLookupRequest", + "returns": "dict[str, object]", + "line": 220, + "doc": "", + "decorator": "app.post('/api/v1/townlight_zoning/parcels/lookup')", + "errors": [ + "HTTPException(status_code=422, detail={'message': 'Provide either parcel_number or address.', 'fix': \"Send parcel_number '100-200-300' or address '123 Main St', or load local parcel records into TOWNLIGHT_ZONING_PARCEL_RULE_DB_URL.\"})", + "HTTPException(status_code=404, detail={'message': result.message, 'fix': result.fix})" + ] + }, + { + "method": "POST", + "path": "/api/v1/townlight_zoning/rules/use", + "router": "app", + "prefix_resolved": true, + "name": "use_rule_lookup", + "signature": "request: UseRuleLookupRequest", + "returns": "dict[str, str]", + "line": 246, + "doc": "", + "decorator": "app.post('/api/v1/townlight_zoning/rules/use')", + "errors": [ + "HTTPException(status_code=404, detail={'message': result.message, 'fix': result.fix})" + ] + }, + { + "method": "POST", + "path": "/api/v1/townlight_zoning/rules/dimensional", + "router": "app", + "prefix_resolved": true, + "name": "dimensional_rule_lookup", + "signature": "request: DimensionalRuleLookupRequest", + "returns": "dict[str, str]", + "line": 261, + "doc": "", + "decorator": "app.post('/api/v1/townlight_zoning/rules/dimensional')", + "errors": [ + "HTTPException(status_code=404, detail={'message': result.message, 'fix': result.fix})" + ] + }, + { + "method": "POST", + "path": "/api/v1/townlight_zoning/standards/process-explanation", + "router": "app", + "prefix_resolved": true, + "name": "discretionary_explanation", + "signature": "request: DiscretionaryExplanationRequest", + "returns": "dict[str, object]", + "line": 283, + "doc": "Explain the variance/CUP process a question is about, with citations.\n\nReturns an explicit ``unavailable`` payload when the loaded rule dataset cannot\nsupport an answer; never a guessed standard, and never a determination.", + "decorator": "app.post('/api/v1/townlight_zoning/standards/process-explanation')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_zoning/questions/answer", + "router": "app", + "prefix_resolved": true, + "name": "zone_question_answer", + "signature": "request: ZoneQuestionRequest", + "returns": "dict[str, object]", + "line": 353, + "doc": "", + "decorator": "app.post('/api/v1/townlight_zoning/questions/answer')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_zoning/planner-review/classify", + "router": "app", + "prefix_resolved": true, + "name": "planner_review_classify", + "signature": "request: PlannerReviewRequest", + "returns": "dict[str, str]", + "line": 378, + "doc": "", + "decorator": "app.post('/api/v1/townlight_zoning/planner-review/classify')", + "errors": [] + }, + { + "method": "GET", + "path": "/api/v1/townlight_zoning/staff/precedents/{precedent_id}", + "router": "app", + "prefix_resolved": true, + "name": "staff_precedent", + "signature": "precedent_id: str, _principal: Annotated[StaffPrincipal, Depends(_require_staff_access)]", + "returns": "dict[str, str]", + "line": 384, + "doc": "", + "decorator": "app.get('/api/v1/townlight_zoning/staff/precedents/{precedent_id}')", + "errors": [ + "HTTPException(status_code=404, detail={'message': 'Staff precedent not found.', 'fix': \"Try precedent_id 'historic-adu'.\"})" + ] + }, + { + "method": "POST", + "path": "/api/v1/townlight_zoning/staff/questions/answer", + "router": "app", + "prefix_resolved": true, + "name": "staff_question_answer", + "signature": "request: StaffQuestionAnswerRequest, principal: Annotated[StaffPrincipal, Depends(_require_staff_access)]", + "returns": "dict[str, object]", + "line": 402, + "doc": "", + "decorator": "app.post('/api/v1/townlight_zoning/staff/questions/answer')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_zoning/staff/ambiguity-reviews", + "router": "app", + "prefix_resolved": true, + "name": "create_ambiguity_review", + "signature": "request: AmbiguityReviewCreateRequest, principal: Annotated[StaffPrincipal, Depends(_require_staff_access)]", + "returns": "dict[str, object]", + "line": 415, + "doc": "", + "decorator": "app.post('/api/v1/townlight_zoning/staff/ambiguity-reviews')", + "errors": [] + }, + { + "method": "GET", + "path": "/api/v1/townlight_zoning/staff/ambiguity-reviews", + "router": "app", + "prefix_resolved": true, + "name": "list_ambiguity_reviews", + "signature": "_principal: Annotated[StaffPrincipal, Depends(_require_staff_access)], status: str | None=None", + "returns": "dict[str, object]", + "line": 429, + "doc": "", + "decorator": "app.get('/api/v1/townlight_zoning/staff/ambiguity-reviews')", + "errors": [] + }, + { + "method": "PATCH", + "path": "/api/v1/townlight_zoning/staff/ambiguity-reviews/{item_id}", + "router": "app", + "prefix_resolved": true, + "name": "update_ambiguity_review", + "signature": "item_id: str, request: AmbiguityReviewUpdateRequest, _principal: Annotated[StaffPrincipal, Depends(_require_staff_access)]", + "returns": "dict[str, object]", + "line": 443, + "doc": "", + "decorator": "app.patch('/api/v1/townlight_zoning/staff/ambiguity-reviews/{item_id}')", + "errors": [ + "HTTPException(status_code=404, detail={'message': 'Ambiguity review item was not found.', 'fix': 'List staff ambiguity reviews and retry with an existing item id.'})", + "HTTPException(status_code=422, detail={'message': 'Ambiguity review update is invalid.', 'fix': str(exc)})" + ] + }, + { + "method": "GET", + "path": "/api/v1/townlight_zoning/staff/questions/analytics", + "router": "app", + "prefix_resolved": true, + "name": "staff_question_analytics", + "signature": "_principal: Annotated[StaffPrincipal, Depends(_require_staff_access)], high_volume_threshold: int=2", + "returns": "dict[str, object]", + "line": 472, + "doc": "", + "decorator": "app.get('/api/v1/townlight_zoning/staff/questions/analytics')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_zoning/staff/reports/outline", + "router": "app", + "prefix_resolved": true, + "name": "staff_report_outline", + "signature": "request: StaffReportOutlineRequest, principal: Annotated[StaffPrincipal, Depends(_require_staff_access)]", + "returns": "dict[str, object]", + "line": 496, + "doc": "", + "decorator": "app.post('/api/v1/townlight_zoning/staff/reports/outline')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_zoning/staff/flagged-answers", + "router": "app", + "prefix_resolved": true, + "name": "create_flagged_answer_review", + "signature": "request: FlaggedAnswerCreateRequest, principal: Annotated[StaffPrincipal, Depends(_require_staff_access)]", + "returns": "dict[str, object]", + "line": 520, + "doc": "", + "decorator": "app.post('/api/v1/townlight_zoning/staff/flagged-answers')", + "errors": [] + }, + { + "method": "PATCH", + "path": "/api/v1/townlight_zoning/staff/flagged-answers/{review_id}/improve", + "router": "app", + "prefix_resolved": true, + "name": "improve_flagged_answer_review", + "signature": "review_id: str, request: FlaggedAnswerImproveRequest, principal: Annotated[StaffPrincipal, Depends(_require_staff_access)]", + "returns": "dict[str, object]", + "line": 536, + "doc": "", + "decorator": "app.patch('/api/v1/townlight_zoning/staff/flagged-answers/{review_id}/improve')", + "errors": [ + "HTTPException(status_code=404, detail={'message': 'Flagged answer review was not found.', 'fix': 'Create or list the flagged answer review before submitting improvements.'})" + ] + } + ], + "models": [ + { + "name": "StaffPrincipal", + "bases": [], + "fields": [ + { + "name": "subject", + "type": "str", + "default": "" + }, + { + "name": "roles", + "type": "tuple[str, ...]", + "default": "" + } + ], + "line": 68, + "doc": "" + }, + { + "name": "ParcelLookupRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "parcel_number", + "type": "str | None", + "default": "Field(default=None)" + }, + { + "name": "address", + "type": "str | None", + "default": "Field(default=None)" + } + ], + "line": 117, + "doc": "" + }, + { + "name": "UseRuleLookupRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "zone_code", + "type": "str", + "default": "" + }, + { + "name": "use", + "type": "str", + "default": "" + } + ], + "line": 122, + "doc": "" + }, + { + "name": "DimensionalRuleLookupRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "zone_code", + "type": "str", + "default": "" + }, + { + "name": "rule_type", + "type": "str", + "default": "" + } + ], + "line": 127, + "doc": "" + }, + { + "name": "ZoneQuestionRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "zone_code", + "type": "str", + "default": "Field(min_length=1, max_length=80)" + }, + { + "name": "question", + "type": "str", + "default": "Field(min_length=1, max_length=1000)" + } + ], + "line": 132, + "doc": "" + }, + { + "name": "PlannerReviewRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "question", + "type": "str", + "default": "" + } + ], + "line": 137, + "doc": "" + }, + { + "name": "StaffQuestionAnswerRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "zone_code", + "type": "str", + "default": "Field(min_length=1, max_length=80)" + }, + { + "name": "question", + "type": "str", + "default": "Field(min_length=1, max_length=1000)" + } + ], + "line": 141, + "doc": "" + }, + { + "name": "AmbiguityReviewCreateRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "zone_code", + "type": "str", + "default": "Field(min_length=1, max_length=80)" + }, + { + "name": "question", + "type": "str", + "default": "Field(min_length=1, max_length=1000)" + }, + { + "name": "reason", + "type": "str", + "default": "Field(min_length=1, max_length=1000)" + } + ], + "line": 146, + "doc": "" + }, + { + "name": "AmbiguityReviewUpdateRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "status", + "type": "str", + "default": "Field(min_length=1, max_length=80)" + }, + { + "name": "assigned_to", + "type": "str | None", + "default": "Field(default=None, max_length=255)" + }, + { + "name": "resolution", + "type": "str | None", + "default": "Field(default=None, max_length=1000)" + } + ], + "line": 152, + "doc": "" + }, + { + "name": "StaffReportOutlineRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "title", + "type": "str", + "default": "Field(min_length=1, max_length=255)" + }, + { + "name": "question_ids", + "type": "list[str]", + "default": "Field(default_factory=list)" + }, + { + "name": "queue_item_ids", + "type": "list[str]", + "default": "Field(default_factory=list)" + } + ], + "line": 158, + "doc": "" + }, + { + "name": "FlaggedAnswerCreateRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "zone_code", + "type": "str", + "default": "Field(min_length=1, max_length=80)" + }, + { + "name": "question", + "type": "str", + "default": "Field(min_length=1, max_length=1000)" + }, + { + "name": "original_answer", + "type": "str", + "default": "Field(min_length=1, max_length=2000)" + }, + { + "name": "flag_reason", + "type": "str", + "default": "Field(min_length=1, max_length=1000)" + }, + { + "name": "citations", + "type": "list[str]", + "default": "Field(default_factory=list)" + } + ], + "line": 164, + "doc": "" + }, + { + "name": "FlaggedAnswerImproveRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "improved_answer", + "type": "str", + "default": "Field(min_length=1, max_length=2000)" + }, + { + "name": "improvement_notes", + "type": "str", + "default": "Field(min_length=1, max_length=1000)" + } + ], + "line": 172, + "doc": "" + }, + { + "name": "DiscretionaryExplanationRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "process_section", + "type": "str", + "default": "Field(default='', max_length=255)" + }, + { + "name": "question", + "type": "str", + "default": "Field(min_length=1, max_length=1000)" + }, + { + "name": "zone_code", + "type": "str", + "default": "Field(default='', max_length=20)" + }, + { + "name": "rule_types", + "type": "list[str]", + "default": "Field(default_factory=list, max_length=12)" + }, + { + "name": "observed", + "type": "dict[str, str]", + "default": "Field(default_factory=dict)" + } + ], + "line": 274, + "doc": "" + } + ], + "configuration": [ + { + "variable": "TOWNLIGHT_ZONING_PARCEL_RULE_DB_URL", + "default": "", + "line": 559 + } + ] + }, + { + "source": "installed-owned-source/townlight_zoning/migrations/__init__.py", + "sha256": "38cbccb2471a214eac40f174b618d28d0367c43a0e66d3eb5807dad737142765", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_zoning/migrations/env.py", + "sha256": "3baae8fbf8726f8811647eb75d257e310d2d9660b0150833f17220dd8fa431ba", + "routes": [], + "models": [], + "configuration": [ + { + "variable": "DATABASE_URL", + "default": "", + "line": 22 + } + ] + }, + { + "source": "installed-owned-source/townlight_zoning/migrations/guards.py", + "sha256": "9346e9812f238cfee1bdd21f5487fb5c51ee4cabeda45da9aaed6ac2db9b5f7c", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_zoning/migrations/versions/__init__.py", + "sha256": "a1087a2a3cedf40641ab02c8e97838630305726600105ad59e30727b61a2f95d", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_zoning/migrations/versions/townlight_zoning_0001_schema.py", + "sha256": "0a6985e6fda034f4e654e63f2cb47610bf2af75dd028fc8f43473604550a2a18", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_zoning/migrations/versions/townlight_zoning_0002_parcel_rule_lookup_records.py", + "sha256": "8a473e69469f9fdbca5adefcdb7e9a41d50850f1a7460381691da5a4f137314d", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_zoning/migrations/versions/townlight_zoning_0003_question_ledger.py", + "sha256": "fd654ca0d15832acb727b88ece26acce25cb45da1ff8b438152ad7c766df0abc", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_zoning/migrations/versions/townlight_zoning_0004_staff_workflows.py", + "sha256": "3c0a145ff691077453b65413f2f08a6b7107a55f3ff21c072a8bc3788028b952", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_zoning/migrations/versions/townlight_zoning_0005_geo_import.py", + "sha256": "8d4c34c15197ddc856c712d7fb8f9005cb553a2befd38a093a2c952a321d20ce", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_zoning/migrations/versions/townlight_zoning_0006_cited_questions.py", + "sha256": "65b8c591b5adf3f0022720a2c4e780c818f0f4b5b51db83b81cab78edb2a1f9d", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_zoning/models.py", + "sha256": "206d16a1b4aa343eceee7bb25bdf39411f2b57e947a98a8be45607664635aba9", + "routes": [], + "models": [ + { + "name": "TimestampMixin", + "bases": [], + "fields": [ + { + "name": "created_at", + "type": "Mapped[object]", + "default": "mapped_column(DateTime(timezone=True), nullable=False, server_default=func.now())" + }, + { + "name": "updated_at", + "type": "Mapped[object]", + "default": "mapped_column(DateTime(timezone=True), nullable=False, server_default=func.now())" + } + ], + "line": 12, + "doc": "" + }, + { + "name": "IdMixin", + "bases": [], + "fields": [ + { + "name": "id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(UUID(as_uuid=True), primary_key=True, server_default=text('gen_random_uuid()'))" + } + ], + "line": 21, + "doc": "" + }, + { + "name": "Zone", + "bases": [ + "IdMixin", + "TimestampMixin", + "Base" + ], + "fields": [ + { + "name": "__table_args__", + "type": "ClassVar[dict]", + "default": "{'schema': 'townlight_zoning'}" + }, + { + "name": "code", + "type": "Mapped[str]", + "default": "mapped_column(String(80), nullable=False)" + }, + { + "name": "name", + "type": "Mapped[str]", + "default": "mapped_column(String(255), nullable=False)" + }, + { + "name": "description", + "type": "Mapped[str | None]", + "default": "mapped_column(Text)" + }, + { + "name": "jurisdiction", + "type": "Mapped[str]", + "default": "mapped_column(String(255), nullable=False)" + }, + { + "name": "source_section_ref", + "type": "Mapped[str | None]", + "default": "mapped_column(String(255))" + }, + { + "name": "is_active", + "type": "Mapped[bool]", + "default": "mapped_column(Boolean, nullable=False, server_default=text('true'))" + } + ], + "line": 27, + "doc": "" + }, + { + "name": "Overlay", + "bases": [ + "IdMixin", + "TimestampMixin", + "Base" + ], + "fields": [ + { + "name": "__table_args__", + "type": "ClassVar[dict]", + "default": "{'schema': 'townlight_zoning'}" + }, + { + "name": "code", + "type": "Mapped[str]", + "default": "mapped_column(String(80), nullable=False)" + }, + { + "name": "name", + "type": "Mapped[str]", + "default": "mapped_column(String(255), nullable=False)" + }, + { + "name": "description", + "type": "Mapped[str | None]", + "default": "mapped_column(Text)" + }, + { + "name": "source_section_ref", + "type": "Mapped[str | None]", + "default": "mapped_column(String(255))" + }, + { + "name": "is_active", + "type": "Mapped[bool]", + "default": "mapped_column(Boolean, nullable=False, server_default=text('true'))" + } + ], + "line": 39, + "doc": "" + }, + { + "name": "Parcel", + "bases": [ + "IdMixin", + "TimestampMixin", + "Base" + ], + "fields": [ + { + "name": "__table_args__", + "type": "ClassVar[dict]", + "default": "{'schema': 'townlight_zoning'}" + }, + { + "name": "parcel_number", + "type": "Mapped[str]", + "default": "mapped_column(String(120), nullable=False)" + }, + { + "name": "address", + "type": "Mapped[str]", + "default": "mapped_column(String(500), nullable=False)" + }, + { + "name": "zone_id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(ForeignKey('townlight_zoning.zones.id'), nullable=False)" + }, + { + "name": "overlay_payload", + "type": "Mapped[dict]", + "default": "mapped_column(JSONB, nullable=False, server_default=text(\"'[]'::jsonb\"))" + }, + { + "name": "geometry_ref", + "type": "Mapped[str | None]", + "default": "mapped_column(Text)" + }, + { + "name": "source_payload", + "type": "Mapped[dict]", + "default": "mapped_column(JSONB, nullable=False, server_default=text(\"'{}'::jsonb\"))" + } + ], + "line": 50, + "doc": "" + }, + { + "name": "UseCategory", + "bases": [ + "IdMixin", + "TimestampMixin", + "Base" + ], + "fields": [ + { + "name": "__table_args__", + "type": "ClassVar[dict]", + "default": "{'schema': 'townlight_zoning'}" + }, + { + "name": "code", + "type": "Mapped[str]", + "default": "mapped_column(String(120), nullable=False)" + }, + { + "name": "label", + "type": "Mapped[str]", + "default": "mapped_column(String(255), nullable=False)" + }, + { + "name": "description", + "type": "Mapped[str | None]", + "default": "mapped_column(Text)" + } + ], + "line": 62, + "doc": "" + }, + { + "name": "UseRule", + "bases": [ + "IdMixin", + "TimestampMixin", + "Base" + ], + "fields": [ + { + "name": "__table_args__", + "type": "ClassVar[dict]", + "default": "{'schema': 'townlight_zoning'}" + }, + { + "name": "zone_id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(ForeignKey('townlight_zoning.zones.id'), nullable=False)" + }, + { + "name": "use_category_id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(ForeignKey('townlight_zoning.use_categories.id'), nullable=False)" + }, + { + "name": "status", + "type": "Mapped[str]", + "default": "mapped_column(String(80), nullable=False)" + }, + { + "name": "review_path", + "type": "Mapped[str | None]", + "default": "mapped_column(String(255))" + }, + { + "name": "source_section_ref", + "type": "Mapped[str | None]", + "default": "mapped_column(String(255))" + }, + { + "name": "conditions", + "type": "Mapped[dict]", + "default": "mapped_column(JSONB, nullable=False, server_default=text(\"'[]'::jsonb\"))" + } + ], + "line": 71, + "doc": "" + }, + { + "name": "DimensionalRule", + "bases": [ + "IdMixin", + "TimestampMixin", + "Base" + ], + "fields": [ + { + "name": "__table_args__", + "type": "ClassVar[dict]", + "default": "{'schema': 'townlight_zoning'}" + }, + { + "name": "zone_id", + "type": "Mapped[uuid.UUID]", + "default": "mapped_column(ForeignKey('townlight_zoning.zones.id'), nullable=False)" + }, + { + "name": "rule_type", + "type": "Mapped[str]", + "default": "mapped_column(String(120), nullable=False)" + }, + { + "name": "value_text", + "type": "Mapped[str]", + "default": "mapped_column(String(255), nullable=False)" + }, + { + "name": "source_section_ref", + "type": "Mapped[str | None]", + "default": "mapped_column(String(255))" + }, + { + "name": "applies_to", + "type": "Mapped[str | None]", + "default": "mapped_column(String(255))" + } + ], + "line": 85, + "doc": "" + }, + { + "name": "Citation", + "bases": [ + "IdMixin", + "TimestampMixin", + "Base" + ], + "fields": [ + { + "name": "__table_args__", + "type": "ClassVar[dict]", + "default": "{'schema': 'townlight_zoning'}" + }, + { + "name": "source_section_ref", + "type": "Mapped[str]", + "default": "mapped_column(String(255), nullable=False)" + }, + { + "name": "citation_text", + "type": "Mapped[str]", + "default": "mapped_column(String(500), nullable=False)" + }, + { + "name": "url", + "type": "Mapped[str | None]", + "default": "mapped_column(Text)" + }, + { + "name": "retrieved_at", + "type": "Mapped[object | None]", + "default": "mapped_column(DateTime(timezone=True))" + } + ], + "line": 96, + "doc": "" + }, + { + "name": "Precedent", + "bases": [ + "IdMixin", + "TimestampMixin", + "Base" + ], + "fields": [ + { + "name": "__table_args__", + "type": "ClassVar[dict]", + "default": "{'schema': 'townlight_zoning'}" + }, + { + "name": "title", + "type": "Mapped[str]", + "default": "mapped_column(String(500), nullable=False)" + }, + { + "name": "body", + "type": "Mapped[str]", + "default": "mapped_column(Text, nullable=False)" + }, + { + "name": "visibility", + "type": "Mapped[str]", + "default": "mapped_column(String(80), nullable=False)" + }, + { + "name": "source_ref", + "type": "Mapped[str | None]", + "default": "mapped_column(String(255))" + }, + { + "name": "tags", + "type": "Mapped[dict]", + "default": "mapped_column(JSONB, nullable=False, server_default=text(\"'[]'::jsonb\"))" + } + ], + "line": 106, + "doc": "" + }, + { + "name": "InterpretationNote", + "bases": [ + "IdMixin", + "TimestampMixin", + "Base" + ], + "fields": [ + { + "name": "__table_args__", + "type": "ClassVar[dict]", + "default": "{'schema': 'townlight_zoning'}" + }, + { + "name": "zone_id", + "type": "Mapped[uuid.UUID | None]", + "default": "mapped_column(ForeignKey('townlight_zoning.zones.id'))" + }, + { + "name": "note_text", + "type": "Mapped[str]", + "default": "mapped_column(Text, nullable=False)" + }, + { + "name": "visibility", + "type": "Mapped[str]", + "default": "mapped_column(String(80), nullable=False)" + }, + { + "name": "status", + "type": "Mapped[str]", + "default": "mapped_column(String(80), nullable=False)" + } + ], + "line": 117, + "doc": "" + }, + { + "name": "ZoneQuestion", + "bases": [ + "IdMixin", + "TimestampMixin", + "Base" + ], + "fields": [ + { + "name": "__table_args__", + "type": "ClassVar[dict]", + "default": "{'schema': 'townlight_zoning'}" + }, + { + "name": "question_text", + "type": "Mapped[str]", + "default": "mapped_column(Text, nullable=False)" + }, + { + "name": "audience", + "type": "Mapped[str]", + "default": "mapped_column(String(80), nullable=False)" + }, + { + "name": "status", + "type": "Mapped[str]", + "default": "mapped_column(String(80), nullable=False)" + }, + { + "name": "answer_text", + "type": "Mapped[str | None]", + "default": "mapped_column(Text)" + }, + { + "name": "citation_payload", + "type": "Mapped[dict]", + "default": "mapped_column(JSONB, nullable=False, server_default=text(\"'[]'::jsonb\"))" + }, + { + "name": "escalation_reason", + "type": "Mapped[str | None]", + "default": "mapped_column(String(255))" + } + ], + "line": 127, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_zoning/parcel_lookup.py", + "sha256": "3629424d9af4d5ac514f285835f9b8179c1cf6ceb22d586576603a270edb5671", + "routes": [], + "models": [ + { + "name": "ParcelLookupResult", + "bases": [], + "fields": [ + { + "name": "parcel_number", + "type": "str", + "default": "" + }, + { + "name": "address", + "type": "str", + "default": "" + }, + { + "name": "zone_code", + "type": "str", + "default": "" + }, + { + "name": "zone_name", + "type": "str", + "default": "" + }, + { + "name": "overlays", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "constraints", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "source", + "type": "str", + "default": "" + }, + { + "name": "disclaimer", + "type": "str", + "default": "" + } + ], + "line": 12, + "doc": "" + }, + { + "name": "ParcelLookupError", + "bases": [], + "fields": [ + { + "name": "message", + "type": "str", + "default": "" + }, + { + "name": "fix", + "type": "str", + "default": "" + } + ], + "line": 24, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_zoning/public_ui.py", + "sha256": "75d1542af38b920b5a4527da79af374ade3abf03d7a78f5d9ad2b075790681a5", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_zoning/qa.py", + "sha256": "374b232775a482a3a02ce283d047652e0c188f7f856e0046e465d663ef863315", + "routes": [], + "models": [ + { + "name": "ZoneAnswer", + "bases": [], + "fields": [ + { + "name": "answer", + "type": "str", + "default": "" + }, + { + "name": "citations", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "reason", + "type": "str", + "default": "" + }, + { + "name": "confidence", + "type": "str", + "default": "" + }, + { + "name": "next_step", + "type": "str", + "default": "" + }, + { + "name": "disclaimer", + "type": "str", + "default": "DISCLAIMER" + } + ], + "line": 16, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_zoning/question_ledger.py", + "sha256": "0fca91aa0a7338771f760fe9032da442023c3407584d0ee0c621ce0290a65e7b", + "routes": [], + "models": [ + { + "name": "ZoneQuestionLedgerRecord", + "bases": [], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "zone_code", + "type": "str", + "default": "" + }, + { + "name": "question_text", + "type": "str", + "default": "" + }, + { + "name": "audience", + "type": "str", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "answer_text", + "type": "str | None", + "default": "" + }, + { + "name": "citation_payload", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "disclaimer", + "type": "str", + "default": "" + }, + { + "name": "escalation_reason", + "type": "str | None", + "default": "" + }, + { + "name": "created_at", + "type": "datetime", + "default": "" + }, + { + "name": "updated_at", + "type": "datetime", + "default": "" + } + ], + "line": 32, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_zoning/rule_lookup.py", + "sha256": "5c53135c7a413e0eecf663061593945c56330eae6a96808d61d69bd4e6d996a2", + "routes": [], + "models": [ + { + "name": "UseRuleResult", + "bases": [], + "fields": [ + { + "name": "zone_code", + "type": "str", + "default": "" + }, + { + "name": "use", + "type": "str", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "review_path", + "type": "str", + "default": "" + }, + { + "name": "citation", + "type": "str", + "default": "" + }, + { + "name": "disclaimer", + "type": "str", + "default": "DISCLAIMER" + } + ], + "line": 14, + "doc": "" + }, + { + "name": "DimensionalRuleResult", + "bases": [], + "fields": [ + { + "name": "zone_code", + "type": "str", + "default": "" + }, + { + "name": "rule_type", + "type": "str", + "default": "" + }, + { + "name": "value", + "type": "str", + "default": "" + }, + { + "name": "citation", + "type": "str", + "default": "" + }, + { + "name": "disclaimer", + "type": "str", + "default": "DISCLAIMER" + } + ], + "line": 24, + "doc": "" + }, + { + "name": "RuleLookupError", + "bases": [], + "fields": [ + { + "name": "message", + "type": "str", + "default": "" + }, + { + "name": "fix", + "type": "str", + "default": "" + } + ], + "line": 33, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_zoning/staff_context.py", + "sha256": "50784c2b595741098e2de9d9ad90a7957607ae09839afe6167af13e38037c91c", + "routes": [], + "models": [ + { + "name": "EscalationResult", + "bases": [], + "fields": [ + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "reason", + "type": "str", + "default": "" + }, + { + "name": "next_step", + "type": "str", + "default": "" + } + ], + "line": 9, + "doc": "" + }, + { + "name": "StaffPrecedent", + "bases": [], + "fields": [ + { + "name": "title", + "type": "str", + "default": "" + }, + { + "name": "summary", + "type": "str", + "default": "" + }, + { + "name": "visibility", + "type": "str", + "default": "'staff_only'" + } + ], + "line": 16, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_zoning/staff_ui.py", + "sha256": "69448abc334931b5f19168fdffbef81497e250dd61f1912811d4ebdb28ee0b25", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_zoning/staff_workflows.py", + "sha256": "27cf6da89c7a1472b23cbcace93adb63a0384be443b95228c882eb3bfb0ed642", + "routes": [], + "models": [ + { + "name": "CodeCrossReference", + "bases": [], + "fields": [ + { + "name": "citation", + "type": "str", + "default": "" + }, + { + "name": "source", + "type": "str", + "default": "" + }, + { + "name": "relevance", + "type": "str", + "default": "" + } + ], + "line": 80, + "doc": "" + }, + { + "name": "StaffQuestionRecord", + "bases": [], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "zone_code", + "type": "str", + "default": "" + }, + { + "name": "question_text", + "type": "str", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "answer_text", + "type": "str", + "default": "" + }, + { + "name": "citations", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "code_cross_references", + "type": "tuple[CodeCrossReference, ...]", + "default": "" + }, + { + "name": "created_by", + "type": "str", + "default": "" + }, + { + "name": "created_at", + "type": "datetime", + "default": "" + }, + { + "name": "visibility", + "type": "str", + "default": "STAFF_VISIBILITY" + }, + { + "name": "disclaimer", + "type": "str", + "default": "DISCLAIMER" + } + ], + "line": 87, + "doc": "" + }, + { + "name": "AmbiguityReviewItem", + "bases": [], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "zone_code", + "type": "str", + "default": "" + }, + { + "name": "question_text", + "type": "str", + "default": "" + }, + { + "name": "reason", + "type": "str", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "assigned_to", + "type": "str | None", + "default": "" + }, + { + "name": "resolution", + "type": "str | None", + "default": "" + }, + { + "name": "source_question_id", + "type": "str | None", + "default": "" + }, + { + "name": "created_by", + "type": "str", + "default": "" + }, + { + "name": "created_at", + "type": "datetime", + "default": "" + }, + { + "name": "updated_at", + "type": "datetime", + "default": "" + }, + { + "name": "visibility", + "type": "str", + "default": "STAFF_VISIBILITY" + } + ], + "line": 102, + "doc": "" + }, + { + "name": "HighVolumeQuestion", + "bases": [], + "fields": [ + { + "name": "zone_code", + "type": "str", + "default": "" + }, + { + "name": "question_text", + "type": "str", + "default": "" + }, + { + "name": "count", + "type": "int", + "default": "" + }, + { + "name": "statuses", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "latest_question_id", + "type": "str", + "default": "" + } + ], + "line": 118, + "doc": "" + }, + { + "name": "StaffQuestionAnalytics", + "bases": [], + "fields": [ + { + "name": "total_questions", + "type": "int", + "default": "" + }, + { + "name": "by_status", + "type": "dict[str, int]", + "default": "" + }, + { + "name": "high_volume_questions", + "type": "tuple[HighVolumeQuestion, ...]", + "default": "" + }, + { + "name": "generated_at", + "type": "datetime", + "default": "" + }, + { + "name": "visibility", + "type": "str", + "default": "STAFF_VISIBILITY" + } + ], + "line": 127, + "doc": "" + }, + { + "name": "StaffReportOutline", + "bases": [], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "title", + "type": "str", + "default": "" + }, + { + "name": "sections", + "type": "tuple[dict[str, object], ...]", + "default": "" + }, + { + "name": "source_question_ids", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "source_queue_item_ids", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "created_by", + "type": "str", + "default": "" + }, + { + "name": "created_at", + "type": "datetime", + "default": "" + }, + { + "name": "visibility", + "type": "str", + "default": "STAFF_VISIBILITY" + }, + { + "name": "disclaimer", + "type": "str", + "default": "'Draft staff outline only; verify citations before publication.'" + } + ], + "line": 136, + "doc": "" + }, + { + "name": "FlaggedAnswerReview", + "bases": [], + "fields": [ + { + "name": "id", + "type": "str", + "default": "" + }, + { + "name": "zone_code", + "type": "str", + "default": "" + }, + { + "name": "question_text", + "type": "str", + "default": "" + }, + { + "name": "original_answer", + "type": "str", + "default": "" + }, + { + "name": "flag_reason", + "type": "str", + "default": "" + }, + { + "name": "citations", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "improved_answer", + "type": "str | None", + "default": "" + }, + { + "name": "improvement_notes", + "type": "str | None", + "default": "" + }, + { + "name": "reviewed_by", + "type": "str | None", + "default": "" + }, + { + "name": "created_by", + "type": "str", + "default": "" + }, + { + "name": "created_at", + "type": "datetime", + "default": "" + }, + { + "name": "updated_at", + "type": "datetime", + "default": "" + }, + { + "name": "visibility", + "type": "str", + "default": "STAFF_VISIBILITY" + } + ], + "line": 149, + "doc": "" + } + ], + "configuration": [] + } + ], + "bridge": [ + { + "source": "installed-owned-source/townlight_runtime/zoning_bridge.py", + "sha256": "eb80d79ffc4fc736789aab4f3d3b75a4d9d01101d6414a69a29053c7d5f90505", + "routes": [ + { + "method": "POST", + "path": "/desktop/v1/zoning/imports", + "router": "router", + "prefix_resolved": true, + "name": "imports", + "signature": "payload: dict, actor_id: str=Depends(actor)", + "returns": "", + "line": 68, + "doc": "", + "decorator": "router.post('/imports')", + "errors": [ + "HTTPException(422, detail)", + "HTTPException(503, 'Zoning persistence unavailable.')" + ] + }, + { + "method": "POST", + "path": "/desktop/v1/zoning/parcels/lookup", + "router": "router", + "prefix_resolved": true, + "name": "parcel_lookup", + "signature": "body: _ParcelLookupIn, _actor: str=Depends(actor)", + "returns": "", + "line": 91, + "doc": "", + "decorator": "router.post('/parcels/lookup')", + "errors": [ + "HTTPException(503, 'Townlight Code database/schema is not ready; no determination.')", + "HTTPException(503, 'Zoning persistence unavailable.')" + ] + }, + { + "method": "GET", + "path": "/desktop/v1/zoning/questions/{question_id}/history", + "router": "router", + "prefix_resolved": true, + "name": "question_history", + "signature": "question_id: UUID, actor_id=Depends(actor), provider=Depends(meeting_provider)", + "returns": "", + "line": 209, + "doc": "", + "decorator": "router.get('/questions/{question_id}/history')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/zoning/meetings/search", + "router": "router", + "prefix_resolved": true, + "name": "search_meetings", + "signature": "p: MeetingSearch, actor_id=Depends(actor), provider=Depends(meeting_provider)", + "returns": "", + "line": 216, + "doc": "", + "decorator": "router.post('/meetings/search')", + "errors": [ + "HTTPException(status_code=503, detail='Meeting search unavailable')" + ] + }, + { + "method": "POST", + "path": "/desktop/v1/zoning/questions/{question_id}/meetings", + "router": "router", + "prefix_resolved": true, + "name": "link_meeting", + "signature": "question_id: UUID, p: MeetingLink, actor_id=Depends(actor), provider=Depends(meeting_provider)", + "returns": "", + "line": 242, + "doc": "", + "decorator": "router.post('/questions/{question_id}/meetings')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/zoning/questions/{question_id}/snapshots", + "router": "router", + "prefix_resolved": true, + "name": "create_snapshot", + "signature": "question_id: UUID, p: SourceSnapshot, actor_id=Depends(actor), provider=Depends(meeting_provider)", + "returns": "", + "line": 259, + "doc": "", + "decorator": "router.post('/questions/{question_id}/snapshots')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/zoning/rules", + "router": "router", + "prefix_resolved": true, + "name": "create_rule", + "signature": "p: Rule, actor_id=Depends(actor)", + "returns": "", + "line": 291, + "doc": "", + "decorator": "router.post('/rules')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/zoning/questions", + "router": "router", + "prefix_resolved": true, + "name": "create_question", + "signature": "p: Question, actor_id=Depends(actor)", + "returns": "", + "line": 300, + "doc": "", + "decorator": "router.post('/questions')", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/zoning/workspace", + "router": "router", + "prefix_resolved": true, + "name": "get_workspace", + "signature": "actor_id=Depends(actor)", + "returns": "", + "line": 313, + "doc": "", + "decorator": "router.get('/workspace')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/zoning/questions/{question_id}/reviews", + "router": "router", + "prefix_resolved": true, + "name": "create_review", + "signature": "question_id: UUID, p: Review, actor_id=Depends(actor)", + "returns": "", + "line": 318, + "doc": "", + "decorator": "router.post('/questions/{question_id}/reviews')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/zoning/outlines", + "router": "router", + "prefix_resolved": true, + "name": "create_outline", + "signature": "p: Outline, actor_id=Depends(actor)", + "returns": "", + "line": 325, + "doc": "", + "decorator": "router.post('/outlines')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/zoning/code-context", + "router": "router", + "prefix_resolved": true, + "name": "create_code_context", + "signature": "p: CodeContext, actor_id=Depends(actor)", + "returns": "", + "line": 332, + "doc": "", + "decorator": "router.post('/code-context')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/zoning/standards/process-explanation", + "router": "router", + "prefix_resolved": true, + "name": "standards_explanation", + "signature": "p: StandardsExplanation, actor_id=Depends(actor)", + "returns": "", + "line": 373, + "doc": "Cited variance/CUP/nonconformity process; never a determination.", + "decorator": "router.post('/standards/process-explanation')", + "errors": [ + "HTTPException(422, f\"Unknown rule type '{rule_type}'.\")" + ] + }, + { + "method": "POST", + "path": "/townlight_zoning/questions", + "router": "public_router", + "prefix_resolved": true, + "name": "public_question", + "signature": "p: Question", + "returns": "", + "line": 423, + "doc": "", + "decorator": "public_router.post('/questions', dependencies=[Depends(public_active)])", + "errors": [] + }, + { + "method": "POST", + "path": "/townlight_zoning/parcels/lookup", + "router": "public_router", + "prefix_resolved": true, + "name": "public_parcel_lookup", + "signature": "p: _ParcelLookupIn", + "returns": "", + "line": 434, + "doc": "", + "decorator": "public_router.post('/parcels/lookup', dependencies=[Depends(public_active)])", + "errors": [] + } + ], + "models": [ + { + "name": "_ParcelLookupIn", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "jurisdiction", + "type": "str", + "default": "Field(min_length=1, max_length=255)" + }, + { + "name": "query", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + } + ], + "line": 60, + "doc": "" + }, + { + "name": "Question", + "bases": [ + "Strict" + ], + "fields": [ + { + "name": "jurisdiction", + "type": "str", + "default": "Field(min_length=1, max_length=255)" + }, + { + "name": "query", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + }, + { + "name": "question", + "type": "str", + "default": "Field(min_length=1, max_length=2000)" + }, + { + "name": "kind", + "type": "Literal['use', 'dimension']", + "default": "" + }, + { + "name": "key", + "type": "str", + "default": "Field(min_length=1, max_length=255)" + }, + { + "name": "audience", + "type": "Literal['resident', 'staff']", + "default": "'resident'" + } + ], + "line": 150, + "doc": "" + }, + { + "name": "Rule", + "bases": [ + "Strict" + ], + "fields": [ + { + "name": "jurisdiction", + "type": "str", + "default": "Field(min_length=1, max_length=255)" + }, + { + "name": "zone_code", + "type": "str", + "default": "Field(..., min_length=1, max_length=80)" + }, + { + "name": "key", + "type": "str", + "default": "Field(..., min_length=1, max_length=120)" + }, + { + "name": "section_number", + "type": "str", + "default": "Field(min_length=1, max_length=255)" + }, + { + "name": "kind", + "type": "Literal['use', 'dimension']", + "default": "" + }, + { + "name": "value", + "type": "str", + "default": "Field(..., min_length=1, max_length=255)" + }, + { + "name": "overlay_code", + "type": "str | None", + "default": "Field(default=None, max_length=255)" + } + ], + "line": 159, + "doc": "" + }, + { + "name": "Review", + "bases": [ + "Strict" + ], + "fields": [ + { + "name": "answer", + "type": "str", + "default": "Field(default='', max_length=10000)" + }, + { + "name": "notes", + "type": "str", + "default": "Field(default='', max_length=10000)" + }, + { + "name": "queue_status", + "type": "Literal['open', 'in_review', 'resolved', 'closed']", + "default": "'resolved'" + } + ], + "line": 169, + "doc": "" + }, + { + "name": "Outline", + "bases": [ + "Strict" + ], + "fields": [ + { + "name": "title", + "type": "str", + "default": "Field(min_length=1, max_length=255)" + }, + { + "name": "question_ids", + "type": "list[UUID]", + "default": "Field(min_length=1, max_length=50)" + } + ], + "line": 175, + "doc": "" + }, + { + "name": "CodeContext", + "bases": [ + "Strict" + ], + "fields": [ + { + "name": "section_number", + "type": "str", + "default": "Field(min_length=1, max_length=255)" + }, + { + "name": "as_of", + "type": "date | None", + "default": "None" + } + ], + "line": 180, + "doc": "" + }, + { + "name": "MeetingSearch", + "bases": [ + "Strict" + ], + "fields": [ + { + "name": "query", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + } + ], + "line": 185, + "doc": "" + }, + { + "name": "MeetingLink", + "bases": [ + "Strict" + ], + "fields": [ + { + "name": "source_id", + "type": "str", + "default": "Field(min_length=1, max_length=200)" + }, + { + "name": "expected_sha256", + "type": "str", + "default": "Field(pattern='^[0-9a-f]{64}$')" + }, + { + "name": "relation", + "type": "Literal['hearing', 'context', 'precedent']", + "default": "" + } + ], + "line": 189, + "doc": "" + }, + { + "name": "SourceSnapshot", + "bases": [ + "Strict" + ], + "fields": [ + { + "name": "visibility", + "type": "Literal['public', 'staff_only']", + "default": "" + }, + { + "name": "meeting_event_ids", + "type": "list[UUID]", + "default": "Field(default_factory=list, max_length=50)" + } + ], + "line": 195, + "doc": "" + }, + { + "name": "StandardsExplanation", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "question", + "type": "str", + "default": "Field(min_length=1, max_length=2000)" + }, + { + "name": "process_section", + "type": "str", + "default": "Field(default='', max_length=255)" + }, + { + "name": "zone_code", + "type": "str", + "default": "Field(default='', max_length=40)" + }, + { + "name": "rule_types", + "type": "list[str]", + "default": "Field(default_factory=list, max_length=10)" + }, + { + "name": "observed", + "type": "dict[str, str]", + "default": "Field(default_factory=dict)" + } + ], + "line": 342, + "doc": "" + } + ], + "configuration": [ + { + "variable": "TOWNLIGHT_ZONING_PARCEL_RULE_DB_URL", + "default": "", + "line": 359 + } + ] + } + ] + }, + "planning": { + "package": "townlight_planning", + "source": [ + { + "source": "installed-owned-source/townlight_planning/__init__.py", + "sha256": "d6a014eba48a6bdcdaea2a444cfcaa743cd2ba33cec6d63ea5e450266ad71c82", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_planning/connections.py", + "sha256": "649c8474e787fca1e30a11f153d2f776283204b5dc8053b7e88fbc325cdcf944", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_planning/consistency.py", + "sha256": "d18ef439391d859f0d1a020356edaf91d2441333eacf36036d03d1b7ea467210", + "routes": [], + "models": [ + { + "name": "ConsistencyCheck", + "bases": [], + "fields": [ + { + "name": "policy_id", + "type": "str", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "factors", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "staff_next_step", + "type": "str", + "default": "" + }, + { + "name": "disclaimer", + "type": "str", + "default": "DISCLAIMER" + } + ], + "line": 11, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_planning/integration_mocks.py", + "sha256": "09c350c13fe4e14c3f385549021f57c09341c8dbe110b18e6e4739cf70ac6254", + "routes": [], + "models": [ + { + "name": "IntegrationError", + "bases": [], + "fields": [ + { + "name": "provider", + "type": "str", + "default": "" + }, + { + "name": "message", + "type": "str", + "default": "" + }, + { + "name": "fix", + "type": "str", + "default": "" + }, + { + "name": "code", + "type": "str", + "default": "" + } + ], + "line": 18, + "doc": "" + }, + { + "name": "IntegrationResult", + "bases": [], + "fields": [ + { + "name": "provider", + "type": "str", + "default": "" + }, + { + "name": "records", + "type": "tuple[dict[str, Any], ...]", + "default": "" + }, + { + "name": "source", + "type": "str", + "default": "" + }, + { + "name": "warnings", + "type": "tuple[str, ...]", + "default": "()" + } + ], + "line": 26, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_planning/main.py", + "sha256": "34aaae27da4bc8f34570849cc446a134efb78c004294425ac62ef2c80abb1adf", + "routes": [ + { + "method": "GET", + "path": "/", + "router": "app", + "prefix_resolved": true, + "name": "root", + "signature": "", + "returns": "dict[str, str]", + "line": 129, + "doc": "Return current product state without overstating unshipped behavior.", + "decorator": "app.get('/')", + "errors": [] + }, + { + "method": "GET", + "path": "/health", + "router": "app", + "prefix_resolved": true, + "name": "health", + "signature": "", + "returns": "dict[str, str]", + "line": 147, + "doc": "Return dependency/version health for deployment smoke checks.", + "decorator": "app.get('/health')", + "errors": [] + }, + { + "method": "GET", + "path": "/townlight_planning", + "router": "app", + "prefix_resolved": true, + "name": "public_townlight_planning_page", + "signature": "q: str='', goal: str='', topic: str='', plan_type: str='', clear: str='', neighborhood: str=''", + "returns": "str", + "line": 193, + "doc": "Explore the adopted plan sources this deployment actually holds.\n\nPublic readers get only adopted, effective, public municipal revisions. When\nno plan database is configured the page says so instead of showing sample text.", + "decorator": "app.get('/townlight_planning', response_class=HTMLResponse)", + "errors": [] + }, + { + "method": "GET", + "path": "/api/v1/townlight_planning/public/plan-explore", + "router": "app", + "prefix_resolved": true, + "name": "public_plan_explore", + "signature": "q: str='', goal: str='', topic: str='', plan_type: str='', neighborhood: str=''", + "returns": "dict[str, object]", + "line": 220, + "doc": "The same persisted-source exploration as the page, as JSON.", + "decorator": "app.get('/api/v1/townlight_planning/public/plan-explore')", + "errors": [ + "HTTPException(503, 'No plan source database is configured for this deployment.')" + ] + }, + { + "method": "GET", + "path": "/api/v1/townlight_planning/public/policy/{revision_id}/{policy_id}", + "router": "app", + "prefix_resolved": true, + "name": "public_policy_citation", + "signature": "revision_id: str, policy_id: str", + "returns": "dict[str, object]", + "line": 237, + "doc": "One cited policy for a public reader, or a refusal.\n\nA staff-only, pending, superseded or non-effective revision is refused here by\nthe service; naming its id does not reach it.", + "decorator": "app.get('/api/v1/townlight_planning/public/policy/{revision_id}/{policy_id}')", + "errors": [ + "HTTPException(503, 'No plan source database is configured for this deployment.')", + "HTTPException(404, str(exc))" + ] + }, + { + "method": "POST", + "path": "/api/v1/townlight_planning/policies/lookup", + "router": "app", + "prefix_resolved": true, + "name": "policy_lookup", + "signature": "request: PolicyLookupRequest, is_staff=Depends(audience)", + "returns": "dict[str, object]", + "line": 256, + "doc": "", + "decorator": "app.post('/api/v1/townlight_planning/policies/lookup')", + "errors": [ + "HTTPException(404, 'No supported adopted policy found; inspect imported sources.')" + ] + }, + { + "method": "POST", + "path": "/api/v1/townlight_planning/policies/ingest", + "router": "app", + "prefix_resolved": true, + "name": "ingest_policy", + "signature": "request: PolicyIngestRequest, x_townlight_planning_role: Annotated[str | None, Header()]=None, x_townlight_planning_staff_key: Annotated[str | None, Header()]=None", + "returns": "dict[str, object]", + "line": 270, + "doc": "", + "decorator": "app.post('/api/v1/townlight_planning/policies/ingest')", + "errors": [ + "HTTPException(409, detail={'message': 'Metadata-only ingestion cannot establish plan provenance.', 'fix': 'Use POST /api/v1/townlight_planning/source-imports with a staff-verified source bundle.'})" + ] + }, + { + "method": "GET", + "path": "/api/v1/townlight_planning/plans/navigator", + "router": "app", + "prefix_resolved": true, + "name": "plans_navigator", + "signature": "plan_type: str | None=None, is_staff=Depends(audience)", + "returns": "dict[str, object]", + "line": 283, + "doc": "", + "decorator": "app.get('/api/v1/townlight_planning/plans/navigator')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_planning/questions/answer", + "router": "app", + "prefix_resolved": true, + "name": "plan_question_answer", + "signature": "request: PlanQuestionRequest, is_staff=Depends(audience)", + "returns": "dict[str, object]", + "line": 292, + "doc": "", + "decorator": "app.post('/api/v1/townlight_planning/questions/answer')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_planning/plans/synthesis", + "router": "app", + "prefix_resolved": true, + "name": "plan_synthesis", + "signature": "request: PlanSynthesisRequest, is_staff=Depends(audience)", + "returns": "dict[str, object]", + "line": 306, + "doc": "", + "decorator": "app.post('/api/v1/townlight_planning/plans/synthesis')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_planning/context/townlight_meetings", + "router": "app", + "prefix_resolved": true, + "name": "townlight_meetings_context", + "signature": "request: TownlightMeetingsContextRequest, is_staff=Depends(audience)", + "returns": "dict[str, object]", + "line": 314, + "doc": "", + "decorator": "app.post('/api/v1/townlight_planning/context/townlight_meetings')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_planning/integrations/mock", + "router": "app", + "prefix_resolved": true, + "name": "integration_mock", + "signature": "request: IntegrationMockRequest", + "returns": "dict[str, object]", + "line": 328, + "doc": "", + "decorator": "app.post('/api/v1/townlight_planning/integrations/mock')", + "errors": [ + "HTTPException(status_code=422, detail={'message': result.message, 'fix': result.fix, 'code': result.code, 'provider': result.provider})" + ] + }, + { + "method": "POST", + "path": "/api/v1/townlight_planning/context/zoning", + "router": "app", + "prefix_resolved": true, + "name": "zoning_policy_context", + "signature": "request: ZoningPolicyContextRequest, is_staff=Depends(audience)", + "returns": "dict[str, object]", + "line": 349, + "doc": "", + "decorator": "app.post('/api/v1/townlight_planning/context/zoning')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_planning/consistency/check", + "router": "app", + "prefix_resolved": true, + "name": "consistency_check", + "signature": "request: ConsistencyRequest, is_staff=Depends(audience)", + "returns": "dict[str, object]", + "line": 378, + "doc": "", + "decorator": "app.post('/api/v1/townlight_planning/consistency/check')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_planning/staff-analysis/draft", + "router": "app", + "prefix_resolved": true, + "name": "staff_analysis", + "signature": "request: StaffAnalysisRequest, x_townlight_planning_role: Annotated[str | None, Header()]=None, x_townlight_planning_staff_key: Annotated[str | None, Header()]=None", + "returns": "dict[str, object]", + "line": 392, + "doc": "", + "decorator": "app.post('/api/v1/townlight_planning/staff-analysis/draft')", + "errors": [ + "HTTPException(404, 'No supported adopted policy found.')" + ] + }, + { + "method": "GET", + "path": "/api/v1/townlight_planning/staff-analysis/{analysis_id}", + "router": "app", + "prefix_resolved": true, + "name": "get_staff_analysis", + "signature": "analysis_id: str, native_request: Request, x_townlight_planning_role: Annotated[str | None, Header()]=None, x_townlight_planning_staff_key: Annotated[str | None, Header()]=None", + "returns": "dict[str, object]", + "line": 419, + "doc": "", + "decorator": "app.get('/api/v1/townlight_planning/staff-analysis/{analysis_id}')", + "errors": [ + "HTTPException(status_code=503, detail={'message': 'Townlight Planning policy persistence is not configured.', 'fix': 'Set TOWNLIGHT_PLANNING_POLICY_DB_URL to retrieve persisted staff-analysis records.'})", + "HTTPException(status_code=404, detail={'message': 'Staff-analysis record not found.', 'fix': 'Use an analysis_id returned by POST /api/v1/townlight_planning/staff-analysis/draft.'})" + ] + }, + { + "method": "POST", + "path": "/api/v1/townlight_planning/export", + "router": "app", + "prefix_resolved": true, + "name": "policy_export", + "signature": "request: PolicyExportRequest, native_request: Request, is_staff=Depends(audience)", + "returns": "dict[str, object]", + "line": 451, + "doc": "", + "decorator": "app.post('/api/v1/townlight_planning/export')", + "errors": [ + "HTTPException(403, 'Staff authentication is required to export analysis snapshots.')", + "HTTPException(422, 'Select a reviewed immutable snapshot; a policy ID alone is not an export.')", + "HTTPException(404, 'Snapshot not found.')" + ] + } + ], + "models": [ + { + "name": "PolicyLookupRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "topic", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + }, + { + "name": "plan_type", + "type": "str", + "default": "Field(default='comprehensive', min_length=1, max_length=120)" + } + ], + "line": 64, + "doc": "" + }, + { + "name": "ZoningPolicyContextRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "topic", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + }, + { + "name": "zone_code", + "type": "str | None", + "default": "Field(default=None, max_length=80)" + }, + { + "name": "use", + "type": "str | None", + "default": "Field(default=None, max_length=160)" + }, + { + "name": "parcel_number", + "type": "str | None", + "default": "Field(default=None, max_length=120)" + }, + { + "name": "address", + "type": "str | None", + "default": "Field(default=None, max_length=500)" + }, + { + "name": "plan_type", + "type": "str", + "default": "Field(default='comprehensive', min_length=1, max_length=120)" + }, + { + "name": "townlight_zoning_context_id", + "type": "str | None", + "default": "Field(default=None, max_length=160)" + } + ], + "line": 69, + "doc": "" + }, + { + "name": "ConsistencyRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "proposal", + "type": "str", + "default": "Field(min_length=1, max_length=5000)" + }, + { + "name": "policy_id", + "type": "str", + "default": "Field(min_length=1, max_length=160)" + } + ], + "line": 79, + "doc": "" + }, + { + "name": "StaffAnalysisRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "project_name", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + }, + { + "name": "proposal", + "type": "str", + "default": "Field(min_length=1, max_length=5000)" + }, + { + "name": "policy_id", + "type": "str", + "default": "Field(min_length=1, max_length=160)" + } + ], + "line": 84, + "doc": "" + }, + { + "name": "PolicyExportRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "title", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + }, + { + "name": "policy_id", + "type": "str", + "default": "Field(min_length=1, max_length=160)" + }, + { + "name": "format", + "type": "str", + "default": "Field(default='markdown', min_length=1, max_length=40)" + }, + { + "name": "snapshot_id", + "type": "str | None", + "default": "Field(default=None, min_length=36, max_length=36)" + } + ], + "line": 90, + "doc": "" + }, + { + "name": "PolicyIngestRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "topic_key", + "type": "str", + "default": "Field(min_length=1, max_length=160)" + }, + { + "name": "policy_id", + "type": "str", + "default": "Field(min_length=1, max_length=160)" + }, + { + "name": "plan_type", + "type": "str", + "default": "Field(min_length=1, max_length=120)" + }, + { + "name": "title", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + }, + { + "name": "citation", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + }, + { + "name": "excerpt", + "type": "str", + "default": "Field(min_length=1, max_length=5000)" + }, + { + "name": "relevance", + "type": "str", + "default": "Field(min_length=1, max_length=2000)" + }, + { + "name": "adoption_status", + "type": "str", + "default": "Field(default='adopted', min_length=1, max_length=80)" + }, + { + "name": "source_document", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + } + ], + "line": 97, + "doc": "" + }, + { + "name": "PlanQuestionRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "question", + "type": "str", + "default": "Field(min_length=1, max_length=2000)" + }, + { + "name": "plan_type", + "type": "str", + "default": "Field(default='comprehensive', min_length=1, max_length=120)" + } + ], + "line": 109, + "doc": "" + }, + { + "name": "PlanSynthesisRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "topic", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + } + ], + "line": 114, + "doc": "" + }, + { + "name": "TownlightMeetingsContextRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "agenda_item", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + }, + { + "name": "topic", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + } + ], + "line": 118, + "doc": "" + }, + { + "name": "IntegrationMockRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "provider", + "type": "str", + "default": "Field(min_length=1, max_length=120)" + }, + { + "name": "payload", + "type": "dict[str, object]", + "default": "Field(default_factory=dict)" + } + ], + "line": 123, + "doc": "" + } + ], + "configuration": [ + { + "variable": "TOWNLIGHT_PLANNING_POLICY_DB_URL", + "default": "", + "line": 469 + }, + { + "variable": "TOWNLIGHT_PLANNING_DEMO_MODE", + "default": "", + "line": 496 + } + ] + }, + { + "source": "installed-owned-source/townlight_planning/migrations/__init__.py", + "sha256": "daf5e64cefda400a5db1023d952e41bef6f7954db19406d63ea84770c82dccd9", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_planning/migrations/__main__.py", + "sha256": "321e543984ca92e2540d1f4d9eca54658dc608987b95bc5abc61b651b4305fd6", + "routes": [], + "models": [], + "configuration": [ + { + "variable": "TOWNLIGHT_PLANNING_POLICY_DB_URL", + "default": "", + "line": 7 + } + ] + }, + { + "source": "installed-owned-source/townlight_planning/migrations/env.py", + "sha256": "832a41b6c40d14da47178b486650eba98bff574a66652e3b614cc782db04f8df", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_planning/migrations/versions/townlight_planning_0001_sources.py", + "sha256": "807e5a18d1fa295d482f3963f7799f244f046ab98297bfc33cbd17131fb44d17", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_planning/migrations/versions/townlight_planning_0002_workflows.py", + "sha256": "7c6fcdfe4a1fa33c9289cef975a25f4b0f6746471c380226c14520f8a5f09dbf", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_planning/migrations/versions/townlight_planning_0003_municipal.py", + "sha256": "64735db3119b22b54a232e0a4486657a91b5304e4a253b14ce7cae1acb204681", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_planning/migrations/versions/townlight_planning_0004_neighborhoods.py", + "sha256": "006f8f8f9859da76189efee9035d1f89c65e0b27172b5df9e316e1aa173434f8", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_planning/municipal.py", + "sha256": "dbd5bd841f3f90d2ab7256eafb30ed8b7ba6036bd3921e23595d7df6715b8555", + "routes": [], + "models": [ + { + "name": "Measurement", + "bases": [ + "BundleModel" + ], + "fields": [ + { + "name": "recorded_on", + "type": "date", + "default": "" + }, + { + "name": "value", + "type": "Decimal", + "default": "Field(allow_inf_nan=False)" + }, + { + "name": "evidence", + "type": "str", + "default": "Field(min_length=1, max_length=2000)" + } + ], + "line": 41, + "doc": "" + }, + { + "name": "Milestone", + "bases": [ + "BundleModel" + ], + "fields": [ + { + "name": "title", + "type": "str", + "default": "Field(min_length=1, max_length=255)" + }, + { + "name": "due_on", + "type": "date", + "default": "" + }, + { + "name": "completed_on", + "type": "date | None", + "default": "None" + }, + { + "name": "evidence", + "type": "str", + "default": "Field(default='', max_length=2000)" + } + ], + "line": 53, + "doc": "" + }, + { + "name": "InitiativeInput", + "bases": [ + "BundleModel" + ], + "fields": [ + { + "name": "expected_revision", + "type": "str | None", + "default": "Field(default=None, min_length=36, max_length=36)" + }, + { + "name": "title", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + }, + { + "name": "policy", + "type": "PolicySelection", + "default": "" + }, + { + "name": "responsible_staff", + "type": "str", + "default": "Field(min_length=1, max_length=255)" + }, + { + "name": "target", + "type": "Decimal", + "default": "Field(allow_inf_nan=False)" + }, + { + "name": "unit", + "type": "str", + "default": "Field(min_length=1, max_length=80)" + }, + { + "name": "due_on", + "type": "date", + "default": "" + }, + { + "name": "status", + "type": "Literal['planned', 'active', 'completed', 'cancelled']", + "default": "'planned'" + }, + { + "name": "milestones", + "type": "list[Milestone]", + "default": "Field(default_factory=list, max_length=100)" + }, + { + "name": "measurements", + "type": "list[Measurement]", + "default": "Field(default_factory=list, max_length=1000)" + }, + { + "name": "note", + "type": "str", + "default": "Field(min_length=1, max_length=5000)" + } + ], + "line": 66, + "doc": "" + }, + { + "name": "AmendmentInput", + "bases": [ + "BundleModel" + ], + "fields": [ + { + "name": "expected_revision", + "type": "str | None", + "default": "Field(default=None, min_length=36, max_length=36)" + }, + { + "name": "title", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + }, + { + "name": "policy", + "type": "PolicySelection", + "default": "" + }, + { + "name": "proposal", + "type": "str", + "default": "Field(min_length=1, max_length=20000)" + }, + { + "name": "responsible_staff", + "type": "str", + "default": "Field(min_length=1, max_length=255)" + }, + { + "name": "status", + "type": "Literal['draft', 'review', 'adopted', 'withdrawn']", + "default": "'draft'" + }, + { + "name": "review_note", + "type": "str", + "default": "Field(default='', max_length=5000)" + }, + { + "name": "adoption_revision", + "type": "str | None", + "default": "Field(default=None, min_length=36, max_length=36)" + }, + { + "name": "note", + "type": "str", + "default": "Field(min_length=1, max_length=5000)" + } + ], + "line": 90, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_planning/municipal_api.py", + "sha256": "b71876bd1b6f354f7a9ad8d06f19d8ae7c071a0315f19421d3ff4df07bb8dc1f", + "routes": [ + { + "method": "POST", + "path": "/api/v1/townlight_planning/initiatives", + "router": "router", + "prefix_resolved": true, + "name": "create_initiative", + "signature": "data: InitiativeInput, actor=Depends(staff), repo=Depends(municipal)", + "returns": "", + "line": 17, + "doc": "", + "decorator": "router.post('/initiatives', status_code=201)", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_planning/initiatives/{item_id}/revisions", + "router": "router", + "prefix_resolved": true, + "name": "update_initiative", + "signature": "item_id: str, data: InitiativeInput, actor=Depends(staff), repo=Depends(municipal)", + "returns": "", + "line": 22, + "doc": "", + "decorator": "router.post('/initiatives/{item_id}/revisions')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_planning/amendments", + "router": "router", + "prefix_resolved": true, + "name": "create_amendment", + "signature": "data: AmendmentInput, actor=Depends(staff), repo=Depends(municipal)", + "returns": "", + "line": 29, + "doc": "", + "decorator": "router.post('/amendments', status_code=201)", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_planning/amendments/{item_id}/revisions", + "router": "router", + "prefix_resolved": true, + "name": "update_amendment", + "signature": "item_id: str, data: AmendmentInput, actor=Depends(staff), repo=Depends(municipal)", + "returns": "", + "line": 34, + "doc": "", + "decorator": "router.post('/amendments/{item_id}/revisions')", + "errors": [] + }, + { + "method": "GET", + "path": "/api/v1/townlight_planning/municipal-work/{item_id}/history", + "router": "router", + "prefix_resolved": true, + "name": "history", + "signature": "item_id: str, actor=Depends(staff), repo=Depends(municipal)", + "returns": "", + "line": 41, + "doc": "", + "decorator": "router.get('/municipal-work/{item_id}/history')", + "errors": [ + "HTTPException(404, 'Municipal workflow not found')" + ] + }, + { + "method": "GET", + "path": "/api/v1/townlight_planning/progress/targets", + "router": "router", + "prefix_resolved": true, + "name": "progress", + "signature": "policy_id: str | None=None, offset: int=Query(0, ge=0, le=100000), limit: int=Query(50, ge=1, le=100), actor=Depends(staff), repo=Depends(municipal)", + "returns": "", + "line": 49, + "doc": "", + "decorator": "router.get('/progress/targets')", + "errors": [] + }, + { + "method": "GET", + "path": "/api/v1/townlight_planning/amendments/history", + "router": "router", + "prefix_resolved": true, + "name": "amendments", + "signature": "plan_type: str | None=None, offset: int=Query(0, ge=0, le=100000), limit: int=Query(50, ge=1, le=100), actor=Depends(staff), repo=Depends(municipal)", + "returns": "", + "line": 60, + "doc": "", + "decorator": "router.get('/amendments/history')", + "errors": [] + } + ], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_planning/persistence.py", + "sha256": "30d920165ab9b4f9675a0d61dd887587823b6c075ef160e3a56670db95d2cc7e", + "routes": [], + "models": [ + { + "name": "StoredStaffAnalysis", + "bases": [], + "fields": [ + { + "name": "analysis_id", + "type": "str", + "default": "" + }, + { + "name": "project_name", + "type": "str", + "default": "" + }, + { + "name": "proposal", + "type": "str", + "default": "" + }, + { + "name": "policy_id", + "type": "str", + "default": "" + }, + { + "name": "heading", + "type": "str", + "default": "" + }, + { + "name": "bullets", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "citations", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "review_required", + "type": "bool", + "default": "" + }, + { + "name": "disclaimer", + "type": "str", + "default": "" + }, + { + "name": "created_at", + "type": "datetime", + "default": "" + } + ], + "line": 51, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_planning/plan_workflows.py", + "sha256": "e69084e3608fa33bbc6ab140d4570efa3850cb04317000b407c5a5f5ca635115", + "routes": [], + "models": [ + { + "name": "PlanPolicyIngestRecord", + "bases": [], + "fields": [ + { + "name": "topic_key", + "type": "str", + "default": "" + }, + { + "name": "policy", + "type": "PlanPolicy", + "default": "" + }, + { + "name": "adoption_status", + "type": "PlanStatus", + "default": "" + }, + { + "name": "source_document", + "type": "str", + "default": "" + } + ], + "line": 14, + "doc": "" + }, + { + "name": "PlanQuestionAnswer", + "bases": [], + "fields": [ + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "answer", + "type": "str", + "default": "" + }, + { + "name": "citations", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "source_policy_ids", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "review_required", + "type": "bool", + "default": "" + }, + { + "name": "disclaimer", + "type": "str", + "default": "DISCLAIMER" + } + ], + "line": 22, + "doc": "" + }, + { + "name": "PlanAmendment", + "bases": [], + "fields": [ + { + "name": "amendment_id", + "type": "str", + "default": "" + }, + { + "name": "plan_type", + "type": "str", + "default": "" + }, + { + "name": "title", + "type": "str", + "default": "" + }, + { + "name": "adoption_status", + "type": "PlanStatus", + "default": "" + }, + { + "name": "adopted_date", + "type": "str | None", + "default": "" + }, + { + "name": "citation", + "type": "str", + "default": "" + }, + { + "name": "summary", + "type": "str", + "default": "" + } + ], + "line": 32, + "doc": "" + }, + { + "name": "ProgressTarget", + "bases": [], + "fields": [ + { + "name": "target_id", + "type": "str", + "default": "" + }, + { + "name": "policy_id", + "type": "str", + "default": "" + }, + { + "name": "metric", + "type": "str", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "evidence", + "type": "str", + "default": "" + }, + { + "name": "citation", + "type": "str", + "default": "" + }, + { + "name": "updated_at", + "type": "datetime", + "default": "" + } + ], + "line": 43, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_planning/policy_lookup.py", + "sha256": "eef53ba621332d75f069f00ddcac34c19bca42d469a697fd22555eb3d11c68b2", + "routes": [], + "models": [ + { + "name": "PlanPolicy", + "bases": [], + "fields": [ + { + "name": "policy_id", + "type": "str", + "default": "" + }, + { + "name": "plan_type", + "type": "str", + "default": "" + }, + { + "name": "title", + "type": "str", + "default": "" + }, + { + "name": "citation", + "type": "str", + "default": "" + }, + { + "name": "excerpt", + "type": "str", + "default": "" + }, + { + "name": "relevance", + "type": "str", + "default": "" + }, + { + "name": "disclaimer", + "type": "str", + "default": "DISCLAIMER" + } + ], + "line": 16, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_planning/policy_service.py", + "sha256": "c5e5461fadea4b32cba43366e1c9795ecb4cd8212db30734f5eadd24a9144808", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_planning/public_explore.py", + "sha256": "c5cbb2de92661538857e52b25f2e0bc4e7cd4f5c9d91eb0fa7d0518b28374720", + "routes": [], + "models": [ + { + "name": "Exploration", + "bases": [], + "fields": [ + { + "name": "query", + "type": "str", + "default": "''" + }, + { + "name": "plan_type", + "type": "str", + "default": "''" + }, + { + "name": "goal", + "type": "str", + "default": "''" + }, + { + "name": "topic", + "type": "str", + "default": "''" + }, + { + "name": "neighborhood", + "type": "str", + "default": "''" + }, + { + "name": "plans", + "type": "list", + "default": "field(default_factory=list)" + }, + { + "name": "total", + "type": "int", + "default": "0" + }, + { + "name": "review_required", + "type": "bool", + "default": "True" + }, + { + "name": "disclaimer", + "type": "str", + "default": "''" + }, + { + "name": "empty_reason", + "type": "str | None", + "default": "None" + }, + { + "name": "facets", + "type": "dict", + "default": "field(default_factory=dict)" + } + ], + "line": 34, + "doc": "One exploration request and what the persisted sources support for it." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_planning/public_explore_ui.py", + "sha256": "bd137701e16391a4ee820c4c88b5db583944491d5fc487ff7580b1083e944e5d", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_planning/public_ui.py", + "sha256": "8551ce36f854a4a7fc4573a20b73dbb0b6f01d7b60b7267d8c73b5f21f246ccc", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_planning/records_export.py", + "sha256": "6894fb9450f5d0177ebf86babcd489be1a789a714ce2c3c825c7afd5ed51bb23", + "routes": [], + "models": [ + { + "name": "PolicyExport", + "bases": [], + "fields": [ + { + "name": "title", + "type": "str", + "default": "" + }, + { + "name": "policy_id", + "type": "str", + "default": "" + }, + { + "name": "format", + "type": "str", + "default": "" + }, + { + "name": "checklist", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "retention_note", + "type": "str", + "default": "" + } + ], + "line": 11, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_planning/source_api.py", + "sha256": "4af39debaf4f9cbb219c294ddfeaea642495d45e492e62852049372e296f1df4", + "routes": [ + { + "method": "POST", + "path": "/api/v1/townlight_planning/source-imports", + "router": "router", + "prefix_resolved": true, + "name": "import_sources", + "signature": "request: ImportRequest, actor: str=Depends(staff), repo=Depends(repository)", + "returns": "", + "line": 51, + "doc": "", + "decorator": "router.post('/source-imports')", + "errors": [ + "HTTPException(409, str(exc))" + ] + }, + { + "method": "GET", + "path": "/api/v1/townlight_planning/source-plans/{plan_id}/history", + "router": "router", + "prefix_resolved": true, + "name": "source_history", + "signature": "plan_id: str, _actor=Depends(staff), repo=Depends(repository)", + "returns": "", + "line": 63, + "doc": "", + "decorator": "router.get('/source-plans/{plan_id}/history')", + "errors": [] + }, + { + "method": "GET", + "path": "/api/v1/townlight_planning/source-revisions/{revision_id}", + "router": "router", + "prefix_resolved": true, + "name": "source_revision", + "signature": "revision_id: str, _actor=Depends(staff), repo=Depends(repository)", + "returns": "", + "line": 68, + "doc": "", + "decorator": "router.get('/source-revisions/{revision_id}')", + "errors": [ + "HTTPException(404, 'Planning source revision not found.')" + ] + }, + { + "method": "GET", + "path": "/api/v1/townlight_planning/source-revisions/{revision_id}/documents/{document_id}", + "router": "router", + "prefix_resolved": true, + "name": "source_document", + "signature": "revision_id: str, document_id: str, _actor=Depends(staff), repo=Depends(repository)", + "returns": "", + "line": 76, + "doc": "", + "decorator": "router.get('/source-revisions/{revision_id}/documents/{document_id}')", + "errors": [ + "HTTPException(404, 'Planning source document not found.')" + ] + } + ], + "models": [ + { + "name": "ImportRequest", + "bases": [ + "BundleModel" + ], + "fields": [ + { + "name": "bundle", + "type": "PlanBundle", + "default": "" + }, + { + "name": "expected_previous_revision", + "type": "str | None", + "default": "Field(default=None, min_length=36, max_length=36)" + } + ], + "line": 45, + "doc": "" + } + ], + "configuration": [ + { + "variable": "TOWNLIGHT_PLANNING_POLICY_DB_URL", + "default": "", + "line": 31 + } + ] + }, + { + "source": "installed-owned-source/townlight_planning/source_bundle.py", + "sha256": "f6547516067e27697dfcd6ba80de6e2ca03d1473370209aa354a5bf95b7db98a", + "routes": [], + "models": [ + { + "name": "SourceDocument", + "bases": [ + "BundleModel" + ], + "fields": [ + { + "name": "document_id", + "type": "str", + "default": "Field(min_length=1, max_length=160, pattern='^[A-Za-z0-9][A-Za-z0-9._:-]*$')" + }, + { + "name": "filename", + "type": "str", + "default": "Field(min_length=1, max_length=255)" + }, + { + "name": "media_type", + "type": "Literal['text/plain', 'text/markdown', 'application/pdf', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document']", + "default": "" + }, + { + "name": "sha256", + "type": "str", + "default": "Field(pattern='^[0-9a-f]{64}$')" + }, + { + "name": "content_base64", + "type": "str", + "default": "Field(min_length=1, max_length=14000000)" + } + ], + "line": 18, + "doc": "" + }, + { + "name": "SourcePolicy", + "bases": [ + "BundleModel" + ], + "fields": [ + { + "name": "policy_id", + "type": "str", + "default": "Field(min_length=1, max_length=160)" + }, + { + "name": "document_id", + "type": "str", + "default": "Field(min_length=1, max_length=160)" + }, + { + "name": "goal", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + }, + { + "name": "objective", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + }, + { + "name": "topic_key", + "type": "str", + "default": "Field(min_length=1, max_length=160)" + }, + { + "name": "neighborhoods", + "type": "list[str]", + "default": "Field(default_factory=list, max_length=100)" + }, + { + "name": "title", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + }, + { + "name": "citation", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + }, + { + "name": "anchor", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + }, + { + "name": "excerpt", + "type": "str", + "default": "Field(min_length=1, max_length=20000)" + }, + { + "name": "relevance", + "type": "str", + "default": "Field(min_length=1, max_length=2000)" + }, + { + "name": "staff_verified", + "type": "Literal[True]", + "default": "" + } + ], + "line": 62, + "doc": "" + }, + { + "name": "AdoptionEvidence", + "bases": [ + "BundleModel" + ], + "fields": [ + { + "name": "kind", + "type": "Literal['manual-record', 'meeting-reference', 'source-document']", + "default": "" + }, + { + "name": "reference", + "type": "str", + "default": "Field(min_length=1, max_length=1000)" + }, + { + "name": "document_id", + "type": "str | None", + "default": "Field(default=None, min_length=1, max_length=160)" + }, + { + "name": "note", + "type": "str", + "default": "Field(min_length=1, max_length=4000)" + } + ], + "line": 77, + "doc": "" + }, + { + "name": "PlanBundle", + "bases": [ + "BundleModel" + ], + "fields": [ + { + "name": "schema_version", + "type": "Literal[1]", + "default": "1" + }, + { + "name": "plan_id", + "type": "str", + "default": "Field(min_length=1, max_length=160, pattern='^[A-Za-z0-9][A-Za-z0-9._:-]*$')" + }, + { + "name": "title", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + }, + { + "name": "jurisdiction", + "type": "str", + "default": "Field(min_length=1, max_length=255)" + }, + { + "name": "plan_type", + "type": "PlanType", + "default": "" + }, + { + "name": "status", + "type": "Literal['pending', 'adopted', 'superseded']", + "default": "" + }, + { + "name": "visibility", + "type": "Literal['staff', 'public']", + "default": "'staff'" + }, + { + "name": "dataset_kind", + "type": "Literal['municipal', 'demo']", + "default": "'municipal'" + }, + { + "name": "source_date", + "type": "date", + "default": "" + }, + { + "name": "adopted_on", + "type": "date | None", + "default": "None" + }, + { + "name": "effective_on", + "type": "date | None", + "default": "None" + }, + { + "name": "change_note", + "type": "str", + "default": "Field(min_length=1, max_length=4000)" + }, + { + "name": "reviewer_label", + "type": "str", + "default": "Field(min_length=1, max_length=255)" + }, + { + "name": "documents", + "type": "list[SourceDocument]", + "default": "Field(min_length=1, max_length=20)" + }, + { + "name": "policies", + "type": "list[SourcePolicy]", + "default": "Field(min_length=1, max_length=1000)" + }, + { + "name": "adoption_evidence", + "type": "list[AdoptionEvidence]", + "default": "Field(default_factory=list, max_length=100)" + } + ], + "line": 84, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_planning/source_schema.py", + "sha256": "1c429c22247cda2aaec5abe6807639177f035cae843993666dbf8b2824bbdbf1", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_planning/source_store.py", + "sha256": "97022c50baa5b7e81bcc12fccd6c2e429af35f163680542cbf99b65722905d82", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_planning/staff_analysis.py", + "sha256": "71ab2f06804f1c01678f708c60a27714d7bd9b14444e1d2c8546cedb8ac1bd69", + "routes": [], + "models": [ + { + "name": "StaffAnalysisDraft", + "bases": [], + "fields": [ + { + "name": "project_name", + "type": "str", + "default": "" + }, + { + "name": "heading", + "type": "str", + "default": "" + }, + { + "name": "bullets", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "citations", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "review_required", + "type": "bool", + "default": "" + }, + { + "name": "disclaimer", + "type": "str", + "default": "DISCLAIMER" + } + ], + "line": 12, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_planning/workflow_api.py", + "sha256": "6a48664442a3a8bae19a8cea7676e91f53ca3360f65e912dec666504862e792b", + "routes": [ + { + "method": "POST", + "path": "/api/v1/townlight_planning/analyses", + "router": "router", + "prefix_resolved": true, + "name": "create_analysis", + "signature": "data: AnalysisInput, actor=Depends(staff), repo=Depends(workflows)", + "returns": "", + "line": 45, + "doc": "", + "decorator": "router.post('/analyses')", + "errors": [ + "HTTPException(422, 'New analyses have no previous revision.')" + ] + }, + { + "method": "POST", + "path": "/api/v1/townlight_planning/analyses/{analysis_id}/revisions", + "router": "router", + "prefix_resolved": true, + "name": "revise_analysis", + "signature": "analysis_id: str, data: AnalysisInput, actor=Depends(staff), repo=Depends(workflows)", + "returns": "", + "line": 52, + "doc": "", + "decorator": "router.post('/analyses/{analysis_id}/revisions')", + "errors": [ + "HTTPException(422, 'Supply the analysis previous revision.')" + ] + }, + { + "method": "GET", + "path": "/api/v1/townlight_planning/analyses/{analysis_id}", + "router": "router", + "prefix_resolved": true, + "name": "read_analysis", + "signature": "analysis_id: str, revision_id: str | None=None, actor=Depends(staff), repo=Depends(workflows)", + "returns": "", + "line": 59, + "doc": "", + "decorator": "router.get('/analyses/{analysis_id}')", + "errors": [ + "HTTPException(404, 'Analysis not found.')" + ] + }, + { + "method": "GET", + "path": "/api/v1/townlight_planning/analyses/{analysis_id}/history", + "router": "router", + "prefix_resolved": true, + "name": "analysis_history", + "signature": "analysis_id: str, actor=Depends(staff), repo=Depends(workflows)", + "returns": "", + "line": 67, + "doc": "", + "decorator": "router.get('/analyses/{analysis_id}/history')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_planning/analyses/{analysis_id}/snapshots", + "router": "router", + "prefix_resolved": true, + "name": "create_snapshot", + "signature": "analysis_id: str, data: SnapshotInput, actor=Depends(staff), repo=Depends(workflows)", + "returns": "", + "line": 77, + "doc": "", + "decorator": "router.post('/analyses/{analysis_id}/snapshots')", + "errors": [] + }, + { + "method": "GET", + "path": "/api/v1/townlight_planning/snapshots/{snapshot_id}", + "router": "router", + "prefix_resolved": true, + "name": "read_snapshot", + "signature": "snapshot_id: str, actor=Depends(staff), repo=Depends(workflows)", + "returns": "", + "line": 82, + "doc": "", + "decorator": "router.get('/snapshots/{snapshot_id}')", + "errors": [ + "HTTPException(404, 'Snapshot not found.')" + ] + }, + { + "method": "GET", + "path": "/api/v1/townlight_planning/snapshots/{snapshot_id}/export", + "router": "router", + "prefix_resolved": true, + "name": "export_snapshot", + "signature": "snapshot_id: str, actor=Depends(staff), repo=Depends(workflows)", + "returns": "", + "line": 90, + "doc": "", + "decorator": "router.get('/snapshots/{snapshot_id}/export')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_planning/snapshots/{snapshot_id}/access-advice", + "router": "router", + "prefix_resolved": true, + "name": "access_advice", + "signature": "snapshot_id: str, actor=Depends(staff), repo=Depends(workflows)", + "returns": "", + "line": 98, + "doc": "", + "decorator": "router.post('/snapshots/{snapshot_id}/access-advice')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_planning/policies/search", + "router": "router", + "prefix_resolved": true, + "name": "search_policies", + "signature": "data: SearchInput, is_staff=Depends(audience), sources=Depends(repository)", + "returns": "", + "line": 108, + "doc": "", + "decorator": "router.post('/policies/search')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_planning/connections/search", + "router": "router", + "prefix_resolved": true, + "name": "search_connections", + "signature": "data: ConnectionSearch, actor=Depends(staff), repo=Depends(workflows)", + "returns": "", + "line": 118, + "doc": "", + "decorator": "router.post('/connections/search')", + "errors": [] + }, + { + "method": "GET", + "path": "/api/v1/townlight_planning/policy-sources/{revision_id}/documents/{document_id}", + "router": "router", + "prefix_resolved": true, + "name": "public_original", + "signature": "revision_id: str, document_id: str, sources=Depends(repository)", + "returns": "", + "line": 123, + "doc": "", + "decorator": "router.get('/policy-sources/{revision_id}/documents/{document_id}')", + "errors": [ + "HTTPException(404, 'Public policy source unavailable.')", + "HTTPException(404, 'Public policy document not found.')" + ] + } + ], + "models": [ + { + "name": "SnapshotInput", + "bases": [ + "BundleModel" + ], + "fields": [ + { + "name": "expected_revision", + "type": "str", + "default": "Field(min_length=36, max_length=36)" + }, + { + "name": "visibility", + "type": "Literal['staff_only', 'public']", + "default": "'staff_only'" + } + ], + "line": 71, + "doc": "" + }, + { + "name": "SearchInput", + "bases": [ + "BundleModel" + ], + "fields": [ + { + "name": "query", + "type": "str", + "default": "Field(min_length=1, max_length=2000)" + }, + { + "name": "plan_type", + "type": "str | None", + "default": "Field(default=None, max_length=40)" + } + ], + "line": 102, + "doc": "" + }, + { + "name": "ConnectionSearch", + "bases": [ + "BundleModel" + ], + "fields": [ + { + "name": "provider", + "type": "Literal['meetings', 'zoning']", + "default": "" + }, + { + "name": "query", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + } + ], + "line": 112, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_planning/workflow_models.py", + "sha256": "d22e978fe778d7f4fdc3989a043370d9f6966b1e4920ed2c75698c73a8ee4e04", + "routes": [], + "models": [ + { + "name": "PolicySelection", + "bases": [ + "BundleModel" + ], + "fields": [ + { + "name": "plan_id", + "type": "str", + "default": "Field(min_length=1, max_length=160)" + }, + { + "name": "revision_id", + "type": "str", + "default": "Field(min_length=36, max_length=36)" + }, + { + "name": "policy_id", + "type": "str", + "default": "Field(min_length=1, max_length=160)" + } + ], + "line": 7, + "doc": "" + }, + { + "name": "LinkedSource", + "bases": [ + "BundleModel" + ], + "fields": [ + { + "name": "provider", + "type": "Literal['meetings', 'zoning']", + "default": "" + }, + { + "name": "source_id", + "type": "str", + "default": "Field(min_length=1, max_length=200)" + }, + { + "name": "expected_sha256", + "type": "str", + "default": "Field(pattern='^[0-9a-f]{64}$')" + }, + { + "name": "relation", + "type": "Literal['adoption-evidence', 'hearing', 'context', 'precedent']", + "default": "" + } + ], + "line": 13, + "doc": "" + }, + { + "name": "Consideration", + "bases": [ + "BundleModel" + ], + "fields": [ + { + "name": "policy", + "type": "PolicySelection", + "default": "" + }, + { + "name": "stance", + "type": "Literal['supporting', 'conflicting', 'uncertain']", + "default": "" + }, + { + "name": "note", + "type": "str", + "default": "Field(min_length=1, max_length=5000)" + } + ], + "line": 20, + "doc": "" + }, + { + "name": "AnalysisInput", + "bases": [ + "BundleModel" + ], + "fields": [ + { + "name": "expected_previous_revision", + "type": "str | None", + "default": "Field(default=None, min_length=36, max_length=36)" + }, + { + "name": "project_name", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + }, + { + "name": "proposal", + "type": "str", + "default": "Field(min_length=1, max_length=10000)" + }, + { + "name": "selected_policies", + "type": "list[PolicySelection]", + "default": "Field(min_length=1, max_length=50)" + }, + { + "name": "considerations", + "type": "list[Consideration]", + "default": "Field(default_factory=list, max_length=100)" + }, + { + "name": "analysis_text", + "type": "str", + "default": "Field(default='', max_length=50000)" + }, + { + "name": "public_summary", + "type": "str", + "default": "Field(default='', max_length=10000)" + }, + { + "name": "staff_notes", + "type": "str", + "default": "Field(default='', max_length=10000)" + }, + { + "name": "audience", + "type": "Literal['staff', 'public']", + "default": "'staff'" + }, + { + "name": "review_state", + "type": "Literal['draft', 'reviewed']", + "default": "'draft'" + }, + { + "name": "reviewer_label", + "type": "str", + "default": "Field(default='', max_length=255)" + }, + { + "name": "reviewed_on", + "type": "date | None", + "default": "None" + }, + { + "name": "review_notes", + "type": "str", + "default": "Field(default='', max_length=5000)" + }, + { + "name": "linked_sources", + "type": "list[LinkedSource]", + "default": "Field(default_factory=list, max_length=50)" + } + ], + "line": 26, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_planning/workflow_schema.py", + "sha256": "11d864214fabc6d509351fdc7f3e3eb90a910a5db1a137f84a7a8efca5d0002e", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_planning/workflow_store.py", + "sha256": "4d4fec6d6c876997726ff1d8f2ff39302f44228fae748edc013739267d210741", + "routes": [], + "models": [], + "configuration": [] + } + ], + "bridge": [ + { + "source": "installed-owned-source/townlight_runtime/planning_bridge.py", + "sha256": "74a855b995b7f323873b9c788cd15bd4b0ebe3fc1c53879596e1b5043c2825bb", + "routes": [ + { + "method": "POST", + "path": "/desktop/v1/planning/imports/preview", + "router": "router", + "prefix_resolved": true, + "name": "preview_import", + "signature": "body: Import, identity=Depends(actor)", + "returns": "", + "line": 80, + "doc": "", + "decorator": "router.post('/imports/preview')", + "errors": [ + "HTTPException(422, 'Invalid source bundle; verify metadata, excerpts, anchors and original hashes.')" + ] + }, + { + "method": "POST", + "path": "/desktop/v1/planning/imports", + "router": "router", + "prefix_resolved": true, + "name": "import_source", + "signature": "request: Request, body: Import, identity=Depends(actor)", + "returns": "", + "line": 89, + "doc": "", + "decorator": "router.post('/imports')", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/planning/sources", + "router": "router", + "prefix_resolved": true, + "name": "source_list", + "signature": "request: Request, limit: int=Query(50, ge=1, le=100), offset: int=Query(0, ge=0, le=100000), identity=Depends(actor)", + "returns": "", + "line": 98, + "doc": "", + "decorator": "router.get('/sources')", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/planning/sources/{plan_id}/history", + "router": "router", + "prefix_resolved": true, + "name": "source_history", + "signature": "request: Request, plan_id: str, offset: int=Query(0, ge=0, le=100000), identity=Depends(actor)", + "returns": "", + "line": 104, + "doc": "", + "decorator": "router.get('/sources/{plan_id}/history')", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/planning/revisions/{revision_id}", + "router": "router", + "prefix_resolved": true, + "name": "revision", + "signature": "request: Request, revision_id: UUID, identity=Depends(actor)", + "returns": "", + "line": 109, + "doc": "", + "decorator": "router.get('/revisions/{revision_id}')", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/planning/revisions/{revision_id}/documents/{document_id}", + "router": "router", + "prefix_resolved": true, + "name": "staff_original", + "signature": "request: Request, revision_id: UUID, document_id: str, identity=Depends(actor)", + "returns": "", + "line": 127, + "doc": "", + "decorator": "router.get('/revisions/{revision_id}/documents/{document_id}')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/planning/policies/search", + "router": "router", + "prefix_resolved": true, + "name": "policies", + "signature": "request: Request, body: Search, identity=Depends(actor)", + "returns": "", + "line": 137, + "doc": "", + "decorator": "router.post('/policies/search')", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/planning/analyses", + "router": "router", + "prefix_resolved": true, + "name": "analyses", + "signature": "request: Request, limit: int=Query(50, ge=1, le=100), offset: int=Query(0, ge=0, le=100000), identity=Depends(actor)", + "returns": "", + "line": 142, + "doc": "", + "decorator": "router.get('/analyses')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/planning/analyses", + "router": "router", + "prefix_resolved": true, + "name": "create_analysis", + "signature": "request: Request, body: dict, identity=Depends(actor)", + "returns": "", + "line": 155, + "doc": "", + "decorator": "router.post('/analyses')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/planning/analyses/{analysis_id}/revisions", + "router": "router", + "prefix_resolved": true, + "name": "revise_analysis", + "signature": "request: Request, analysis_id: UUID, body: dict, identity=Depends(actor)", + "returns": "", + "line": 165, + "doc": "", + "decorator": "router.post('/analyses/{analysis_id}/revisions')", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/planning/analyses/{analysis_id}", + "router": "router", + "prefix_resolved": true, + "name": "analysis", + "signature": "request: Request, analysis_id: UUID, identity=Depends(actor)", + "returns": "", + "line": 175, + "doc": "", + "decorator": "router.get('/analyses/{analysis_id}')", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/planning/analyses/{analysis_id}/history", + "router": "router", + "prefix_resolved": true, + "name": "analysis_history", + "signature": "request: Request, analysis_id: UUID, offset: int=Query(0, ge=0, le=100000), identity=Depends(actor)", + "returns": "", + "line": 180, + "doc": "", + "decorator": "router.get('/analyses/{analysis_id}/history')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/planning/analyses/{analysis_id}/snapshot-preview", + "router": "router", + "prefix_resolved": true, + "name": "preview_snapshot", + "signature": "request: Request, analysis_id: UUID, body: Snapshot, identity=Depends(actor)", + "returns": "", + "line": 190, + "doc": "", + "decorator": "router.post('/analyses/{analysis_id}/snapshot-preview')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/planning/analyses/{analysis_id}/snapshots", + "router": "router", + "prefix_resolved": true, + "name": "snapshot", + "signature": "request: Request, analysis_id: UUID, body: Snapshot, identity=Depends(actor)", + "returns": "", + "line": 195, + "doc": "", + "decorator": "router.post('/analyses/{analysis_id}/snapshots')", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/planning/snapshots", + "router": "router", + "prefix_resolved": true, + "name": "snapshots", + "signature": "request: Request, limit: int=Query(50, ge=1, le=100), offset: int=Query(0, ge=0, le=100000), identity=Depends(actor)", + "returns": "", + "line": 200, + "doc": "", + "decorator": "router.get('/snapshots')", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/planning/snapshots/{snapshot_id}", + "router": "router", + "prefix_resolved": true, + "name": "document", + "signature": "request: Request, snapshot_id: UUID, identity=Depends(actor)", + "returns": "", + "line": 206, + "doc": "", + "decorator": "router.get('/snapshots/{snapshot_id}')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/planning/snapshots/{snapshot_id}/access-advice", + "router": "router", + "prefix_resolved": true, + "name": "access_advice", + "signature": "request: Request, snapshot_id: UUID, identity=Depends(actor)", + "returns": "", + "line": 211, + "doc": "", + "decorator": "router.post('/snapshots/{snapshot_id}/access-advice')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/planning/connections/search", + "router": "router", + "prefix_resolved": true, + "name": "connections", + "signature": "request: Request, body: ConnectionSearch, identity=Depends(actor)", + "returns": "", + "line": 221, + "doc": "", + "decorator": "router.post('/connections/search')", + "errors": [] + }, + { + "method": "POST", + "path": "/townlight_planning/policies/search", + "router": "public_router", + "prefix_resolved": true, + "name": "public_policies", + "signature": "request: Request, body: Search", + "returns": "", + "line": 226, + "doc": "", + "decorator": "public_router.post('/policies/search', dependencies=[Depends(available)])", + "errors": [] + }, + { + "method": "POST", + "path": "/townlight_planning/plan-explore", + "router": "public_router", + "prefix_resolved": true, + "name": "public_plan_explore", + "signature": "request: Request, body: PublicExplore", + "returns": "", + "line": 238, + "doc": "Topic/goal/plan-type exploration over adopted public plan sources only.", + "decorator": "public_router.post('/plan-explore', dependencies=[Depends(available)])", + "errors": [] + }, + { + "method": "GET", + "path": "/townlight_planning/snapshots", + "router": "public_router", + "prefix_resolved": true, + "name": "public_snapshots", + "signature": "request: Request, limit: int=Query(50, ge=1, le=100), offset: int=Query(0, ge=0, le=100000)", + "returns": "", + "line": 254, + "doc": "", + "decorator": "public_router.get('/snapshots', dependencies=[Depends(available)])", + "errors": [] + }, + { + "method": "GET", + "path": "/townlight_planning/snapshots/{snapshot_id}", + "router": "public_router", + "prefix_resolved": true, + "name": "public_document", + "signature": "request: Request, snapshot_id: UUID", + "returns": "", + "line": 260, + "doc": "", + "decorator": "public_router.get('/snapshots/{snapshot_id}', dependencies=[Depends(available)])", + "errors": [] + }, + { + "method": "GET", + "path": "/townlight_planning/revisions/{revision_id}/documents/{document_id}", + "router": "public_router", + "prefix_resolved": true, + "name": "public_original", + "signature": "request: Request, revision_id: UUID, document_id: str", + "returns": "", + "line": 265, + "doc": "", + "decorator": "public_router.get('/revisions/{revision_id}/documents/{document_id}', dependencies=[Depends(available)])", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/planning/progress/targets", + "router": "router", + "prefix_resolved": true, + "name": "municipal_progress", + "signature": "request: Request, offset: int=Query(0, ge=0, le=100000), identity=Depends(actor)", + "returns": "", + "line": 270, + "doc": "", + "decorator": "router.get('/progress/targets')", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/planning/amendments/history", + "router": "router", + "prefix_resolved": true, + "name": "municipal_amendments", + "signature": "request: Request, offset: int=Query(0, ge=0, le=100000), identity=Depends(actor)", + "returns": "", + "line": 275, + "doc": "", + "decorator": "router.get('/amendments/history')", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/planning/municipal-work/{item_id}/history", + "router": "router", + "prefix_resolved": true, + "name": "municipal_history", + "signature": "request: Request, item_id: UUID, identity=Depends(actor)", + "returns": "", + "line": 280, + "doc": "", + "decorator": "router.get('/municipal-work/{item_id}/history')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/planning/initiatives", + "router": "router", + "prefix_resolved": true, + "name": "create_initiative", + "signature": "request: Request, body: InitiativeInput, identity=Depends(actor)", + "returns": "", + "line": 285, + "doc": "", + "decorator": "router.post('/initiatives')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/planning/initiatives/{item_id}/revisions", + "router": "router", + "prefix_resolved": true, + "name": "update_initiative", + "signature": "request: Request, item_id: UUID, body: InitiativeInput, identity=Depends(actor)", + "returns": "", + "line": 290, + "doc": "", + "decorator": "router.post('/initiatives/{item_id}/revisions')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/planning/amendments", + "router": "router", + "prefix_resolved": true, + "name": "create_amendment", + "signature": "request: Request, body: AmendmentInput, identity=Depends(actor)", + "returns": "", + "line": 295, + "doc": "", + "decorator": "router.post('/amendments')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/planning/amendments/{item_id}/revisions", + "router": "router", + "prefix_resolved": true, + "name": "update_amendment", + "signature": "request: Request, item_id: UUID, body: AmendmentInput, identity=Depends(actor)", + "returns": "", + "line": 300, + "doc": "", + "decorator": "router.post('/amendments/{item_id}/revisions')", + "errors": [] + } + ], + "models": [ + { + "name": "Import", + "bases": [ + "BundleModel" + ], + "fields": [ + { + "name": "bundle", + "type": "dict", + "default": "" + }, + { + "name": "expected_previous_revision", + "type": "str | None", + "default": "Field(default=None, min_length=36, max_length=36)" + } + ], + "line": 74, + "doc": "" + }, + { + "name": "Search", + "bases": [ + "BundleModel" + ], + "fields": [ + { + "name": "query", + "type": "str", + "default": "Field(min_length=1, max_length=2000)" + }, + { + "name": "plan_type", + "type": "str | None", + "default": "Field(default=None, max_length=40)" + } + ], + "line": 131, + "doc": "" + }, + { + "name": "Snapshot", + "bases": [ + "BundleModel" + ], + "fields": [ + { + "name": "expected_revision", + "type": "UUID", + "default": "" + }, + { + "name": "visibility", + "type": "Literal['staff_only', 'public']", + "default": "" + } + ], + "line": 184, + "doc": "" + }, + { + "name": "ConnectionSearch", + "bases": [ + "BundleModel" + ], + "fields": [ + { + "name": "provider", + "type": "Literal['meetings', 'zoning']", + "default": "" + }, + { + "name": "query", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + } + ], + "line": 215, + "doc": "" + }, + { + "name": "PublicExplore", + "bases": [ + "BundleModel" + ], + "fields": [ + { + "name": "goal", + "type": "str", + "default": "Field(default='', max_length=500)" + }, + { + "name": "topic", + "type": "str", + "default": "Field(default='', max_length=160)" + }, + { + "name": "neighborhood", + "type": "str", + "default": "Field(default='', max_length=255)" + }, + { + "name": "plan_type", + "type": "str", + "default": "Field(default='', max_length=120)" + } + ], + "line": 230, + "doc": "" + } + ], + "configuration": [] + } + ] + }, + "permitting": { + "package": "townlight_permitting", + "source": [ + { + "source": "installed-owned-source/townlight_permitting/__init__.py", + "sha256": "a5b97430c7d8d5cfff984857fe16a7c72868d652340640cb9bdcdfe39ddb209c", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_permitting/connections.py", + "sha256": "4159a4eb4a407bebbefeb49bb760788cff3ac51a45c34af094d3be4b5a746798", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_permitting/intake_review.py", + "sha256": "694f531a12e56c283579e92f85651d08da776e916021ab19f4d7108c3120b41d", + "routes": [], + "models": [ + { + "name": "IntakeReadiness", + "bases": [], + "fields": [ + { + "name": "project_type", + "type": "str", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "missing_or_unclear", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "next_step", + "type": "str", + "default": "" + }, + { + "name": "disclaimer", + "type": "str", + "default": "DISCLAIMER" + } + ], + "line": 11, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_permitting/integration_mocks.py", + "sha256": "d1f1b614d502ada64a87d879703e9afa72402b69e8df5a1cf25cbd78f783e111", + "routes": [], + "models": [ + { + "name": "IntegrationMockResult", + "bases": [], + "fields": [ + { + "name": "scenario", + "type": "str", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "review_required", + "type": "bool", + "default": "" + }, + { + "name": "findings", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "boundary", + "type": "str", + "default": "" + } + ], + "line": 10, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_permitting/main.py", + "sha256": "d1186d8d291225cfff5dc66e40ab435d899d8a059506a6be6f3b413b7a5c8b90", + "routes": [ + { + "method": "GET", + "path": "/", + "router": "app", + "prefix_resolved": true, + "name": "root", + "signature": "", + "returns": "dict[str, str]", + "line": 104, + "doc": "Return current product state without overstating unshipped behavior.", + "decorator": "app.get('/')", + "errors": [] + }, + { + "method": "GET", + "path": "/health", + "router": "app", + "prefix_resolved": true, + "name": "health", + "signature": "", + "returns": "dict[str, str]", + "line": 124, + "doc": "Return dependency/version health for deployment smoke checks.", + "decorator": "app.get('/health')", + "errors": [] + }, + { + "method": "GET", + "path": "/townlight_permitting", + "router": "app", + "prefix_resolved": true, + "name": "public_townlight_permitting_page", + "signature": "", + "returns": "str", + "line": 163, + "doc": "Return the public sample permit pre-application UI.", + "decorator": "app.get('/townlight_permitting', response_class=HTMLResponse)", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_permitting/requirements/lookup", + "router": "app", + "prefix_resolved": true, + "name": "requirement_lookup", + "signature": "request: RequirementLookupRequest", + "returns": "dict[str, object]", + "line": 170, + "doc": "", + "decorator": "app.post('/api/v1/townlight_permitting/requirements/lookup')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_permitting/intake/review", + "router": "app", + "prefix_resolved": true, + "name": "intake_review", + "signature": "request: IntakeReviewRequest, x_townlight_permitting_role: Annotated[str | None, Header()]=None, x_townlight_permitting_staff_key: Annotated[str | None, Header()]=None", + "returns": "dict[str, object]", + "line": 179, + "doc": "", + "decorator": "app.post('/api/v1/townlight_permitting/intake/review')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_permitting/pathway/explain", + "router": "app", + "prefix_resolved": true, + "name": "pathway_explain", + "signature": "request: PathwayRequest", + "returns": "dict[str, object]", + "line": 305, + "doc": "Cited likely pathway/attachments/timeline/explainer, no model call.", + "decorator": "app.post('/api/v1/townlight_permitting/pathway/explain')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_permitting/pathway/explain-assisted", + "router": "app", + "prefix_resolved": true, + "name": "pathway_explain_assisted", + "signature": "request: PathwayRequest", + "returns": "dict[str, object]", + "line": 319, + "doc": "Same, plus an actual configured-provider call; `assistance` says what ran.", + "decorator": "app.post('/api/v1/townlight_permitting/pathway/explain-assisted')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_permitting/context/development-review", + "router": "app", + "prefix_resolved": true, + "name": "development_review_context", + "signature": "request: DevelopmentReviewContextRequest", + "returns": "dict[str, object]", + "line": 339, + "doc": "", + "decorator": "app.post('/api/v1/townlight_permitting/context/development-review')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_permitting/integrations/mock/development-review", + "router": "app", + "prefix_resolved": true, + "name": "integration_mock_development_review", + "signature": "request: IntegrationMockRequest", + "returns": "dict[str, object]", + "line": 372, + "doc": "", + "decorator": "app.post('/api/v1/townlight_permitting/integrations/mock/development-review')", + "errors": [] + }, + { + "method": "GET", + "path": "/api/v1/townlight_permitting/intake/{intake_id}", + "router": "app", + "prefix_resolved": true, + "name": "get_intake_review", + "signature": "intake_id: str, x_townlight_permitting_role: Annotated[str | None, Header()]=None, x_townlight_permitting_staff_key: Annotated[str | None, Header()]=None", + "returns": "dict[str, object]", + "line": 384, + "doc": "", + "decorator": "app.get('/api/v1/townlight_permitting/intake/{intake_id}')", + "errors": [ + "HTTPException(status_code=503, detail={'message': 'Townlight Permitting intake persistence is not configured.', 'fix': 'Set TOWNLIGHT_PERMITTING_INTAKE_DB_URL to retrieve persisted intake review records.'})", + "HTTPException(status_code=404, detail={'message': 'Permit intake record not found.', 'fix': 'Use an intake_id returned by POST /api/v1/townlight_permitting/intake/review.'})" + ] + }, + { + "method": "POST", + "path": "/api/v1/townlight_permitting/submittal/outline", + "router": "app", + "prefix_resolved": true, + "name": "submittal_outline", + "signature": "request: SubmittalOutlineRequest", + "returns": "dict[str, object]", + "line": 411, + "doc": "", + "decorator": "app.post('/api/v1/townlight_permitting/submittal/outline')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_permitting/export", + "router": "app", + "prefix_resolved": true, + "name": "permit_export", + "signature": "request: PermitExportRequest", + "returns": "dict[str, object]", + "line": 421, + "doc": "", + "decorator": "app.post('/api/v1/townlight_permitting/export')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_permitting/staff/reviews", + "router": "app", + "prefix_resolved": true, + "name": "create_staff_review", + "signature": "request: StaffReviewCreateRequest, x_townlight_permitting_role: Annotated[str | None, Header()]=None, x_townlight_permitting_staff_key: Annotated[str | None, Header()]=None", + "returns": "dict[str, object]", + "line": 431, + "doc": "", + "decorator": "app.post('/api/v1/townlight_permitting/staff/reviews')", + "errors": [] + }, + { + "method": "GET", + "path": "/api/v1/townlight_permitting/staff/reviews", + "router": "app", + "prefix_resolved": true, + "name": "list_staff_reviews", + "signature": "status: str | None=None, x_townlight_permitting_role: Annotated[str | None, Header()]=None, x_townlight_permitting_staff_key: Annotated[str | None, Header()]=None", + "returns": "dict[str, object]", + "line": 449, + "doc": "", + "decorator": "app.get('/api/v1/townlight_permitting/staff/reviews')", + "errors": [] + }, + { + "method": "PATCH", + "path": "/api/v1/townlight_permitting/staff/reviews/{review_id}", + "router": "app", + "prefix_resolved": true, + "name": "update_staff_review", + "signature": "review_id: str, request: StaffReviewUpdateRequest, x_townlight_permitting_role: Annotated[str | None, Header()]=None, x_townlight_permitting_staff_key: Annotated[str | None, Header()]=None", + "returns": "dict[str, object]", + "line": 466, + "doc": "", + "decorator": "app.patch('/api/v1/townlight_permitting/staff/reviews/{review_id}')", + "errors": [ + "HTTPException(status_code=404, detail={'message': 'Townlight Permitting staff review item was not found.', 'fix': 'List staff reviews and retry with an existing review_id.'})", + "HTTPException(status_code=422, detail={'message': 'Staff review update is invalid.', 'fix': str(exc)})" + ] + }, + { + "method": "GET", + "path": "/api/v1/townlight_permitting/staff/reviews/summary", + "router": "app", + "prefix_resolved": true, + "name": "staff_review_summary", + "signature": "x_townlight_permitting_role: Annotated[str | None, Header()]=None, x_townlight_permitting_staff_key: Annotated[str | None, Header()]=None", + "returns": "dict[str, object]", + "line": 498, + "doc": "", + "decorator": "app.get('/api/v1/townlight_permitting/staff/reviews/summary')", + "errors": [] + } + ], + "models": [ + { + "name": "RequirementLookupRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "project_type", + "type": "str", + "default": "Field(min_length=1, max_length=255)" + }, + { + "name": "location_context", + "type": "str", + "default": "Field(default='', max_length=500)" + } + ], + "line": 45, + "doc": "" + }, + { + "name": "IntakeReviewRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "proposal", + "type": "str", + "default": "Field(min_length=1, max_length=5000)" + }, + { + "name": "project_type", + "type": "str", + "default": "Field(min_length=1, max_length=255)" + } + ], + "line": 50, + "doc": "" + }, + { + "name": "DevelopmentReviewContextRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "project_type", + "type": "str", + "default": "Field(min_length=1, max_length=255)" + }, + { + "name": "proposal", + "type": "str", + "default": "Field(min_length=1, max_length=5000)" + }, + { + "name": "location_context", + "type": "str", + "default": "Field(default='', max_length=500)" + }, + { + "name": "zoning_context_id", + "type": "str | None", + "default": "Field(default=None, max_length=160)" + }, + { + "name": "code_context_id", + "type": "str | None", + "default": "Field(default=None, max_length=160)" + } + ], + "line": 55, + "doc": "" + }, + { + "name": "SubmittalOutlineRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "project_name", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + }, + { + "name": "proposal", + "type": "str", + "default": "Field(min_length=1, max_length=5000)" + }, + { + "name": "project_type", + "type": "str", + "default": "Field(min_length=1, max_length=255)" + } + ], + "line": 65, + "doc": "" + }, + { + "name": "PermitExportRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "title", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + }, + { + "name": "project_type", + "type": "str", + "default": "Field(min_length=1, max_length=255)" + }, + { + "name": "format", + "type": "str", + "default": "Field(default='markdown', min_length=1, max_length=40)" + } + ], + "line": 71, + "doc": "" + }, + { + "name": "StaffReviewCreateRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "proposal", + "type": "str", + "default": "Field(min_length=1, max_length=5000)" + }, + { + "name": "project_type", + "type": "str", + "default": "Field(min_length=1, max_length=255)" + }, + { + "name": "reason", + "type": "str", + "default": "Field(min_length=1, max_length=1000)" + }, + { + "name": "intake_id", + "type": "str | None", + "default": "Field(default=None, max_length=36)" + } + ], + "line": 77, + "doc": "" + }, + { + "name": "StaffReviewUpdateRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "status", + "type": "str", + "default": "Field(min_length=1, max_length=80)" + }, + { + "name": "assigned_to", + "type": "str | None", + "default": "Field(default=None, max_length=255)" + }, + { + "name": "resolution", + "type": "str | None", + "default": "Field(default=None, max_length=2000)" + } + ], + "line": 84, + "doc": "" + }, + { + "name": "PathwayRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "project_type", + "type": "str", + "default": "Field(min_length=1, max_length=255)" + }, + { + "name": "proposal", + "type": "str", + "default": "Field(default='', max_length=5000)" + }, + { + "name": "location_context", + "type": "str", + "default": "Field(default='', max_length=500)" + }, + { + "name": "use_model_assistance", + "type": "bool", + "default": "Field(default=False)" + } + ], + "line": 90, + "doc": "" + }, + { + "name": "IntegrationMockRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "scenario", + "type": "str", + "default": "Field(default='development-review-context', max_length=160)" + } + ], + "line": 97, + "doc": "" + } + ], + "configuration": [ + { + "variable": "TOWNLIGHT_PERMITTING_INTAKE_DB_URL", + "default": "", + "line": 508 + }, + { + "variable": "TOWNLIGHT_PERMITTING_LLM_MODEL", + "default": "", + "line": 233 + }, + { + "variable": "TOWNLIGHT_PERMITTING_LLM_PROVIDER", + "default": "''", + "line": 218 + } + ] + }, + { + "source": "installed-owned-source/townlight_permitting/migrations/__init__.py", + "sha256": "01c6b95137260717ee792116a0479392b3f2da330542c55dbd181c4a93d404a3", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_permitting/migrations/env.py", + "sha256": "91715ad26e140d1b25b30ad38b3418d36ea63da4a195348aa5fe621c99edbe5e", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_permitting/migrations/versions/townlight_permitting_0001_connected.py", + "sha256": "e3fc90959836887334b429888407537140fa2d119c202886b63c538feb4e9360", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_permitting/pathway.py", + "sha256": "b1e311809d61f4efab043c681efa9d711d5bf4bf76b5f33f808c1769e3687d08", + "routes": [], + "models": [ + { + "name": "AssistantProvider", + "bases": [ + "Protocol" + ], + "fields": [ + { + "name": "name", + "type": "str", + "default": "" + } + ], + "line": 74, + "doc": "Structural type of the townlight_core LLM provider used for the explainer." + }, + { + "name": "PathwayStage", + "bases": [], + "fields": [ + { + "name": "key", + "type": "str", + "default": "" + }, + { + "name": "label", + "type": "str", + "default": "" + }, + { + "name": "source_id", + "type": "str", + "default": "" + }, + { + "name": "typical_time", + "type": "str", + "default": "" + } + ], + "line": 91, + "doc": "A cited step in the pre-application pathway.\n\n``source_id`` is resolved through the configured public source providers;\nthe displayed citation and text are copied from the resolved source so the\npathway can never show a citation that does not exist." + }, + { + "name": "Pathway", + "bases": [], + "fields": [ + { + "name": "project_type", + "type": "str", + "default": "" + }, + { + "name": "title", + "type": "str", + "default": "" + }, + { + "name": "stages", + "type": "tuple[PathwayStage, ...]", + "default": "" + }, + { + "name": "attachments_citation", + "type": "str", + "default": "" + }, + { + "name": "attachments", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "note", + "type": "str", + "default": "''" + } + ], + "line": 106, + "doc": "" + }, + { + "name": "PathwayExplanation", + "bases": [], + "fields": [ + { + "name": "project_type", + "type": "str", + "default": "" + }, + { + "name": "title", + "type": "str", + "default": "" + }, + { + "name": "likely_permits", + "type": "list[dict[str, str]]", + "default": "field(default_factory=list)" + }, + { + "name": "attachments", + "type": "list[dict[str, str]]", + "default": "field(default_factory=list)" + }, + { + "name": "timeline", + "type": "list[dict[str, str]]", + "default": "field(default_factory=list)" + }, + { + "name": "unavailable", + "type": "list[dict[str, str]]", + "default": "field(default_factory=list)" + }, + { + "name": "fee", + "type": "dict[str, object]", + "default": "field(default_factory=dict)" + }, + { + "name": "resident_explanation", + "type": "str", + "default": "''" + }, + { + "name": "assistance", + "type": "dict[str, object]", + "default": "field(default_factory=dict)" + }, + { + "name": "review_required", + "type": "bool", + "default": "True" + }, + { + "name": "determination_made", + "type": "bool", + "default": "False" + }, + { + "name": "citations", + "type": "list[str]", + "default": "field(default_factory=list)" + }, + { + "name": "boundary", + "type": "str", + "default": "BOUNDARY" + }, + { + "name": "disclaimer", + "type": "str", + "default": "DISCLAIMER" + } + ], + "line": 132, + "doc": "Assembled, citation-checked pre-application explanation." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_permitting/persistence.py", + "sha256": "cea7301cde02497e65601351e58100b3211cf79e85e3036f251107f7d21fe95b", + "routes": [], + "models": [ + { + "name": "StoredIntakeReview", + "bases": [], + "fields": [ + { + "name": "intake_id", + "type": "str", + "default": "" + }, + { + "name": "project_type", + "type": "str", + "default": "" + }, + { + "name": "proposal", + "type": "str", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "missing_or_unclear", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "next_step", + "type": "str", + "default": "" + }, + { + "name": "disclaimer", + "type": "str", + "default": "" + }, + { + "name": "created_at", + "type": "datetime", + "default": "" + } + ], + "line": 72, + "doc": "" + }, + { + "name": "StaffReviewQueueItem", + "bases": [], + "fields": [ + { + "name": "review_id", + "type": "str", + "default": "" + }, + { + "name": "intake_id", + "type": "str | None", + "default": "" + }, + { + "name": "project_type", + "type": "str", + "default": "" + }, + { + "name": "proposal", + "type": "str", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "reason", + "type": "str", + "default": "" + }, + { + "name": "assigned_to", + "type": "str | None", + "default": "" + }, + { + "name": "resolution", + "type": "str | None", + "default": "" + }, + { + "name": "created_by", + "type": "str", + "default": "" + }, + { + "name": "created_at", + "type": "datetime", + "default": "" + }, + { + "name": "updated_at", + "type": "datetime", + "default": "" + }, + { + "name": "visibility", + "type": "str", + "default": "'staff_only'" + } + ], + "line": 84, + "doc": "" + }, + { + "name": "StaffReviewSummary", + "bases": [], + "fields": [ + { + "name": "total_items", + "type": "int", + "default": "" + }, + { + "name": "by_status", + "type": "dict[str, int]", + "default": "" + }, + { + "name": "open_items", + "type": "int", + "default": "" + }, + { + "name": "generated_at", + "type": "datetime", + "default": "" + }, + { + "name": "visibility", + "type": "str", + "default": "'staff_only'" + } + ], + "line": 100, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_permitting/public_ui.py", + "sha256": "0f06685bd18b171987cc08413bc930112f400a03468c0f27e98badba6b732f29", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_permitting/records_export.py", + "sha256": "231801e8bd30b92f0fe6aeb0a8f2aed2d5097acae5f2cc5eda2e18f9c9a1fae8", + "routes": [], + "models": [ + { + "name": "PermitExport", + "bases": [], + "fields": [ + { + "name": "title", + "type": "str", + "default": "" + }, + { + "name": "project_type", + "type": "str", + "default": "" + }, + { + "name": "format", + "type": "str", + "default": "" + }, + { + "name": "checklist", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "retention_note", + "type": "str", + "default": "" + } + ], + "line": 11, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_permitting/requirement_lookup.py", + "sha256": "f9a1fbd111096e7d4c00cc6cb7f25b9cf91af522f26c743f86234a0ecffe783c", + "routes": [], + "models": [ + { + "name": "PermitRequirement", + "bases": [], + "fields": [ + { + "name": "requirement_id", + "type": "str", + "default": "" + }, + { + "name": "project_type", + "type": "str", + "default": "" + }, + { + "name": "title", + "type": "str", + "default": "" + }, + { + "name": "citation", + "type": "str", + "default": "" + }, + { + "name": "required_materials", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "staff_note", + "type": "str", + "default": "" + }, + { + "name": "disclaimer", + "type": "str", + "default": "DISCLAIMER" + } + ], + "line": 16, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_permitting/sources.py", + "sha256": "8e26b8c98635689f985e14d57a0137f6538145c50414da918ba0cb41a7f489a3", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_permitting/submittal_outline.py", + "sha256": "f6465de3058d51bb47b7d278e10b67a2ac1ac46aeefa2563eabd041dcb54aae1", + "routes": [], + "models": [ + { + "name": "SubmittalOutline", + "bases": [], + "fields": [ + { + "name": "project_name", + "type": "str", + "default": "" + }, + { + "name": "heading", + "type": "str", + "default": "" + }, + { + "name": "required_materials", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "applicant_message", + "type": "str", + "default": "" + }, + { + "name": "review_required", + "type": "bool", + "default": "" + }, + { + "name": "disclaimer", + "type": "str", + "default": "DISCLAIMER" + } + ], + "line": 12, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_permitting/workflow_models.py", + "sha256": "3d09f3ae137c5c48091e22a60a3e732ea3ec299236778d377df55807bb8bbfdd", + "routes": [], + "models": [ + { + "name": "Material", + "bases": [ + "Model" + ], + "fields": [ + { + "name": "material_id", + "type": "str", + "default": "Field(pattern='^[a-zA-Z0-9_-]{1,80}$')" + }, + { + "name": "description", + "type": "str", + "default": "Field(min_length=1, max_length=2000)" + }, + { + "name": "citation", + "type": "str", + "default": "Field(min_length=1, max_length=1000)" + } + ], + "line": 20, + "doc": "" + }, + { + "name": "PathwayStep", + "bases": [ + "Model" + ], + "fields": [ + { + "name": "step", + "type": "str", + "default": "Field(min_length=1, max_length=2000)" + }, + { + "name": "citation", + "type": "str", + "default": "Field(min_length=1, max_length=1000)" + }, + { + "name": "typical_time", + "type": "str", + "default": "Field(default='', max_length=1000)" + } + ], + "line": 26, + "doc": "" + }, + { + "name": "SourceLink", + "bases": [ + "Model" + ], + "fields": [ + { + "name": "provider", + "type": "Literal['code', 'zoning']", + "default": "" + }, + { + "name": "source_id", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + }, + { + "name": "expected_sha256", + "type": "str", + "default": "Field(pattern='^[a-f0-9]{64}$')" + } + ], + "line": 32, + "doc": "" + }, + { + "name": "RequirementBundle", + "bases": [ + "Model" + ], + "fields": [ + { + "name": "requirement_id", + "type": "str", + "default": "Field(pattern='^[a-zA-Z0-9_-]{1,100}$')" + }, + { + "name": "title", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + }, + { + "name": "jurisdiction", + "type": "str", + "default": "Field(min_length=1, max_length=255)" + }, + { + "name": "project_type", + "type": "str", + "default": "Field(min_length=1, max_length=255)" + }, + { + "name": "source_reference", + "type": "str", + "default": "Field(min_length=1, max_length=1000)" + }, + { + "name": "source_date", + "type": "date", + "default": "" + }, + { + "name": "effective_on", + "type": "date", + "default": "" + }, + { + "name": "dataset_kind", + "type": "Literal['municipal', 'fictional']", + "default": "" + }, + { + "name": "filename", + "type": "str", + "default": "Field(pattern='^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$')" + }, + { + "name": "content_base64", + "type": "str", + "default": "Field(min_length=1, max_length=14000000)" + }, + { + "name": "sha256", + "type": "str", + "default": "Field(pattern='^[a-f0-9]{64}$')" + }, + { + "name": "materials", + "type": "list[Material]", + "default": "Field(min_length=1, max_length=100)" + }, + { + "name": "pathway", + "type": "list[PathwayStep]", + "default": "Field(default_factory=list, max_length=100)" + }, + { + "name": "fee_link", + "type": "SourceLink | None", + "default": "None" + }, + { + "name": "staff_note", + "type": "str", + "default": "Field(default='', max_length=4000)" + }, + { + "name": "change_note", + "type": "str", + "default": "Field(min_length=1, max_length=2000)" + } + ], + "line": 38, + "doc": "" + }, + { + "name": "MaterialReview", + "bases": [ + "Model" + ], + "fields": [ + { + "name": "material_id", + "type": "str", + "default": "Field(min_length=1, max_length=80)" + }, + { + "name": "status", + "type": "Literal['not_reviewed', 'provided', 'missing', 'unclear']", + "default": "'not_reviewed'" + }, + { + "name": "note", + "type": "str", + "default": "Field(default='', max_length=2000)" + } + ], + "line": 70, + "doc": "" + }, + { + "name": "IntakeInput", + "bases": [ + "Model" + ], + "fields": [ + { + "name": "expected_revision", + "type": "UUID | None", + "default": "None" + }, + { + "name": "project_name", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + }, + { + "name": "project_description", + "type": "str", + "default": "Field(min_length=1, max_length=10000)" + }, + { + "name": "location", + "type": "str", + "default": "Field(min_length=1, max_length=1000)" + }, + { + "name": "applicant_contact", + "type": "str", + "default": "Field(default='', max_length=2000)" + }, + { + "name": "requirement_revision", + "type": "UUID", + "default": "" + }, + { + "name": "materials", + "type": "list[MaterialReview]", + "default": "Field(min_length=1, max_length=100)" + }, + { + "name": "linked_sources", + "type": "list[SourceLink]", + "default": "Field(default_factory=list, max_length=30)" + }, + { + "name": "staff_notes", + "type": "str", + "default": "Field(default='', max_length=10000)" + }, + { + "name": "assigned_to", + "type": "str", + "default": "Field(default='', max_length=255)" + }, + { + "name": "review_state", + "type": "Literal['draft', 'follow_up', 'reviewed']", + "default": "'draft'" + }, + { + "name": "review_notes", + "type": "str", + "default": "Field(default='', max_length=4000)" + }, + { + "name": "public_summary", + "type": "str", + "default": "Field(default='', max_length=10000)" + } + ], + "line": 76, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_permitting/workflow_schema.py", + "sha256": "07dfc3dfafd5131ffee8b087add38fd7ebf446c2cf104100920636e732aaee59", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_permitting/workflow_store.py", + "sha256": "c3415dd94aaed609a593d28b60d0719f2dc1a504a5f15391d9708714038ea259", + "routes": [], + "models": [], + "configuration": [] + } + ], + "bridge": [ + { + "source": "installed-owned-source/townlight_runtime/permitting_bridge.py", + "sha256": "786abd0dfc18ed0ce7ada70fcd120f96795d8e1ee46f38ca0770a8217b4d6e1d", + "routes": [ + { + "method": "POST", + "path": "/desktop/v1/permitting/requirements", + "router": "router", + "prefix_resolved": true, + "name": "import_requirements", + "signature": "request: Request, body: Import, identity=Depends(actor)", + "returns": "", + "line": 85, + "doc": "", + "decorator": "router.post('/requirements')", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/permitting/requirements", + "router": "router", + "prefix_resolved": true, + "name": "requirements", + "signature": "request: Request, offset: int=Query(0, ge=0, le=100000), identity=Depends(actor)", + "returns": "", + "line": 91, + "doc": "", + "decorator": "router.get('/requirements')", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/permitting/requirements/{revision_id}", + "router": "router", + "prefix_resolved": true, + "name": "requirement", + "signature": "request: Request, revision_id: UUID, identity=Depends(actor)", + "returns": "", + "line": 96, + "doc": "", + "decorator": "router.get('/requirements/{revision_id}')", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/permitting/cases", + "router": "router", + "prefix_resolved": true, + "name": "cases", + "signature": "request: Request, offset: int=Query(0, ge=0, le=100000), identity=Depends(actor)", + "returns": "", + "line": 101, + "doc": "", + "decorator": "router.get('/cases')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/permitting/cases", + "router": "router", + "prefix_resolved": true, + "name": "create_case", + "signature": "request: Request, body: IntakeInput, identity=Depends(actor)", + "returns": "", + "line": 106, + "doc": "", + "decorator": "router.post('/cases')", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/permitting/cases/{case_id}", + "router": "router", + "prefix_resolved": true, + "name": "case", + "signature": "request: Request, case_id: UUID, identity=Depends(actor)", + "returns": "", + "line": 111, + "doc": "", + "decorator": "router.get('/cases/{case_id}')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/permitting/cases/{case_id}/revisions", + "router": "router", + "prefix_resolved": true, + "name": "revise", + "signature": "request: Request, case_id: UUID, body: IntakeInput, identity=Depends(actor)", + "returns": "", + "line": 116, + "doc": "", + "decorator": "router.post('/cases/{case_id}/revisions')", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/permitting/cases/{case_id}/history", + "router": "router", + "prefix_resolved": true, + "name": "history", + "signature": "request: Request, case_id: UUID, identity=Depends(actor)", + "returns": "", + "line": 121, + "doc": "", + "decorator": "router.get('/cases/{case_id}/history')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/permitting/cases/{case_id}/packets", + "router": "router", + "prefix_resolved": true, + "name": "packet", + "signature": "request: Request, case_id: UUID, body: Packet, identity=Depends(actor)", + "returns": "", + "line": 131, + "doc": "", + "decorator": "router.post('/cases/{case_id}/packets')", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/permitting/packets/{packet_id}", + "router": "router", + "prefix_resolved": true, + "name": "document", + "signature": "request: Request, packet_id: UUID, identity=Depends(actor)", + "returns": "", + "line": 136, + "doc": "", + "decorator": "router.get('/packets/{packet_id}')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/permitting/pathway", + "router": "router", + "prefix_resolved": true, + "name": "pathway", + "signature": "request: Request, body: Pathway, identity=Depends(actor)", + "returns": "", + "line": 149, + "doc": "Cited likely permit pathway, attachments and timeline; informational only.\n\n``use_model_assistance`` does not exist here: the resident live-model\nassistance flag (F-07) stays excluded, so only the deterministic cited\npathway is reachable from the shared shell.", + "decorator": "router.post('/pathway')", + "errors": [ + "HTTPException(503, f'Configured public permit sources unavailable: {exc}')" + ] + }, + { + "method": "POST", + "path": "/desktop/v1/permitting/connections/search", + "router": "router", + "prefix_resolved": true, + "name": "connections", + "signature": "request: Request, body: Search, identity=Depends(actor)", + "returns": "", + "line": 199, + "doc": "", + "decorator": "router.post('/connections/search')", + "errors": [] + } + ], + "models": [ + { + "name": "Import", + "bases": [ + "Model" + ], + "fields": [ + { + "name": "bundle", + "type": "RequirementBundle", + "default": "" + }, + { + "name": "expected_revision", + "type": "UUID | None", + "default": "None" + } + ], + "line": 79, + "doc": "" + }, + { + "name": "Packet", + "bases": [ + "Model" + ], + "fields": [ + { + "name": "expected_revision", + "type": "UUID", + "default": "" + }, + { + "name": "visibility", + "type": "Literal['staff_only', 'records_copy']", + "default": "" + } + ], + "line": 125, + "doc": "" + }, + { + "name": "Pathway", + "bases": [ + "Model" + ], + "fields": [ + { + "name": "project_type", + "type": "str", + "default": "Field(min_length=1, max_length=120)" + }, + { + "name": "proposal", + "type": "str", + "default": "Field(default='', max_length=4000)" + }, + { + "name": "location_context", + "type": "str", + "default": "Field(default='', max_length=1000)" + }, + { + "name": "requirement_revision", + "type": "UUID | None", + "default": "None" + }, + { + "name": "fee_link", + "type": "SourceLink | None", + "default": "None" + } + ], + "line": 140, + "doc": "" + }, + { + "name": "Search", + "bases": [ + "Model" + ], + "fields": [ + { + "name": "provider", + "type": "Literal['code', 'zoning']", + "default": "" + }, + { + "name": "query", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + } + ], + "line": 193, + "doc": "" + } + ], + "configuration": [] + } + ] + }, + "inspections": { + "package": "townlight_inspections", + "source": [ + { + "source": "installed-owned-source/townlight_inspections/__init__.py", + "sha256": "eff685acecf3985653f811403aaabc6862d52ce7e343c38aa5242f40d4266c47", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_inspections/_whistle_driver.py", + "sha256": "90ce9276c7d1de4d3259a2c00ff581e5d55d28dd8da913ed7b8bd2d7c89a5264", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_inspections/adapters.py", + "sha256": "ab76d8c1a8b57167acf759390b49a3941f04b4483a606be2abbae69f4f8165db", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_inspections/case_lookup.py", + "sha256": "b68030ecdf6a7f83ed35aec636afcb70c5ce247a40ed7d60a3283655bfdb3214", + "routes": [], + "models": [ + { + "name": "RepeatCaseResult", + "bases": [], + "fields": [ + { + "name": "property_reference", + "type": "str", + "default": "" + }, + { + "name": "violation_type", + "type": "str", + "default": "" + }, + { + "name": "repeat_case_count", + "type": "int", + "default": "" + }, + { + "name": "related_case_ids", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "staff_note", + "type": "str", + "default": "" + }, + { + "name": "disclaimer", + "type": "str", + "default": "DISCLAIMER" + } + ], + "line": 15, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_inspections/connections.py", + "sha256": "82221673e19e1bd48215cfc9dbeab837070cd9a6bdd3f3cf57cf3034f3ac3bef", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_inspections/integration_mocks.py", + "sha256": "dfc700d977badb104db5abddded3120b1bff99445a6bbf18f7a6925c9087c797", + "routes": [], + "models": [ + { + "name": "IntegrationMockResult", + "bases": [], + "fields": [ + { + "name": "scenario", + "type": "str", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "review_required", + "type": "bool", + "default": "" + }, + { + "name": "findings", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "boundary", + "type": "str", + "default": "" + } + ], + "line": 10, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_inspections/main.py", + "sha256": "16306b47d0e6e526176c050b2eb2edb6a047edea3bb5f313df48c026a81cc53e", + "routes": [ + { + "method": "GET", + "path": "/", + "router": "app", + "prefix_resolved": true, + "name": "root", + "signature": "", + "returns": "dict[str, str]", + "line": 130, + "doc": "Return current product state without overstating unshipped behavior.", + "decorator": "app.get('/')", + "errors": [] + }, + { + "method": "GET", + "path": "/health", + "router": "app", + "prefix_resolved": true, + "name": "health", + "signature": "", + "returns": "dict[str, str]", + "line": 150, + "doc": "Return dependency/version health for deployment smoke checks.", + "decorator": "app.get('/health')", + "errors": [] + }, + { + "method": "GET", + "path": "/townlight_inspections", + "router": "app", + "prefix_resolved": true, + "name": "public_townlight_inspections_page", + "signature": "", + "returns": "str", + "line": 162, + "doc": "Return the public sample inspection support UI.", + "decorator": "app.get('/townlight_inspections', response_class=HTMLResponse)", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_inspections/cases/repeat-lookup", + "router": "app", + "prefix_resolved": true, + "name": "repeat_case_lookup", + "signature": "request: RepeatCaseLookupRequest", + "returns": "dict[str, object]", + "line": 169, + "doc": "", + "decorator": "app.post('/api/v1/townlight_inspections/cases/repeat-lookup')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_inspections/reports/draft", + "router": "app", + "prefix_resolved": true, + "name": "inspection_report_draft", + "signature": "request: ReportDraftRequest", + "returns": "dict[str, object]", + "line": 178, + "doc": "", + "decorator": "app.post('/api/v1/townlight_inspections/reports/draft')", + "errors": [] + }, + { + "method": "GET", + "path": "/api/v1/townlight_inspections/reports/{report_id}", + "router": "app", + "prefix_resolved": true, + "name": "get_inspection_report", + "signature": "report_id: str", + "returns": "dict[str, object]", + "line": 215, + "doc": "", + "decorator": "app.get('/api/v1/townlight_inspections/reports/{report_id}')", + "errors": [ + "HTTPException(status_code=503, detail={'message': 'Townlight Inspections case persistence is not configured.', 'fix': 'Set TOWNLIGHT_INSPECTIONS_CASE_DB_URL to retrieve persisted inspection report records.'})", + "HTTPException(status_code=404, detail={'message': 'Inspection report record not found.', 'fix': 'Use a report_id returned by POST /api/v1/townlight_inspections/reports/draft.'})" + ] + }, + { + "method": "POST", + "path": "/api/v1/townlight_inspections/evidence/retain", + "router": "app", + "prefix_resolved": true, + "name": "retain_evidence_route", + "signature": "request: EvidenceRetainRequest", + "returns": "dict[str, object]", + "line": 291, + "doc": "Retain original evidence bytes (photos, documents and raw audio) with hashes.", + "decorator": "app.post('/api/v1/townlight_inspections/evidence/retain')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_inspections/media/analyse", + "router": "app", + "prefix_resolved": true, + "name": "media_analyse", + "signature": "request: MediaAnalysisRequest", + "returns": "dict[str, object]", + "line": 307, + "doc": "Draft-only analysis of retained media; inspector review always required.", + "decorator": "app.post('/api/v1/townlight_inspections/media/analyse')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_inspections/notices/draft", + "router": "app", + "prefix_resolved": true, + "name": "notice_draft", + "signature": "request: NoticeDraftRequest", + "returns": "dict[str, object]", + "line": 325, + "doc": "", + "decorator": "app.post('/api/v1/townlight_inspections/notices/draft')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_inspections/context/inspection-review", + "router": "app", + "prefix_resolved": true, + "name": "inspection_review_context", + "signature": "request: InspectionContextRequest", + "returns": "dict[str, object]", + "line": 336, + "doc": "", + "decorator": "app.post('/api/v1/townlight_inspections/context/inspection-review')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_inspections/integrations/mock/inspection-context", + "router": "app", + "prefix_resolved": true, + "name": "integration_mock_inspection_context", + "signature": "request: IntegrationMockRequest", + "returns": "dict[str, object]", + "line": 365, + "doc": "", + "decorator": "app.post('/api/v1/townlight_inspections/integrations/mock/inspection-context')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_inspections/export", + "router": "app", + "prefix_resolved": true, + "name": "inspection_export", + "signature": "request: InspectionExportRequest", + "returns": "dict[str, object]", + "line": 377, + "doc": "", + "decorator": "app.post('/api/v1/townlight_inspections/export')", + "errors": [] + }, + { + "method": "POST", + "path": "/api/v1/townlight_inspections/staff/reviews", + "router": "app", + "prefix_resolved": true, + "name": "create_staff_review", + "signature": "request: StaffReviewCreateRequest, _staff_principal: object=Depends(_require_staff_key)", + "returns": "dict[str, object]", + "line": 387, + "doc": "", + "decorator": "app.post('/api/v1/townlight_inspections/staff/reviews')", + "errors": [] + }, + { + "method": "GET", + "path": "/api/v1/townlight_inspections/staff/reviews", + "router": "app", + "prefix_resolved": true, + "name": "list_staff_reviews", + "signature": "status: str | None=None, _staff_principal: object=Depends(_require_staff_key)", + "returns": "dict[str, object]", + "line": 403, + "doc": "", + "decorator": "app.get('/api/v1/townlight_inspections/staff/reviews')", + "errors": [] + }, + { + "method": "PATCH", + "path": "/api/v1/townlight_inspections/staff/reviews/{review_id}", + "router": "app", + "prefix_resolved": true, + "name": "update_staff_review", + "signature": "review_id: str, request: StaffReviewUpdateRequest, _staff_principal: object=Depends(_require_staff_key)", + "returns": "dict[str, object]", + "line": 418, + "doc": "", + "decorator": "app.patch('/api/v1/townlight_inspections/staff/reviews/{review_id}')", + "errors": [ + "HTTPException(status_code=404, detail={'message': 'Townlight Inspections staff review item was not found.', 'fix': 'List staff reviews and retry with an existing review_id.'})", + "HTTPException(status_code=422, detail={'message': 'Staff review update is invalid.', 'fix': str(exc)})" + ] + }, + { + "method": "GET", + "path": "/api/v1/townlight_inspections/staff/reviews/summary", + "router": "app", + "prefix_resolved": true, + "name": "staff_review_summary", + "signature": "_staff_principal: object=Depends(_require_staff_key)", + "returns": "dict[str, object]", + "line": 448, + "doc": "", + "decorator": "app.get('/api/v1/townlight_inspections/staff/reviews/summary')", + "errors": [] + } + ], + "models": [ + { + "name": "RepeatCaseLookupRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "property_reference", + "type": "str", + "default": "" + }, + { + "name": "violation_type", + "type": "str", + "default": "''" + } + ], + "line": 50, + "doc": "" + }, + { + "name": "ReportDraftRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "inspection_id", + "type": "str", + "default": "" + }, + { + "name": "property_reference", + "type": "str", + "default": "" + }, + { + "name": "inspector_notes", + "type": "str", + "default": "" + }, + { + "name": "photo_observations", + "type": "list[str]", + "default": "[]" + }, + { + "name": "voice_notes", + "type": "str", + "default": "''" + }, + { + "name": "analysis", + "type": "AnalysisRecord | None", + "default": "None" + } + ], + "line": 55, + "doc": "" + }, + { + "name": "NoticeDraftRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "case_id", + "type": "str", + "default": "" + }, + { + "name": "property_reference", + "type": "str", + "default": "" + }, + { + "name": "violation_type", + "type": "str", + "default": "" + }, + { + "name": "observations", + "type": "list[str]", + "default": "" + } + ], + "line": 64, + "doc": "" + }, + { + "name": "InspectionExportRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "title", + "type": "str", + "default": "" + }, + { + "name": "case_id", + "type": "str", + "default": "" + }, + { + "name": "format", + "type": "str", + "default": "'markdown'" + } + ], + "line": 71, + "doc": "" + }, + { + "name": "InspectionContextRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "inspection_id", + "type": "str", + "default": "" + }, + { + "name": "property_reference", + "type": "str", + "default": "" + }, + { + "name": "violation_type", + "type": "str", + "default": "" + }, + { + "name": "code_context_id", + "type": "str", + "default": "''" + }, + { + "name": "case_context_id", + "type": "str", + "default": "''" + }, + { + "name": "source_date_status", + "type": "str", + "default": "'current'" + } + ], + "line": 77, + "doc": "" + }, + { + "name": "IntegrationMockRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "scenario", + "type": "str", + "default": "'inspection-context'" + }, + { + "name": "role", + "type": "str", + "default": "'staff'" + }, + { + "name": "code_context_id", + "type": "str", + "default": "''" + }, + { + "name": "case_context_id", + "type": "str", + "default": "''" + }, + { + "name": "official_finding", + "type": "bool", + "default": "False" + }, + { + "name": "citation_issued", + "type": "bool", + "default": "False" + }, + { + "name": "fine_amount", + "type": "str | None", + "default": "None" + }, + { + "name": "photo_analysis_source", + "type": "str", + "default": "'inspector_observation'" + }, + { + "name": "source_date_status", + "type": "str", + "default": "'current'" + } + ], + "line": 86, + "doc": "" + }, + { + "name": "EvidenceItemRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "filename", + "type": "str", + "default": "" + }, + { + "name": "media_type", + "type": "str", + "default": "" + }, + { + "name": "description", + "type": "str", + "default": "''" + }, + { + "name": "content_base64", + "type": "str", + "default": "" + }, + { + "name": "sha256", + "type": "str", + "default": "" + } + ], + "line": 98, + "doc": "" + }, + { + "name": "EvidenceRetainRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "items", + "type": "list[EvidenceItemRequest]", + "default": "" + } + ], + "line": 106, + "doc": "" + }, + { + "name": "MediaAnalysisRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "items", + "type": "list[EvidenceItemRequest]", + "default": "" + }, + { + "name": "code_links", + "type": "list[dict[str, str]]", + "default": "[]" + }, + { + "name": "inspector_supplied_text", + "type": "str", + "default": "''" + } + ], + "line": 110, + "doc": "" + }, + { + "name": "StaffReviewCreateRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "inspection_id", + "type": "str", + "default": "" + }, + { + "name": "property_reference", + "type": "str", + "default": "" + }, + { + "name": "reason", + "type": "str", + "default": "" + }, + { + "name": "report_id", + "type": "str | None", + "default": "None" + } + ], + "line": 116, + "doc": "" + }, + { + "name": "StaffReviewUpdateRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "assigned_to", + "type": "str | None", + "default": "None" + }, + { + "name": "resolution", + "type": "str | None", + "default": "None" + } + ], + "line": 123, + "doc": "" + } + ], + "configuration": [ + { + "variable": "TOWNLIGHT_INSPECTIONS_CASE_DB_URL", + "default": "", + "line": 456 + } + ] + }, + { + "source": "installed-owned-source/townlight_inspections/media_analysis.py", + "sha256": "be51101ee98596bca3055f99136531e3a76e28f2dc584148cf26098d75a94c5a", + "routes": [], + "models": [ + { + "name": "RetainedEvidence", + "bases": [], + "fields": [ + { + "name": "filename", + "type": "str", + "default": "" + }, + { + "name": "media_type", + "type": "str", + "default": "" + }, + { + "name": "description", + "type": "str", + "default": "" + }, + { + "name": "size_bytes", + "type": "int", + "default": "" + }, + { + "name": "sha256", + "type": "str", + "default": "" + }, + { + "name": "raw", + "type": "bytes", + "default": "field(repr=False)" + } + ], + "line": 55, + "doc": "Original evidence bytes with their verified digest and provenance." + }, + { + "name": "VisionProvider", + "bases": [ + "Protocol" + ], + "fields": [ + { + "name": "name", + "type": "str", + "default": "" + }, + { + "name": "supports_images", + "type": "bool", + "default": "" + } + ], + "line": 110, + "doc": "The owned townlight_core provider shape (multimodal generate)." + }, + { + "name": "TranscriptionProvider", + "bases": [ + "Protocol" + ], + "fields": [ + { + "name": "name", + "type": "str", + "default": "" + } + ], + "line": 121, + "doc": "Adapter that turns retained audio bytes into text." + }, + { + "name": "MediaAnalysis", + "bases": [], + "fields": [ + { + "name": "draft_observations", + "type": "list[dict[str, Any]]", + "default": "field(default_factory=list)" + }, + { + "name": "cited_sections", + "type": "list[dict[str, str]]", + "default": "field(default_factory=list)" + }, + { + "name": "unavailable", + "type": "list[dict[str, str]]", + "default": "field(default_factory=list)" + }, + { + "name": "retained", + "type": "list[dict[str, Any]]", + "default": "field(default_factory=list)" + }, + { + "name": "runtime", + "type": "dict[str, Any]", + "default": "field(default_factory=dict)" + }, + { + "name": "review_required", + "type": "bool", + "default": "True" + }, + { + "name": "determination_made", + "type": "bool", + "default": "False" + }, + { + "name": "boundary", + "type": "str", + "default": "BOUNDARY" + } + ], + "line": 139, + "doc": "Result of a draft-only analysis pass." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_inspections/migrations/__init__.py", + "sha256": "e18fc02330135cd7d0dd678a3e17f9e81966a9e187c3ed0ec002439fa8d3bbb1", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_inspections/migrations/env.py", + "sha256": "9612897b28e02e86d1fa5b9ed48d951b76bb5a87151112d0c1cdbe10a0d343e3", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_inspections/migrations/versions/townlight_inspections_0001_connected.py", + "sha256": "0e71ed311993f45634eb42ba22f5c2b2c4a3854639b221857af76f826d1b68de", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_inspections/notice_draft.py", + "sha256": "ef44c7d6bcf131bc703f6d0282510fe8a49cc6b5988f6252d01353e15551a2f6", + "routes": [], + "models": [ + { + "name": "NoticeDraft", + "bases": [], + "fields": [ + { + "name": "case_id", + "type": "str", + "default": "" + }, + { + "name": "property_reference", + "type": "str", + "default": "" + }, + { + "name": "heading", + "type": "str", + "default": "" + }, + { + "name": "draft_body", + "type": "str", + "default": "" + }, + { + "name": "required_staff_actions", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "disclaimer", + "type": "str", + "default": "DISCLAIMER" + } + ], + "line": 11, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_inspections/persistence.py", + "sha256": "a4c75976a7fe2cc25d2c9a9074eee1a2870eb47bcf6890564d2fb31b113579e3", + "routes": [], + "models": [ + { + "name": "StoredInspectionReport", + "bases": [], + "fields": [ + { + "name": "report_id", + "type": "str", + "default": "" + }, + { + "name": "inspection_id", + "type": "str", + "default": "" + }, + { + "name": "property_reference", + "type": "str", + "default": "" + }, + { + "name": "summary", + "type": "str", + "default": "" + }, + { + "name": "observation_bullets", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "inspector_review_required", + "type": "bool", + "default": "" + }, + { + "name": "disclaimer", + "type": "str", + "default": "" + }, + { + "name": "created_at", + "type": "datetime", + "default": "" + } + ], + "line": 70, + "doc": "" + }, + { + "name": "StaffReviewQueueItem", + "bases": [], + "fields": [ + { + "name": "review_id", + "type": "str", + "default": "" + }, + { + "name": "report_id", + "type": "str | None", + "default": "" + }, + { + "name": "inspection_id", + "type": "str", + "default": "" + }, + { + "name": "property_reference", + "type": "str", + "default": "" + }, + { + "name": "status", + "type": "str", + "default": "" + }, + { + "name": "reason", + "type": "str", + "default": "" + }, + { + "name": "assigned_to", + "type": "str | None", + "default": "" + }, + { + "name": "resolution", + "type": "str | None", + "default": "" + }, + { + "name": "created_by", + "type": "str", + "default": "" + }, + { + "name": "created_at", + "type": "datetime", + "default": "" + }, + { + "name": "updated_at", + "type": "datetime", + "default": "" + }, + { + "name": "visibility", + "type": "str", + "default": "'staff_only'" + } + ], + "line": 82, + "doc": "" + }, + { + "name": "StaffReviewSummary", + "bases": [], + "fields": [ + { + "name": "total_items", + "type": "int", + "default": "" + }, + { + "name": "by_status", + "type": "dict[str, int]", + "default": "" + }, + { + "name": "open_items", + "type": "int", + "default": "" + }, + { + "name": "generated_at", + "type": "datetime", + "default": "" + }, + { + "name": "visibility", + "type": "str", + "default": "'staff_only'" + } + ], + "line": 98, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_inspections/public_ui.py", + "sha256": "c14bd5b3d45dc1434edeffb931cd6abb8804bff675989769c8eb89c85a46f965", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_inspections/records_export.py", + "sha256": "6adcb9a04cbff7d9d455f41598a0bdb1dfd736aa13f439a61f1e2ed98f8b49bb", + "routes": [], + "models": [ + { + "name": "InspectionExport", + "bases": [], + "fields": [ + { + "name": "title", + "type": "str", + "default": "" + }, + { + "name": "case_id", + "type": "str", + "default": "" + }, + { + "name": "format", + "type": "str", + "default": "" + }, + { + "name": "checklist", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "retention_note", + "type": "str", + "default": "" + } + ], + "line": 9, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_inspections/report_draft.py", + "sha256": "40faeb3103ac9ba5ae45fd74136d5cff0a96c5fa73acb96f4a16a34d1cb7ebd5", + "routes": [], + "models": [ + { + "name": "InspectionReportDraft", + "bases": [], + "fields": [ + { + "name": "inspection_id", + "type": "str", + "default": "" + }, + { + "name": "property_reference", + "type": "str", + "default": "" + }, + { + "name": "summary", + "type": "str", + "default": "" + }, + { + "name": "observation_bullets", + "type": "tuple[str, ...]", + "default": "" + }, + { + "name": "inspector_review_required", + "type": "bool", + "default": "" + }, + { + "name": "cited_sections", + "type": "tuple[str, ...]", + "default": "()" + }, + { + "name": "disclaimer", + "type": "str", + "default": "DISCLAIMER" + } + ], + "line": 11, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_inspections/transcription.py", + "sha256": "0289536c591fa63b6bfa25512444c4a36edc1f160a93d195d3e5aea9e718289f", + "routes": [], + "models": [], + "configuration": [ + { + "variable": "TOWNLIGHT_INSPECTIONS_FFMPEG", + "default": "", + "line": 53 + }, + { + "variable": "TOWNLIGHT_INSPECTIONS_TEXTFLOWKIT_PYTHON", + "default": "", + "line": 49 + } + ] + }, + { + "source": "installed-owned-source/townlight_inspections/workflow_models.py", + "sha256": "7f61e6c7bde5b79202b562d9183c5558d5504fe19eda9ed8fe52541d92152377", + "routes": [], + "models": [ + { + "name": "AnalysisObservation", + "bases": [ + "Model" + ], + "fields": [ + { + "name": "source", + "type": "str", + "default": "Field(min_length=1, max_length=64)" + }, + { + "name": "filename", + "type": "str", + "default": "Field(default='', max_length=160)" + }, + { + "name": "media_type", + "type": "str", + "default": "Field(default='', max_length=80)" + }, + { + "name": "text", + "type": "str", + "default": "Field(min_length=1, max_length=4000)" + }, + { + "name": "adapter", + "type": "str", + "default": "Field(default='', max_length=120)" + }, + { + "name": "citation_source_ids", + "type": "list[str]", + "default": "Field(default_factory=list, max_length=30)" + } + ], + "line": 23, + "doc": "One draft observation, named with the adapter that actually produced it." + }, + { + "name": "CitedSection", + "bases": [ + "Model" + ], + "fields": [ + { + "name": "source_id", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + }, + { + "name": "citation", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + }, + { + "name": "title", + "type": "str", + "default": "Field(default='', max_length=500)" + }, + { + "name": "version", + "type": "str", + "default": "Field(default='', max_length=80)" + } + ], + "line": 40, + "doc": "One resolved public Code section; never a caller-supplied quotation." + }, + { + "name": "AnalysisRecord", + "bases": [ + "Model" + ], + "fields": [ + { + "name": "observations", + "type": "list[AnalysisObservation]", + "default": "Field(default_factory=list, max_length=30)" + }, + { + "name": "cited_sections", + "type": "list[CitedSection]", + "default": "Field(default_factory=list, max_length=30)" + }, + { + "name": "unavailable", + "type": "list[str]", + "default": "Field(default_factory=list, max_length=30)" + }, + { + "name": "runtime", + "type": "dict", + "default": "Field(default_factory=dict)" + }, + { + "name": "review_required", + "type": "bool", + "default": "True" + } + ], + "line": 49, + "doc": "The adapter output that accompanies a saved inspection draft." + }, + { + "name": "AnalysisRecord", + "bases": [ + "Model" + ], + "fields": [ + { + "name": "observations", + "type": "list[AnalysisObservation]", + "default": "Field(default_factory=list, max_length=30)" + }, + { + "name": "cited_sections", + "type": "list[CitedSection]", + "default": "Field(default_factory=list, max_length=30)" + }, + { + "name": "unavailable", + "type": "list[str]", + "default": "Field(default_factory=list, max_length=30)" + }, + { + "name": "runtime", + "type": "dict", + "default": "Field(default_factory=dict)" + }, + { + "name": "review_required", + "type": "bool", + "default": "True" + } + ], + "line": 74, + "doc": "The adapter output that accompanies a saved inspection draft." + }, + { + "name": "Evidence", + "bases": [ + "Model" + ], + "fields": [ + { + "name": "filename", + "type": "str", + "default": "Field(pattern='^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,150}$')" + }, + { + "name": "description", + "type": "str", + "default": "Field(min_length=1, max_length=2000)" + }, + { + "name": "media_type", + "type": "Literal['text/plain', 'image/jpeg', 'image/png', 'image/webp', 'application/pdf', 'audio/webm', 'audio/ogg', 'audio/wav', 'audio/mpeg', 'audio/mp4']", + "default": "" + }, + { + "name": "content_base64", + "type": "str", + "default": "Field(min_length=1, max_length=14000000)" + }, + { + "name": "sha256", + "type": "str", + "default": "Field(pattern='^[a-f0-9]{64}$')" + } + ], + "line": 118, + "doc": "" + }, + { + "name": "SourceLink", + "bases": [ + "Model" + ], + "fields": [ + { + "name": "provider", + "type": "Literal['code']", + "default": "'code'" + }, + { + "name": "source_id", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + }, + { + "name": "expected_sha256", + "type": "str", + "default": "Field(pattern='^[a-f0-9]{64}$')" + } + ], + "line": 138, + "doc": "" + }, + { + "name": "InspectionInput", + "bases": [ + "Model" + ], + "fields": [ + { + "name": "expected_revision", + "type": "UUID | None", + "default": "None" + }, + { + "name": "title", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + }, + { + "name": "property_reference", + "type": "str", + "default": "Field(min_length=1, max_length=1000)" + }, + { + "name": "inspection_reference", + "type": "str", + "default": "Field(min_length=1, max_length=160)" + }, + { + "name": "dataset_kind", + "type": "Literal['municipal', 'fictional']", + "default": "" + }, + { + "name": "inspector_notes", + "type": "str", + "default": "Field(min_length=1, max_length=10000)" + }, + { + "name": "photo_observations", + "type": "list[str]", + "default": "Field(default_factory=list, max_length=30)" + }, + { + "name": "voice_notes", + "type": "str", + "default": "Field(default='', max_length=10000)" + }, + { + "name": "evidence", + "type": "list[Evidence]", + "default": "Field(default_factory=list, max_length=10)" + }, + { + "name": "linked_sources", + "type": "list[SourceLink]", + "default": "Field(default_factory=list, max_length=30)" + }, + { + "name": "assigned_to", + "type": "str", + "default": "Field(default='', max_length=255)" + }, + { + "name": "staff_notes", + "type": "str", + "default": "Field(default='', max_length=10000)" + }, + { + "name": "notice_draft", + "type": "str", + "default": "Field(default='', max_length=10000)" + }, + { + "name": "review_state", + "type": "Literal['draft', 'follow_up', 'reviewed']", + "default": "'draft'" + }, + { + "name": "review_notes", + "type": "str", + "default": "Field(default='', max_length=4000)" + }, + { + "name": "public_summary", + "type": "str", + "default": "Field(default='', max_length=10000)" + }, + { + "name": "analysis", + "type": "AnalysisRecord | None", + "default": "None" + } + ], + "line": 144, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_inspections/workflow_schema.py", + "sha256": "2f8638e3319939ce8b3f7b0b1ef59013f3344b8bcaf9be7d1ad6f3bd4b30ac68", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_inspections/workflow_store.py", + "sha256": "df4ff48879d5f8fe31d71a410a99ed8c359676ab05a267db65e1468cb4764146", + "routes": [], + "models": [], + "configuration": [] + } + ], + "bridge": [ + { + "source": "installed-owned-source/townlight_runtime/inspections_bridge.py", + "sha256": "b7429c3ab988005a198795d6f1dfc3f785c7f96f61410903f8cb0ad38c6f512c", + "routes": [ + { + "method": "POST", + "path": "/desktop/v1/inspections/repeat-cases", + "router": "router", + "prefix_resolved": true, + "name": "repeat_cases", + "signature": "request: Request, body: RepeatLookup, identity=Depends(actor)", + "returns": "", + "line": 93, + "doc": "", + "decorator": "router.post('/repeat-cases')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/inspections/notice-draft", + "router": "router", + "prefix_resolved": true, + "name": "notice", + "signature": "request: Request, body: InspectionInput, identity=Depends(actor)", + "returns": "", + "line": 98, + "doc": "", + "decorator": "router.post('/notice-draft')", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/inspections/cases", + "router": "router", + "prefix_resolved": true, + "name": "cases", + "signature": "request: Request, offset: int=Query(0, ge=0, le=100000), identity=Depends(actor)", + "returns": "", + "line": 105, + "doc": "", + "decorator": "router.get('/cases')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/inspections/cases", + "router": "router", + "prefix_resolved": true, + "name": "create_case", + "signature": "request: Request, body: InspectionInput, identity=Depends(actor)", + "returns": "", + "line": 110, + "doc": "", + "decorator": "router.post('/cases')", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/inspections/cases/{case_id}", + "router": "router", + "prefix_resolved": true, + "name": "case", + "signature": "request: Request, case_id: UUID, identity=Depends(actor)", + "returns": "", + "line": 115, + "doc": "", + "decorator": "router.get('/cases/{case_id}')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/inspections/cases/{case_id}/revisions", + "router": "router", + "prefix_resolved": true, + "name": "revise", + "signature": "request: Request, case_id: UUID, body: InspectionInput, identity=Depends(actor)", + "returns": "", + "line": 120, + "doc": "", + "decorator": "router.post('/cases/{case_id}/revisions')", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/inspections/cases/{case_id}/history", + "router": "router", + "prefix_resolved": true, + "name": "history", + "signature": "request: Request, case_id: UUID, identity=Depends(actor)", + "returns": "", + "line": 125, + "doc": "", + "decorator": "router.get('/cases/{case_id}/history')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/inspections/cases/{case_id}/packets", + "router": "router", + "prefix_resolved": true, + "name": "packet", + "signature": "request: Request, case_id: UUID, body: Packet, identity=Depends(actor)", + "returns": "", + "line": 135, + "doc": "", + "decorator": "router.post('/cases/{case_id}/packets')", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/inspections/packets/{packet_id}", + "router": "router", + "prefix_resolved": true, + "name": "document", + "signature": "request: Request, packet_id: UUID, identity=Depends(actor)", + "returns": "", + "line": 140, + "doc": "", + "decorator": "router.get('/packets/{packet_id}')", + "errors": [] + }, + { + "method": "GET", + "path": "/desktop/v1/inspections/evidence/supported-types", + "router": "router", + "prefix_resolved": true, + "name": "supported_types", + "signature": "identity=Depends(actor)", + "returns": "", + "line": 179, + "doc": "The media types this deployment's product model actually accepts.", + "decorator": "router.get('/evidence/supported-types')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/inspections/evidence/retain", + "router": "router", + "prefix_resolved": true, + "name": "retain", + "signature": "request: Request, body: EvidenceItems, identity=Depends(actor)", + "returns": "", + "line": 188, + "doc": "", + "decorator": "router.post('/evidence/retain')", + "errors": [] + }, + { + "method": "POST", + "path": "/desktop/v1/inspections/media/analyse", + "router": "router", + "prefix_resolved": true, + "name": "media_analyse", + "signature": "request: Request, body: MediaAnalysis, identity=Depends(actor)", + "returns": "", + "line": 199, + "doc": "Run the configured adapters over retained originals; draft only.\n\nThe result carries the same observations/citations the product route returns\nplus ``analysis_record``: the exact ``AnalysisRecord`` the caller puts on its\ncase payload, so the reviewed draft is the analysed one.", + "decorator": "router.post('/media/analyse')", + "errors": [ + "HTTPException(503, str(exc))" + ] + }, + { + "method": "POST", + "path": "/desktop/v1/inspections/connections/search", + "router": "router", + "prefix_resolved": true, + "name": "connections", + "signature": "request: Request, body: Search, identity=Depends(actor)", + "returns": "", + "line": 234, + "doc": "", + "decorator": "router.post('/connections/search')", + "errors": [] + } + ], + "models": [ + { + "name": "RepeatLookup", + "bases": [ + "Model" + ], + "fields": [ + { + "name": "property_reference", + "type": "str", + "default": "Field(min_length=1, max_length=1000)" + } + ], + "line": 88, + "doc": "" + }, + { + "name": "Packet", + "bases": [ + "Model" + ], + "fields": [ + { + "name": "expected_revision", + "type": "UUID", + "default": "" + }, + { + "name": "visibility", + "type": "Literal['staff_only', 'records_copy']", + "default": "" + } + ], + "line": 129, + "doc": "" + }, + { + "name": "EvidenceItem", + "bases": [ + "Model" + ], + "fields": [ + { + "name": "filename", + "type": "str", + "default": "Field(min_length=1, max_length=151)" + }, + { + "name": "media_type", + "type": "str", + "default": "Field(min_length=1, max_length=80)" + }, + { + "name": "description", + "type": "str", + "default": "Field(default='', max_length=2000)" + }, + { + "name": "content_base64", + "type": "str", + "default": "Field(min_length=1, max_length=14000000)" + }, + { + "name": "sha256", + "type": "str", + "default": "Field(pattern='^[a-f0-9]{64}$')" + } + ], + "line": 144, + "doc": "" + }, + { + "name": "EvidenceItems", + "bases": [ + "Model" + ], + "fields": [ + { + "name": "items", + "type": "list[EvidenceItem]", + "default": "Field(min_length=1, max_length=10)" + } + ], + "line": 152, + "doc": "" + }, + { + "name": "CodeLink", + "bases": [ + "Model" + ], + "fields": [ + { + "name": "provider", + "type": "Literal['code']", + "default": "'code'" + }, + { + "name": "source_id", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + }, + { + "name": "expected_sha256", + "type": "str", + "default": "Field(pattern='^[a-f0-9]{64}$')" + } + ], + "line": 156, + "doc": "" + }, + { + "name": "MediaAnalysis", + "bases": [ + "Model" + ], + "fields": [ + { + "name": "items", + "type": "list[EvidenceItem]", + "default": "Field(min_length=1, max_length=10)" + }, + { + "name": "code_links", + "type": "list[CodeLink]", + "default": "Field(default_factory=list, max_length=30)" + }, + { + "name": "inspector_supplied_text", + "type": "str", + "default": "Field(default='', max_length=10000)" + } + ], + "line": 162, + "doc": "" + }, + { + "name": "Search", + "bases": [ + "Model" + ], + "fields": [ + { + "name": "provider", + "type": "Literal['code']", + "default": "" + }, + { + "name": "query", + "type": "str", + "default": "Field(min_length=1, max_length=500)" + } + ], + "line": 228, + "doc": "" + } + ], + "configuration": [] + } + ] + }, + "station": { + "package": "townlight_station", + "source": [ + { + "source": "installed-owned-source/townlight_station/__init__.py", + "sha256": "0e4ae6948a7b82358592fa123efcb0f2f19edd0322d93e8077da9db1dcde1ccc", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_station/air.py", + "sha256": "501f3ab5cd85ef7409e692496b8ab8146c3f894a0c3c963fb40d44a71088a97f", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_station/airplay.py", + "sha256": "49efe58ba56e37260c24e9ac329f942f6520c3f16d341b0d4ece803750ce0988", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_station/api.py", + "sha256": "ac098e06290f5888924bb7a211a3925107161c9e01634f998f7303f05a854b18", + "routes": [ + { + "method": "GET", + "path": "/health", + "router": "app", + "prefix_resolved": true, + "name": "health", + "signature": "", + "returns": "", + "line": 79, + "doc": "", + "decorator": "app.get('/health')", + "errors": [] + }, + { + "method": "GET", + "path": "/v1/identity", + "router": "app", + "prefix_resolved": true, + "name": "identity", + "signature": "proof: str | None=Header(default=None, alias='X-Townlight-Session')", + "returns": "", + "line": 84, + "doc": "", + "decorator": "app.get('/v1/identity')", + "errors": [] + }, + { + "method": "POST", + "path": "/v1/recordings", + "router": "app", + "prefix_resolved": true, + "name": "capture", + "signature": "data: Capture, proof: str | None=Header(default=None, alias='X-Townlight-Session')", + "returns": "", + "line": 89, + "doc": "", + "decorator": "app.post('/v1/recordings', status_code=202)", + "errors": [ + "HTTPException(422, 'Select one recorded file or live input; live input preserves embedded captions')", + "HTTPException(422, 'Configured live input not found')", + "HTTPException(422, 'Source file missing or exceeds configured limit')", + "HTTPException(422, 'Caption sidecar missing or too large')", + "HTTPException(409, 'Agenda item does not belong to this meeting')", + "HTTPException(409, 'Station is busy; live recording must start immediately')", + "HTTPException(429, 'Station queue is full; no capture accepted')", + "HTTPException(409, 'Idempotency key already describes different source evidence')" + ] + }, + { + "method": "GET", + "path": "/v1/recordings/{identity}", + "router": "app", + "prefix_resolved": true, + "name": "get_record", + "signature": "identity: UUID, proof: str | None=Header(default=None, alias='X-Townlight-Session')", + "returns": "", + "line": 187, + "doc": "", + "decorator": "app.get('/v1/recordings/{identity}')", + "errors": [] + }, + { + "method": "GET", + "path": "/v1/recordings/{identity}/content", + "router": "app", + "prefix_resolved": true, + "name": "content", + "signature": "identity: UUID, proof: str | None=Header(default=None, alias='X-Townlight-Session')", + "returns": "", + "line": 191, + "doc": "", + "decorator": "app.get('/v1/recordings/{identity}/content')", + "errors": [ + "HTTPException(409, 'Recording is not complete')", + "HTTPException(409, 'Recording integrity failure')" + ] + }, + { + "method": "POST", + "path": "/v1/recordings/{identity}/retry", + "router": "app", + "prefix_resolved": true, + "name": "retry", + "signature": "identity: UUID, proof: str | None=Header(default=None, alias='X-Townlight-Session')", + "returns": "", + "line": 202, + "doc": "", + "decorator": "app.post('/v1/recordings/{identity}/retry', status_code=202)", + "errors": [ + "HTTPException(404, 'Recording not found')", + "HTTPException(409, 'Only failed/interrupted recordings can be retried')", + "HTTPException(409, 'A live gap cannot be retried; start a new recording')" + ] + }, + { + "method": "GET", + "path": "/v1/live-sources", + "router": "app", + "prefix_resolved": true, + "name": "live_sources", + "signature": "proof: str | None=Header(default=None, alias='X-Townlight-Session')", + "returns": "", + "line": 215, + "doc": "", + "decorator": "app.get('/v1/live-sources')", + "errors": [] + }, + { + "method": "GET", + "path": "/v1/recordings", + "router": "app", + "prefix_resolved": true, + "name": "list_records", + "signature": "proof: str | None=Header(default=None, alias='X-Townlight-Session')", + "returns": "", + "line": 220, + "doc": "", + "decorator": "app.get('/v1/recordings')", + "errors": [] + }, + { + "method": "POST", + "path": "/v1/recordings/{identity}/stop", + "router": "app", + "prefix_resolved": true, + "name": "stop_live", + "signature": "identity: UUID, proof: str | None=Header(default=None, alias='X-Townlight-Session')", + "returns": "", + "line": 226, + "doc": "", + "decorator": "app.post('/v1/recordings/{identity}/stop', status_code=202)", + "errors": [ + "HTTPException(404, 'Recording not found')", + "HTTPException(409, 'This recording is not live')", + "HTTPException(409, 'Recording already ended')" + ] + } + ], + "models": [ + { + "name": "Capture", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "meeting_id", + "type": "UUID", + "default": "" + }, + { + "name": "agenda_ids", + "type": "list[UUID]", + "default": "Field(default_factory=list, max_length=100)" + }, + { + "name": "source_file", + "type": "str | None", + "default": "Field(default=None, pattern='^[A-Za-z0-9][A-Za-z0-9_.-]{0,180}$')" + }, + { + "name": "live_source_id", + "type": "str | None", + "default": "Field(default=None, pattern='^[A-Za-z0-9_-]{1,64}$')" + }, + { + "name": "captions_file", + "type": "str | None", + "default": "Field(default=None, pattern='^[A-Za-z0-9][A-Za-z0-9_.-]{0,180}\\\\.srt$')" + }, + { + "name": "idempotency_key", + "type": "str", + "default": "Field(min_length=1, max_length=100)" + } + ], + "line": 34, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_station/boundary.py", + "sha256": "e3b39156fb3fd3e0c4ff1dc9370ce133b9163ee689eeb4be0f5e235833e5336e", + "routes": [], + "models": [ + { + "name": "Settings", + "bases": [], + "fields": [ + { + "name": "data", + "type": "Path", + "default": "" + }, + { + "name": "database_url", + "type": "str", + "default": "" + }, + { + "name": "suite_url", + "type": "str", + "default": "" + }, + { + "name": "media_source", + "type": "Path", + "default": "" + }, + { + "name": "media_python", + "type": "Path", + "default": "" + }, + { + "name": "media_runtime", + "type": "Path", + "default": "" + }, + { + "name": "ffprobe", + "type": "Path", + "default": "" + }, + { + "name": "max_seconds", + "type": "int", + "default": "7200" + }, + { + "name": "max_bytes", + "type": "int", + "default": "2147483647" + }, + { + "name": "width", + "type": "int", + "default": "1920" + }, + { + "name": "height", + "type": "int", + "default": "1080" + }, + { + "name": "fps", + "type": "int", + "default": "30" + }, + { + "name": "bitrate_kbps", + "type": "int", + "default": "6000" + } + ], + "line": 45, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_station/cli.py", + "sha256": "ffbd1fc7ce709ff255d4b5f190fda532d395c9febddf5c281fdff3345f19a9c9", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_station/live.py", + "sha256": "a35de110d5dbfdcf0b98425baf4b664fc4d0324c640c737086936dbe17adc829", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_station/media_job.py", + "sha256": "15237eaa872c9772c548aaf57dced25ec51a343489b894a462d95de19507e59b", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_station/operations.py", + "sha256": "69019673d277ee4850d4dd1789e0576b6883d684b0f1ead2be9f965cfdf7b7d2", + "routes": [ + { + "method": "POST", + "path": "/v1/schedules", + "router": "app", + "prefix_resolved": true, + "name": "create_schedule", + "signature": "data: ScheduleRequest, proof: str | None=Header(default=None, alias='X-Townlight-Session')", + "returns": "", + "line": 106, + "doc": "", + "decorator": "app.post('/v1/schedules', status_code=202)", + "errors": [ + "HTTPException(422, 'Select one recorded file or live input; live input preserves embedded captions')", + "HTTPException(422, 'Configured live input not found')", + "HTTPException(422, 'Source file missing from managed ingest')", + "HTTPException(422, 'Caption sidecar missing from managed ingest')", + "HTTPException(409, 'Agenda item does not belong to this meeting')" + ] + }, + { + "method": "GET", + "path": "/v1/schedules", + "router": "app", + "prefix_resolved": true, + "name": "list_schedules", + "signature": "proof: str | None=Header(default=None, alias='X-Townlight-Session')", + "returns": "", + "line": 143, + "doc": "", + "decorator": "app.get('/v1/schedules')", + "errors": [] + }, + { + "method": "POST", + "path": "/v1/schedules/{identity}/cancel", + "router": "app", + "prefix_resolved": true, + "name": "cancel_schedule", + "signature": "identity: UUID, proof: str | None=Header(default=None, alias='X-Townlight-Session')", + "returns": "", + "line": 151, + "doc": "", + "decorator": "app.post('/v1/schedules/{identity}/cancel', status_code=202)", + "errors": [ + "HTTPException(409, 'Only a schedule that has not started can be cancelled')" + ] + }, + { + "method": "POST", + "path": "/v1/playouts", + "router": "app", + "prefix_resolved": true, + "name": "create_playout", + "signature": "data: PlayoutRequest, proof: str | None=Header(default=None, alias='X-Townlight-Session')", + "returns": "", + "line": 163, + "doc": "", + "decorator": "app.post('/v1/playouts', status_code=202)", + "errors": [ + "HTTPException(404, 'Recording not found')", + "HTTPException(409, 'Only a complete, verified recording can be committed to air')" + ] + }, + { + "method": "GET", + "path": "/v1/playouts", + "router": "app", + "prefix_resolved": true, + "name": "list_playouts", + "signature": "proof: str | None=Header(default=None, alias='X-Townlight-Session')", + "returns": "", + "line": 187, + "doc": "", + "decorator": "app.get('/v1/playouts')", + "errors": [] + }, + { + "method": "GET", + "path": "/v1/playouts/{identity}", + "router": "app", + "prefix_resolved": true, + "name": "get_playout", + "signature": "identity: UUID, proof: str | None=Header(default=None, alias='X-Townlight-Session')", + "returns": "", + "line": 194, + "doc": "", + "decorator": "app.get('/v1/playouts/{identity}')", + "errors": [ + "HTTPException(404, 'Playout not found')" + ] + }, + { + "method": "GET", + "path": "/v1/on-air", + "router": "app", + "prefix_resolved": true, + "name": "on_air", + "signature": "proof: str | None=Header(default=None, alias='X-Townlight-Session')", + "returns": "", + "line": 203, + "doc": "", + "decorator": "app.get('/v1/on-air')", + "errors": [] + }, + { + "method": "POST", + "path": "/v1/on-air/live", + "router": "app", + "prefix_resolved": true, + "name": "live_override", + "signature": "data: LiveOverrideRequest, proof: str | None=Header(default=None, alias='X-Townlight-Session')", + "returns": "", + "line": 215, + "doc": "Put a configured live input on air, in place of the scheduled program.", + "decorator": "app.post('/v1/on-air/live', status_code=202)", + "errors": [ + "HTTPException(422, 'Configured live input not found')" + ] + }, + { + "method": "POST", + "path": "/v1/on-air/return-to-schedule", + "router": "app", + "prefix_resolved": true, + "name": "return_to_schedule", + "signature": "proof: str | None=Header(default=None, alias='X-Townlight-Session')", + "returns": "", + "line": 232, + "doc": "", + "decorator": "app.post('/v1/on-air/return-to-schedule', status_code=202)", + "errors": [] + }, + { + "method": "POST", + "path": "/v1/playouts/{identity}/approve", + "router": "app", + "prefix_resolved": true, + "name": "approve", + "signature": "identity: UUID, data: ApprovalRequest, proof: str | None=Header(default=None, alias='X-Townlight-Session')", + "returns": "", + "line": 243, + "doc": "", + "decorator": "app.post('/v1/playouts/{identity}/approve', status_code=202)", + "errors": [ + "HTTPException(409, 'Only a rendered playout can be approved for public playback')" + ] + }, + { + "method": "POST", + "path": "/v1/playouts/{identity}/publish", + "router": "app", + "prefix_resolved": true, + "name": "publish", + "signature": "identity: UUID, proof: str | None=Header(default=None, alias='X-Townlight-Session')", + "returns": "", + "line": 256, + "doc": "", + "decorator": "app.post('/v1/playouts/{identity}/publish', status_code=202)", + "errors": [ + "HTTPException(404, 'Playout not found')", + "HTTPException(409, 'Explicit staff approval is required before public playback')" + ] + }, + { + "method": "GET", + "path": "/v1/public/playback/{identity}", + "router": "app", + "prefix_resolved": true, + "name": "public_playback", + "signature": "identity: UUID", + "returns": "", + "line": 285, + "doc": "", + "decorator": "app.get('/v1/public/playback/{identity}')", + "errors": [ + "HTTPException(404, 'Playback not found')", + "HTTPException(409, 'Playback integrity failure')" + ] + }, + { + "method": "GET", + "path": "/v1/public/playback/{identity}/captions", + "router": "app", + "prefix_resolved": true, + "name": "public_captions", + "signature": "identity: UUID", + "returns": "", + "line": 301, + "doc": "", + "decorator": "app.get('/v1/public/playback/{identity}/captions')", + "errors": [ + "HTTPException(404, 'Captions not found')", + "HTTPException(409, 'Caption integrity failure')" + ] + }, + { + "method": "GET", + "path": "/v1/public/playback/{identity}/program", + "router": "app", + "prefix_resolved": true, + "name": "public_program", + "signature": "identity: UUID", + "returns": "", + "line": 315, + "doc": "", + "decorator": "app.get('/v1/public/playback/{identity}/program')", + "errors": [ + "HTTPException(404, 'Playback not found')", + "HTTPException(409, 'Playback integrity failure')" + ] + } + ], + "models": [ + { + "name": "ScheduleRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "meeting_id", + "type": "UUID", + "default": "" + }, + { + "name": "agenda_ids", + "type": "list[UUID]", + "default": "Field(default_factory=list, max_length=100)" + }, + { + "name": "source_file", + "type": "str | None", + "default": "Field(default=None, pattern='^[A-Za-z0-9][A-Za-z0-9_.-]{0,180}$')" + }, + { + "name": "live_source_id", + "type": "str | None", + "default": "Field(default=None, pattern='^[A-Za-z0-9_-]{1,64}$')" + }, + { + "name": "captions_file", + "type": "str | None", + "default": "Field(default=None, pattern='^[A-Za-z0-9][A-Za-z0-9_.-]{0,180}\\\\.srt$')" + }, + { + "name": "start_at", + "type": "datetime", + "default": "" + }, + { + "name": "idempotency_key", + "type": "str", + "default": "Field(min_length=1, max_length=100)" + } + ], + "line": 58, + "doc": "" + }, + { + "name": "PlayoutRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "recording_id", + "type": "UUID", + "default": "" + }, + { + "name": "mode", + "type": "str", + "default": "Field(pattern='^(dry-run|commit)$')" + }, + { + "name": "idempotency_key", + "type": "str", + "default": "Field(min_length=1, max_length=100)" + } + ], + "line": 69, + "doc": "" + }, + { + "name": "ApprovalRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "note", + "type": "str", + "default": "Field(min_length=3, max_length=500)" + } + ], + "line": 76, + "doc": "" + }, + { + "name": "LiveOverrideRequest", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "live_source_id", + "type": "str", + "default": "Field(pattern='^[A-Za-z0-9_-]{1,64}$')" + }, + { + "name": "reason", + "type": "str", + "default": "Field(min_length=3, max_length=200)" + } + ], + "line": 81, + "doc": "An on-air override naming an administrator-configured live input." + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_station/operator.py", + "sha256": "6471894a1240b611a2bf006867ce79848630f6dc69270e29e54b71dbb26f3837", + "routes": [ + { + "method": "POST", + "path": "/v1/operator-ticket", + "router": "app", + "prefix_resolved": true, + "name": "issue", + "signature": "proof: str | None=Header(default=None, alias='X-Townlight-Session')", + "returns": "", + "line": 51, + "doc": "", + "decorator": "app.post('/v1/operator-ticket')", + "errors": [ + "HTTPException(429, 'Too many outstanding operator launches')" + ] + }, + { + "method": "POST", + "path": "/operator/session", + "router": "app", + "prefix_resolved": true, + "name": "exchange", + "signature": "data: Ticket, request: Request", + "returns": "", + "line": 60, + "doc": "", + "decorator": "app.post('/operator/session')", + "errors": [ + "HTTPException(401, 'Launch link expired or already used; reopen Station from the signed-in staff session')", + "HTTPException(429, 'Operator session capacity reached')" + ] + }, + { + "method": "POST", + "path": "/operator/logout", + "router": "app", + "prefix_resolved": true, + "name": "logout", + "signature": "request: Request", + "returns": "", + "line": 75, + "doc": "", + "decorator": "app.post('/operator/logout')", + "errors": [] + }, + { + "method": "GET", + "path": "/operator/catalog", + "router": "app", + "prefix_resolved": true, + "name": "catalog", + "signature": "proof: str | None=Header(default=None, alias='X-Townlight-Session')", + "returns": "", + "line": 82, + "doc": "", + "decorator": "app.get('/operator/catalog')", + "errors": [] + }, + { + "method": "GET", + "path": "/operator/meeting/{identity}", + "router": "app", + "prefix_resolved": true, + "name": "meeting", + "signature": "identity: UUID, proof: str | None=Header(default=None, alias='X-Townlight-Session')", + "returns": "", + "line": 102, + "doc": "", + "decorator": "app.get('/operator/meeting/{identity}')", + "errors": [] + }, + { + "method": "POST", + "path": "/operator/handoff", + "router": "app", + "prefix_resolved": true, + "name": "handoff", + "signature": "data: Handoff, proof: str | None=Header(default=None, alias='X-Townlight-Session')", + "returns": "", + "line": 106, + "doc": "", + "decorator": "app.post('/operator/handoff')", + "errors": [ + "HTTPException(result.status_code if result.status_code in (401, 403, 404, 409, 422) else 503, 'Records did not accept the recording. Check your Records role and request, then retry.')", + "HTTPException(503, 'Records unavailable. Retry safely; existing attachments are preserved.')" + ] + }, + { + "method": "GET", + "path": "/", + "router": "app", + "prefix_resolved": true, + "name": "page", + "signature": "", + "returns": "", + "line": 124, + "doc": "", + "decorator": "app.get('/')", + "errors": [] + }, + { + "method": "GET", + "path": "/operator.js", + "router": "app", + "prefix_resolved": true, + "name": "script", + "signature": "", + "returns": "", + "line": 128, + "doc": "", + "decorator": "app.get('/operator.js')", + "errors": [] + }, + { + "method": "GET", + "path": "/operator.css", + "router": "app", + "prefix_resolved": true, + "name": "style", + "signature": "", + "returns": "", + "line": 132, + "doc": "", + "decorator": "app.get('/operator.css')", + "errors": [] + } + ], + "models": [ + { + "name": "Ticket", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "ticket", + "type": "str", + "default": "Field(min_length=32, max_length=128)" + } + ], + "line": 13, + "doc": "" + }, + { + "name": "Handoff", + "bases": [ + "BaseModel" + ], + "fields": [ + { + "name": "request_id", + "type": "UUID", + "default": "" + }, + { + "name": "recording_id", + "type": "UUID", + "default": "" + }, + { + "name": "expected_sha256", + "type": "str", + "default": "Field(pattern='^[0-9a-f]{64}$')" + } + ], + "line": 18, + "doc": "" + } + ], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_station/packaging.py", + "sha256": "e4b1cbdfaab908f44d8acafb0e024fa99439a66eaedfaeb2655a63293b626e82", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_station/store.py", + "sha256": "d9aca0003057897a435c7c310559620f727a1703d625bd87af5c7c505d7e3fbd", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_station/vod_job.py", + "sha256": "dfb3669fa0331fdb481cf765825e67cdf8432ed8c40eff9b5f2b7b34f42648f8", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_station/windows_service.py", + "sha256": "ed2c3b73b8033413b2d28700a686ee6f71f01db11b3d95c4a2d2109d340c782f", + "routes": [], + "models": [], + "configuration": [] + }, + { + "source": "installed-owned-source/townlight_station/worker.py", + "sha256": "f026f53950f3e7dc881831ad1c15818caf5fed27cb2f01fd3ebb0992121be2a1", + "routes": [], + "models": [], + "configuration": [] + } + ], + "bridge": [] + } + } +} \ No newline at end of file From ac2ead46938208820cb0bcae511475abef290da3 Mon Sep 17 00:00:00 2001 From: Scott Converse Date: Mon, 2 Nov 2026 22:10:03 -0700 Subject: [PATCH 4/7] docs: normalize current generated manual line endings --- docs/beta-1/manuals/core.html | 2016 ++++++++++++++++----------------- docs/beta-1/versions.html | 180 +-- 2 files changed, 1098 insertions(+), 1098 deletions(-) diff --git a/docs/beta-1/manuals/core.html b/docs/beta-1/manuals/core.html index 750bc48..8d3c331 100644 --- a/docs/beta-1/manuals/core.html +++ b/docs/beta-1/manuals/core.html @@ -16,1012 +16,1012 @@ Terms and license

Naming, Access and Notice source candidate · 2 November 2026

Prepared documentation. Build, signing, installed acceptance and publication remain pending.

- - -

Townlight Core Manual

-

Townlight Beta 1 · Naming candidate documentation -edition 2 November 2026

-

Contents

- -

Using this manual

-

Townlight Core helps IT administrators and platform maintainers. Core -provides the shared contracts, ingestion, identity helpers, task -infrastructure and recovery foundation used by Townlight. Staff -encounter these capabilities through Setup, Settings and System Health. -Business decisions stay with their owning product.

-

Staff should begin with First run and Daily workflow. Administrators -should also read Architecture, Technical specifications, Configuration, -Security and Recovery. Developers should use the exact API/data -dictionary and examples. The table of contents and alphabetical subject -index link to the relevant sections in the HTML edition; the PDF -preserves headings and searchable text. An editable Word edition is -included with the same documentation companion.

-

Beta identity

- ---- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IdentityValue
DocumentationTownlight Beta 1 naming, Access and Notice candidate
Intended installer version1.7.0.1; build and acceptance pending
Product componenttownlight-core 1.3.0.dev2
Principal import packagetownlight_core
Native desktop source version1.7.0-1
Candidate hashesPending candidate build, signing and installed acceptance
Current owned software licenseAGPL-3.0-only
Acceptance compositionFresh Windows x64 profile; inspections-preview; Station configured -separately
-

The naming change advances this package’s version and requires a new -signed installer and installed acceptance. Those steps and publication -remain pending. Historical tags, receipts and archived manuals keep -their original names and certify only their identified artifacts. Use an -empty database and fresh profile; no in-place legacy upgrade is -supported. The approved Windows profile path remains -%LOCALAPPDATA%\CivicSuite. Preserve existing profiles, data -and recovery material.

-

First run

-
    -
  1. Obtain the identified signed private candidate and its -corresponding-source companion from the beta coordinator. The landing -pages in this documentation are not an installer download service.
  2. -
  3. On the intended fresh Windows test installation, verify the MSI hash -and publisher signature before installing. Preserve unrelated profiles -and recovery material. Installed acceptance for this source candidate -remains pending; no in-place legacy upgrade is supported.
  4. -
  5. Launch Townlight under the intended named Windows account. Choose -the storage folders. Select Townlight Inspections -candidate (inspections-preview) for the bounded -desktop composition, including Access and Notice. A narrower default -selection will not expose all workspaces.
  6. -
  7. Enter the city profile, time zone and contacts. Create the first -named local administrator, sign in and choose protected backup storage. -Continue without local AI is valid for the -deterministic workflows.
  8. -
  9. Run Health Check and wait for readiness. Open Townlight. In System -Health select Finish Records Migration to activate the -canonical Python/PostgreSQL runtime. Do not fabricate migration receipts -or seed accounts.
  10. -
  11. Create named staff through Settings. Import authorized sources using -each product’s source library. All examples in this package are -synthetic; they are not municipal authority.
  12. -
  13. Provision Station separately if it is part of the beta exercise. -Selecting the desktop composition does not start or configure Station. -Configure vision explicitly only if automatic photo drafting is -selected.
  14. -
-

Daily workflow

-

-

1. Complete setup

-

Choose folders and the full product composition. Create the city -profile and the first named administrator. Choose a protected backup -location. Defer optional local AI if it is not needed.

-

-

2. Activate the runtime

-

Run the first-run health check, wait for readiness and open -Townlight. In System Health select Finish Records Migration to activate -the canonical Python and PostgreSQL services. A running process alone is -not a ready database.

-

-

3. Create staff access

-

Use Settings to create named staff. Sign out and confirm that staff -can sign in with their own account. Keep administrator privileges with -people responsible for setup; ordinary staff cannot administer -users.

-

-

4. Import through the right -product

-

Use the source library of Code, Zoning, Planning or Permitting. -Inspect provenance and permissions there. Core ingestion helpers do not -bypass the owning product’s source review.

-

-

5. Make a coherent backup

-

Save open work. Use Backup Now; it stops writers to preserve a -consistent snapshot. Retain the backup receipt, then use Start to resume -services.

-

-

6. Restore and verify

-

Use Restore Latest Backup after preserving current recovery material. -A result of Restore needs service start is an intermediate state: use -Start, then Check. Reopen a known saved record to confirm recovery.

-

-

7. Collect diagnostics

-

Record the time, selected composition, version, operation and exact -error. Inspect System Health and create a redacted support bundle. Do -not delete a profile as the first repair step.

-

Working safely

-

Use your own named account and save before leaving a screen. A saved -draft is durable; unsaved form text may not be. If a write has an -unknown result, reopen its record before repeating it.

-

Read source jurisdiction, dates, citation, version and visibility. A -copied source hash identifies exact bytes, not their legal -applicability. If a source changes or permission is removed, resolve the -source problem rather than substituting stale cached content.

-

Keep originals and derivatives separate. Review the intended audience -before export. A public summary excludes private fields only through the -applicable copy contract and your review. A renamed private packet is -still private content.

-

Drafting, review, approval, attachment, export, fulfillment and -publication are separate operations. A Townlight workpaper does not -itself adopt law, issue a permit, impose a fine or release a records -response. The responsible staff member records the applicable -decision.

-

Connected workflows

-

All products use selected Core contracts. Core does not create -unrestricted access between products. Access and Notice provide the -bounded staff workflows documented in their current manuals; installed -acceptance remains pending.

- ---- - - - - - - - - - - - - - - - - -
DirectionMaterial
InputAdministrator setup choices, named staff accounts, source material -submitted through the owning product, and protected backup storage.
OutputReady local services, permission-aware shared contracts, task -results, diagnostics and coherent backup or restore receipts.
-

Product boundary

-

Shared catalog, exemption and module-generator code exists in this -private candidate. It is not a centrally hosted federation service. A -business product still owns its decisions, identity mapping and -permission checks. Historical placeholder ADRs are retained as history, -rather than descriptions of the current implementation.

-

Architecture

-
- - -
-

The drawing shows the principal staff/evidence path. Native commands -carry trusted identity to Python business services; PostgreSQL and -retained original files hold durable state. A downstream copy does not -silently transfer decision authority. Station has its own configured -authority/media boundary, database and mutable files. The -connected-workflow text supplies the drawing’s reading order and -accessibility alternative.

-

Shared catalog rules and -scaffolding

-

These are existing Core developer and administrator contracts. They -do not add a new Core administration screen. Staff use the owning -product’s normal controls; developers call the library only inside an -authenticated application or an isolated synthetic test. The caller owns -authorization and database commit or rollback.

-

Catalog import and readback

-
    -
  1. Review the catalog’s catalog_version, domain names and -systems. Each system supplies vendor name, protocol, data shape, record -types, redaction tier 1–3 and optional discovery hints. Hints are -limited to ports, db_patterns and -service_accounts; do not put credentials in them.
  2. -
  3. In an authorized application transaction, call -townlight_core.catalog.import_catalog(session, bundle, actor_id=actual_actor_id). -The actor is the authenticated application’s identity. A changed or -incomplete existing version is refused rather than overwritten. Use a -newly reviewed version for changed catalog contents.
  4. -
  5. Read domains(session), -system_catalog(session, domain) and -connectors_for(session, domain) before committing. Commit -only the intended import; roll back on refusal. Repeating an identical -complete version is a no-op.
  6. -
  7. Treat returned systems and connector recommendations as catalog -information. Import does not discover vendor endpoints, install a -connector or establish access to a city’s system.
  8. -
-

The following synthetic library example belongs inside an existing -authorized async transaction. session and -actual_actor_id are supplied by that application; this is -not a command that seeds an administrator.

-
from townlight_core.catalog import import_catalog, system_catalog
-
-bundle = {
-    "catalog_version": "synthetic-1",
-    "domains": [{"domain": "synthetic-records", "systems": [{
-        "vendor_name": "Synthetic file source",
-        "access_protocol": "file", "data_shape": "json",
-        "common_record_types": ["synthetic minutes"],
-        "redaction_tier": 2, "discovery_hints": {}
-    }]}]
-}
-loaded = await import_catalog(session, bundle, actor_id=actual_actor_id)
-rows = await system_catalog(session, "synthetic-records")
-

The Records compatibility facade reads its bundled -app/data/systems_catalog.json through Core. Its existing -administrator POST /catalog/load takes no replacement -bundle body; GET /catalog/domains, -/catalog/systems?domain=... and -/catalog/connectors?domain=... expose readback. These -non-desktop routes use the application’s actual authenticated -staff/admin dependencies. Do not substitute an invented role header. The -shared SDK example above is the route for a developer-supplied -bundle.

-

Jurisdictional rule -evaluation and review

-

Select the jurisdiction and active reviewed rule versions before -evaluating document text. Core’s Rule carries -id, state_code, category, -rule_type, definition and integer -version. Supported supplied rule types are -keyword and regex; an unsupported rule or -incomplete/timed-out scan raises RuleEvaluationError. An -error must remain an incomplete scan, never “no exemptions found.” Core -does not assume a jurisdiction or claim complete legal coverage.

-
from uuid import UUID
-from townlight_core.exemptions import Rule, evaluate, RuleEvaluationError
-
-rule = Rule(
-    id=UUID("11111111-1111-4111-8111-111111111111"),
-    state_code="CO", category="Synthetic review flag",
-    rule_type="keyword", definition="synthetic protected text", version=1
-)
-try:
-    flags = evaluate("Contains synthetic protected text", "CO", rules=[rule])
-except RuleEvaluationError:
-    raise  # The owning application records an incomplete scan.
-

This is fictional test text, not a Colorado exemption rule. Read each -result’s matched text, rule identity/version and confidence, then use -Records’ explicit reviewer decision and legal/source basis. A flag is -not an authorized withholding or redaction. Records’ existing exemption -rule/history/test and flag-review endpoints are listed in its technical -reference; record changes through those controls, preserving -history.

-

Scaffold plan and generate

-

Run the existing CLI from a developer environment containing the -matching Core package. Choose an existing empty parent workspace -directory, not an installed application’s directory. The module’s own -directory will be created underneath it. The following creates only a -fictional module project; it does not register, install, migrate or run -it.

-
& $control -m townlight_core.scaffold plan civicnotes `
-  --name 'Synthetic Notes' --description 'Synthetic scaffold exercise'
-& $control -m townlight_core.scaffold generate civicnotes `
-  --name 'Synthetic Notes' --description 'Synthetic scaffold exercise' `
-  --target 'C:\TownlightSynthetic' --dry-run
-

Here $control is the Python executable in that isolated -developer environment. Inspect the plan and files, then remove ---dry-run only when that exact target is approved for -generation. Existing files are refused, not silently overwritten. Exit 0 -indicates success; refusal exits 2. Options include ---version, --townlight_core-min-version, ---permission-key, repeated --staff-role and ---route-path; inspect --help for the exact -invocation. Keep generated access requirements and migration stubs under -the new module’s own review. No automatic product deployment follows -generation.

-

Source contracts: townlight_core/catalog/__init__.py, -townlight_core/exemptions/__init__.py, -townlight_core/scaffold/cli.py, project.py, -and the Records catalog facade.

-

Technical specifications

-

Runtime and storage

-

The accepted package targets Windows x64 fresh -installation. Its native shell uses Rust 2021, Tauri 2 -and Microsoft WebView2; browser assets are JavaScript built -with Vite 8.1.6. This describes the native desktop -frontend; Station has a separate React operator, specified below or in -its product manual. Canonical business workflows use bundled -CPython 3.13.5, FastAPI, Pydantic, SQLAlchemy and -Alembic, with PostgreSQL 17 / PostGIS and -managed original files. The installed runtime tested here contains -FastAPI 0.162.0. Package minimum Python requirements can differ from the -bundled executable; the metadata reference preserves both. No stack -rewrite is implied by the beta label.

-

The native transport is fixed to loopback -127.0.0.1:15480; PostgreSQL uses the configured local -runtime port (default 15432). Optional local model service -defaults to 127.0.0.1:15434. Those are deployment defaults, -not internet endpoints. The runtime has health, module and readiness -endpoints; readiness is stronger than process existence. The task queue -is the existing local Core task infrastructure, not an assertion that a -separate Redis service is required for this desktop composition.

-

The default native profile is %LOCALAPPDATA%\CivicSuite; -the historical directory name remains part of compatibility. Do not -rename it to Townlight. A configured TOWNLIGHT_PROFILE_ROOT -must be absolute. Local configuration and secrets live under that -profile; protected managed files and database state must be backed up -coherently. Source/runtime identity is distinct from a product’s display -label.

-

Data and consistency

-

Named local accounts; native sessions; source and department -authority; task receipts; profile configuration; coherent backup -manifests; catalog, exemption and scaffold contracts.

-

Versioned saves use expected prior revision identifiers where -defined. Reopen and reconcile on conflict. Exact exports and handoffs -use source IDs, current visibility, revision and SHA256. Review belongs -to the saved revision and does not transfer silently to edited text. -Database changes use the owning product’s migrations; a request or -readiness check is not an authorization to mutate schema.

-

Capacity and platform -statements

-

This beta has synthetic single-profile workflow evidence. It does not -have a published benchmark for concurrent staff capacity, minimum -RAM/CPU, large-source limits or a field SLA. Do not turn a developer -machine’s specification into a supported minimum. The new installer size -remains pending its build; allow additional disk for extracted runtime, -database, originals, exports, media and backups. Select -equipment/storage after sizing those actual workloads.

-

The exact runtime payload -lock records pinned files, sizes and hashes. The component -metadata records shipped dependency declarations. These references -are more precise than a manually copied dependency list. Third-party and -historical license notices must accompany their matching payloads.

-

Configuration and -administration

-

Native deployment -configuration

-

Use Setup, Settings and System Health for supported staff operation. -Administrators provision folders, backup storage, named accounts and the -city profile. Select inspections-preview for the bounded -desktop composition, including Access and Notice. Station remains a -separate service boundary. Do not use a standalone product’s demo server -as a substitute for the installed workspace.

-

Technical deployments use TOWNLIGHT_PRODUCT_PROFILE, -TOWNLIGHT_PROFILE_ROOT, DATABASE_URL, -TOWNLIGHT_RUNTIME_PORT, PORTAL_MODE and the -runtime-managed secret files. Treat database URLs and native session -proofs as secrets. The installed native domain runtime explicitly -refuses non-loopback binding. PORTAL_MODE=private is the -accepted posture; changing it does not by itself commission an internet -portal, authentication provider or reverse proxy.

-

The isolated documentation exporter sets a fictional profile and -unusable synthetic database origin only to read schemas; those values -are not deployment configuration. Keep deployment values in the intended -process/account scope. An already-running process does not automatically -inherit later environment edits.

-

API and integration examples

-

Native command example

-

The following JavaScript belongs in the existing trusted Townlight -frontend/development environment with invoke imported from -@tauri-apps/api/core. It is not a command for an arbitrary -web page or an instruction for nontechnical staff. IDs must come from -records created in an isolated synthetic exercise.

-
import { invoke } from '@tauri-apps/api/core';
-const result = await invoke('get_app_state', {});
-console.log(result);
-

Trusted local HTTP example

-

An administrator/developer can inspect an already-configured isolated -runtime from a trusted local process. This PowerShell example reads the -signed-in synthetic profile’s existing proof into memory; it does not -create a user, seed a session, reveal the proof in output or bypass a -permission check. Do not use real city data in development examples. A -read response does not prove approval or publication.

-
$profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite'
-$sessionPath = Join-Path $profilePath 'config\local-session.json'
-$session = Get-Content -LiteralPath $sessionPath -Raw | ConvertFrom-Json
-$headers = @{ 'X-Townlight-Session' = $session.session_hash }
-Invoke-RestMethod -Uri 'http://127.0.0.1:15480/desktop/v1/suite/state' -Headers $headers
-Remove-Variable session, headers
-

A synthetic write -with subsequent readback

-

This example demonstrates the existing Meetings HTTP contract in an -isolated exercise. It is intentionally fictional. It does not start a -service. Its authentication setup is included so it can be run -independently under the signed-in synthetic account. If a write times -out, inspect current records before repeating it.

-
$profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite'
-$sessionPath = Join-Path $profilePath 'config/local-session.json'
-$session = Get-Content -LiteralPath $sessionPath -Raw | ConvertFrom-Json
-$headers = @{ 'X-Townlight-Session' = $session.session_hash }
-$body = @{
-  title = 'Synthetic documentation exercise'
-  scheduled_start = '2026-11-05T18:00:00-07:00'
-  location = 'Synthetic room'
-  meeting_type = 'regular'
-} | ConvertTo-Json
-$meeting = Invoke-RestMethod -Method Post `
-  -Uri 'http://127.0.0.1:15480/desktop/v1/meetings/meetings' `
-  -Headers $headers -ContentType 'application/json' -Body $body
-Invoke-RestMethod `
-  -Uri ('http://127.0.0.1:15480/desktop/v1/meetings/meetings/' + $meeting.id) `
-  -Headers $headers
-Remove-Variable session, headers
-

This write requires Meetings to be enabled and the signed-in staff -role to permit it. It is a cross-suite integration example; for this -product’s request models, use the complete technical reference -below.

-

Complete technical contract

-

Read the Core API reference -for every documented operation, request field, constraint, response -declaration and source supplement. Download the OpenAPI JSON for tools. For -Station this is the suite-side schema only; its separate service -contract is documented in the API supplement. The reference directory includes -configuration/source inventories, dependency declarations, native -command contracts, MCP signatures and candidate evidence.

-

MCP and automation boundary

-

No direct product MCP server is exposed by the accepted Townlight -desktop or Station boundary. Do not configure an invented -townlight mcp command or assume an AI client has staff -permissions. The integration surfaces for this beta are native IPC, the -documented HTTP APIs, source bundle imports, exact exports and the -existing Station CLI.

-

The bundled transcription code includes a TextFlowKit MCP -adapter as a separate source capability. It offers job-based -transcribe_media, get_transcript, -list_jobs, get_job_status and -export_transcript, and additional tools declared in that -adapter. It uses stdio first and optional Streamable HTTP, with the MCP -SDK as an optional extra. It is not automatically launched, -authenticated as Townlight staff or accepted as a Townlight product MCP -deployment. This documentation does not add such a service.

-

For a transcription client already provisioned separately, an -illustrative tool call is:

-
{"name":"get_job_status","arguments":{"job_id":"synthetic-existing-job-id"}}
-

Use a job ID returned by that transcription service. This example -does not create a Townlight record or bypass its review/Records handoff. -The exact optional adapter tool signatures are supplied in the MCP source reference. Station -meeting capture does not become live speech recognition because this -optional donor adapter exists.

-

Security and permissions

-

Use your own named account and save before leaving a screen. A saved -draft is durable; unsaved form text may not be. If a write has an -unknown result, reopen its record before repeating it.

-

Read source jurisdiction, dates, citation, version and visibility. A -copied source hash identifies exact bytes, not their legal -applicability. If a source changes or permission is removed, resolve the -source problem rather than substituting stale cached content.

-

Keep originals and derivatives separate. Review the intended audience -before export. A public summary excludes private fields only through the -applicable copy contract and your review. A renamed private packet is -still private content.

-

Drafting, review, approval, attachment, export, fulfillment and -publication are separate operations. A Townlight workpaper does not -itself adopt law, issue a permit, impose a fine or release a records -response. The responsible staff member records the applicable -decision.

-

The native session is validated and mapped to a persisted SQL -identity. An editable actor/reviewer label is not authentication. -Product/module permissions and source visibility apply at the server -boundary. Revoked/unavailable authority fails closed for new Station -operations; a previous permission result is not a perpetual -authorization.

-

Use protected local folders, account permissions and credential -storage. Never include the native session file, database passwords, -provider keys or unredacted support bundles in a public issue or -generated public documentation. A local public view is not automatically -a secured internet deployment. Keep network exposure and real equipment -acceptance specific to the chosen beta site.

-

Backup recovery and -maintenance

-

Save work and use Core’s canonical Backup Now before -maintenance. That operation stops writers. Preserve the coherent -profile/database/document backup and its receipt, then use -Start to resume. A source export is not a full -backup.

-

Use Restore Latest Backup through the supported -controls. If the result says Restore needs service -start, use Start, then Check, -and reopen a known record. Do not repeat restore merely because services -need to start. The fresh-profile acceptance verified that a fulfilled -request survived restore and a post-backup marker did not.

-

Keep Station’s dedicated database and media evidence together in its -own backup. Core’s native-profile backup must not be assumed to include -an external Station data directory. Stop writers during a coordinated -backup. Preserve failed media attempts and logs.

-

On failure, record the time, selected composition, -component/installer versions and exact message. Check System Health for -stopped, starting, ready or failed dependencies. Use the existing Retry -control after readiness; do not create duplicate business records to -refresh a stale view. Share only a redacted diagnostic bundle. Preserve -secrets, original evidence, recovery material and unrelated -installations.

-

Troubleshooting

- ----- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SymptomLikely meaningNext action
Workspace absentWrong product composition or unavailable canonical runtime.Check selected composition; activate through Finish Records -Migration; wait for readiness.
Cannot sign in / 401Missing or expired named account session.Sign in normally; reopen a Station launch ticket if applicable.
Permission denied / 403Account, module, source or browser-origin permission.Ask the authorized administrator to inspect the intended permission; -do not invent role headers.
Save conflict / 409The saved revision, expected source hash or lifecycle changed.Keep edits, reopen current state and reconcile deliberately.
Invalid input / 422Required field, format, geometry, source envelope or state is -invalid.Read the field detail and correct the input/source; preserve -originals.
Service unavailable / 503Database, schema, connected source or configuration -unavailable.Inspect System Health and the named dependency. Preserve work; retry -only after readiness.
Export refusedMissing exact review, approval, audience or source -authorization.Read the refusal and complete the owning product’s explicit -decision.
Restore needs service startThe snapshot was restored but services have not resumed.Use Start, then Check and verify a saved record; do not blindly -repeat restore.
-

Verified workflows and -limits

- ----- - - - - - - - - - - - - - - -
ProductRecorded resultPrecisely exercised
CorePASSNormal empty-profile setup; canonical activation; UI-created staff -and sign-in; staff denied user administration; coherent backup, -mutation, restore, Start/Check and retained/absent record readback.
-

These results come from the identified signed candidate’s fresh -normal-profile Sandbox exercise: real native IPC/HTTP/PostgreSQL and -selected headless controls. All accounts, source bundles and media were -synthetic. The guest install/uninstall and recovery passed, and the -owned Sandbox stopped. No host installed application or standalone -CivicCast was changed. This documentation task reuses those receipts; it -does not claim a new software acceptance run.

-

The workflow -matrix identifies raw receipt filenames. The evidence -index retains their original hashes; raw receipts remain in the -private beta handoff rather than being silently republished with the -documentation site.

-

The limits remain: actual city field acceptance and equipment/network -commissioning; Station automatic provisioning/SCM commissioning; every -UI/role combination; field recognition accuracy; and historical in-place -upgrades are not certified. They are not five invented feature -requirements. Fresh-install controlled beta handoff remains the accepted -scope. This package makes no city-deployment, publication or -general-availability claim.

-

Terms of service and license

-

Scope and status

-

These terms describe the Townlight Beta 1 software and this -documentation package. This is a locally prepared private beta, not a -hosted-service subscription, a city deployment agreement or a public -release. No uptime commitment, support response time, indemnity, -data-processing agreement or paid service is created by these documents. -A separate signed agreement, if any, governs services it actually -provides.

-

Software license and rights

-

Current Townlight-owned distributions identified in this candidate -use AGPL-3.0-only. The full license is supplied with -this documentation and with the source companion. The license governs -rights to run, copy, modify and convey the covered software; these -operational terms do not add restrictions to those rights. Historical -grants and dependency licenses retain their own terms. CivicCast remains -a separate product and is not relicensed by this documentation work.

-

When conveying covered software, retain applicable notices and -provide the corresponding source and installation/build information -required by the license. For a modified version supporting remote -network interaction, follow section 13’s source-offer requirement. The -companion archive identifies the source for this candidate; a link to a -different public branch is not a substitute for the matching source. -Read the supplied license for the complete conditions. See the GNU license -reference and GNU licensing -FAQ.

-

Data ownership and access

-

Importing a document does not transfer its ownership or grant -permission to publish it. The operating organization controls its -accounts, access decisions, lawful source use, retention and -review/release policy. Keep resident information, credentials, private -notes and restricted evidence in their authorized locations. -Documentation examples contain fictional data. No real city account, -credential or record is required to exercise these examples in an -isolated test environment.

-

Local operation and -external processors

-

The accepted beta workflow is local and uses named staff accounts. -Station has separate storage and credentials. Configure backup -destinations and optional model/network providers deliberately. A -configured external provider may receive submitted prompts, images or -audio according to that configuration and provider’s terms; this -documentation does not promise that every optional configuration is -offline. An email outbox or local public view does not establish -external delivery or an internet deployment. This static documentation -site has no analytics, account collection or remote font dependency.

-

Staff decisions and -source applicability

-

Staff verify the jurisdiction, source currency, permissions, -citations and proposed audience. Model output and generated guidance -require review. No draft is automatically an official legal -interpretation, zoning determination, permit approval, fee assessment, -enforcement notice or records-release decision. Official permit fee -authority remains with the adopted source and responsible organization; -imported amounts do not become a new authoritative calculation.

-

Beta operation and recovery

-

Use the identified candidate in its supported fresh-install scope. -Preserve backups and original evidence. Test physical equipment and -chosen network/service configuration before relying on them. The -supplied acceptance describes selected synthetic workflows, not every -screen, vendor, field condition or upgrade. Operators decide whether a -particular deployment meets their own operational obligations.

-

Warranty and liability

-

The covered software’s warranty and liability conditions are those in -sections 15–17 of the supplied AGPL and any applicable separate written -undertaking. This documentation creates no additional warranty or -limitation beyond those terms. Third-party software is subject to its -retained license notices. Nothing here removes rights that applicable -law makes nonwaivable.

-

Support and incident -reporting

-

Use the project’s existing SUPPORT and SECURITY guidance for its -matching repository. Report reproducible behavior with the version, -operation and redacted logs. Do not put credentials, resident records or -unredacted evidence in a public issue. Coordinate sensitive reports -through the channel designated in SECURITY. No new support address or -service commitment is invented here.

-

Ending a beta -exercise and document changes

-

When an organization ends testing, it controls retention/export and -removes access according to its policy. Uninstall may retain data; back -up and inspect the selected removal options. Ending an exercise does not -revoke rights already granted by AGPL. Later software/documentation -versions must identify their changed candidate and scope; historical -receipts retain their original identities. These terms do not claim that -a city has accepted a contract merely by reading a manual.

-

Glossary

- ---- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TermMeaning
ApprovalAn explicit authorized decision on the saved text/artifact. It is -separate from saving or attachment.
Canonical recordThe owning product’s retained identity and saved version, rather -than an editable copied label.
CompositionThe selected set of desktop modules; inspections-preview exposes the -eight staff products.
Corresponding sourceThe source/build material matching the delivered covered program, -subject to its license.
Derivative / Records copyA separately prepared document with its own intended audience and -hash.
Hash / SHA256A fingerprint of exact bytes. It detects change; it does not -establish legal authority.
IdempotencyRepeating the same identified request has the same intended effect; -changing its payload can be refused.
IPCThe native desktop command boundary between its browser interface -and Rust host.
MCPModel Context Protocol; no direct Townlight product server is -enabled by this beta.
OriginalRetained source bytes. A reviewed derivative does not replace -them.
ProvenanceSource, version, date, actor and relationship information retained -with evidence.
RevisionAn immutable saved version. Later edits do not inherit an earlier -review automatically.
SnapshotA fixed audience-specific copy tied to a source/reviewed -revision.
StationTownlight’s separate media boundary using a pinned CivicCast-derived -engine; standalone CivicCast remains separate.
-

Alphabetical subject index

- - - -

Source and document control

-

This edition is authored from the immutable corresponding-source -companion, the generated installed-domain schema and the retained -workflow receipts. The current software versions and signed artifacts -are unchanged. Public historical pages are not synchronized or published -by this local documentation task.

-

Workflow subject index

- + + +

Townlight Core Manual

+

Townlight Beta 1 · Naming candidate documentation +edition 2 November 2026

+

Contents

+ +

Using this manual

+

Townlight Core helps IT administrators and platform maintainers. Core +provides the shared contracts, ingestion, identity helpers, task +infrastructure and recovery foundation used by Townlight. Staff +encounter these capabilities through Setup, Settings and System Health. +Business decisions stay with their owning product.

+

Staff should begin with First run and Daily workflow. Administrators +should also read Architecture, Technical specifications, Configuration, +Security and Recovery. Developers should use the exact API/data +dictionary and examples. The table of contents and alphabetical subject +index link to the relevant sections in the HTML edition; the PDF +preserves headings and searchable text. An editable Word edition is +included with the same documentation companion.

+

Beta identity

+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IdentityValue
DocumentationTownlight Beta 1 naming, Access and Notice candidate
Intended installer version1.7.0.1; build and acceptance pending
Product componenttownlight-core 1.3.0.dev2
Principal import packagetownlight_core
Native desktop source version1.7.0-1
Candidate hashesPending candidate build, signing and installed acceptance
Current owned software licenseAGPL-3.0-only
Acceptance compositionFresh Windows x64 profile; inspections-preview; Station configured +separately
+

The naming change advances this package’s version and requires a new +signed installer and installed acceptance. Those steps and publication +remain pending. Historical tags, receipts and archived manuals keep +their original names and certify only their identified artifacts. Use an +empty database and fresh profile; no in-place legacy upgrade is +supported. The approved Windows profile path remains +%LOCALAPPDATA%\CivicSuite. Preserve existing profiles, data +and recovery material.

+

First run

+
    +
  1. Obtain the identified signed private candidate and its +corresponding-source companion from the beta coordinator. The landing +pages in this documentation are not an installer download service.
  2. +
  3. On the intended fresh Windows test installation, verify the MSI hash +and publisher signature before installing. Preserve unrelated profiles +and recovery material. Installed acceptance for this source candidate +remains pending; no in-place legacy upgrade is supported.
  4. +
  5. Launch Townlight under the intended named Windows account. Choose +the storage folders. Select Townlight Inspections +candidate (inspections-preview) for the bounded +desktop composition, including Access and Notice. A narrower default +selection will not expose all workspaces.
  6. +
  7. Enter the city profile, time zone and contacts. Create the first +named local administrator, sign in and choose protected backup storage. +Continue without local AI is valid for the +deterministic workflows.
  8. +
  9. Run Health Check and wait for readiness. Open Townlight. In System +Health select Finish Records Migration to activate the +canonical Python/PostgreSQL runtime. Do not fabricate migration receipts +or seed accounts.
  10. +
  11. Create named staff through Settings. Import authorized sources using +each product’s source library. All examples in this package are +synthetic; they are not municipal authority.
  12. +
  13. Provision Station separately if it is part of the beta exercise. +Selecting the desktop composition does not start or configure Station. +Configure vision explicitly only if automatic photo drafting is +selected.
  14. +
+

Daily workflow

+

+

1. Complete setup

+

Choose folders and the full product composition. Create the city +profile and the first named administrator. Choose a protected backup +location. Defer optional local AI if it is not needed.

+

+

2. Activate the runtime

+

Run the first-run health check, wait for readiness and open +Townlight. In System Health select Finish Records Migration to activate +the canonical Python and PostgreSQL services. A running process alone is +not a ready database.

+

+

3. Create staff access

+

Use Settings to create named staff. Sign out and confirm that staff +can sign in with their own account. Keep administrator privileges with +people responsible for setup; ordinary staff cannot administer +users.

+

+

4. Import through the right +product

+

Use the source library of Code, Zoning, Planning or Permitting. +Inspect provenance and permissions there. Core ingestion helpers do not +bypass the owning product’s source review.

+

+

5. Make a coherent backup

+

Save open work. Use Backup Now; it stops writers to preserve a +consistent snapshot. Retain the backup receipt, then use Start to resume +services.

+

+

6. Restore and verify

+

Use Restore Latest Backup after preserving current recovery material. +A result of Restore needs service start is an intermediate state: use +Start, then Check. Reopen a known saved record to confirm recovery.

+

+

7. Collect diagnostics

+

Record the time, selected composition, version, operation and exact +error. Inspect System Health and create a redacted support bundle. Do +not delete a profile as the first repair step.

+

Working safely

+

Use your own named account and save before leaving a screen. A saved +draft is durable; unsaved form text may not be. If a write has an +unknown result, reopen its record before repeating it.

+

Read source jurisdiction, dates, citation, version and visibility. A +copied source hash identifies exact bytes, not their legal +applicability. If a source changes or permission is removed, resolve the +source problem rather than substituting stale cached content.

+

Keep originals and derivatives separate. Review the intended audience +before export. A public summary excludes private fields only through the +applicable copy contract and your review. A renamed private packet is +still private content.

+

Drafting, review, approval, attachment, export, fulfillment and +publication are separate operations. A Townlight workpaper does not +itself adopt law, issue a permit, impose a fine or release a records +response. The responsible staff member records the applicable +decision.

+

Connected workflows

+

All products use selected Core contracts. Core does not create +unrestricted access between products. Access and Notice provide the +bounded staff workflows documented in their current manuals; installed +acceptance remains pending.

+ ++++ + + + + + + + + + + + + + + + + +
DirectionMaterial
InputAdministrator setup choices, named staff accounts, source material +submitted through the owning product, and protected backup storage.
OutputReady local services, permission-aware shared contracts, task +results, diagnostics and coherent backup or restore receipts.
+

Product boundary

+

Shared catalog, exemption and module-generator code exists in this +private candidate. It is not a centrally hosted federation service. A +business product still owns its decisions, identity mapping and +permission checks. Historical placeholder ADRs are retained as history, +rather than descriptions of the current implementation.

+

Architecture

+
+ + +
+

The drawing shows the principal staff/evidence path. Native commands +carry trusted identity to Python business services; PostgreSQL and +retained original files hold durable state. A downstream copy does not +silently transfer decision authority. Station has its own configured +authority/media boundary, database and mutable files. The +connected-workflow text supplies the drawing’s reading order and +accessibility alternative.

+

Shared catalog rules and +scaffolding

+

These are existing Core developer and administrator contracts. They +do not add a new Core administration screen. Staff use the owning +product’s normal controls; developers call the library only inside an +authenticated application or an isolated synthetic test. The caller owns +authorization and database commit or rollback.

+

Catalog import and readback

+
    +
  1. Review the catalog’s catalog_version, domain names and +systems. Each system supplies vendor name, protocol, data shape, record +types, redaction tier 1–3 and optional discovery hints. Hints are +limited to ports, db_patterns and +service_accounts; do not put credentials in them.
  2. +
  3. In an authorized application transaction, call +townlight_core.catalog.import_catalog(session, bundle, actor_id=actual_actor_id). +The actor is the authenticated application’s identity. A changed or +incomplete existing version is refused rather than overwritten. Use a +newly reviewed version for changed catalog contents.
  4. +
  5. Read domains(session), +system_catalog(session, domain) and +connectors_for(session, domain) before committing. Commit +only the intended import; roll back on refusal. Repeating an identical +complete version is a no-op.
  6. +
  7. Treat returned systems and connector recommendations as catalog +information. Import does not discover vendor endpoints, install a +connector or establish access to a city’s system.
  8. +
+

The following synthetic library example belongs inside an existing +authorized async transaction. session and +actual_actor_id are supplied by that application; this is +not a command that seeds an administrator.

+
from townlight_core.catalog import import_catalog, system_catalog
+
+bundle = {
+    "catalog_version": "synthetic-1",
+    "domains": [{"domain": "synthetic-records", "systems": [{
+        "vendor_name": "Synthetic file source",
+        "access_protocol": "file", "data_shape": "json",
+        "common_record_types": ["synthetic minutes"],
+        "redaction_tier": 2, "discovery_hints": {}
+    }]}]
+}
+loaded = await import_catalog(session, bundle, actor_id=actual_actor_id)
+rows = await system_catalog(session, "synthetic-records")
+

The Records compatibility facade reads its bundled +app/data/systems_catalog.json through Core. Its existing +administrator POST /catalog/load takes no replacement +bundle body; GET /catalog/domains, +/catalog/systems?domain=... and +/catalog/connectors?domain=... expose readback. These +non-desktop routes use the application’s actual authenticated +staff/admin dependencies. Do not substitute an invented role header. The +shared SDK example above is the route for a developer-supplied +bundle.

+

Jurisdictional rule +evaluation and review

+

Select the jurisdiction and active reviewed rule versions before +evaluating document text. Core’s Rule carries +id, state_code, category, +rule_type, definition and integer +version. Supported supplied rule types are +keyword and regex; an unsupported rule or +incomplete/timed-out scan raises RuleEvaluationError. An +error must remain an incomplete scan, never “no exemptions found.” Core +does not assume a jurisdiction or claim complete legal coverage.

+
from uuid import UUID
+from townlight_core.exemptions import Rule, evaluate, RuleEvaluationError
+
+rule = Rule(
+    id=UUID("11111111-1111-4111-8111-111111111111"),
+    state_code="CO", category="Synthetic review flag",
+    rule_type="keyword", definition="synthetic protected text", version=1
+)
+try:
+    flags = evaluate("Contains synthetic protected text", "CO", rules=[rule])
+except RuleEvaluationError:
+    raise  # The owning application records an incomplete scan.
+

This is fictional test text, not a Colorado exemption rule. Read each +result’s matched text, rule identity/version and confidence, then use +Records’ explicit reviewer decision and legal/source basis. A flag is +not an authorized withholding or redaction. Records’ existing exemption +rule/history/test and flag-review endpoints are listed in its technical +reference; record changes through those controls, preserving +history.

+

Scaffold plan and generate

+

Run the existing CLI from a developer environment containing the +matching Core package. Choose an existing empty parent workspace +directory, not an installed application’s directory. The module’s own +directory will be created underneath it. The following creates only a +fictional module project; it does not register, install, migrate or run +it.

+
& $control -m townlight_core.scaffold plan civicnotes `
+  --name 'Synthetic Notes' --description 'Synthetic scaffold exercise'
+& $control -m townlight_core.scaffold generate civicnotes `
+  --name 'Synthetic Notes' --description 'Synthetic scaffold exercise' `
+  --target 'C:\TownlightSynthetic' --dry-run
+

Here $control is the Python executable in that isolated +developer environment. Inspect the plan and files, then remove +--dry-run only when that exact target is approved for +generation. Existing files are refused, not silently overwritten. Exit 0 +indicates success; refusal exits 2. Options include +--version, --townlight_core-min-version, +--permission-key, repeated --staff-role and +--route-path; inspect --help for the exact +invocation. Keep generated access requirements and migration stubs under +the new module’s own review. No automatic product deployment follows +generation.

+

Source contracts: townlight_core/catalog/__init__.py, +townlight_core/exemptions/__init__.py, +townlight_core/scaffold/cli.py, project.py, +and the Records catalog facade.

+

Technical specifications

+

Runtime and storage

+

The accepted package targets Windows x64 fresh +installation. Its native shell uses Rust 2021, Tauri 2 +and Microsoft WebView2; browser assets are JavaScript built +with Vite 8.1.6. This describes the native desktop +frontend; Station has a separate React operator, specified below or in +its product manual. Canonical business workflows use bundled +CPython 3.13.5, FastAPI, Pydantic, SQLAlchemy and +Alembic, with PostgreSQL 17 / PostGIS and +managed original files. The installed runtime tested here contains +FastAPI 0.162.0. Package minimum Python requirements can differ from the +bundled executable; the metadata reference preserves both. No stack +rewrite is implied by the beta label.

+

The native transport is fixed to loopback +127.0.0.1:15480; PostgreSQL uses the configured local +runtime port (default 15432). Optional local model service +defaults to 127.0.0.1:15434. Those are deployment defaults, +not internet endpoints. The runtime has health, module and readiness +endpoints; readiness is stronger than process existence. The task queue +is the existing local Core task infrastructure, not an assertion that a +separate Redis service is required for this desktop composition.

+

The default native profile is %LOCALAPPDATA%\CivicSuite; +the historical directory name remains part of compatibility. Do not +rename it to Townlight. A configured TOWNLIGHT_PROFILE_ROOT +must be absolute. Local configuration and secrets live under that +profile; protected managed files and database state must be backed up +coherently. Source/runtime identity is distinct from a product’s display +label.

+

Data and consistency

+

Named local accounts; native sessions; source and department +authority; task receipts; profile configuration; coherent backup +manifests; catalog, exemption and scaffold contracts.

+

Versioned saves use expected prior revision identifiers where +defined. Reopen and reconcile on conflict. Exact exports and handoffs +use source IDs, current visibility, revision and SHA256. Review belongs +to the saved revision and does not transfer silently to edited text. +Database changes use the owning product’s migrations; a request or +readiness check is not an authorization to mutate schema.

+

Capacity and platform +statements

+

This beta has synthetic single-profile workflow evidence. It does not +have a published benchmark for concurrent staff capacity, minimum +RAM/CPU, large-source limits or a field SLA. Do not turn a developer +machine’s specification into a supported minimum. The new installer size +remains pending its build; allow additional disk for extracted runtime, +database, originals, exports, media and backups. Select +equipment/storage after sizing those actual workloads.

+

The exact runtime payload +lock records pinned files, sizes and hashes. The component +metadata records shipped dependency declarations. These references +are more precise than a manually copied dependency list. Third-party and +historical license notices must accompany their matching payloads.

+

Configuration and +administration

+

Native deployment +configuration

+

Use Setup, Settings and System Health for supported staff operation. +Administrators provision folders, backup storage, named accounts and the +city profile. Select inspections-preview for the bounded +desktop composition, including Access and Notice. Station remains a +separate service boundary. Do not use a standalone product’s demo server +as a substitute for the installed workspace.

+

Technical deployments use TOWNLIGHT_PRODUCT_PROFILE, +TOWNLIGHT_PROFILE_ROOT, DATABASE_URL, +TOWNLIGHT_RUNTIME_PORT, PORTAL_MODE and the +runtime-managed secret files. Treat database URLs and native session +proofs as secrets. The installed native domain runtime explicitly +refuses non-loopback binding. PORTAL_MODE=private is the +accepted posture; changing it does not by itself commission an internet +portal, authentication provider or reverse proxy.

+

The isolated documentation exporter sets a fictional profile and +unusable synthetic database origin only to read schemas; those values +are not deployment configuration. Keep deployment values in the intended +process/account scope. An already-running process does not automatically +inherit later environment edits.

+

API and integration examples

+

Native command example

+

The following JavaScript belongs in the existing trusted Townlight +frontend/development environment with invoke imported from +@tauri-apps/api/core. It is not a command for an arbitrary +web page or an instruction for nontechnical staff. IDs must come from +records created in an isolated synthetic exercise.

+
import { invoke } from '@tauri-apps/api/core';
+const result = await invoke('get_app_state', {});
+console.log(result);
+

Trusted local HTTP example

+

An administrator/developer can inspect an already-configured isolated +runtime from a trusted local process. This PowerShell example reads the +signed-in synthetic profile’s existing proof into memory; it does not +create a user, seed a session, reveal the proof in output or bypass a +permission check. Do not use real city data in development examples. A +read response does not prove approval or publication.

+
$profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite'
+$sessionPath = Join-Path $profilePath 'config\local-session.json'
+$session = Get-Content -LiteralPath $sessionPath -Raw | ConvertFrom-Json
+$headers = @{ 'X-Townlight-Session' = $session.session_hash }
+Invoke-RestMethod -Uri 'http://127.0.0.1:15480/desktop/v1/suite/state' -Headers $headers
+Remove-Variable session, headers
+

A synthetic write +with subsequent readback

+

This example demonstrates the existing Meetings HTTP contract in an +isolated exercise. It is intentionally fictional. It does not start a +service. Its authentication setup is included so it can be run +independently under the signed-in synthetic account. If a write times +out, inspect current records before repeating it.

+
$profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite'
+$sessionPath = Join-Path $profilePath 'config/local-session.json'
+$session = Get-Content -LiteralPath $sessionPath -Raw | ConvertFrom-Json
+$headers = @{ 'X-Townlight-Session' = $session.session_hash }
+$body = @{
+  title = 'Synthetic documentation exercise'
+  scheduled_start = '2026-11-05T18:00:00-07:00'
+  location = 'Synthetic room'
+  meeting_type = 'regular'
+} | ConvertTo-Json
+$meeting = Invoke-RestMethod -Method Post `
+  -Uri 'http://127.0.0.1:15480/desktop/v1/meetings/meetings' `
+  -Headers $headers -ContentType 'application/json' -Body $body
+Invoke-RestMethod `
+  -Uri ('http://127.0.0.1:15480/desktop/v1/meetings/meetings/' + $meeting.id) `
+  -Headers $headers
+Remove-Variable session, headers
+

This write requires Meetings to be enabled and the signed-in staff +role to permit it. It is a cross-suite integration example; for this +product’s request models, use the complete technical reference +below.

+

Complete technical contract

+

Read the Core API reference +for every documented operation, request field, constraint, response +declaration and source supplement. Download the OpenAPI JSON for tools. For +Station this is the suite-side schema only; its separate service +contract is documented in the API supplement. The reference directory includes +configuration/source inventories, dependency declarations, native +command contracts, MCP signatures and candidate evidence.

+

MCP and automation boundary

+

No direct product MCP server is exposed by the accepted Townlight +desktop or Station boundary. Do not configure an invented +townlight mcp command or assume an AI client has staff +permissions. The integration surfaces for this beta are native IPC, the +documented HTTP APIs, source bundle imports, exact exports and the +existing Station CLI.

+

The bundled transcription code includes a TextFlowKit MCP +adapter as a separate source capability. It offers job-based +transcribe_media, get_transcript, +list_jobs, get_job_status and +export_transcript, and additional tools declared in that +adapter. It uses stdio first and optional Streamable HTTP, with the MCP +SDK as an optional extra. It is not automatically launched, +authenticated as Townlight staff or accepted as a Townlight product MCP +deployment. This documentation does not add such a service.

+

For a transcription client already provisioned separately, an +illustrative tool call is:

+
{"name":"get_job_status","arguments":{"job_id":"synthetic-existing-job-id"}}
+

Use a job ID returned by that transcription service. This example +does not create a Townlight record or bypass its review/Records handoff. +The exact optional adapter tool signatures are supplied in the MCP source reference. Station +meeting capture does not become live speech recognition because this +optional donor adapter exists.

+

Security and permissions

+

Use your own named account and save before leaving a screen. A saved +draft is durable; unsaved form text may not be. If a write has an +unknown result, reopen its record before repeating it.

+

Read source jurisdiction, dates, citation, version and visibility. A +copied source hash identifies exact bytes, not their legal +applicability. If a source changes or permission is removed, resolve the +source problem rather than substituting stale cached content.

+

Keep originals and derivatives separate. Review the intended audience +before export. A public summary excludes private fields only through the +applicable copy contract and your review. A renamed private packet is +still private content.

+

Drafting, review, approval, attachment, export, fulfillment and +publication are separate operations. A Townlight workpaper does not +itself adopt law, issue a permit, impose a fine or release a records +response. The responsible staff member records the applicable +decision.

+

The native session is validated and mapped to a persisted SQL +identity. An editable actor/reviewer label is not authentication. +Product/module permissions and source visibility apply at the server +boundary. Revoked/unavailable authority fails closed for new Station +operations; a previous permission result is not a perpetual +authorization.

+

Use protected local folders, account permissions and credential +storage. Never include the native session file, database passwords, +provider keys or unredacted support bundles in a public issue or +generated public documentation. A local public view is not automatically +a secured internet deployment. Keep network exposure and real equipment +acceptance specific to the chosen beta site.

+

Backup recovery and +maintenance

+

Save work and use Core’s canonical Backup Now before +maintenance. That operation stops writers. Preserve the coherent +profile/database/document backup and its receipt, then use +Start to resume. A source export is not a full +backup.

+

Use Restore Latest Backup through the supported +controls. If the result says Restore needs service +start, use Start, then Check, +and reopen a known record. Do not repeat restore merely because services +need to start. The fresh-profile acceptance verified that a fulfilled +request survived restore and a post-backup marker did not.

+

Keep Station’s dedicated database and media evidence together in its +own backup. Core’s native-profile backup must not be assumed to include +an external Station data directory. Stop writers during a coordinated +backup. Preserve failed media attempts and logs.

+

On failure, record the time, selected composition, +component/installer versions and exact message. Check System Health for +stopped, starting, ready or failed dependencies. Use the existing Retry +control after readiness; do not create duplicate business records to +refresh a stale view. Share only a redacted diagnostic bundle. Preserve +secrets, original evidence, recovery material and unrelated +installations.

+

Troubleshooting

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SymptomLikely meaningNext action
Workspace absentWrong product composition or unavailable canonical runtime.Check selected composition; activate through Finish Records +Migration; wait for readiness.
Cannot sign in / 401Missing or expired named account session.Sign in normally; reopen a Station launch ticket if applicable.
Permission denied / 403Account, module, source or browser-origin permission.Ask the authorized administrator to inspect the intended permission; +do not invent role headers.
Save conflict / 409The saved revision, expected source hash or lifecycle changed.Keep edits, reopen current state and reconcile deliberately.
Invalid input / 422Required field, format, geometry, source envelope or state is +invalid.Read the field detail and correct the input/source; preserve +originals.
Service unavailable / 503Database, schema, connected source or configuration +unavailable.Inspect System Health and the named dependency. Preserve work; retry +only after readiness.
Export refusedMissing exact review, approval, audience or source +authorization.Read the refusal and complete the owning product’s explicit +decision.
Restore needs service startThe snapshot was restored but services have not resumed.Use Start, then Check and verify a saved record; do not blindly +repeat restore.
+

Verified workflows and +limits

+ +++++ + + + + + + + + + + + + + + +
ProductRecorded resultPrecisely exercised
CorePASSNormal empty-profile setup; canonical activation; UI-created staff +and sign-in; staff denied user administration; coherent backup, +mutation, restore, Start/Check and retained/absent record readback.
+

These results come from the identified signed candidate’s fresh +normal-profile Sandbox exercise: real native IPC/HTTP/PostgreSQL and +selected headless controls. All accounts, source bundles and media were +synthetic. The guest install/uninstall and recovery passed, and the +owned Sandbox stopped. No host installed application or standalone +CivicCast was changed. This documentation task reuses those receipts; it +does not claim a new software acceptance run.

+

The workflow +matrix identifies raw receipt filenames. The evidence +index retains their original hashes; raw receipts remain in the +private beta handoff rather than being silently republished with the +documentation site.

+

The limits remain: actual city field acceptance and equipment/network +commissioning; Station automatic provisioning/SCM commissioning; every +UI/role combination; field recognition accuracy; and historical in-place +upgrades are not certified. They are not five invented feature +requirements. Fresh-install controlled beta handoff remains the accepted +scope. This package makes no city-deployment, publication or +general-availability claim.

+

Terms of service and license

+

Scope and status

+

These terms describe the Townlight Beta 1 software and this +documentation package. This is a locally prepared private beta, not a +hosted-service subscription, a city deployment agreement or a public +release. No uptime commitment, support response time, indemnity, +data-processing agreement or paid service is created by these documents. +A separate signed agreement, if any, governs services it actually +provides.

+

Software license and rights

+

Current Townlight-owned distributions identified in this candidate +use AGPL-3.0-only. The full license is supplied with +this documentation and with the source companion. The license governs +rights to run, copy, modify and convey the covered software; these +operational terms do not add restrictions to those rights. Historical +grants and dependency licenses retain their own terms. CivicCast remains +a separate product and is not relicensed by this documentation work.

+

When conveying covered software, retain applicable notices and +provide the corresponding source and installation/build information +required by the license. For a modified version supporting remote +network interaction, follow section 13’s source-offer requirement. The +companion archive identifies the source for this candidate; a link to a +different public branch is not a substitute for the matching source. +Read the supplied license for the complete conditions. See the GNU license +reference and GNU licensing +FAQ.

+

Data ownership and access

+

Importing a document does not transfer its ownership or grant +permission to publish it. The operating organization controls its +accounts, access decisions, lawful source use, retention and +review/release policy. Keep resident information, credentials, private +notes and restricted evidence in their authorized locations. +Documentation examples contain fictional data. No real city account, +credential or record is required to exercise these examples in an +isolated test environment.

+

Local operation and +external processors

+

The accepted beta workflow is local and uses named staff accounts. +Station has separate storage and credentials. Configure backup +destinations and optional model/network providers deliberately. A +configured external provider may receive submitted prompts, images or +audio according to that configuration and provider’s terms; this +documentation does not promise that every optional configuration is +offline. An email outbox or local public view does not establish +external delivery or an internet deployment. This static documentation +site has no analytics, account collection or remote font dependency.

+

Staff decisions and +source applicability

+

Staff verify the jurisdiction, source currency, permissions, +citations and proposed audience. Model output and generated guidance +require review. No draft is automatically an official legal +interpretation, zoning determination, permit approval, fee assessment, +enforcement notice or records-release decision. Official permit fee +authority remains with the adopted source and responsible organization; +imported amounts do not become a new authoritative calculation.

+

Beta operation and recovery

+

Use the identified candidate in its supported fresh-install scope. +Preserve backups and original evidence. Test physical equipment and +chosen network/service configuration before relying on them. The +supplied acceptance describes selected synthetic workflows, not every +screen, vendor, field condition or upgrade. Operators decide whether a +particular deployment meets their own operational obligations.

+

Warranty and liability

+

The covered software’s warranty and liability conditions are those in +sections 15–17 of the supplied AGPL and any applicable separate written +undertaking. This documentation creates no additional warranty or +limitation beyond those terms. Third-party software is subject to its +retained license notices. Nothing here removes rights that applicable +law makes nonwaivable.

+

Support and incident +reporting

+

Use the project’s existing SUPPORT and SECURITY guidance for its +matching repository. Report reproducible behavior with the version, +operation and redacted logs. Do not put credentials, resident records or +unredacted evidence in a public issue. Coordinate sensitive reports +through the channel designated in SECURITY. No new support address or +service commitment is invented here.

+

Ending a beta +exercise and document changes

+

When an organization ends testing, it controls retention/export and +removes access according to its policy. Uninstall may retain data; back +up and inspect the selected removal options. Ending an exercise does not +revoke rights already granted by AGPL. Later software/documentation +versions must identify their changed candidate and scope; historical +receipts retain their original identities. These terms do not claim that +a city has accepted a contract merely by reading a manual.

+

Glossary

+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TermMeaning
ApprovalAn explicit authorized decision on the saved text/artifact. It is +separate from saving or attachment.
Canonical recordThe owning product’s retained identity and saved version, rather +than an editable copied label.
CompositionThe selected set of desktop modules; inspections-preview exposes the +eight staff products.
Corresponding sourceThe source/build material matching the delivered covered program, +subject to its license.
Derivative / Records copyA separately prepared document with its own intended audience and +hash.
Hash / SHA256A fingerprint of exact bytes. It detects change; it does not +establish legal authority.
IdempotencyRepeating the same identified request has the same intended effect; +changing its payload can be refused.
IPCThe native desktop command boundary between its browser interface +and Rust host.
MCPModel Context Protocol; no direct Townlight product server is +enabled by this beta.
OriginalRetained source bytes. A reviewed derivative does not replace +them.
ProvenanceSource, version, date, actor and relationship information retained +with evidence.
RevisionAn immutable saved version. Later edits do not inherit an earlier +review automatically.
SnapshotA fixed audience-specific copy tied to a source/reviewed +revision.
StationTownlight’s separate media boundary using a pinned CivicCast-derived +engine; standalone CivicCast remains separate.
+

Alphabetical subject index

+ + + +

Source and document control

+

This edition is authored from the immutable corresponding-source +companion, the generated installed-domain schema and the retained +workflow receipts. The current software versions and signed artifacts +are unchanged. Public historical pages are not synchronized or published +by this local documentation task.

+

Workflow subject index

+
Townlight · AGPL-3.0-only · Candidate evidence applies only to its identified artifacts.
\ No newline at end of file diff --git a/docs/beta-1/versions.html b/docs/beta-1/versions.html index 4a621bf..04ad542 100644 --- a/docs/beta-1/versions.html +++ b/docs/beta-1/versions.html @@ -16,94 +16,94 @@ Terms and license

Naming, Access and Notice source candidate · 2 November 2026

Prepared documentation. Build, signing, installed acceptance and publication remain pending.

- - -

Component versions

-

This is the prepared naming, Access and Notice candidate. It has not -yet passed signed Windows installed acceptance or been published.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ProductDistributionCandidate version
Townlight Coretownlight-core1.3.0.dev2
Townlight Recordstownlight-records1.8.0.dev2
Townlight Meetingstownlight-meetings1.0.5
Townlight Codetownlight-code1.0.9
Townlight Accesstownlight-access0.5.0
Townlight Noticetownlight-notice0.3.0
Townlight Zoningtownlight-zoning0.2.3
Townlight Planningtownlight-planning0.4.0.dev2
Townlight Permittingtownlight-permitting0.3.0+dev.2
Townlight Inspectionstownlight-inspections0.3.0+dev.2
Townlight Stationtownlight-station0.3.0
Runtimetownlight-runtime0.2.0
-

Desktop source version: 1.7.0-1. Intended MSI version: -1.7.0.1. Candidate MSI, signature, hashes and installed -acceptance remain pending.

-

Historical releases retain their original package identities, version -numbers and evidence. These candidate names do not rename historical -artifacts.

-

Station remains the existing Beta 1 Python service. Its separate Rust -development line and standalone CivicCast are outside this -migration.

+ + +

Component versions

+

This is the prepared naming, Access and Notice candidate. It has not +yet passed signed Windows installed acceptance or been published.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ProductDistributionCandidate version
Townlight Coretownlight-core1.3.0.dev2
Townlight Recordstownlight-records1.8.0.dev2
Townlight Meetingstownlight-meetings1.0.5
Townlight Codetownlight-code1.0.9
Townlight Accesstownlight-access0.5.0
Townlight Noticetownlight-notice0.3.0
Townlight Zoningtownlight-zoning0.2.3
Townlight Planningtownlight-planning0.4.0.dev2
Townlight Permittingtownlight-permitting0.3.0+dev.2
Townlight Inspectionstownlight-inspections0.3.0+dev.2
Townlight Stationtownlight-station0.3.0
Runtimetownlight-runtime0.2.0
+

Desktop source version: 1.7.0-1. Intended MSI version: +1.7.0.1. Candidate MSI, signature, hashes and installed +acceptance remain pending.

+

Historical releases retain their original package identities, version +numbers and evidence. These candidate names do not rename historical +artifacts.

+

Station remains the existing Beta 1 Python service. Its separate Rust +development line and standalone CivicCast are outside this +migration.

Townlight · AGPL-3.0-only · Candidate evidence applies only to its identified artifacts.
\ No newline at end of file From 3021821bf9a92c790a399ad12aed821d65b09105 Mon Sep 17 00:00:00 2001 From: Scott Converse Date: Mon, 2 Nov 2026 22:36:43 -0700 Subject: [PATCH 5/7] Synchronize current suite documentation and working catalog links --- .../docx/Townlight-Access-Manual-Beta-1.docx | Bin 0 -> 19050 bytes .../docx/Townlight-Code-Manual-Beta-1.docx | Bin 0 -> 29556 bytes .../Townlight-Inspections-Manual-Beta-1.docx | Bin 0 -> 29706 bytes .../Townlight-Meetings-Manual-Beta-1.docx | Bin 0 -> 28339 bytes .../docx/Townlight-Notice-Manual-Beta-1.docx | Bin 0 -> 14492 bytes .../Townlight-Permitting-Manual-Beta-1.docx | Bin 0 -> 28799 bytes .../Townlight-Planning-Manual-Beta-1.docx | Bin 0 -> 29421 bytes .../docx/Townlight-Records-Manual-Beta-1.docx | Bin 0 -> 30264 bytes .../docx/Townlight-Station-Manual-Beta-1.docx | Bin 0 -> 46805 bytes .../docx/Townlight-Suite-Manual-Beta-1.docx | Bin 0 -> 30201 bytes .../docx/Townlight-Zoning-Manual-Beta-1.docx | Bin 0 -> 29612 bytes .../pre-naming-2026-11/USER-MANUAL.html | 1601 +++++++++++++++++ .../station/pre-naming-2026-11/USER-MANUAL.md | 848 +++++++++ docs/beta-1/index.html | 2 +- docs/beta-1/manuals/access.html | 528 ++++++ docs/beta-1/manuals/code.html | 1003 +++++++++++ docs/beta-1/manuals/core.html | 26 +- docs/beta-1/manuals/inspections.html | 1046 +++++++++++ docs/beta-1/manuals/meetings.html | 969 ++++++++++ docs/beta-1/manuals/notice.html | 198 ++ docs/beta-1/manuals/permitting.html | 981 ++++++++++ docs/beta-1/manuals/planning.html | 1013 +++++++++++ docs/beta-1/manuals/records.html | 1027 +++++++++++ docs/beta-1/manuals/station.html | 1588 ++++++++++++++++ docs/beta-1/manuals/suite.html | 1130 ++++++++++++ docs/beta-1/manuals/zoning.html | 1002 +++++++++++ .../pdf/Townlight-Access-Manual-Beta-1.pdf | Bin 0 -> 213724 bytes .../pdf/Townlight-Code-Manual-Beta-1.pdf | Bin 0 -> 337440 bytes .../Townlight-Inspections-Manual-Beta-1.pdf | Bin 0 -> 342852 bytes .../pdf/Townlight-Meetings-Manual-Beta-1.pdf | Bin 0 -> 326845 bytes .../pdf/Townlight-Notice-Manual-Beta-1.pdf | Bin 0 -> 100135 bytes .../Townlight-Permitting-Manual-Beta-1.pdf | Bin 0 -> 325029 bytes .../pdf/Townlight-Planning-Manual-Beta-1.pdf | Bin 0 -> 334163 bytes .../pdf/Townlight-Records-Manual-Beta-1.pdf | Bin 0 -> 341705 bytes .../pdf/Townlight-Station-Manual-Beta-1.pdf | Bin 0 -> 581409 bytes .../pdf/Townlight-Suite-Manual-Beta-1.pdf | Bin 0 -> 339044 bytes .../pdf/Townlight-Zoning-Manual-Beta-1.pdf | Bin 0 -> 336575 bytes docs/beta-1/products/access/index.html | 1 + docs/beta-1/products/code/index.html | 1 + docs/beta-1/products/core/index.html | 1 + docs/beta-1/products/inspections/index.html | 1 + docs/beta-1/products/meetings/index.html | 1 + docs/beta-1/products/notice/index.html | 1 + docs/beta-1/products/permitting/index.html | 1 + docs/beta-1/products/planning/index.html | 1 + docs/beta-1/products/records/index.html | 1 + docs/beta-1/products/station/index.html | 1 + docs/beta-1/products/zoning/index.html | 1 + docs/beta-1/reference/source-inventory.json | 6 +- docs/index.html | 2 +- 50 files changed, 12963 insertions(+), 18 deletions(-) create mode 100644 docs/beta-1/docx/Townlight-Access-Manual-Beta-1.docx create mode 100644 docs/beta-1/docx/Townlight-Code-Manual-Beta-1.docx create mode 100644 docs/beta-1/docx/Townlight-Inspections-Manual-Beta-1.docx create mode 100644 docs/beta-1/docx/Townlight-Meetings-Manual-Beta-1.docx create mode 100644 docs/beta-1/docx/Townlight-Notice-Manual-Beta-1.docx create mode 100644 docs/beta-1/docx/Townlight-Permitting-Manual-Beta-1.docx create mode 100644 docs/beta-1/docx/Townlight-Planning-Manual-Beta-1.docx create mode 100644 docs/beta-1/docx/Townlight-Records-Manual-Beta-1.docx create mode 100644 docs/beta-1/docx/Townlight-Station-Manual-Beta-1.docx create mode 100644 docs/beta-1/docx/Townlight-Suite-Manual-Beta-1.docx create mode 100644 docs/beta-1/docx/Townlight-Zoning-Manual-Beta-1.docx create mode 100644 docs/beta-1/history/station/pre-naming-2026-11/USER-MANUAL.html create mode 100644 docs/beta-1/history/station/pre-naming-2026-11/USER-MANUAL.md create mode 100644 docs/beta-1/manuals/access.html create mode 100644 docs/beta-1/manuals/code.html create mode 100644 docs/beta-1/manuals/inspections.html create mode 100644 docs/beta-1/manuals/meetings.html create mode 100644 docs/beta-1/manuals/notice.html create mode 100644 docs/beta-1/manuals/permitting.html create mode 100644 docs/beta-1/manuals/planning.html create mode 100644 docs/beta-1/manuals/records.html create mode 100644 docs/beta-1/manuals/station.html create mode 100644 docs/beta-1/manuals/suite.html create mode 100644 docs/beta-1/manuals/zoning.html create mode 100644 docs/beta-1/pdf/Townlight-Access-Manual-Beta-1.pdf create mode 100644 docs/beta-1/pdf/Townlight-Code-Manual-Beta-1.pdf create mode 100644 docs/beta-1/pdf/Townlight-Inspections-Manual-Beta-1.pdf create mode 100644 docs/beta-1/pdf/Townlight-Meetings-Manual-Beta-1.pdf create mode 100644 docs/beta-1/pdf/Townlight-Notice-Manual-Beta-1.pdf create mode 100644 docs/beta-1/pdf/Townlight-Permitting-Manual-Beta-1.pdf create mode 100644 docs/beta-1/pdf/Townlight-Planning-Manual-Beta-1.pdf create mode 100644 docs/beta-1/pdf/Townlight-Records-Manual-Beta-1.pdf create mode 100644 docs/beta-1/pdf/Townlight-Station-Manual-Beta-1.pdf create mode 100644 docs/beta-1/pdf/Townlight-Suite-Manual-Beta-1.pdf create mode 100644 docs/beta-1/pdf/Townlight-Zoning-Manual-Beta-1.pdf create mode 100644 docs/beta-1/products/access/index.html create mode 100644 docs/beta-1/products/code/index.html create mode 100644 docs/beta-1/products/core/index.html create mode 100644 docs/beta-1/products/inspections/index.html create mode 100644 docs/beta-1/products/meetings/index.html create mode 100644 docs/beta-1/products/notice/index.html create mode 100644 docs/beta-1/products/permitting/index.html create mode 100644 docs/beta-1/products/planning/index.html create mode 100644 docs/beta-1/products/records/index.html create mode 100644 docs/beta-1/products/station/index.html create mode 100644 docs/beta-1/products/zoning/index.html diff --git a/docs/beta-1/docx/Townlight-Access-Manual-Beta-1.docx b/docs/beta-1/docx/Townlight-Access-Manual-Beta-1.docx new file mode 100644 index 0000000000000000000000000000000000000000..2edaf64861c25b0383c5dd0f85787f348f2892c0 GIT binary patch literal 19050 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 Bj*x4Qq2Y%us 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 literal 0 HcmV?d00001 diff --git a/docs/beta-1/docx/Townlight-Code-Manual-Beta-1.docx b/docs/beta-1/docx/Townlight-Code-Manual-Beta-1.docx new file mode 100644 index 0000000000000000000000000000000000000000..54b01ede2123d5fb003b5c6aeb7105ef2ef31d57 GIT binary patch literal 29556 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 I{`KyE01n)FHUIzs literal 0 HcmV?d00001 diff --git a/docs/beta-1/docx/Townlight-Inspections-Manual-Beta-1.docx b/docs/beta-1/docx/Townlight-Inspections-Manual-Beta-1.docx new file mode 100644 index 0000000000000000000000000000000000000000..a8018813aa17b8fc36c98e54d24a740e18ffd81c GIT binary patch literal 29706 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 xQG$4V4s9P;NeO*C@a=ck#PIe2{ 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 literal 0 HcmV?d00001 diff --git a/docs/beta-1/docx/Townlight-Notice-Manual-Beta-1.docx b/docs/beta-1/docx/Townlight-Notice-Manual-Beta-1.docx new file mode 100644 index 0000000000000000000000000000000000000000..3c633834b1d5ab1fb8f2785612cae640189e03da GIT binary patch literal 14492 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 literal 0 HcmV?d00001 diff --git a/docs/beta-1/docx/Townlight-Permitting-Manual-Beta-1.docx b/docs/beta-1/docx/Townlight-Permitting-Manual-Beta-1.docx new file mode 100644 index 0000000000000000000000000000000000000000..390e03b9e920969901d1199f04310059d5483a8f GIT binary patch literal 28799 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µu89tOu~yy(J6|CGFwLzT6!r8i{BSVby#REZiu?=*1GLB|O zYQ7Iht452EF}Lc+Lu90A9!d##^Azap#`|n>>?KSP=C}i1?;h>Rlp3p{pZKibVJ5QV z6xiP|Lf}&cZrT``?7OEB?kU2Nq`NABJ_jF5_Q(aQ=<;PP4p9`ZA*B zlDd{fUu$}CAR^ewby}4hs@dr)^3oI|P4d$+>##;_g6r226KOq+k!HPYzYyK=_2)SqCm+jNtN1VL5tf>5 z;pW`kkq-A@=k*VN0jV4&JB+J>Yvjm!M}2>n?e~gb@3;Pc6|;MPrhk3@Kc($H68KnI z?Kisiz0>@w&e})d#}Z_}fj#ec`2Q3n`w0ISsq`DZEdCGt|A<@qNa(AcKEh{~rtYBl@G|^&6dP_|L^Z+F>6_e0irx6ViW iN7eKj|7`gW{)3{Dl>i0%>nw!#FAT`LQnUK&-~RyguQcZX literal 0 HcmV?d00001 diff --git a/docs/beta-1/docx/Townlight-Records-Manual-Beta-1.docx b/docs/beta-1/docx/Townlight-Records-Manual-Beta-1.docx new file mode 100644 index 0000000000000000000000000000000000000000..7802795c0009281b3358665930ac6ce790ef49c9 GIT binary patch literal 30264 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 N4h#qg!~U;#{|CPa*n|K8 literal 0 HcmV?d00001 diff --git a/docs/beta-1/docx/Townlight-Station-Manual-Beta-1.docx b/docs/beta-1/docx/Townlight-Station-Manual-Beta-1.docx new file mode 100644 index 0000000000000000000000000000000000000000..bb4e7a940e1451d278223cd0bb6369af4c91290d GIT binary patch literal 46805 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%0Dc*eT80Sia_itWs^PdK!Q;pwVIuymOW9n7Ffj z5{S}(Wg@xBzO7RFc=E0q8*JRk2Aeb3V52rR*qCyAgDA=8D+*W}(aX)XYXL`?NSC?S zBn!$ONc&0=q78c;?svo+vQY7YD!)w(fK+Vpxv_80A2ugw3moCiC>i_!ei>fDg>G>| zWp5$KcMOAs_+4>&(id3N>&X;|N3ktkk|<+fL75JM3@sFq1c}1pV>06?io^CX##Jjy zkj*<;XKM!QY}Up)o49)_6E&69aWY@lp{;wRC2+ClS&n8ux+^HeQG81dxq&QC<1t(5 zs?Z8pPYV{1(GA)i8Ja5rSUR7q*4UoG8e6ro##RU1E{y8TDC(UnkC=d& zkuO*i%`sHe1j@I@PZxuW@N&E zdCep?mH*0=14|0(hf}=BkzyMHreF-Skl~qXY_WYOTRfk^7TdM4#db%$C9#Umpeya3 zuj$Fk4$VEAdb9xoYaEig$uhJsxk4EkdFpOb9)$e!3$PeG43TItm}E+KUAW(t!b>z< z&MAt|u>ml2;Pf$Wf1(nwgRLh z{uX_(=t>~p*wnDou@~NZk%;C1hE*vYj9QP#Z;qV41Ic6=*D{TBx5;3!`6dm1Q8k8n zaVNvPoWU?JYGareU}%J~sckU%ulc(w$g3uzVx5qVc#TJzC*=ml=~4_j2siI%M;=XV=9fbu)W6F96X+L#;c0fe1O)%D1~pk%Zh!kTJhi%=Dnd&E zf9`WM49yKcPciPWBl3uUf}P6L$O7KUM6eA3E-c(|ahV2OkB2HOkIo}p0jw(zGi<-Y zR%f{H+9)f#h}3DCTV=tMR(zdczmoB_e#z57nPPIBS2!Fu}hXC&7e-SPu9MV|8O&d{W4GzEskcba68KSmEwPJgr=0)s3DwR0PLYw|UGB^TM zG*;L+vwSKYE^|L1>14PCvz{q7Q5h`<+Z>P4nN?q?b4oi~22LULHS07R-OsqBifE7Y zh?5C7-{D!|!sz0#RmIUczCiYwsQeV&3m|P6y6?}KqWdOR-7-rpdJS8~Iz&sXWrzi? zULJzH4!K{`mV1;81lOBfHV$@6bqXjo6PZw)F)YAs48qV7_BBEtI8*37`g6$Azo$Iv!zQVxSzg=SsjyHAK^*X?FQDV=W0M%otF zqBcMDm|x@oH0EkBfK8Vw&Lp@i=j!P}1OHW~{_K(V%v;e}+c%~KdnMx6T!sXBVJdz+m2xe8fuG_GZ7`?F=PsyZYXEej zlsBS_auzXZDp|ra)BdHO-_1ML>61LumM)3VI{G#UG%9#WAq`(dSWwE|p7vhj|gpwbm| zpX{>zZsk+!N`x}!sux-)-}~zx7e}Lv%4Omja#PHbOG3{Cs@;?mC{%K7A~`~aU|Mlt zv)c8!Gv~cgs`t_^px-tD{5CA5Z967vyD>!~!6h}yof>yo8Dk^ZT-3IdE0Bg+VTejRZSLDQEg^tML5BxC@BgJpQ9KBGxWRzuv71w zTT!v4NL@IEa)|D(=9uyIy0~tsBnB&5II?W(2ZS+rr_vF|)P5pzJ-+h;4gQ*l=Yj}R zMNPJ@Xh95vce|$jVh#DCw#8nVWw>d7uELV8ICbF5EoMJ^>_FPWu1Y(|uwQeLoeowg zRd_oqdRz2J#;>-bt!xSyONWc^tv0|MH(}D5-at(<=mxiahl}!Ev6IGH7@s{#Lp7?8 z;$NoKbg0|~bwc^R~ zaHv)G1TX+kq#pjS3hTg1JG+r~h-NwNyg0n+V*?u*s7~2e+Y-`{Js%&P_C@z%t*dLc zEfC5Y$nxqT*NWx+9{B3BF4jy+yvZYq=l0|C`w`-A_a^c_I57Q5qVE0ZfB7|!vmJ9` zJ_kO3eed^G-pZ?cKl(JoD_wCTYv#W;{jrIEys%%||LWf2OvB?TPm4`mI4s?q(>lW3 z|Gl64?|)fh^0NZ}jJ7~?=>MSG;sibhFu~ItcgD%)(q9jo^7y(=$nL76(`@OFh${9z z%i1?m^XcG>22d^S-d2C@#j9Qq{=eOO4u3BF0fDnOPU1{O-sJPSnk@M_6}QM*lI>ov zc01tj4>2bnRe32nJ?*yZ9HGN~7o23Qo}5ahZSOOA3#Kf^0P2Joxt?5)U>Nrp4Q6&x zO|c<0H=D4>3^07wndq35zO;QHIW66Fj-4p(aYu}#f(-?*A+L~&6pf?YHJvKx)v&J( zj+|L#fO#ouOXWf@3vk{P?6ROr?D46>S&v;bcX+*WF^{^2a6G|ykEh!)DXU5zcu+!2 z94i@>(gc{58WIG@1EHfHRCCPmTrNs)(W6}xSgJrIM5Xjzm!c<6bOx1!j*+KA$740I z7>W#w04FX-6tOLp>sbchK{*A>2~9~LP9bpu(huOV8C5o8J3K+#Q1;$*%%y4w;>~A) zgh@kXpfRz!oxcNu(=!nX;4XXAYldeMiPa(HuFb0q zLKR*%+x=^%LE*n56Qzh-t>NJ7bwXT;FB^j)) zQqtHg&+od1!YgD_1%^stP2W^7S&PO#ny!;!%xt)eoGw{!t!+MUZNAuOZErs3MjwOt zO$5{UnXOi@*Tetu&w+@PLNE1Sv|LunRVGsL8pBT;%Dg|`?u_)3YStNchyd?t#z$!mRo*$DI0rSi*a;^xj4@AXoPH+3pc)yA;kYnOWn zYZE=pp5+P|(`~!34qyVnk&7`eoUW?Lq$tB%EHE`ab?7y16@&m80!^`@Vqd+o9px3) zRMG8N=xlt^_;;#~iI4l~{T}G4wMFve_ek;~0 zMG=gt&Ma#10Zp+;!RH#h32!tnyX4^4927EE;WmV@u1dh1dTp+#sd@Q!s|1|pT>d(N zb@N}F{@BDnUf3_~e@malL1DV&=VXk9r9XWYy7n;EXZ_{EkF%cL@|#>0b2$do4S3%{@ubQQRVMDC%1)Q$lP=AN>zj^zx>Usz zc~6T-=T#*iW*Zu^&$6x6{afJwy{2s=6nyAXDyHiCnj>Z$wP740CPmS~%M4w>PjWn7 zQD>ylDi{psZhZ@CZIm2ykA?lMZ7oa>*ji}p^Muq0M*3Rx<$L<)SF?iLfyj z?V!R`D~;|O;<|WrRPl3b?UgHcS`ONiOBi^;w$REZCP6dinvAhQ3On^AmNF6&qe%(# z8oPy!CZh@G6=;{5r{=J^R=9gcrx1)^92&4i9*ck)xP;F^Nl$$L2%)4Rzao2FOD=_a$_Mbt+ZPU)$HV<59nFYSOJoxbnILn9oO%b;Xq zBk#2IGXR$62Fy!oFVgHkE?@TW(WQ$we3k%L-Hc|3P+tIun~Tv{jx-!m6L}JgJH{gS z{qbhk)bdy%GzErg=9lCHjS~PO2mdb21Pf$-PPmpZU48s^s7q6nu&&WmK~70}Hxd{J z!}u3i1*E6O7I6Vq5)kAP`fR8+uex=%l*m;hnNqco5UoB&7Vh0a597tnqoVS+jL(}~ z0i}nZWNJs8<%rosDA5|jzeTy49nfTOeaf>7%96QEAZJmHN+ovYWTrusE!dIS0!<~e zQBf4*^TYwTf?!94Y0@ns0(b5D>WoX43L0IJoH0yiCO#HH5v$khB>|Zg?jEruK>>p1 zxzUo{GUo>c2rkw5Ek+YPyj;eVjh1n)OXFHhm1HqBg#f29b%7XPDw_uDbA1LV`_X%% z+FTb72A2iiRLuvta~8oyX%>M2;cA;Xz-_KnM~E;3o=*^GwfO-j{CYQr*uCCi_v7p5 z>I-mrtTciDF4(tS^zGbS2{SvJHIIX=vkf(^B8i||b}Er>S(VA$F_j3oHi7^>P8wq{ z)h&XDsHdh|1W|ifK%>)u1$u8d>4*dP0b!V5pU$+H+jgyl{^_Jpd3B;Pqtw6Tj4I89RyfZQ=ISw7ikc8iv{plQbSyfNf-i`$_!8h zW7Hg>M$O0J7Y7sUsVas5u&Z8xh@L1!`d2qkFhUj|<0Zmvn;ClA z#1+f7aiYs1NgD3r8a7P>w+T}^j*3$=efmRO>V?6H#sP&D-NKRljNCQm?xDfN$%lDG zAx!hP8GWK>7Aq~lXwEDo^JmRR-YrceNvcFFn$oMy7Q}L{9T*qy?Q$;O%|WZS`Ww6I zM03)Z(|03I+j-E{spr1#Wco{`c+0W7#VSE5eX^cb>1Rmb-7;`=b`kdy7=3(e$bVG>Ty;!T!b4O~U)i=H^fOOrz z+_+=Mt%E2G5x~3NiemA(jbKtE7ZoEMl(}^ z>hqWRU3Q=}zH6?|@zm4<8>|GnoTgD0$#sanr~PS|>HeXS+>GEW1sPDlPe@X}bv!;GSAfx29;u)H1D<_iX|%2>Ak z0bG?+FAc!T9^^sDm;{U2^G`Ur@kM8?vt8-bD9-3B4VxI4c&s@@JGTSOZ8Dg5rX~WE z8kxaW^)ly6w5()6vsfXxKjZJB3Nb@dur)u&`h-008X98Y|S*~ykT{nNYM5S0KA3fT?Scu)!XwY5NwDGircdoH>( zY~shm)0%W94TCU{4AbK)EY1|k9Sn6CDGiP@%1O#ap`Sy6UULYd*ICRcV#naQXOf3WDfm3k^KdbeK}?f9Vssrb zf1`L{>a-_FPlu<7P{IY6XL`xpTpH_vC=<9a8Z3ta_Aribx;fCqF##sTQ(v>eCMm7%)_P>QNWfrswkiDF%fJ)?0I)&;9LB3VRnZF zW=+{)`FJ-rE9#`!REqg33F8T+i0l@*IxMj1AW%$63||>3VhT?DKuoE*~NUn@)(ZY7D2#S6Sd|jWz0!j9VOlvl&RmmJKEcQw|jiN zzuVva&CfJL^c0=jN-_pd6^IQM4H+oK1W}qKX!DK{Ek|YC#Xhd61~i8KqN`ml7cKi5u| zurHgdqr7+1xDQP@g2rjMGPOuYGSQk_00^b5Pd@YO5 zRs#Bd3KxA!JWvZNL&IXHe!(R!-FUlV;9V?0y%PKvP!8m@l@MGJ#;c>$ z+$EKllyCYtI5T;S9qJI{Kr4~V+7Fz1vhX5qn%-ZT8Q|r}f7!$0hIfu~+$bUcc@mBu zNXf}Rg@)1x3sfPmoZVp#&BwEM~nrA?Zf#wiz$;>a`M2gAb{c^-XLX~L>BDLDzI zp9rFhI!=NV^a1D$7SJXC2K2VVT6K^;IC_?iWh{!rOd-XzutLWcY8Ym#h9x{DH>$Yzs^x6fIb-58k%KZ<&au6iovq8ppMa2aL_ zWSG0_c4_R@hWMnemZW`^8EW!N1A@NL)iPgC7?JOF);d)pp)El}9u~7$O8azE{Il%? zx2?T|)mO>5FKD(X0#BKo-B#yir%D)hK`W-z-t*2z=Xp(hFHKb{XY%NENtlBn2Nddc z){9x-rIrQGcbZ(N?f$XI=}w^R9v^aM*ra7lk1y7R7u`A>OIr+WugMtE14383gm&sd zsg=>%vo4IZ&`nmAE7s;PtH+{n@`5;rMzM=LO=4{olb)bR|TdbU}(h&Bj(1g(WgJ25)8UZZM@%>S<_5=_W&?`LLc@>?xAt=DFl(h zXJv>rtM1(xCbChW&XgiHH=yJ*akepzsmhhY{@v?=&^*D>qgVL}oHlFZWixa6)-@ed z7Lc-*JBSHjy#|}XgsWPt-9B(QSQe?S@|A zq`H^8;@Y{}c}6mllr#oObJ8nSF?OHG`33>4 z+#A9d4`;t%Sda#mlzJht#GfLM*j$fsQk1a`q0TjpS)WnTkR8YAS;y_VQ+?MvMLM_0 zDm7$pE-QIjd0Q=U5u_BG!#F|S7%b}#eQ|nl^3&no!OxG{od<>t9v9+wfTE&LG-Qj9 z;l@@eFG_ichV1DfJ1H!qHfC@l6}l_dkX=1STGGTGCo-s%0PM8Wz4vA^8Wpe#p&e=w{MsKOCg-!4so8c!+RR*`=-1_MPBTiaRF;D*L(lxf35Xi^jc!0Cx!_-KHE4K=zNgq9oI0+O^$?H zGi}6=<-|_Uu;4#75fpRM(4nrHgiMZo@9(Ev4{qqtaY!#HxhOj#kL)-^m)$l^rBiLs zapW57<~KHx=M}Xn+h!7{+6}3?G8>f=3CQa$5!;ft@^CIn8n#CSIf=L7Dn6qZH3 z8#-59g3>rQYP3N8!1X!Q=WSE$wrK7OHcV;0AuGPO60EMw^WKA&4ghr{rpadmd$c0Oj!$4bg2Xe4d1G*Rc`NE3~&0ycavml zOC{8qKfib`z3q*)-uCv^mU_AV{JGj5dY&iO*W~k;8>+XlIZ!WO3~LLT9b-?t!7N}X z0c0mHBL*!Ga#+Ol&%PPY$>2Ywc&Kz(8Pp+#F~l&!9e|}%}hLV?4+Gc zWs|K#LyMH_&aF|{m?+Uxl+?S@HUnOx6&sbda7dx&!qlOvIPifQ6L0Zj%(i?6tqf*} z|3g2mG!AlZm>@=KML%)U#5H<|6IX%HNhsIkKq)TQT16&1svf^2;I2Tu zxD+r=TX0o_Q(alyf5t!q)?J^jwY0uEfdQe%;CyuIy2H>%SzNbFI3t}a zur@BgDVL!uN8NC3HlfPV2qf8jLn7dEqV6DIDg3S_OPnqUTNc~!DwS^(FcAw|^NZ(O zRob1a)GbUt#2lNu0`APzJj|ZUS5nN?o6vg-^4u##U^wTvasA2W`L8d4s->*<%?WuuYz|LLIxw2MPslE zwW3ypO76twOvH^T+j^~>jE+;)hGn)(sr5FtBDbeJi5e5qv9YX63!q-;>44%~ZR(Sp zL1cI)69q-NI^DHr9>~+TBK0iK!o?+#WD; z^(UDIXeQlz8sUF2lHyp-MnahRmJj4`-TNK)KjkA+x_0kJ|FHNqR~`WQ2ax0KX3)Dj zyQt`*zSF$_(9g;XFZ)o7r+d|zrT=;3SI`}8PcdSS=x22`5m}NsSJ@Ubqdp}?oed{egFLup6cHgzvhPs zL`#!t{UX{HIK9V3)|yVnf{pyWce@m4_j3hE>+!w2W?jO@Rjw%6KQ?X?%B?JQ~Z>s$59R~e%xuyfw+p7sy^ zeAwSR+CNxA(zK%nSeN_C`>Dc%XSSt14LMf%p;dn9Zr!)XkW6M8n9CAPLvR)C&C9A6 zS6QJ&=TpALtWcBcL6*7zx=|6Bhlp8hXssqYtLyvLihI6N?!or#y18fZlvz2uwI!j` z*|>uZKi^dXdX<1)_~Q4{Ns`5c`>~uGIKct3;}0}o=0}F*n>`2YX?9X$CVG$X&uX;3 zXDY!Or81q&YeX_#LP^&E>HHwa{AlpY4X}|)FW${$67~CbcLufr%>=OaWE74x8dt< znwV=2WtK5u@+M9Xq&KSDY^#sx4ajL$=kw1?srdRaM^~F5TOJbU{j$D_@?KBfu8fUu zK+NyO(S=I0e%z*Lp{jV1n?wBCQqQ~kIFvzzi0R9?{5Lq2V8!&anEp)~kC&b8XOjQE zLb~cUYCMutm9_VHe%2D6LbHG~R^=~GYmzK)0fU`XpBSU6<0mo+7GdnxR`YkF#_@$} z+rzExoE~bPRwiGot}WaYL+RE&-wa1ZG1+)Rp&QiWaf9pBs0A7fuz$RJd}ymz!r8l*K{nzErNw~3VnlY=PL&nD@&ZlopcxN1 zmM5oKJZ9*p0j_J&=u~*O803*3nkk4p%ux8{DQq}DF{jxfJlGBQaBaLU4S}Tb5dyw5 zqQMieQkpfz!@6SnuA7DgJ9F3gA?Npiu|J1VX#y%wy=YBMZB{&p*3L!}D!K^LI6_Kv z#1T&1;E9fAr#LjLDTCwg!rZQMI~TG1Ti_I%zVurFx~nYbhR-%<^6Xvq!xL;4L?910 zqC2WA=u{Z%c;~b4 zp95KCzZ$LgS6u^7a2q~UusR#IZn!z;doIFL-!5vbwU1`cub;Q2^$>Mmvtq9;E?TP% zSIvv7Ztc_w0eOoqs!tI{pa(D1N)OI;%{97UE7yAES~pHCFa5kt&L#cK>P7#Y#5y~J zPZX|p_9a_6+H-ZZms832)1XE-W!?=dD)M4q`5(xJSVI0>M%$q_A39HirF7vAv?mj_ zFEiPks`$Ct;Z5%?T-K4U{i9DG-W~q7Jux^$f_&1Y^mI`{oCN?R#M_-DM1?Tw10H6`{Th%TCAkSHzO^6#x2|o zGPsf%S09b`#OvMDgU=sN-Yx#vmr+VQXwrv`F#a0;R_aOQC1wHJS7zXdUaD$q(|J{OBT3mn+qH|AhU~Nq_g<=l9DwMr27@Hc5jEnW+_Grx;jxk!kB}H|-W;DCyWyK(fejW~! zG#;pxl~Jumjy#bMM;}iQPEHT|D^W4O5{?y@R^-zCqYwR0C%~ky|E+(px2oz~DrSA? zAdAB)xPet^cF>IbP;uFO8;*DTZ^E8ZNh$L} zj;IX~@L?@M%~}8QkE)pgo7k;+O3ggV(?KGAy4Vwvu z^eetf!gzuM70fgmErw}4HjndEg417oHI#Xn=?)5EJAgrWBN?43Ek-JZ&n8JY!KpUh zCT{Fw#8Mq%-D`2Pn92c^YwTOd;=V_ zQQ=}7+jkS|o$|X&V~OD1bG@j2ybz_a9y$X~r?E-EpK*jYi0-5xcoHw3o<#7CEbv4c zhsxbxoG7K~TOz)Ua2%D)ie2Hwz~i>t)!s;rWs7D?!6o3UhBBag7RCdR7t$XGQJ^z3 z-3c~@BajX=oca_g4<5y%TFecCRk|~UHR8OMuy}i}@m7}yWSL%fnvGSODCMw@L8{o< zFH^e|$Uj!HOP523t6_Fk+bZ zTWaWEXKJl^ECpUILzEwrj*8B3GM!n|Se~oTd3xW4)x1_%i1@*+>AP5W%%rG)ryF&9 zbs~M_FOS1=d)Ts#WQ3(7!{4&(GH%)emum+h{vf_HOYfEtUAx9)>)wp$`h5qDzt5Ta zl707m2Q*HQJQ8N}VLL&^2D`8qtz#73cOzK&4>KAKTVz51Km~d&8rI04DzFOZQw!LM zxZyub`XB5+TEZWYLB^fG=7{)I7IXp~)Xiwv2N@hjKYd(G;eiVQ6L@CuXAb8^1{o0o zOeOGqzWZKCjb_uL7KH!7>oG0k<(c}9xa0KT-N9a8tcf=#NAE>)_8E;dEk3l{{g5bAX-!Fo->`riISoIh=Sy20+sjjulXplj*Y3R;@#1Yhabf8?&;~LqmzAM80!1Z z5PiICCOYpN&j(k2NdDn4Q0bIV`Tl#u^-i-bllk4LnsP;A5-ak$?T*9NR6Y&4t?rHzv&xidbEi`G*c0%U6>V4(?RN=wB z`pB`2(|PXS=UUsEA0kOGJ$V1=KaDDLx|YpzNh!=E`GHT)rWcQsP-W_x%a*DvoxmqM z)kaM>3q8f6$D(MAH$?>X?V`q^WnOsy$xu~!aU7gs!OO}V zU74dRb97~nuFTN|n4>I%@n1t3gv#GROH&4s2;(y@TC|4fl~OON()voQ(QeIkbce&j z?6-wrL~o$*FjFbfmg?g!F{4Tac7BV#8`IA4^MMwLOtAtjoH#$>Rq1$SCe#-R{{+M1 zT1LpZ5jr2E8zJ_&3@ue@9tn8{N3Jt*mMg8{ce#{}s?)HLUF1=!LOS<&@C%mMb;MC* z>g({CSWBsS!8hih^m&jJyGPE-O&zeZ^>hJ6?z72Edu9PuueTT|Pf+U$2dcg#Vc-SX zj@Ugu1Va7_^v|>{5!Cqr=#u4`5^#9t$`v=ZS`qB}okg%4MG-6=XdBL`4e#{MsT7tA zmfHr4O6l6FV0lr!pCb)f&w_1vynS?57ERje$i zcsfven%PYyc~Mf`5qq@Xlt>28=9+YOtql$0G&l<)u23)4;Og@%PN-!b%#ONN8vAMS`r;Ys=PS$Y575FFDdM2M+6!0s^UEP zF!pi{kBR*Fl4J);6cAPdsTjbq&8?cXvH?s2a|yLr13LaHule_nOGN%rO)!am|NN_Q zcx$5+-LCej1rV*!>{Zz$wcmm2+7)LHedytdA(MhpsX9HadE zU+QEP*N?UGzwh+F?<ZVZzy9XL{oj}|sjD2(T*{c$}F0hBcKT31)-{-0fE2zWf(CS3_L8`p$)C4__ zsIk2f>921KT5YKZR}e-#<{5r&igQ?T2c0<2IQmkZMWm!kMIgDtPypuPI})zRNbU{;5w;YACFMDx*sg-)m%0TUND3I!L`wzOtqN)|qrxdBm z+Ss0;q6S31niH6P7i6%Muv)f#6^>nnW4Qx{)J9Rx-uVRtTD5kTuO+zokk+SEWqH~F z1@J`naczz0k1`M&SM2;r21TticK6gMcbB+^wayCG8$gVoX5kH}b$-Bwu2_ZGp!9ov zYi?*o??Y70Fiw~70P1YmmszI9b$aXfk54tH@4W$S$n~FObNIU*Hel5ixo>mDesdNi zzy0k>dETWwYgV5txSM&~i#4W6-b#J&CCDnoyT4s)cfM=>hVWyk1n`JJM$BD8RD%q` zV=Nj8p~noX)XCQC2|s9yi$9r$=Ob&@Tv>Ym_)>F@VBW?>Qi+D&hg!wxG6%*_ z9DFaL;vzQo0JwOh{8vqhUR2!H&J+YZgNtK)|K=chGpi{dP~(hH&WmTm28BMaq21P7 zqirz9=^U1I)WGlWAD?&#iQ2DgE?U2TP3VJ`KVItP7ek&>9?sptpCa1%SJX;yt?Ikp zOFzo8G9@LJHOBP6sQE(g2MD$FNc-D|OPi<$rzZr1DLhuP*s^#(XX#X4wiT zZUIDJ0maRH@CqpI=}vV86gPjMxNgn!&0i~Uu#^ZT@Z|`|)8ZlL>6iwHYeD%}ngou~ zNFm{~d6aAAcf{eaG_HIogHX4os)bS&stXyJhF~5hp2@(p4x<;>HDm3OP1KI?V=9}{ zW(Ir=4@qG;$)qE8X*oO*T}Jv+rJ81%NATnk08{@r^Oz+1RW_9g$9CyTPu>;bWWE8%XAiIje3hy;o!qlpgi zqge_p4!@ouGp1s1{{vh$c$k-`DX4egYPzFmc}mrI_$x6F;e#{6Q%i+$&Hwq2|2-4y z;;T9j9?=!2ASPZ*?_A^wksX*9sF?wY>`kU~8N;_F$c!_E;$=tdf%ro*i3s*{p~L_l z0Z%9$5!kZ$z;Wkh!90lL^RZ0N58wrtuLA#vXPX;Hma9LfxQYG5<}>&gPTu(8*`L>6 zZuegFp1<7O8m_A~HS7(xUaBqcMeoI$zp?T1xi|FJo^Pu1GjCP~Z%HbjZB$SLdzPVq z4?`qF5FtMy!QuoYC`I6mCY!5%+5;6cyLe^+JdBiS>o`w6V+z#7(R_!I=H?zh(f$Xx zOZaO~-)p;gZ|c6Y;xYis9Jk6672A!60h!1k)`$y1LxXtqvK+pl6_I9~Yp@gYBmr6Y zasODnKR)=e-9Keh089jUxPr5S>z$22CR%Yxv=kD|231_}GZi6UBj@Yj4BmRnJ-?a3 zPl+qA-*Ogn&$bLv0NvXxygwvrWf$ZA4M3IAR=G|*@GF9c0`|zFG_fhkKxT2z^KMyLBYs_I(Y&cwd*{c8(Pto`#J|FOL(LWSP4?)t$QxZPbcptT3CU3WA| zMk?A7r0}#D$qW9awO$X^Mhb={d~`<~9$##dzhmNFz4c9e^w!qK7QGMl6!?;sa3H-A zE)5=r=y&i0Fhj|NMbAl(;>$>!tBLN2<224}IE?)U5vdG=B|BudnwW~r;R8{|?kWXQ zqLwI}01ZAO*`~^G2a$DDfh2JrWv?D`HV?5@tHv?^MUImOWa_I2tvzm9UHsCUlSO&G zjEf$NYkB$lc2Oggj~CY0%VT3Yb)Ii+2W+wk?KB1%TBATP?`cL7u1WOAluTWw5~iEx zYIgKTq>U-F;jRS+=xq>GPenngFj0zOo?+A!|ofkoq?2r!NC@#Gzt z5cCjuO%kLNG&8n)!k}ri%Daot19)*TRM@{Nz&b5HMS(eKY_avNZOk#iHX{rzn?>rb z*%O#SU=wx3iK1vRQxS|JIm8?Wt%BrlOY9yW0%bVG2P;6UrX6F9Zx88#kG9eJ?sU{H z@XLiU??hU~YBkUizcbQ|c=)}uW0LDke2 zoqtX5BF3@rn(NirS3{YHz)q1D)A0jCt-W0D{h$A})_c)wiH)8ZCcrY=;N6JxK?0WV zQDQ>4CV~z2GmBl#$27AZU;!ch_q%`oe0s2V^kM(>u`9aC=j(wV@nU-uNb{X<2>E=y z*ZaOD)P;Jg(EelT@ab^B|F$LyY^);*HePJ@kcAtv;kO5eKfdkPb>=T{$Lnj`y_xZl z1#I`tac%sKZgP`O_Vr=^WVe6t`H!#b+w=Mh*!32OyWS3|K9q>?<6-b+c9rP@$k0Ff z^x+-y_~+C9ZvXJ;!{-VMqacLIm7Bmt7<=c|b_sKhRtKtTtC%MoB~fWG48T|!a9vT3 z#!!EDHXijTXYv$0HE4UP)o+ z33w75#UeY!#C&j&g3eIAp6M_91qiYJZ(E8RW2o1xM)OUoebF7 zNvM!L(6W{R?kqz)0Zj-hs_D=GO18SA31)cX6m5}i63Pi!kW_+%31D7R3*HX22;pQd zWrPp5mby1mehzj>i;PdSYB}s@_C*U-7s%C~>SE~{9}XItRQW@;E86WEPZJZzd`-Mj z5c)f~Ku@)i2zcaNgoZnW&%%+GY}Y&z#}lyVBREwhqde(=tpuc_-@rxKI<_oT@H?FBIAroSlm@~w+}x9E0q^OfaAmcc?Am}IO-2~vxFXYogmaC1{P0~ zs?%s^OY?@GV}%~ARRhW#*Id09B2KgR(cl;5)mL^-aRHn%u#BPceK1KBMRMv}{P$lC zX!+uCRO=sf*PJ6*#@RhTs;qsyv=pyR%pCf4vUoMqs7V>U!(}uCYU7fFG>y|;qM$eh z&ks8s_PDj=QK*T{g0)_a*ZFERRQrZl=X{s_Z4JM5=Jw(VzntTYz9s#-)XcIHE_3IX zWv%R4$(084$+tV?tqF6O8dk2HNqv4Eg!eBhZW7z8FUzP%yLGMk_;7!vNWY@MMs1AJ zU&ckhS>=+Z9(|N&?GO2E$=w7+w~9qQfy{lkd)hzv^I?DQX#ZddNz;xRpr9+(_phcU z-)%_Gcg^3>utr31JGzWYU}0EfCH%lQ2xM_mOg=QlRP;%OIrGl4f)F=$YVNmXC1WAu zn>aoAGP?`niPYshC#5uYwCy9`)~&g*=7azd-E39HC&XSu5e&KYd!)jUi=@3U)@ny^ z1u<5vQmr)?ml|{=E6k|AxXVpe*x04541>?1{1W?&v}h`9GgWRSbNyF3Pq4OF$BaT3 zTm;^p)LBOyM(~Sio@88IYJds-Jms%{i3hHl7Mqp`nUOw^O>9|)1=1}Ge`l(Gsf2ci zs(N8t)UoC(?WMs$VQF|73(Hgy^#1Zf=M*a7U{ z&tW-)2Z^MlF1G2ybd`khgg#7UcVzMvE|NcOi9@CD)Oec3;-CNce{sLrKmYOn;eJ6L zsFV&CzMF?xwJx-+SzTzQpKssQrM6Y-Qj-u)9#|Sp1Tix8*BrpdEH#4Lw^bt?GN%op2CetGKYL> zE{5wH$Wjm#z{!2v_l~9a1dH1B)dl=gLfl=x7TD!EOTaFm@gj&W;`6$YO@lFZD`Oi# z8jl;Y;ooNxWM*3?iSEKh?IK=Dg{4uKanTxL7?m3&giHrPmP!QJQy`A96@`C*og-<^ z)i(Iq2pPm1MT9&`eYA|R!a64&oAwRvx6r~PJVuhq_%I!Z^rZtxD|(h38PUhlY}u~KMo=+AyU20Qn2s(uCIx;ev3D~s)WKe;k$ogqzq zRJlJ`U4y7%e7HIhnd+lUtyk*|{8w|mmi9W;$2Yai9L@<&^N3)y z$YGW)8sp}FU~Cq_1i)uMjxSYuO2J*T-x6L}0rgq9)dqu(+WcL-$D)2^F^HIPoKCJx z7a?CAR+7UuTLwhT!jQG#g%=8^jf_h0VP=j9s7hPBE1-I6%FOaqWi1Tm=dfkq!GV#q|CzcW|aPx9CbVIRb3L`p#E z>Dc;vG?^gsRf6+TXhc*AK6-{aG2qcO#7&yh;7lQCfMSfBWl}N2q?%gV=8X{BMJ9)x3pq zZ5=aNkcD-E$2LH)Jw&w>Lw)_&%P|#W8wfbE{%AL~@gm8>Q_g0<;d21>)Y+M zwRUf-zxLu)uLu9%?mdS;=YLih)*yCS9ny{WDvjgu{7=TzKz+_8$x7;7JDpUW<)KU; zeJoF7&NSS(SYoffA1}bCH&<`*R9nW|ys8a)$~7}Z#4*m4{O@zsKTAlg`4>{HZEe2j zb$zAJvpDHqtaWXphx84o%}JAYmsPm@cJXVj-v?__#-`4uyZW&D zR`RaVwq$J@^+b*13)QxZt&P8G&%xH$pF8VVy7OqW;6?+}0HceZiY&$^1{L9f`Gg&H zrEvjqX?XlDe3UxUGVDDtT^3S!X{>cyV-4{v*eM#z3(uq}-Lap0JTKSu=8JLct5CP7 zqYYndamhr1jFYONN^vAGfiGQF>(hCObh;I?t5@{txCSBu?lPSh?Gbzt4~MlkWS+S8 zB|L=_)AwQCzOdfRsSYddr}V;rklIw_&y+8Z*YTC{oQ{u9`(k!;8W>>iTpzvM8$R10 zD6bjyK{aifWd+>pKb#(Yz@FA5l%B=*EBc*2end-y~XB}76YimaLc z+VsaJ{_(w{7B3TLID&z}%HBRCT9LmY(b2V9U*6IPOY?<>NATw$3bKHL4+b_TXo{=5-dnHHixpD*nyXy--87FP!kIu+ z3xpX;C2BqJ?qqZoKE5MPl$;r=UI2lnJ^t?B>;`7m+ubDcg!+Q{-~jPFa3+Ze36h*| zfxy`-`B_t3{u?*k#g$juHTv`j>PkVo;*fPFv%G{sLb0u;?B2V%vG%5fjp*Yn0*q5& zd@D|azp5hQX2M&Z48x|}c?xfpQ;H^h3Wsg}1@;miH;);pJ>C^F@e&yz3LD`^I0!bB zBGXFmp7MGX$Ea$`xN}}v%Qwe|9ul?wjRZok-&abo;wr<15DK_u)3tce1aOqp|8@8_-GP@X5La^n>Zmzc}08_ zVqT5|J(d}^kMYxKrp8bPA)2ZdLJgnC#*#PnNSkv*%s1;TW;XzQrYclYW8yNIAcp2J z4~Ib*(oaY;SISpnHu8>q+`FEjweOrO_n^ap2lxmJX9Th@ z4TI=hq(s{E(BE2ncKe-rYk%i{H_8sq!nsT?kA0O+ZXHi)qM-q=XrPyE<^;xexR@=M zfFA}b^jpGX?8P9;S|zAh<%QCu^U*Wl(45eD0xW=!L_pfhD2!`4iuI>GilanDcnp}W zoZAUxaUAN7cmw~mtUxK#z`zZo<=oaFWT@43EJYlJ1SPD6RteHxS!~J@@TD%FshLED zTPq(-|H;o|<7v;MDC_XSi}12Ioy_G}42q`~7Dt+Ez71~&(FKqXJVK>g!h(8wlk!!7 zA4Jm=%IwL&Pu}kxQ}K+%IDw{H=|G zv|$yn#!O9Ffo@LF?9`|!{fac4~8scAprz~B!r7-?(+an z2Pnp~$25lZP=ew~r@YkNc7t7#oa46It1HLZOmvAZSs)CW4z?iM(<1_SRA_qYjWD}}71j`(2 zXMc$YZJY<%n7d`pZlFF>OuWLfX2u5=u!S>~eJ)sV2{#bJHU12YQ6=u#l(i%AVdR9yt>vU{Zsg&j3^qMR-?YL=yTIrx#9SYhD8R8Jg|+J4%Q6omuW=XiXu zw&R>hQ*Q36N8DKq6ixZ2(h{901zH==;w%a{w4gl6eNk|bj@o`4p`tZ3C%)I!0!nvI zrrRn_rqjyHQ*gZ~YE*LBYl{}0nirCRR(j#wFWdw;L120c3E|thJsb#^7s^({gi2me z)0Tics8od6CvJ4{Q#s^lZJwfOxg+w3e*(Wa78#gVVk{?y6{ZFPjo94Gqw@$?kkV*F zjLgT0ip>3_OZ!w~fgWJ*Q3l3bmtWw>w9hk^S~!pn!>3-5nPkHSIP5lwfCixT=65k| z7AW@^P6Sd$ZWt(S1kGSVk3%wn2nkXk`5B5GM(l8r0i>Rd7=XAs!--01d4^tqRKpHc zpK=^=c)=+}^Gjfy!Xb^P>fCTbRu*JAkrs@Y5Tg;4RWwyc^CI>imBO%Na29|J;J}ry z(%^#ZWkl++DFXQw)kvQ1WDFC?0Dg?guLAry_ z2x|aV&6OSfh~vP<7?Xx?41-7^Kihn>bd$ksx{h_T`6|GpVFz=put?l}{L1lx(@Y-O zJj0zPf@|8ikrUu)lp^5{`|AG5q28N zfeK50d1;tiM;xC3yyX`aw~~g(KTU*DD->bACvTNR03bG)ga# zd0QMo!0~$LYC`fokKhH8R)n@DTvZcI*EAr|N;tk(@cA6zEdP{* z>C6xh##cO^LJM*W4DxI$MneJ{zKOSnkhM3Kq(N|LwOMAk|f*Ia-1-nklm zr)bsDdEqM1^4xJOb7$ zY)ljq9gK?5kYQK$fvc!%CWCYYz|qJ7C$HEO}w>?sxGfU}UXv4jd%%gIw! z`ah5+ky5^Pl|H&6SGJbt0`Y}k%v$$whI*y7vbrXpTMFxnqZ#e0J=pO^Mxt{ZgBS$c zz(#J&foeKm)arDyY^a0VQ%?OD$?1kIpwEm>ux~5%x~RU59Z#wf?MW1+&R+)OIfZ|K zF=UHe4U-e*k6-*I&zyIa73?kh2K1*?uVl0W+B+OtaLb*m+iMJFQpDiSnpB#z4#{M| zjJvC^0!p7La^eFHmf*n|DO>1twmI9D@J2yVp)f~eO#KQSoHbS@0vn;ZM@d7IdxMn} zMQj-NixaCTG4{jJAupyfWm>yki&LWLDA;B?^gh)%G36;?e0E!S?@6hB6wyM!P;J@x z5;73B^|XMOLpJ=e>NwT`M|S9o2pF&%L>M0lf#@dM!|Ue|&KL}PGX3ceiqi>rbYthPZa(!s_h}rgi@#!^5ICv=?L9?3WcEaZJZ7`u(K%E2xr57N9k0-K}Z!= z9ofK*BTfn=p>izQ7C05b*dc`N+$w{1N?qkE? zi}Fi91^U3xs3zbfhF@O8hlJ96MUC+ zORn)V@l1J%CYoqA@*FG=0Y7~M+Y%h8 zcLm*8rI5y#@ToRiRi%jY!p?tJpI=22kp39&d`7^t>_K37H=EAP6>E1EDz^+U;;KQ5 zZ3cr-coe%EfNe8kj+cv~H?@vZCLOaTnmiHPmOPb92GWPYP>4(*#RK27f@!d=!R_u2OLI}rvnyEa^isX^+nP0#0E7?{~}gYNRSq1 zDjuUF=;Vch>l6a51v!~WWo*CWjVz24Z1XCw9!@#~`-anHaheuV0?2F{({_aY?V<{x z8BB3%f|g|~tt++`r#bdbV5nt!Dyg|Onvx9!Zd2<1D=&UwOmS!w#B^}PwkWZ|Q*T4t_L)PYyWsk*Z;SwP|MorX+`@W>kLIQW+E%%q(~1+UG1Xh=9^c z3)_qjKZq|0ud9r*Zb7VWtMXU?E8I8hF>i|^l8GLH33e&9jp+MgkY`04e}py=$NecZ zyfAja@F#`zOa_&`QL3-QyaAOb7y}7iPG?;X!XWZNL`>%`n!y%*_KmEIho1ieCB?3F z*|7LFQtjNN8hCly2-)o(MtS4NzfH>4eVfRX9H#O3%It>esv5@wgw)PG&M{aYA5Y#j zF0>A7lSG`>)^Dwlzv1}Co8#wz!a1VtFn#CVz4*@NX6*^E(_l0_yH z0^Y+JRRL0V%a$P-Ov4?Pwy+(nNSneo92UDgle4N47RnjOzrMj7xi({Fp6ua@IGheP z>DZKxgxWJQ>|bZrF$Io`v>>c~S@@bZ8|5Se+mlixn1e$bgZT>k60ahD-pLpE*C4zl zPqlp~*3tHQk*Bih@HTStFpMuX)u@HR7>Hh5*6Jslgm-V{q%6JlItgk<%W`Q%S2f^T zOk|WBn-F=>u2y)V4947vV;}XH2H+VzINMK*n1r{6WDx%2DupXF-}JF|(iHgA)lF?G zFF@8xSQY3ATYsT?DKK^ToIFF#u2%}lzX9n@C*FhR+XW1bps^T(=CyjP)#7^2E+nSrJ30yfv(0_~bem+nlPte}0>!g#>L{m!n_~1uOE=k`5X+-^NlTuATB@^Q4tnJ&V zAwnH-_6Ep3&pYmVjU1o?US%t>ZFh=sS51ACEn92bkIgV*o{pxe8k1v!6?=?|hjrEnZmc7S>5-CLcq;x|g& z#9o~6`WX?THki^=e38*D*YI@aV5?(wB2mz?KPiWz8IUZkHIR(M>{6yyeO!ZeF_xNX z=BIg^)SeV#5ibgXQeP#u3AIdL0T{o?s4ldc4;(;13u{rYNH$VhR>rxWDRTwsO5_QF zyOYGrxG~bUTiO0YQzr_hks3$v0&d{K`dYNxs0gdE`qgGuZ$*7II;J*S|#Q7#+@GOc8RymS=y_~LqzekYh-iF zKjxjBLZ)}lmE-q}XHm?agnv+Vtj>V@bE;x3SE>gF2(_?O7uLeC`{VJu_C}}I#@tzj zC9qFL9Xyu$XzN(O3xgna?Ml;#4T~;i`_(a+6H)&mKGQzVax@<(RVL?DbDd16E{3co z#vi><6Vr(Wze0&lW{e$knOq+iqGhpQiXC1QW&u)e-q+lFNWL?@wIkjJm?Izq3D_da zZ1=gtMm5W|p)b>d2la&*pZ-LT@JX&Gc?GXU1&WD9FBhrD2)h24o6ywXvQhYqO0=Gb3x!C6ev1g0tfRH>)OqS@Yj+Bn#cA3nO>%ojQQaTfP1(rnd58f1nyyMKCk zn6Q#HuzjaBPy$*e+Xt0ksz-srT&4h4ZMFc`y$JV4j+)UM=V}QYj;-jCPG}dtK0#HX zU@=`;X06zlkE*2%et^^FbBgHExOs|yvl639;4_dyf3ZF(Syx3DK^jNn+woau+?hMErnXC1Q{>vTovA{X#)U169}%bZ-Jo}b z{7|&KbNs|~`xWn>d)|ivIut;G8}4#DglNiTVGQ(QS%1d``is0n31uQcj1e+H3Wzd7 z<#sL><8)ks?76AoZ zkP8c*r|Fc%?nuPOkp|=mtF~g=KWB-_hLzcsBEOP3mXfJM=IPEX1JemCd>P*ncpT5u zaC@A7I+lqHhoE&7gVT($q%+R5LHvayhgVTW+&f(Aq96g1iC>m7jQk9Q5e}{5g0Fy> z5LO5sX#_-p$4%fPC5RRe>^@`jk#HajaTrHgxxBE_Ex!|LWV-}4Ld@EBVws~sY;;aR zde!GN(`|7JDC7Q2Enu$qoEK#>HE6m{L#kOvkuEl7BuY3t1=5;xIe3tPEoSV9_Y|=N zZp6ZE{7eCZbC!d79(gXi<&e8@T!KZgy8?X^6>(a|Vj~7k&=cb2{*@xqSlEoqjLdf# z)T&f%IaJhS4Pw<`ZJ}!QI7GxwRH43f+p1+(%qWiRD$JAVc@BNaI-AbhCY-IJ3fL%U z7k@4r6+0%qh*TVtRCN_}4BE(*GxlX>9*7LRJiH5&X~zAzvt##psbd$lz!fEFvrV;K z846cUD@Oayx!w}n^<9c26%i!U>|fx0P#1UGC_zE7=Tg};>oB9Yt~O|cctyL%rG`p) zO{f(an8~O&mw1_02o9Ptq`(2s%p9{N>m1gSUbc~9T{IOseA}Y_gd@DHi5PGa;T0o4 zPFtp%z`43qL74!Feb~+s9bTNWLF_9`q7y`dsrEs}P0KN1Oc3i*ETQSai-!V81rNgF`ASkSI!1R_=*gXnZO)KGkH$d;tbq*j@q-OQDn{Ba;g7n z9N1YoY7$ePBev-gdS>dkkp(A3HiY7+gI}l-CZ4XUvoR49V?#BSQBVjGs0_Ym5izAH z0LAve0R*G+oYos%O7PZZH+<2FeFbqbYaZdHfa{WEyU;?9fl+45FuG!Cv4>Mc5X8 zq09;BDIir$B1Z}heg@9w)QBYp8DVH=*jyXju@r+El#RAZ$EM^=XB&?~!s}3tv+vGH zmlC;u-dG#(mJa(o9y@R41ChlYj8WqHJ9%@P`r&g-kX&w}^r!|E`1)>@yS31cChJ~Oij5%`3&|=#Wqap!iU<0qFnymF^;9&_MXetSBz<;nB z)+hxIm=Vslo4!)O7+V~#i5+&2X%?!nt#+qoCXh=%pE=ua>dtKyckV2VwXSne-;d@6 zH*awT&hx{wjhEXqL3rHvyO)gx;lZk&>!(ZKslWB|F6f=^<=h%dc1;LkQMAASq3z8q zr2%YY!#InkR2K_#y9Kl#x1Kmlo$5L@&mh2Pp@S}OM(fUA0oX%U)S@WfpWPwr{0fUK z?&drAh4omT2p~(i<7RjP;f*(h+64;HA_-jtFci*fbaPV~%SG>4lZ4{G2?rd__*JeV zP^AHB=C~Tt#=bYBhGU_mrWKf?5r-w{d?p%@%E<%*sp7wZq+q;_TUWhoTUgQvO7FY* z7NYBl{;~FHVM4n!v#uz=blwJeofd8M`s@vqE7;M{4C21U-iod`eY?B9wY@lk4uMB8 zaS%i#Cra~PNY7#Z0B*i<4{$E}tgM+C2V>*@%^>h$(LS;$@}9V%K(4{76gM}p!sG%K zKeueFhC`tI4pW}Nf5GpR6YRr4FAd>w4U|Vi=zYAmNHJ_$?X9A-L$F;d#z1A4%8YI@ z_+^|l8%iS^PS7nL-QG+-M|!^BJ6@QhK*`EI?nuLdE!qFy-j(jQjb!Wp^Av@di$(_! zwb=3&qx-^f+=(%r*kdcb;9_8u$dbi`VzIf{(KH6=cbIv?ev(_~)I!px9noURQlv&B zi6vRA<Budo^%dxhX3R~zo zO|8!bbJQ_hL&)Ej`kHS``4dJZXn@5fSw?-@N3|$X7KpDN{)Kj_yxrR&ro{WRBcC$#g=jx#U29 zAB5kscy&|`EeyJ0L3wC7)=n_268AMP5?^9AZB$BX(wVNA;6SC8^5|Dbe4yH1Cx;sr z7FZAc)$1)9$HmI|m6457y}xYn%~?OhOU;VQ@x5lY^3&E^f=+ZbuI_u5T@@=MOONB5 zHY!N9Kuy<6ihf|KaohB_nKr?dk)(~=y##UuMX7++vocbHWweeMakC;)y%1|B4{s$_ zsSW|l9L&ndhT+f2FQ>*$8%5A#9a<}?onWbamDtH@}brq(tPK7lqC1O!@3PnB0 z`uLYwST+H@Wf7fAU7znVFN@jgxJVxLgQ+oQ znw6N>@ZH9aS$hG|2yL72-X^>^ha?S{JC}ff%zorKha9 z%)~q!1}qtKeh>Fzsb!`-?uJF>kws}pLMjUk3qa`x#?w?6!UOHWI-VKWP+eMx&s(sF zZ`%;@qbLd#@HdSlV?fM-@NZ>=9ng8Ej+lX?X5gq9G+e$h(?Tt?inJv^5G{}%u|nHb zNRm8gO;+o7i7NI+RVmBuBi&eE-&XuX2aoC4PzXDN_&u8b^USWzL9swpfpiy2G6Vw&U)1_j}&<_Q9Sz@_KvyhRvxb zFXh?^-MPexz!eFh4HN;C-4vMuiU_Z(X1M>dzenBO?Ou0xcV~wkZ0+r_-I43MbgM`A z4z^i$yFX+H`=e$BZ?5HBL*Y~Okhoqt8Vd-4Ljcm|tCS-&RF~*1CUP#0o{Pg9PyN(g zytR`ql{v&#b}%{+DFCsqv+z?0C^(P>Ss4LSIX*{C$1&4!)O0Xm)U1p>VF}kx%r1pB z4X|Ot)Q}Kz5~kG4Ne3kCyEve$qs@MyJH7tCxFYFxPu!I|9_`Y;JM8zi_Gs7L?Rjj+ z8xC2+D(%TjxvoNoaDfG%s*?0zndK}o^C-EahA_g0c+IqE>nBl|4Uy~-;Ho1kI`tJC z9{@eCPys~(laYZ940V7>CMV;V$uulmb(e1q1&k}l2#_-*ky9$^+g7vw0#LshidJDl z4ot`?O{i%>d%`lVov;n)ClmVtMDk`hF5)_>QIX09FIT<-L0=CGz%Tpp*NyIoifL*H?F{%3i zwIotI3>m<>(f|?7bHrT4Z`3n@ua%T8$mamS<>m{8Ai;=XiTDUPO(v4G2-z5bk4QqA z`pN8+3?=a`5cKFW%{g$cYEevS?#?G*T-DO~eJlAB8l@QWhpc7FR|f*Z>~g~#-Q`l> zmRJ-Pk-lxiUxFEBg4WCkgutkc9oOUlQJ`rg;Dn zRapJ2Ckwj^kcE3-`(K|doULpzg^`4<1xUiy*Dnb=TMt~aV6?ju(|z^ip|=2e=zab2 za3S%z^W2m6QddtRb`~HJJ72#<06(nG6|H2crxA#~1qj66iU>r$P%(yF;!|(0VMAL5 z0VUrpSDo2V@r5KykLH4&VfNb%tBa!`fH+;mLrK-1Qm9K>t~u`=G&|>06LC}lLa;NB z&QF(X*8AONXKg};6Pm{Uy;$KhPqtyZ=!Z-`+YekGT6;r&Wp-eQpW zpj+U&?(O&3&d%P!?r68W-`^VT>}_rJ`#sm)+1;ak;J@DA@AgZ1lSUIBko*gnWNlWK zQvwvBzw&I54K?iAO_4S!&moI| zT1)|C;cP6K04f*bq}<7uYs8qRm{sR}?9=QZNoXUh8e}t>*lh%e?U~F-9Y4BFPComI z#kS}C_A$iX;OS|8qc(Xj4E-Gc!DEogfurqgx4RCA15$J=k`zmW%r`j6bB5{Ik3C2D zrRh|I6(%Z6MzT;bk+)&&_sCf+4O6TP&DmrWr5WbS%+|M%1wISYmZ?B)8Q4W03)^`_ zvjAntw>V7A(>|Q)y{(&k>lbpz03Va1u-HnvNtBw009mXm#2>`YpkmhQxFuE)b0<{C zL|RyJDb{r|L`p#2MuYj|8~}vJKsoe0x+y- zc?ZFQ!u3RNgwu`eb7-!3nW{9PwiZ+Ewj6~yW*xC^CU&m4v=bag@fuSVFA2FFBd=%! zrpp7L9mc{kbK(4pJ(ex*F04|%@n)$@%zFfM8LTSL%N~t!~DeJ zp_tO-cueEj+!#0q_AIXnqr%t{mqM6CJXUnc)TW;{{j} zK^4b`vz_{BfTk#DDSd5qvQW4%Vgem>W?TY|bVEM?@Xc?Psro!CtOi));V)XY6c*Id zLEnwE^$<=(s8(@$g=Re#t2TG*++0HVG=U=+1Aw~}c(fuh3v2EOL>OYIWX#Nf3yqql zL|mMrv!g5>YX?errdajWAk81a0LW0lP@;l`a*<%Y^)v zu}r9!I18bUv?D(wUKj}rPW%-Li!Q+^Q|Jn{gA=oLj?tVFPObh0W3>7xMxd`y3i>rcKw>cIXN^>ozST`ZGI3yNwR7Zk_J7KJ0k6Fmxdg{ z6D^G|Kl-{9TU|mZBVfHLekm}lwVT3J^v)=Pv1Aaib)ydoyH${4zrb>gW$0yus}8uJ z0Z*_hSY2SXni2Nsp1~?y4i$KC!iT%{ccRtjt=9IYZ|qL;|=L%4B4v#oga1Z z&iycBiLG^f+uqvkcaDyZRZoUe7dqymP!45KUiG8^y@n1ZiTiyl_M3$enzyM`-ktaJ z8+?*|7Jp_9bh6?>LVYvqdFnILsE<`U9%8tR-{Mn#==HPh_#wWy{|3R{-g$> zR=AKw&@h+4{QId*lu?gn6UM@UlgE}lDb8p)p8+>7NjMxM4%ilQFd>6@<%EYk;?OOW z7<^8+PhgNNu6LV!k>`HD07F}ft~-ga)gpUWO7U3)pVjcq^7!+i%u3n!kVnY%g-{9r z77axeG^HfwT&5q+d6Hho?D8K!ntT&@2t3kXV@Y&wV{!Aw*hVL$#pS3@aeR{Yp`|j6 zG90R3Lt{G&mF3io*V&MUN%?IU_}Al9Ll%*V4@A?p(%VBeg8pSpo|ry46*g9xTCtJt zSeT;E6JF?BnmCjhEXkg$oo<73FAVA{RohTwbS?6Uu?Q<<^+`3hMMq(Ju#S!&=qg&9 z_c*EtO;$@luL|9*U?!^y0ScM)v%u4-YFjssIP?&HOi-@L_929DA;(HnSSuy}9o<$d zS(4=MqRxk#Pfx) zLs93;r)+|(3_TWhZPhkZuGASA!vj8JmD>MRO>-FQ-+la1?-8_c=4X-FxBCZiS8BY&=PyTIh#a_<*)peI=<}bcXAt_yRWg>QMdub}8 zt1B!_0UfenBTv-)1Ai|C%6dMt%w~E4I6|W>4A*)`V-oaM8+umyTx*Nf&sqT54 zu7Om&X6{clzPQ)z?sqprG^-FL%#B%k#lo945Tz$6sKMFK?|(df^LB7`IXD`ep1r@i zyck@apS*c^!B)^q`1d^XsOMPy^C|A$9Nj8VVU1TX7Oapko3Pk-$?5sc+(D|R#l~cI z6~TB%;w>`tkp@zZQFzDoW3RFrQ0&6I6M86oQLqFjQI_6~*gt*g=8a|K=7XiFqs(Xk zIvKr)0`ZwK4=`osz_=yWN{Gcn7@~q8aMUd)$uvpXB*98Iv3`lJAf#cr?ZNTb2pWpW z>Fbut7*T5_#PQGK1cVV+M-e!5Nm&RA4N1I21`Q`xbo;Nc}(mNdtM zccHDr7gi(-F}0=Bjlyv8V;*AZT*}GZ*^URTN^!RK4xqk07AGC5o-YO@qDc~sW6YWr zxpGWWG}oK(aV##7L266GG$j=-wv&+$7pF@iIZ2$p>~y{f(nDRjsr};X^zbDb?f*OB z9{Wy?{2Mxn4xtt#bf@2Kb!{nk)q-W|+Y>rr1sM@fig|WD&ZVN9q!orZCSIWNLUw($ z$!q>RCW^hzB6~oB5-Z%Sw$dHq2((K{aV%L6#o>Sg71G<JGl+?u7v&ww6jz?;RrJrc7Sc4G6huDcJlw(X>2+qUiGpZk9Iy}q}{H@>QIYMiQ3 zbDdLruf1x`x!2i8%XqZtQO9yGD;OB5R*Q;}iR?R&#!%b4VmJ%bqw>6Rn1_)<(jB~d zV*xj}vTT#dJ$gj{fd$W0$%3Jy(G_1ucF#QsnuR?YZHAkQ8A$}NHAdag5(2fjvYOAM z|G;}^JZj;vZFgGGv&6_8UCXvA>wxoYH~YhvVk8c9tyxuDj?SR*iX8WwwpNde*xYwbx27f(@AXP$XK3r5b6Hr(YiV58ne zj0u}Bkv@OT=DUK5r~m*{isO(Fzp=%uH6XZm(y=UXg5~TzNo-^C4}hw_6w=l)luW_U7O@0z)xCUDFJ)h_rWdot}C$Y-T z3}(kfESdRp2Wc-xQ0r;RMfxqUhJ1M-195hrUTl2<2cZKeCk zS{C?IXcFx?CorWe5gT+QMxRQgAq_KLARmRBQEI1n{W?$^8#d57)uPn=myGx0N^yXt zz}M91HK-LaaZzaZ_#8= z8R2UrigbM+r04@)G9#^m@>zsLHvo~x=|XxiJ@8gBS|>xOmqvkyaB;h!EuDtE3^ zzS&T9(y-}0tCpbMeZ@=Jn8LT;%RH#|9JC@FTB=C+MuY1p*YGRUxl*8}OHF%ahht*< zkj~2N=qlZF%PMMbEZz08R<}N#d(CB{{!8fm6s53p_oV1$7mm=$Z9Pnwfu6MAW}nK^ zrkH7Umlq#@t9C)exWY=NWt3caNPgS5GGahHHK$#Y^Yd4cP?^ST-R|zD>l1Zm+9N8U zNX?>2$0TD_eKZ}3i=*>+wu9Yq&ZAeGciQ>m4cs}25AA^ie27#a13F~X;%%lPAI_Ck zr>bg;mo)I+;jkr9yKu<`96OuByoEEMd1j!!#BMP5#-$|o+MCu_@C>Ef+r+`>n2f?I z;|$1Cl28-DVclCG0QxP#PPJwg((-AYYUMCp2uusSGyDRa<-FgART#FB-vhMcD)OcVRyLe z0*u#}g*$XLD{ZYmxosK0C%)vah3ZSoLdK@=n{F1k&KNT<(oHi0;F^0h9o8fEe!tSI zStB*G8TPG2gc}k?U1(_qAnaZ%+8jtEum4WgNtZl5ORUzFULR9-EE1b$U6!H)x7=im z;Z5v@-CJY7G!wK3`=B~m;mLL4M^pezEtTl@@cz2PA8o_(m2oIL=$4|5j4?%!0uvv| z3p`F_TZMW~Scd#1Si^_ysaW{+79eTIAh{&kDva_hzR=h_YuiVKhG4c;G`t{X33{b< zGdI?Yc1W+U;2q_2YLlhC9yDPIuP6fvI+3adZLAsC$k7}E^+OkI4kQ+;4CqL&*jVc* zhuCisLm(49MJhXPTB2`z`poAIM)C7Hf~3g+<_y1us``T}w~~=wc;4zMLX;FxB?9bA zF}_wQD&B%2^(e%rplF6K*H_C%LV^2uiE6M23DC;qpua=_C-Ax-)xoheHNX8@70k&C zF4&38SLjjV3i+TP`T}niSd_#yOrVwrQSu?);E>sI?%DLHpy0ojy;NKO^MZ9&c$mMs zO68PuyZTs*(q}>#C*~r$2rkQ>N8o{x^$6bbC6p|oot~}u^gxEH%0m#Oa4`?*5t+Y! zA;%#*gY<;{N&~w6S7fm997&)B*fs6X@De@IlNj!FHIrSUEBhzb`ML^@GkPrjFSbSd zS@*`>NWs~}(pzS- zscC_O;{2pR(Q0}=LM~@gB}_fri&*4Xx0P22-x0W-diTW`EX09I#J^g?z>34m_!D1q zB4UxGNk75@k%#n0)_!#hwL(F!%$HG}GyPn&%Fyg*te5@F%ObB-ZMU#2z#QlUjMEak6;;+5Y|sYu@L#-^C^grDPH@=z&AL?ec!*os6>{W~=Wf)gbv&{1L zx{5k(Lz4RO6O9&=6!+gq$uAF+@t`2kg^1n=#QWu?lNSK)B1l(jE^uit5_kIEhl2A# zqf83}4P+xu7>emFRSj!QLq68GwD&{L;6Ux+*_PMiJ;~#v6?*1p+sikNRN12R0b%a9 zO>6Z;<7o9JAS8iCzeOtAEn`G5rgbT3l3wLceqr&8p|miWr582_g3Y1rMj>d?FCSFm z5O@E)Bo)n+u#X$(*dLtajrA;h*3s|2^AH4gS2p^#TPJWCTaa3~E1+;+yt;ND;Z51K zqNK9_fXcpc2ZuFJDQkxSFiQ*#(|Nl#4-eR$*FqSr^}8Vv={C@$&GOWfIe7a%oFKQ; zWMB%m`GN05Vl@FO94J6Eg@fWTBxp8(iCz4%1yKLq;R$~CwnWf+0juS>98rcox419Z z0&Iy!jttwE-m#;7$OTr zVRP3h5m*=tT_CNRC>PLIejqjm^2RqPmm~`rHJL77CjIUjkSVBY(XhI1CdQr?FAwt z#$P)+_P(?ww!7q@2P}@m7v6o3W_(U&l3!_!jV<9{Ul+PpY99{7{2Q71dv#g8)|{Vg zKnHlZf#lEHZa}3rOYFwYow=W5E2Uc%zpybLX4_S#OU@RXioWMuJJ^^i;V+MBl%mgz zC78z_cMt7t9>0#wmCi_79h35dN@dL)t8TnnzieJUnt;;?k?-|r9}7?CN^lAB_cgL3 zX>0jyq_^?$wzNE6ez$u*-+c-+CM0gKftRJvDDGynwJG&%awXg+`f8IBl_ zLrnm%xr%s=;&Dj>l!OrrWQE0NEj~X96|QjI>97DIpX(SlxkE5;71z3SSQK_VMdQZM7QaxlP6*}Clb4joT zNZNvzl=CkPZ`#aFW>(fy6b~5KKO7VmU2-G~LKYHnW<(HQN20;M;f`9-}qcYMVVl-nz z0RjMkgaZJ;0RRB_X6s-~ujgQ5TYHdaL*C%5OQ#Pp#C}5jvUskb& zrlYMaG(|MoRV)gNW$?PX!7u&1cvdKfRwnYSv*yU$dw-EWUtJAM0g@*zfNOxt>6Z!A z!^Ba*0n1}LWQUqGX?T-{T|OUQ15)k3;x?cxgMAOF8L4uT^)8q-B^5U%p3U-%&5ap- zl2Vc%tHGuAk=^FVFVG_P)M8f0XZ6e@+HW4*gf{hn9Dd7YQ1NI6-FY&w8%fG;-V0+; zXIApj3OZo8cJB3oE2uhG_vJ<2r`_Vj^z^nH=QpJm=k`mo`YHswGVl=@^B;}xN zGuD8bhKpXlg9BG?_uZQMXM>;8B@TISBT%~FLh_hIBP#vYWGIXYa(!@~NSmn;wxr&W zvf$bB)@hxek?9c{4l$&O<|F!ZT|A4{)5&3>$esHGuY+w1CkI35o2BElWu)YS)AffI zx_33!VE3aE_~G$N6gN}E_8{&mM&FD^=AvAw=pHoE5%D+<_Sn}^{<|&C#dIMV4oNam zj+L1XaD>oa1C|?Jsh2jUncOK^`sX^+%Cu+!7H-u+j$($D2vd&zFusod_8}jLyWOxH z&d8vS;Fm+z6dhdynO8nh98qGq4exF#gVcFNYaa@-w_0{1>$)C{PyVR#f`1Q;|~vIEp=Q&1gh?gw?EodGj($1(Cb=EuiL>OlMuqk{#gS@` zZ2M!G?2lPJZkEY60<`Q$%mQk2CE3nna2w|thdbvZ1`qOB$$@WSeVNn&%7!TgHH`z% zO5{1P2pAXX9XvwKX>+DGqBpg!1Kx>MpEu-I)2mO_`*-j9J#rTee8!3nEC2wc|Msqp zv$dg#gSm~_U;Wyjyk@h^fa0S^8d^89^@<2&p_wg_z$LSm$9Tp?0!G6LR|9Nr`@-ZA zz^kff;6f11@HIFc#D-`*lP?uH({XgIS1P=oHV=lhZ(+H4&n08jXp@eRhSnWW56fsVZcye{aAsVwpwZ)uQ6?QsrdDvKi8w;X7V;eeCga}o zAsnq^Si4qoY%E3Ft|IW7m|5&iXSsbYwGO~6hX6hM4(c!g> z$WbK02~;sm)#O5DirMiY14w;qDiw~-)Ro%9&L_``@9+1GZ%_#`hwoQEqvJ#BYY_D(Rdyh%Rsd0yM z`e(g{6L$BHiHD1fb@$z+Al;}2m$t^o9B+a?FK!IieLy_l2XKdMArp^)D4$894*aaQ zb*3#;rZ-}zL46(^3t$*)fy0D0|2_A&uXW_fQyB>B%^1m(HxzZbxRKvL5@)qvk-IAK}ED4OFx-lX|YPIQvd`+d(tTHMF1rb#J2*{VxadcQm}H7hxI?qJC2pxd&$oaoZHr2QGsHKnI$*5$p?%!TY)5AIR&FwD@J7 z{qtzII$`!(Y)MhgOvQY{b1!7d@U zcPOEMz-4nib*&2%Url$8VT4E+QS=ev@1ghfm>|5;YJ+JwPcaP|2aXW1<3(}mfS76O z#?txL(rno6MR&XLnr2H#IRPm+qSjU=kxNE~P7x*cp_oq9_9+qSVD^7^uqEqQc?45{ zA~63UIFQaEL>kbyBPAT85U0?071b;~T7!SKtJ#baZb^#?UUEsib3!s4=wm8Ef_c(U zvSoZ%;5jc9Tg!JoyW598RUJ-+dhlHbK4nn!=Td0Bc6EYB5}3cc0q ziu(bExodz3VSO9N`CMrd!9XvIt&x36>Jo@-4LN9nqgpOS7R*GG?PAqSJnzC`L4iyr zsLgi6xzN`9+pDm}DDsg(u*o7C)afgYH$m)?^4vS9KZIAbP5~*rJD*@zq`ug+J8lnL zyFzZ>_Dv#&qFYKUhb?kFO(UFbEx9Z*?ZB5^j^GZO`3Q5wO z`Q=M+bJaEvw39P$8lE^m#wHNLFRMe6;9|>}<<(5H*4cpXGLwA|IN80^8LuSeFgP=6 zGr7XGDVQCm*oe_P>4@(tM7uT9xE*sTJpAaMAbJKK^*e{m5T;k4r~5oaqVSzxeA?0o zb|gVC8wH~6*9LFHY73f`_8sP>sj5wJ)Jo@;;$ZTD<4)EsWwK-nksic`6_#oJ?v z@6d3HI~B!THjRr`$HF9Sbn7CC8M)0n5mIpoMJ=hcPC_FeDhFdd9`4l=4-Vu^y<#r^?J4Ayyf(1x>2hwNtr1xnv z+nsvnlT@|ST|({^U#X|B`)Q`k@zB~5=;3N&vw4owIxyEq2EHCKyNWDo>0e%WM`uy= zVbs$Y%MkFV^Eun%A@q(T_$F2YF9i8~+wkvgD2%K1UbX?XexZ-{(upBx%(HDGQOtl? zjtFw^$oGZNnKStXbEwKiaifRlp**lwo|R7!)6_fU131T@TgYb%!u-%c#z>F2{^c~k zUV|1$t!5(Ku0xg}&80vGKdHevvx)$RqEZfsc$%a~mr*OHw%>u~UM7jQPwc6&C)TFD zO0Qpp0JrcgRXvuTU~Yuh%{iWy(z0*5-WpV!6hguSlziCJFwbfZ(@YgtLrr6>i3*~+ zBoT`1ZupG!t9{1IT}PIK7s$hK3rKprbMdWLk_Y}sCpsp3B|GN0R|=^z#5syD>6?2# zf*f|;(fjFZoOE0)Jv3|c&e&N2)!{X&Auz&8QJ&Olv2;R?fb%&W*$Ye54k5PdP=t6# z$!3Lu(gPU#q;Xp7RTP-=6t1LRk@>3M+!&Izbe*V}p4~WUmG@ko%2)(OrQ+K-?9cGT*@fEZTO`hYSoO>Q`v?5|3%0h$~{`chDB>=VbuTMMwN{_)ko6AbcFV9z>?u>;c^39|0N0*%kx zPG<~-wYI#qIun9{ge;8@9sksWerIiuyQWRmhJG3kIUbuqLtBU6fOKl}3rRtw5{M$0 z|6Hfi;P!#L&uMVPlGJz~hs9=vGo-~mS<$@3C3$W$*_l+LP0r2pCL^4DtR5#am z8ovxlD!H*o_KUa9e-o%S0AzEtPkJl`{0{>4FJhb?+il~|028DKx+g32?I#(?t>PVM z1FryzV2JScAe*trOMab|&YVmUx>(|ycc)e1vR4yfDoiY>Uf5XyLh==s=1Ek&t2g&9 zz2Sm#^(nw2F!pe4mlCGs6!Q;7$?10cP&R~cxq7%sN?A%g6A&w4KQ`fz1F$D$l!hdHt-DGB%INT;>dPhzDp8{J<o$Q zf)A89?8J^HTGc8!DJ>L>F=N`2#{qZ$Ie3KFP_b7$`XF$OPPtBg^!_`!VZ))!?pZ;9 zvy*`*q)IXhWf%&@rG|P6QyC6Wp1{_zWGgC8_Q7Vg_oh|nJgp>84WG3wGjIE(U~qlVHO{=slo98H{@J_VWo8w<)Zwkr%U?H6hweDu|+c^Zf;XW2UQLfj~JEv-Z|)$&6q6#W@5 zCt}_d>yz2gE;V!8-Hr8wkTkSdn)p4L0Tc%&Lchw_}0}hCB4M!bGxA69+1devxV#^HS(5B=;*r#HK z@8k_E;z^u-z7z}Bp2z(V8_fDhAf4=S46Bfz544cYRH}gIE#ZZ<5JWD45h;mEDGG;c zd&VipqO1)-N;9gB_)f2;M`G4AKOeGO-AGR;j<)^$Tsf3WO$?# zRl~7gjE=`~BG7};ogoG5XWONv|K-Gn6|6|gp=0WjMsm@m+$!N-V6*}RJB?(>VbkOh z_boEO)2jyxtRKd~e)c>0eX$sJO~+_2FEbJ=^>^X~UV>uwj?&3u)Y$GW-Lm(dcfj3* z*Wl8$xg5;W^{64er?{`Ow6DnsP#H+fLng_pdv7~s;HuH)$ld}}% z`KgbhKzPS9&Gv2hWXKlmIT()JfU|Jdb1`209iC%@u)j*Ku=CLGl?qKsox|U3Ef((;vCc>Hva}Vq=~t#6 z;?7=&GU~oYHo}_t>9#Iglb;#j{Q^_OT=)NVD)wL|Bu{;yRK-IXRha&^3c7Pu`RxY! z-@e7tM`vg88DI83{R`orgTlbh?mr_!QO36C)3xN5y^GunKLb^O;1o!T%OV*G7l&B! zifElgJP63gciC2#wE=V9rHdzCZkMBDMYV3sa8yaUUVD@ufZ`QQgkdI+8GI4@TU5>M z*;=_Q801}GMbR#piQ`A0go#P=%-DpqF+&N($-T2E!h6k|RSK`l{!Ye71I$3^;7tBj zc^pj#(^5^tl8!idm|!QF=fbqe(|yBu49dYNg*7c6u1l-@2pjJE{O9m#S@&nQqpd} z?NY@qw`^EvQxC=UqNx5{3JX^DE5^6Qa{}$=neZKBrOpukWYIXma_Wt{v5S^aracQu z_qyV4+B2WbaJvPN7r2>uAx_o&oFL<%X+CrG2@Oz79>vZ_yhlbyhYto^+2w03Y3N?3 z5b}KEXs?<;et+`NeG!bi54Gz*;{F?>MJ^FI06-Ki008P|zx-#)#_6kxwF&)yUK#)D zoHNbOanFX)0l(-?;Pj1lD3L$ZJ&-@OUILrN<_Dg6as!4^j)0;>L{8Uah6^S`7PgDJ z@0trn5URQ_YU}9$$k%FTe#7`QjvN{#8_hb6Bn$|e*ooc;ucz-4^9iL7UO;dNJ3ql_ zds~dL06^(*cl4K;&SAjwg8-X+x-pQjvJx4^R-2xe3Ny8RlLCKuf{^fSCK-%e20+j! zjjSg0M(gDeLhY^wFyTYF4HfJ$`u~VsAU9cIu{6Qo?g9Y3B|R%20%?VSF_ILT2DYpD zk~!$@yE&xKbc)n)K;}_c{p-rlc*xb1mOc)U??9)g3y_3XXqchkhmeyVhK~T#Vma3R(G!|nesO4&HRIZa9j7tuUE#|pgSd)rthLz_u+$K*S(zFYXsp4`C zEK*$xHHJ(aRFf^R3M@Kx8ef{F>sjK&>=D})<_zHlBI;309a3qSx5?^T&=CBm$i znA7u{Ply*GNM9L~>r^C%?}4wHaG=ocw5-mE(|&*2?w`s%5R3ZG@BaFDI8~{SEytT} zvgp^%GIse~X#4K=O#1lJh_A>0)BrIwGpN?-d3PMe&%UBaA?W>ZI(K76-}&)enVI?3 z*BVUBd=ud%*gy3UVYQ%xCBQ|A#n7xDjyHH_(S>1;!G}>Z>;zh_do4`}s6H4@QErDW z&RiS58SRWZ^vsP0NgcX*>j}#EhvIa0Sr-($p~N&=xSx5kh7$oD!vR8+FrO#%%XQy@ z`&IroN|&`}Xs-Cf#?x$IRN`C=q&K!;iXZl{qCn4}DPJ=47+2(7-A(TIM^)gWp^wy* zgeeZA5D(mMY1!0fTL4Y?=HZQ1IQ%H=y?#^gXa zRa77#Qpx4&NF;~xhfO=76WuOzJBgI;e~QGM5SGSo3odapktIVoVz*+}qZG3af^Mrp zmPwdg5e@DV;t+*cebSD~BOFsZZy~QeM4Mi@<5DK3=zv2=;`Lq)woC_iB#pkGj7O7f zWuC}e<%IDZ4E@&1siafSZ^%@9m>b;0oPVm1R+vqMXlsw(u_fDzr;Nkhu`i;)V%ELH z93XtriHg+@s+l;*yyy%8Is9#wuuor0FNK6-7<_<|fG`*egUsSugLA$~PS@IXhYkZA z`&;)x{!4<+?g)NH$3o=8+igpKG0Vyp8gY%6by5xEyX*2YUbvqQiRHbBn#a_fu2cPq z6F0n$wS7g)p$WbFQkd?2PSRRd(pX)2m{>14yq6NZ-&@Z?7qawV#!uwBF=iQtq+}bO z=$YcJeqq68PkCJT>(UY>PJG&GC9pV!uA)aEXxj<@Y?M)^npEj#s!0cofcO!#)xpv7 zBrB7xoc^d+TrR$MliuN1r2JSx`<7`Z7V142fAzA`xtk=?L{3DeQXNiJ+xB5uqTNm5!aEzAyl=hkV^IZKjERy>@<1P9L-~s ztoYJrH{z<#b!M^P(n4Chbt^R|IY+~q=8`|_k`_Amjiz>?8ovM!5^|z3El?Tw(1?lu z`vwQ5p4-79zgw5{Q2zI1vWcW&NRH1BY8E;jVXEp5fLm=<&KlNeojp{`mFqp~6?1jX zlUiKL%^FSI%3zm2*Wit&Y2a#K*WX;s*Ho)0O|dSVJy&kY*Ua6h23PG|X5QO&7+#-- zlaivhu48F^eW(9-vO|32i@o-l?1+EPT>o!w)6~|+N!h^A>OXAiEPgEVv-%kP= z@c|cxFb+R3az9F^wWt7o(+4uKD#A0J!RmXr@DBA<@cK_r+uGCZm?Fgg4wuq+ueL0gSLKw2T~XqQ*ZUPrWE)6}sU z>dY<=M*MJbn^k8C*9^zWeJt{XVX3WGTx^h-U`iz{4vboyMaCJCPS#%J7oy&+9h_i0 zI5T(rRmkWuuzzZFZ%bCD!pCLM77KAoQ#o5WjIWP=)pCmA!K`dP@D{If%N| zv(nZSWhuv+6=&r(VNE!MHg6-QQu~-9E&4e|5j_YD7rC9MpUc{+zg#yUthCs}EqHh! zA0NOj8Xk`VsU81xnp6kZ%9i(zD*5znz|W-pca;ys*OqbrPw$TSOdJ2=xBq@<34Qwc zr+A{L>}F@;sPk9)_@{x!Z+RC7pQ!0iv(W!S*L|A(zj~qn)Cm0vWJSSKUk&>t5Pcy3 z5o>;9`#w$mCw2WK+yARG`V;J~FUj7sOr-t|&%#-yu_+P)^PyCAjG_TTt_ zYH5GM{}i2m!$Wiashj*QLH!B;Q)u}OpUeFx{C~2`p9cOEJboL9%=>TK{bQ8=3ICJR z{)QhH{Nwn4Gu%JXe=@J%XuqPr5B?_)`_sgq|1-Z$EL8rl`~LB-^C$k#(DWO>Tm3iw Zk3c0a1q$}pw-7#`FdzT`wKade`+p?m{agS5 literal 0 HcmV?d00001 diff --git a/docs/beta-1/docx/Townlight-Suite-Manual-Beta-1.docx b/docs/beta-1/docx/Townlight-Suite-Manual-Beta-1.docx new file mode 100644 index 0000000000000000000000000000000000000000..cda568eee0770728d37177674fa5fae6a881a3c8 GIT binary patch literal 30201 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ÞGXy&pm)7Q}!}8wI@j_a_%rTX2A8a0e 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ⅅ!%0FPF)yE*_Zw+1tj zQAoo2WlVS>61ja}VGVg}q?b_GExD2S_}8Xv4mfJK~WMyYPA{g9Fb9%9m50k>7;Q+2jz4K3`DfhEuo zq<_sJT(oT}1P^iOf^87LTWY))F7!E)D(iZQK?=N0V?r*VOsAkKjf8?0t@pLC9l?G% zA(C!Y6%DRZ-Xs2@SMucW?d5MUME%F3J|$4Xn**%5B5jMO5CS5>beht{(|wu^+mRGr zN%QU`!?gHja#or|u&1bi$d+^{NWR*sdwq!ajiNJ0LraiVq1l3{?Np(sw}MYPE>3F`vqGz{-_@D0u zg+*YvR^4LQmE;Kt@W(c>%2m+TJ09IH=#gTvrj95G98bu@#DpGk=6mGRZBUAa^@Wi#(fTTOs4%FoE44@w zHw+_B=+_erLZ*X;fijNj8K82g1KC7*h~SePFde~zl5p|7AHlM%bSwZBs+nMo2+N3? z&xV3}xKI_BH{uO32C*<@n2;`oA2?UcJ(A#`Oqw|Ef~Bb;z!>k9m%s$pD6K_sW>ZBcnX>?JCcuA-xdQ-y-3>jP#OEb$_Y(PBIY7o_4VlJV zDa#*9`nBWmE^FfBoN3%4r)4NA8W{(4c=`6{$0;7#_#>6%1j-{t8eE|vYB;M>$9}=AK&CK3MP4FsM^_yncflG+07>)}1&?e_ z$-*)r{Zq1H^LCALf6$~EzQmdM9Cni&ed&K8)Zy+mhB+aK+^J;7K@e82whr!y0FjJ< z0kUTSi>qmr?Wg1&5N9x9`G;y3v!>%z7h(>qn}DNTa|n095lV}U6ao)}84m@RMlLj9 zt$5_|R~){dJ`2^f8isU~Lx?X)<#mTnPmX@Y<@Lr$bb)?5v3Bu@r+a&gwYYwK_tC9p zwf(8S42gagX%-9y>q&#m@Wa6$?oF2Yw1HdES@!~TR?>a&5-h7xDxG~|RD_nM3t+iM zT(xnh+(&?V*sE)=;TgCa-F+7apWs&&%|N;Lab@tPU(J&ka~u-~MclcSc@ccZnQ z0k&VE0F#WeDmMvGS3SL=A-Iw7E<@lW zmdTNKPF5+#=n0axK;#~TSv7(eOfeo>R!RC3DXONvRDc%fTqWrLPqhZqH5oYOIu8x~EC5eJM^T>+?cV*n8iOEX6T=cdQS<+H&m$?!)X z#$`NAa!Jyb<^?Btz()eK&lnwIv6}ay1`dn74olzWIm*v(MZpy3b?cAe~HpAT!6 zEp+JRS;msBEfWYKWLpzh>0#zcNnsJ{r)_j@wFb$Uj;EavvekojJG+8=;%T8>FM5l| z5xEhIit#f(K6=)G4xY!(kLp06vGbmSpHdj4#aMKU)6C^n zY3u8AnunGEz(95iY%|`UG5dkoQu23H)xDe}-HYDqEab`bJO|{f7Ns+(O*>IaZefSK z9BK~xk^zHM9Fwqg)m@DLZz!y$gGoB1$>Juv4c>Rg`MI^O>-kQA`f5>qY~6$!_*~kN zA*W>f_R}#}dP)?LEN~ZjH<19*dFaStD;6N`eOJ=UcbME;m%+n8yrOb58BHs4Zv@c4 zcq=l-uUv0^byc=61c&mUk#~T)$l5WhtIjG7f;H+7u6*d+#lC&em?8D~CgR=&h}54a zMcI+yi?e45*N0;(a8x8^g0pJz&$G z@7&7hPd%ewm=ZPrsYErFeJ%VV!$~}29hboA3^yHVDi<^77Pu}bM#j!L?4~X$Y0>uX zU;pxdx1Vz=K)`nB*km&>pN8%!rvoCiVvQibpbnI^`2@6_*}{xn^Q>w3)^2XPl%g|E zwe6~%78K1WGzdb^ER!y>;M4~#$XPo0BY`v&0zE9b6zcd8M;cyJHFK4g zV8e}%+bI?E+PL-O@$vf)r!>!#*M}cJ9G(7~*GJG%hg_F9ZeFaop$<{Rv!JWq4A!u;d;O?#gg1fsVxCeK4cXxMpcX!Rt%$xUShHw3CYjv-? zPv5StT~%k-x#t`W`iSv23J0XS(c8QT{@@n}9ARR~PQQqZNZBTY_pO3C1Y~bJDb6r0zR@zv%L;X2$axO|$I| zEVomYec|_zn36Njg_U6dR*V#6MO_(3bCIA>;3#d?8DdY&5f^=k$^F$(sP0Ic2Iaux zVZUf)P8ov%<-z-$vmyk&ikG3!KI_{@kPyh05S!6Ro>wg^VfHIiUI|+;S|?l(!8!c~ ziloI}zGc0Q5=Wml^Y>2>Ry1%yyX_W6Q4vft^Jl%WuaR>oeKCq|F*Egw$ocLCTHdA% zxPnMYgVZ9l$(qD6>qw%6nfbmKzM(8EE(TSPV>7fC8|mvy5O0rmUVCFzSw-=S*RP_O z8&9O30j3XkgVR=b#$5~z^UoOAF#X<*oGMNU+G_lX$Fvm{ud})9_`xvxS~Yx-nem>G zZJsLj!+lvZGrHrAJWD2m0HI|JPN~%B7HZ3HL2Cjk9&MNb@IiQz@ihewaxeBQt})fr znsYUE(2^~80J7kujDWbC&g?lQYypdi$YyB)H^{)!$vd#qI~0&RrZJP+a;i^{UgRg% zJDw8JRJwlJ%T-#~AeD}6#Bv6uIeD00jf1-zomfzIsqN@}fMOrXBT-}PZT73;N*9T- z`43gfl=Nq;;yg>GOoF~#UR?P<&2fJBE0I3+x2X*yHsVb-tHJDf{S>9~Jo%s4v}57} zL}ye`NKv0+V;k~ zTz-^+_Hy&@L4p}CJPK(VGy3u`%+#=IrVCBNx@4^WYyCmTsNM3g`53qyMi(95$Hi{s zHB}EmXcm@mn6a^<;P5AC`V>z_GxnFew`(z>QA@ab#;Vf4pS-GJ*hHOXMd{!I7W4p=7;Iuh--lW2X*0un{jX;7t zPLhr(&fNKgRIyD9X0PVZkXzbiYvT;7u(0&lR0Wws+hDRSGI8s-(NaE1A>AJwA{tdN z0j4ld1l;U~=tVy?;Rz8k602rb>*c_yp~qz6Msz`StXRtfd1NwQTS`hF!0~?lw!REo zRK~_{Y=OSpF0uxe4QChi z$ar2W!PueFI~pq^{H|4lWW-Dr_U=vk1dfFbPNw1ee!5@3#f+7Zw@I9kt*EFfGVLMc zF1qaDw7rdH3+b$^ExG2!#9L`4y>S-@ldMLAo|Vq+mG07hmib-o^;k~lTs1!3?))PT zL-_F&#Vk2h{If`;TiwFVD+*@7^uh~8LZdE{+6zLk7qgl{V7+OK%U<8nPQcYD7wKR` zs8e`^rs8$TGHH3J-3UqCd$b()(kzjGuPyvkkim{6iOSi<06S#J!^G=cEQ09HFWo5^ zHxIC9F~v3!nLSw^5%HH==RW>?K6pQ69fE~MK|s9&PG{vrj?2pJFRAI)Lx~fcmF6|LNy&rB4=Nv?!wm@G(|nQ0NQv7Zwf4d zC?Cy{QyaSwvUq3JO3brBDdWuY$=q9p@gOyam*f!|9bDJsE)Mdfbo}KU%F}L!DC8Jp zh5QkkcmwUt>Qubz156>kg|?>qKOWvO(iU7>j8#PtQ7^jA1#>RV{+welS~bLda`|6| zi1!n#Odt|VMTBj@@Ab1?^0?2ztB2r()DVM4B!Yu0iO&dTD%QYvZD$aL4}r=LqN3(eQy;p1-i)KU1B{3^fa8Y}FgcM~TVK4D5){&< z1zJD=gpruhO2tp0rv|3von*M;)B3eG8P4rG+JHDVYD7i~r1V$W-iB-m3t6=lT|z)t`I`I9JsI8)w$K{5m3x&SEB zgud%(IC64n@zF$Y2N*tU$$mlyj^Du+8L>jlW?M|go zDZp@V`rkX(@DIZ!fW(%D;-8jn)(f!VUjpU!7JWILab>efjAj_y#v}w4* zHG{a>FEaRcAp1oTf`~#a!|sPuHMT7PgxWN}5P5YaFoyd3mu8x$Hji50wv+*#7|paj zhPM0!p?=+Nv?wi6VC1eY^UcoI1(QWxZCexYS+2SDEz;zW+BqyFN{TwDcoO}a#s*Gi z{&(NS%X)_Z-ZI`ZHRIe}c?`;*l#w9b;~vH5!jgy5<82r{J<-Zh zJWBI=zGhn~AM>pPU{VMvE43W!KR1!lx=nT>7USeHecI+}c40JQv=o?;Y=BLtx_2fL z_+>r!TbVh3w8M4BOO5gf%|ZQJOS-z70;L+{#pSzQmeWJJ8u)LlM#6IlU5AK6bRtjvicRqYPerU`;?OY1?WXwRL z=$r6u;;W)VD_ZoP88zJsSJ9~Ee?e~JvY7{TJm-w|8T*t6YLYEX=CTd|hiwOU83hAmdZvVDdw5L*EvMl0#;_G8@$|_TXEnEZDx%;4G~J zNf_@b;$Xq`7j5ZkK@G%~f6O!=qI#<~Nl62TSDVL}#$`Q$L2u;+((vP#i~ zsIc>8V%;8w=roepXfWj1q7aNR2B^q&z@?IXAqxmuAbTztA?CA6dfo$WnuR_X>j{X~1fg+9~2w^mS`1(lwg{qIH7noS4krl61v)A=!s1Q&C$E zq<9(1$k2GHT33{sj4eMqJ|LZ=<4-7ZQ9d&~t12+cNF3ZdmfkDqS=E#JP_d{!+=KRk zOgsq^d%dNpxH@3Cst(!8iWILym%UgaIqBoMK6DQi4-!FT`*cOKsng%JzpOZj{{Y&g!pF+SGJ7cI9Ky#S07WTb~ZbnwqiqIeM9* z9Q^JzBB3aZ^p0-GTj^&70s+!<~GQ&s1u9Ltxf> z!5hCemR#dHp=MvqsuUiLNZLi2JIQ7Sqb3}_9 zoAt^m92GC=AZrp4j?zqq##v1wDkWUz^Eq_q(8|e6Cw5Jn(Q!v8OAauL4M3XKZzYrb zn&Z<^m)}Y$zVjkcheJUeh}G~t3MWed@gc(;*G`o zF&k{!K=Hrj0DsfLuCeemPA&o=o?w(s5li(kyvwMXG9hiNB@iIs(g-It2a*5&6tiKV z;Y--aXiebIDM>6Nun2plDX|ugOE+%q$r_$1Th~`I3J4c3_Y4yZ)#x;h6($oVO)+Y+ zsp$}_Sdvv`jjyR`!)W7Le;m+KBgFfbuM38~;Px3gI2G84iP)^aU~NQfP?_4K9FyG$ zEl|FGJ9z542AF%^x<>s4IpA0Jyjd7*LG%rVe6i9HK_tdepX@A}25I&Al2zyPU_?rGzY3mjM;tb&OWY{D$O*1b z0cPiY_QLu&b1*`SLXGsP8L?R1{g$%`Ed)0_nQWuI`c@4#;dZG3m|@@C%|L0p1)*N{ zi1VYZIB44O8^5?+7Z6i^cAH!~5=m8{D$t#4nbakWyrR(;L-WBUv` zV8V8zJ_s*!n^2~JmNsjY5I_|&sbP^nN|xZ-Z=yxqg=A!-SG0EOD3+PTlAja$^T`ET zn08qjAl^v#`PZ!Q4xTf-4$8}>8iB_h!p*DKzuA8%=oBjP&i-&LARyd-v)|at%HGn- z-pKBcd|rRif7x=G9`-e^!!tfrBH2iATEF8nMFnv8ga;7ybRCwOEh&3~$14T77BWpo z2^!$WxSPQN9^U0E2dmSvNcfyd$%I*=WR(r0K(7O#Vy&bnm%Dz*&e`1_r?~YEj7G>@ z_yL+xg4n6%^XGBe@=D<3Lv%E5%39No$L~f1Y#qZSly+#Kpli6aMpozuL z6+m3eE=|68p#{|NmCq70W{6M8&47o(!&qVt(fz<-8R2q|BuooQH&gq7G*gE5~`HHhmFe zU$46LA2iJ7PO1s>d8V=HjJfM{s=DHE-Y9y_A#K)wR+Jo?&#@PG!fO&KD%P+38x;-E>F9zGDei!1}WFK zhj}dm-e-fuJB)v`&~5KseS1$W=>ASYI+n@RL)K)E%=>Z;S{x!qB zFW_Gl)rDh-9Fm&EBx=8dNb3*&8X(JTJsmzlx>NNCz(htKh(T6R$UYrl9l9A!Z#@b5km|Lrs2M|VR=0%a;j%N{AHfSp0iSP0oK)5m|qrc$PM8Q zP7Qc8M=U4YY!j9w=H1jeM9yJ=n`ee6FyLb9>X=~07UCf?Q=U$*_J88Ps`wE*RR27o zAWBS&Km;4G(tKN)Z}!48hyy*KISE02fW0EX<)+kRJD{>wBL z_0u(6A3Zz7_{MZ+KF+9)Usv#E7L?BKj788WSOepG#r}Fk^2oIyLE#*x$Ul(iI#&lI3QQ6C>(L_DS-U(;Tuyy1X5 z&@ z#%ahwy54p-dam?1_vLn1<{3IJ{P2w-OsuP_wi<{~=JgS0)F5SF`k`q!&|7IGm}D`c z@#0ZGWT~dLk^GEr_jB2kL`x=={4Q`_Zf?42^=&!?%Zh&<@!aw7IegCb7R$@l=3)R4 zwS_=$yaoT4f=vkK)E)l;o#LL?>h{AFijFt+FJ4Y}thizU3p&e0EyT~s(rp4K<)>^< z-@K+9)xBS9wT7GD4~3%Zd0SF0P`UfPY!%fqPSpG+zTY}?_y zwGYybcj0-xYTiAh)pfMfVvq#EDB2>?aR13r_KEoRj_%(K-~(X<#f1g}x-kU;LijHO z?Cf34|1-U4M_? zpQo+4?komsN7OmC)IVf-5%hR)0-X1N@qF$fZ8HUp-25ZFCy3hcGhWviH_;ehiR}k; zxp2%tVJ-L$;#&N6U0+RV$P*{i5Z4+3i4)fpHQBh~PGIrVUcb||BZyWAuc6O;tWY9m z!5kjoMIH2%G%*vpuCUm9j=5XG(@fPgpn3`&kglfZpm$U6r0(oxTq;4ISyt?GuYV^QG~);l-iKuPQ0!7-aUn z^~gwYYk9A51t8PDOQzzkcnR!*u2?`>I8Ne=#QoNQ^cSOMxiImlapXM6anLC{uL!6R zPHW`Y*FD{+2eof=w#Jx2AR+)h?^cGzPbDgmk#&>OSgW93D*4IPjQSIXzM;Q^`vwJ@ zV*|8zm~o2)w>JW1}e5vK1r?<9{>=E&i!fwxNQ>__~)4U>+$BxC-@3y zr^(=H(_#TYih%8yK(pa&zc%5vPH?7&R%F59_T&e>V{I+~)#>fN4d59q{K5cDN!UVx*ay)jd z2@zjTwT}XRh#64y5aI7)bafdazR+qys5wkB4j2Xu6R_e%uxo*RQ`e6E>{Cs%ZoM1X z>B4QCDJEeLB4>wIU6DX89{zKZD82{Pc(S@jflv#x*VERDtZn%LLJpe1G)SO7l}(V; zzh_%QC`v9yuIDnMQF5dT|8z&a5jFHXEhc2q1@ZPV$xwi|u`mhdaWBcH;ccG#oJ4dr z&)LjQ55{C=C>7eirxrrefXJ`KpS7BmUBcc-Zo( za=7-4CWqh}iOqxhpTS`pL>9jYDS*gWGSDq3qFYfa5nZ6II*2XPnZGQ%?gLDn{e=l@ zTiDKKixUX?yP2&FY>JW>!KACm!Q<>yvMDlP#~Z8`DxPDx=MVDoq|(7Hx9ZLWH|Jho zgv>@z4)ubK7SN$jUTC}sq7M~k-@yH#JR-I7ND*9l1UkZXMWT+10?i zWMV(@nkHYwtozH@!YOstR|b_ytnJ+mx?D-e4RTr}w@jzUw@kyj+{&LxYbP};*VSAl zeRBj4AB$z@_@10yy^a$W)2o81LtP=OV4OL}0#lnF|2`}4-Bab0q&V=(7U5>AZ0u_$ zreD`Rvi}|(M-08F{E+}3UCJb@Vw|zY0(zUC=(Eqx>XpiHDJ}zGPpeMn2-T!uvYlih z#%TXcd|M{csh+}Vmrdd3`}q;7tN%f_eefIN)H2LekDG7=zQeP3OA5iZI2dLe z-)Nm(@5H%Radph%+zV?rBu?X=szCFtb}iFXY_D6uS;ut>lR3A(wnh`*qT>{{%Zoa0 z7#6IIhKO5g*KF+dQafA^<6UYk4Y)A*j0!a5E2jrWjOiY~Atp%6Y>St+i3GC+^O1J)^R5_OF&^^kypXAo6(SoQ{ji*|- zNfV?v=4s(4)H$SA5a3Xh%YYD1k#uP@Xk=CQ+S1%fCD8VWKGt_dTeeo{^a>N;=AS03 zM$-|@4s*LW#L`lJ@0qH#0M{gi5_1D5A9B~vF`vc!ri`nmqBhz<1yxxT56y8qbV_Ps zlQwY9rvgI#m@cJdM< z852zh^QCcn^fZs^;0jG26!EwqM`EQ=GA@hH;p{WnGjqf?A-3~i*w?nAjWRifdkEGE z!<6RB2nfZ86aIx_3?~JK;G3~SrWHY0TomzcaYt#*`J^^i|6hi-WaCbz@<#f@q*R~3 z%0v_p{gP9EJD@m~Q%H<C+6|Hk_snVJwlj)e1FE=x;N+xAx zx!vRYOn^c=f^L&}a4eZG!$C`;5QG2p;)j$yYOxl26X+lSzGM8_%TS0&J3kd+ok(kEV z2-Y*gp#w8bo7O6z=S4B}^g_i*!%Ci9VSFHP7g^hTffT1|M9K>#B9vID=Uao9I&7KkXThe^=w#RjwLz$jOQ)@&E8Ooc_sh6u@$18SrD z%02pNvXJPC!8Ngu?G|p#AS!ytRsxOzTFXoCpv|ej*Kw|Q zBfCxi{Jj+rC-^eF^o$K@JPYbM4>CXK_c71)F3Nt$&|V}mBzrU$=QkSPG;u1K(FfM^ z*Y;Iu@{Lh#AmzI$l-D&AZ4;!chzAG*0^otDaM*bGOj++lv;D^xG z0E?m9b8d~f)~r+khG_h&SG#%sl1Bq!GHf)sPRMBGPUp%l+u)VMquWkzAQpN_8}e>QOBn!k9)zl=X5iU zOIX|{vYFB_pzdM7@B=b1QS&wVC%X7q)0v}GHsv3xSNHT|f^V~49L@_wVnV8^#L z&?;BRNNAv%jT+JxJ@mW!%_1O1{}g?}qYH!tw9B;fV)Wk14CxQ1cg_g-eLL=dL@pZO*E%sXB}u%d23j4$k9k}cQX(yo>2MpMd#nGh;IpsviQCZ zw|VzU|Ciw1z{=u}{O*4WLaCFTKf4JKAvRP#ttm`%#|kIi$=`jdLm=p57U+w@M7h75 zpHe-@B;6rly!K+-zI=f+_@bd7)Q0w~MND-J=Qy^mZu9zD*xvhSFF8cueH&H0a;}!E z49fsPN}Am1yN3&LY*#7@f_oij$w=tnGoiXS(n-;tv`4_tNrw(GN561Cwg8iK_~z@| zlSxp6M#y>eYk#j3{4-XaK2bS(5yUqr%xBeoxPqW698v}^@e%s?wi+wth5Ot%e{Ci; zQI1wMD{EuFNClg$eP>E@dhPbND~g}uX>T9YaY?iZL)`b?B>Go7yi4M;wpP}5bOu(o zMt?ZwxzVG4lxpzTA-&?RoE8A4mO{u#;}gh&>KU!7FP(i5y%Sif@0VJN{n~1C?P|(k&TVgN1Jetx{9{kR-H2}6--TO7plN@rhgY!=(so z_dT3~wl_X=;4vMw14+3~)xJSq!XBVRcnQA3{JT$KxsZkhzxSz`_vaslFaB;z2RnN! zi$7X3b*vM*iyjedLg!Os{SQ1L@oDXz>Y$_6oMaZ=D#B*kr~5o8Pw#%c!2X(7YOY?0 zL@p6xgxYwJtlq)?#erw*(y^-ZC5=9?MD9q6=dU84M+)VBo`C4(G|f~p!`lHGd$_3W z$21x;v_OTFMN4Id%6b4rH`_b&-&x)gQYOyM4;Wge&kD~#|9#>J=@=li?;U^w{2yen zGqSgT7ia!M21O~WcVV>kTm_7Wt};1C4Th@uPoM)=7?bY-q2gDY7SjwJ3BI{EuGLsS>%jB>nXX{T(tFq%-&~r>Xl)VH? z3l_P}R;~WZ7;wO*u}S8RYPg~QJ~6KTh#l!B-tHvd;kHY3i9S5~q%0WgWYo~Dte#mc ziT$tVLZRxjm>|)CjNfsj6J2&8WwLVtX42^jWeD6w+@H(@P>NuMiz1Q=Lg8DUa7wW# ztNoEv464IC=~Q$`zBSCv{aC7OB}@`)t>cSs-2f)%+Gq&#UKEUH8S`7zKh%n-V%sak zz+*e+>jHG9Nx=D9b!h1FA6tHbD3Gvio4lYAUvMlnkGta=DFee!AsMvYFnYj!4fl8V z=z@mmg|)Sr@g%=16veJ;8|mg|LjFSSNgT&bP{`U=JW+@i-PxgC^49eRyc72lT%0nS zg;~57F{twxVF!AXfTgzL?P!rg)|bCKN4Erl(*<;e%QGgm(u zv|qyO;f#E>o0lxePxbKnAmlOE{Q6Er@4pGkQtvBNa8X9&r@pR$Z(o)>U4I}2bI)gM zv-bgJ_q~51{*x4X*4BSALSD+M>%D8qEO`~U=D&|r{sNO=N$>gdNI2L;3ztP|#A3m~ zetSwcJFfPdaxb1ga&tN!9?7e8VuqrLf9|$H4FdjJ#z+`q^pM6Awzo;u*qW)4%?u## zfGCJ`#Ec(11SgD7kY&Oqq>UPkD@^R3K^59<+^CRyQS`GnMDAw-!GL7+GtY7Bu5i#y zS@n`)>V0*0OxOPMwAsSXhcINwlDIB6B?8w#o#+EQD>g<26YCBP_d66K5BbVuo-_vB zP;1pHtI!Jx*_<&=_Wi(zg4?!L3P!n5d{WR76ui@B>DfT`gCuuI&T?_+F&t ztqmPi=ktQvGYKp>X%m3c!Wn^P<87my1V9)T=bAs&3xmkgRfm1xD7~^W--?`-5AMhR+>}-G2<4P}GX-L9!+y5ZXHH`GA z3gGo4|G6g&xc#ki^eRq#K^*k?$1|-KUG=vciyuA z+7K4J2<)9`2jh8vx(4tj*NR~?TL$5oCe{HIviRi1!m>Ih(i}1AGq4?1eO4U-foQ5e zXw4`6U?!Cgy!x>zY*{o4?|D_!5&%#%(c|6s9*>@4b8*G@9w6|D+rJ=ayPFKLfWSZF zZtE^Fp20%q1_C#DcLI>HGU6FTR~nuc^V2nb5(0wU!AN*E67+^I{GsR)hF9XcBXzO} zp?6mN8S$ZA2J?0q{DPwA$&HqozZ>CibpQe1ke-$ff;B_I8i)%{fm&Dbrw@4fYz*o$ zo*>ulley(r_FeiK4mumt(!~Jt>}z#(0F%%P4$x=OS)EIKeWo8xf&l2BMRq&TbQGI4UBqM3I@6_c%Jmh70XHfUt4 zoM?uXXV$J&|J*29%N!$WO+S4(a}*{*+nw!8Vkj`E3@lfz%yireD+hsrKx=T#tVzy{ zD13R;?J)#ln@I)Y0|Lo6BFOAhCR8WL&wikXhs?&x2L(E`TVbjZ54%=mO2=zD{@!b?_~DAXoM%P>&wHzWVtT340oo{f^R4D=*3gM z)tk!`>BDn9z7FqW9n|3TfJ(dj?NJ0T>#{tBfY<%W?DaRg_TNwC>FFju77(JQ8;H-r ze#r-jD|v0q{*DUF`rmrtxr3({9O-xIy&2R)j$z(25vK@()CR-L%WQv+G1Ww9L_eke zdFn!gtP0b(`3P+oBtMl|(gDq?FE)i9>T4QhLL*LWDd?P$P?CIE=!rV?wfD)Q2~U1z zk#wqa0~P$Mw{!Ry;uP{qw<>!+?g``2p^z@FeU{XSxZ5RW^|^HtBj>t(JJrQ>QN z3`gui{YfS$8gVuN`IRM@BFF|#1mp=ki9bDuVOjP)aqQjRh!T7x%%O^c5XC_R(!T2r zEsM%b6R;5voplv1ukrp*qCY@U54Og6+5c{u_irEHG2 zcyd@jxRm41B3mUc$KjH_kKvf(LX!9`!9^}c(qxE-tmaHQl%f`aFfCOmQgIW@BEcPk zY$8xAkD3uVgrh2FP2|-F=u^wL9E!vgZSaT*-0$Ib-%}y&NF(ni-a{ywnZ|Qg*kRoV zemXU?D`?g7>N6G|WCu4e<(}xG=VuZjS=r#XZAv%eDdKRp?Fq{EeU8)G z8OBd*n-9N#y=m$#WM1AxC$93aNT_0Xb6#4)3-#3^`Fd6a=LJ{S4g1I zT^85%s<=pj9iO&R0U}1Oqu>Dq#%kOz6Lo~KDp|6TYQh%aA3Kb`GB8q_U~aUT)f@4G z%fa(z)IIcqoEt4*(==tzOuZ}Rr&>}xd!0ZU&yK`cti`Tu)jA|iw9~ApQ5;(2Xhd9l z{5`%kY$^Vc@Yd2Y$En+u+?6h{$`fCL?p#Fg<+?&aOI0urCNZzi2FDQeoTO{abj9LK z`6y};8&{~>ReD=mP9xb;v9|WdU`&`wXV*2FiMH4T!#6Uy+OQvnl#*cp=wl}DXx5Zs^wz6L&;yh%R5#f zM^E_mzZRCsX&~;AjOKDsr^S8qbGRD`{kCGjjN7u#8O=(p#l5X~9kr}%Os&D4UsYPH z{5t@g9=i(x6@u`-B^p2#;rCUDZDQ}=!+pxx+IeI$oPyo|rcde~W) z)@tbs#xn*E1#`xn$YA}`mNr` zr37vX0nR#-rjDa^O?P7mN+iD`Gsc4%!1UP6M-qK3Ko zuijCC(r`{X)Sn({GxpudVPz2NgTh>NqnUmC^ zN-LYit6+H)hGck>bxH!w1o|f&68Ym~Y|hl7v|{bQ)-{Bn|UR7-XToA zo1*dc;p(UQ-u1>@;>O3=D9BF^z4yPT??lY*HA^d{ufm$IXlhvWwPuzE!h#%KW>lF& z)kATz9}3)InX7B%7wW{u8IuVM10oh?P;iDN6Ezoj1*vzc2gX_UPfhLm@)_Lv_f8D% ztjJ1~csTT0qM=S`%4hP2@O3dRn@#|3+&XexZvEZA>A`S*gZ$g8iqh73N_}5h4ZlB8 z|GUC+GSXN0hhwD`KKzG2D17hx8?mbX$7dmN{D#72B1K+;Is@#ljHD>)yz80Rox2_> z!?Z^cPWnDy(FG|Z65~MxBK+VCDAObMtfL%i*U^0J+q#PVV%dl~RWnjn<)tY{8|7zY zHsFld1UGKNCX;&@!_9ixMv&YH^cOfCrk+Y#D*3PK5SN>5;OE`kP>%ND7W9usKva%? z*-xlKYGlfKMHIdFZQ%Ds`~SbNX?<@o*v z_Pn3r|0&M*5&kg*@Nam8_+Rkm zki`ATCo#zFw24AKwSe?R$R{B?UQ1#l_|y0=j_xwa*hHX`(%Q16W~Xz!eNAYKFJ{pe zAbiFb;*N}YB1juxT@ZoMlL}ZPq3!{(~B@`1TnhMT6$Levl3F3>#%IcGF#uhtCG?O~$F00;M z=S7iuC^$9#HKhA!%X&85LSJo%W+Ol^i)~oqWSDh=#8$EKB^|QRg1QIiF_)}*o(%ie z5ogINGA=Ty+ALT%hMwReIerq~D3ltugYd+|h#2KjFWTR`jrsF5mTCu`?M{7JEc`GG zt_(s+QVRRb7J4Ggy(*i0va@Pvjhg|d?|DSux(qxy$1^}_@NR*stw{$ftVe(+L8%6sd@F5MVfrN{@QpKf43J zN0bl#f|Goab7_$wVv!|c4i_qtlG2Ak(|n$f$J%{Qi2vSgvAi{T7>n3G4mMUtPgxZy z{cyx4P7vn=3;`Dc{;%ooVx?oW_LU@!E}ng`e^q6~w^%TD3F}QM1Ih?S>dcz5@Y0=3*PpRMe z@M9hgaykH(n6`0V+V6eMWODjr#Vyn0Q;XD4(^dIU`ZwB#aj&E69%o%xP>M7cs zL{X-Fg{20@@#QDNqj}=L0LuRMNt*Vl?pcESnA6q1L(Y6;%9kah=OaSC_xN9_J_PmO z7l4}Qg??X55MdtvHGl9P3j4AkAMMf=SsVkT*;~CONc=g1x(YRs<(vS?7xF*unTs(` z?kIMjFPRZRKJRjLmPZV~PeQL((Pu>F$0-t3ftaL|uKABtzt^Ks?76Rcw!F8%(INZv z=a`&)wvluDA^?@5dL4svD*WgS@!8(jJH|H`!!hgQ=P>neiR_6j`>ET%O8~aO*T3KT zH)Z%luwI!UDy7ob7^DK#qYI*<{H@)wXBosVp0_s6_P4vTm5v!d<-68=3UWR`hNW}+ z-}P-1?0w>H&m4pU#}n4w>JpsC@S=Ab4#JI^JwE8^Xx;4Ww13CCFQ$;ia%YYyKB0=$ z!-OS7lQeuxJ5EUGVQcn}vb!b0o}XAm}5-40?QqLtH(1jQj=%&HPW->?APb%VJ-p z2z16#A1bHoa7LBRvVb}!PqkabB9-P|R?RLvZbbvqATZ^FGn{(Y)cCHVfr}zo8liS7 zbu2e$U-S!4LPmGBxwy-L3WC_nhYD*ksr64`lnsO(DoN5`tGG6a5LIol<0zrZ9<;{`d#j8QuUS1e7cY?# zCyB>tDQmHY!hB|bbu%7Qua_knXra^TbOXXT#mv@gp*(Dh*l~4>zDZ$RimZXHp$e)~ z#(`NgG?EO~NgU*=`tN#m2+U$cbBEby5k|Q6touanD|EpHqde@G@l&`q2~*mqmdju; z>=H}q*}_hPn3?c;WNjnO0|Iw+w?7qJI1(p0bGvgaYPDUcybns&VofN+5)1M}40W`R ztw_^r(#&T|?t!G9mgf^vB8)heu~2T<<>Jh5)_1jhuCY*shc*SDMxF^p1~2~L!SHBR zLjKv!5GOH56I=wb%@V^ji!|v&W_Sbo&l{%~Ild`pY)HBExNb>-W#s9O?0pJBn+x0B zYp6Y~+TBI=yvAFP(u&Vxvy{tBwjCw~M>Y3NTI7+l(Q%kZcAB9Wta>dvM&al64)zV| z2!z{Adv8m|f-?Os@v5dTasv{hyQK=@UDJ~IbMf=)!;N^1^@q$7zhUkwgZ1Q8?4fV< zsSM*qq4j0l7W~hU{*=nt+jnLM`jRI=JrJ5Tpq}C|KF+xT^5rW^c{kN!-`xjL1V~_l)q{lyCy*T$a*6C;Tf~@bW$;T*Qz;&Ru;U z5Bo#K@aM^kYR)K?SZXL-okZXsNc_#oWB)IOQ#D6}8ZVC+4f zIio8~iJJF6qp;GSx0FUeUu$!-hCYmTcJ?@bI<394C4qmvpal;i0Rg#~U*^C^hIj0} zx{pInUrO8fx!HwF!+v8v!)N}A&IG1ixc*(X0-es`7wCOA5B?gCuCl^)kasJ`R^Al# z+ra=jr){_cZ)ovN-rdCbJo_Xa!U2a+-3f?2%^)vIsv%{b!5zISE(pK0<3h7UC+j04 z6K9jF`72FigD{UyAmrvGwm>*@-qCMEm>Y#BwuTg)G2Hg2Z7U{mxb#wVM82kR9AOAUT93w0iZryGJ+r zs4_`=#XWcTfR#nEUddc-qTIO4t1vNdWO~(B570h%fMI`{i2H5(k3L(>5Y=k3%)Qqwabbx0KM9JGc5|wAJ;QKLwSTSF$JZ0GjUU0T5x*_6in& zzH2{6*W|b-idI|V7*ON@#AzyL==l#XC&!FSjmiDr+_%8qp`*ab@+bJ;hoADJ;y20i z^7=T2xZiiiu?6+xe9Z;;pZDJnTaWU`?()6?0g~v6BxBNv@_`sK<~CxyFg}$Bo7LY{ zF>C+sw%04Z-Zr`)Ue!;XSLQA5-ACp<&MigX=YNU+M!2D!(wh0Y2De&zH813bHb@DL zfiKxr%4xF_Usn5xrNf`)Ty11b*252E`qT;2MT|w6OlhHq*t&)KE z#5z`ipkjC>;5t6AVSM6bGuY_imomsSi#ejHSS0n76V571byl5_QR#5oCWyR|Dsjm< z+Y$(oED?0k6i&i!N(;EU=WyPc#^k*24**!r{poQdDp*v!yqG&MzFrK}BL(lR&V*A7 zL@OJ^spPG=5yWJxOa7xGNK2YoT|iqvUtpA@P~Mj_ey|1;<-_m3PFS)IcjwUALxA+o z!$zO=gC9<@=?qhIALi+54ilKJWeuNX>vcpjj`#|F_(GUFm|Viy1^Xm9eieNL4aX_ zwFUyTWJLMYIATLZ14g^ODjb5GRy2 zS{S;&5I9ft5f+Jt<#9ETcRA{jkdvx#UN;XyUxt>&_3CPik4`Gp`$D!J`TGc!;`F;> zyB|<;!G#}Qjbe=-5S4-jTKWWNyW!_fa<7-)S_N_k6x7;hMJDA*DWuWmr27LU?pYWo zW_5G_F8FCOJPK&*zp)ng~(0R194)icY;Kq@vN{`ocg{CJkk$| zfOwV)Yvi@gujoP4jtU}ekvLXQk!UVf>5~DRUW?cu*zGNuKkA9d^BXx!8@3t5X?Y- zhq_p5<|6SAZEkhGFlUDwKzb_bd)CU&>kZSIN*u#6pv8Usq%y07#3I)h zp(&%M83WB1JvTDX4K`{w!i%L<7=&TGthbx>r~KU5%sE#=+A_n@vnjsV+$XfoLeVoQ zDYnf&@I9b5#5R_BrXWSyrBG=UdV|R@T+RKprEJokhPb$~R z?5TGh6mc8HA{n&JSPz_lC;AWjpDWF9;$Ht!?gh9dz^=8CbUcg<)2ew2an}m-3oN_e zgbQ0`IIKxlPo!M4A!{s6uUl&8r<{bTwO%u9Q6JFII20)BzQ{%xOMg|(#dZ?3azLpO zwB}y4dDi$74H5@UH6H$G|M%gb8g`Xa72ycQ0Wz(D2{?tUoj9!ge~$|LR3jUSM9Bi7 z^e7RxC#Y)jpf9$5vc)e{;InD&FI4WcesoR?Vwo8ReSaq&ouj-ScxKrXDQ!bIxGp7x zByB26`}HvB{s7u}Yz`n?L10icP-7cD2WXv0xEEpTrV{{g=%+*+_WpZQ;vC%7i|NEE z?4ZGW3e1fwLjeUUNOL?p1P2!dv6Eet&{9t4g%JrSzdMl5_&vC?sY<=>QIYRet18Ew z_rSI&Z)A71&{P?iqqNw^Ud1* z4~+Q;%nw#Sp{U|3RSq%G;wjb$3vg&~k%AQ_C9#niU4ohd=_wzH3O(`FxTE4l=lS39 zL$r%0!8-^gT=u_=AaXTFCG zweCM^LwfXN`~`Iky$g@5F^1JnQ)Ts<)vVLja~GnkCD)Oz#g0d_7+#@P*06?fEfNC~ z+nljZYT)FDyg+b~XinHV9$jmvc+5LB#bUSr+v6{Gp)jx z&Qf9i)<|oZ${<-p{^L5&i81IBu45XIEh91Oy#ay2+h!;E>33MJ@+KETW}jZHy6t;UH9)uZY9hF&l1VxNkEj)L=#Lp2 zeCnp8o54YzrDUzkB>B|xB|)5H7-N1B=P(&X{-Y+d>)EZiAbMD>yYYIpl+DqWu3UXf zUj4VQ+-~>Sojzj&fVw(OBhC4ktJwx?)Vq2~FxUUnLjNr{>~&c4D>g#0{D7lJ)(TGB zYFWgD+-+Y~oxu?n%cCILQ=qk5`IuB<8|xm+I@ja@(&>%!3*Wvp}#`OqRRs$BY3`d?{kub{K_0m!tW7px+JP0N>T*EsZ<*_ zGVZobP#{_jx1(7)hl$1rVW8@($MA+tYDbyhG_w*J(hE4*qWb_rX7jF_VL9CO3|mXB zw*gaydNV+wODwM|yxc01*^u6H-{)y}@2Jb5w_3~$WCfP06#^t<+uZ^Z0onPj)@I7t z1qEKj6zKIoHVf<{RFPXu9ryZu(+Y-{#z{FNYvm`~S_kRZVMX#@uX7 zkB`doMY)kKCGe@x8BxY0fJUiJJDh;#BE|Xag*hHBG+`MJEj%wdY>X3;=c^_8XQ1;n zm<=H&9hy>AWw9YRLqx*sMn8;^JmU+D!&@aJMPpi{Alb-VwQU|Vlz`GjjGNu;HJP93 zmej01TA?{=qGQ&wh(h+HtY@sZVK9TsOx{kW=0OMwA&$4_}N6h6TP0=tym?1(+y!l|#dCla&DHHYkQ zF@2Fak)I>B*W}3#XGurP?S2jht}5g#k*Ntj#~17lIFwWxl`oAt3%K~9@#l+@W;S#| zer>)ZSIbDnCzpt22##kelYWKjo#{lo?6NfTnrsJI|40}vtr-G|n5rKXkodhZ$;g|N zL^Y*7`@AIZgR(4XS_U41CQy8Q%{}w4(N)qI!Td5^B;5k=d%q1k0LZ^lV{FVb=IIo$ z1XnqR$Z{|P7He_rS;K)k3f;K&oaLtl^qyAGpvRj~Kv*PI^l!{%e*dtf4wH--I%|su z;@pW@%8%gv2|yl|aJjWmpKMkX%r*4jm+raKw|!Z!xWRT*em4Ev9e4A+-nsX%(Z$Ci zT%2=7tQ7xR`I?eS#P-fzjg+FX?W4uDc{&cI1suIo6#!r)Y-+q#80@y(UX3e#&!#Dq zy(Y;;p?$JfwLhg*YGLdr$opLQcVSrF!pBAf@{j$+f|c?3WI0}daUi8D#}T_O!f{TZ zT1H~GrDwbmW{l5WcJ)ErrI3BErS=SWD;qc4JKMUCvEtEJIMsf}{rEdy&~0wjkCO@b z2lf*}SMYwxevEROH1o6bU+s>qokcS1qD5Qi_Zz!8sfk$2tXQq#WBkUQI;yhGS4&UC zo}YJw#CwE~sd{*>Tvd)*uMs)3uKX&MB$XMMF!31um$GV94GKaV*Dc>kra9{C!Wt;u z<5cSeTrG-gY0-K|ly>;pG|40$tck01rmQep7*9H&@loe0M-xU`N_MpFNhIUSmqpM#=1V%}#FA}Z|c$DTEyMeA+TqG0! zWSu8Zj&u5<9D(svHe^r~;E#^wf;~;#5aFdmL&kFGVRbnGf|a&0x?X>%7ur;1o-zCS z%G*{3qR$3ypB&Cc6tF&p-w%xlJ1pEa?*!jmD}rt$wEOk+J5sW!5?{_Wa>>XISaO}C zt`boF3n^{oUXEkIVsJ-V*#7Yt52a0I;mB5H0aijzf2F4v+F9C~oGJQbnxWJvlQ5{d z&(wl>kliNvG+eWag$|zQ-J$bYC*~*>fGcZPaSTPRSSmr=dC)`T^9(Ru3L0Ztm|lwU zE~3=^ER&quIeQQn6vIKx|F}mMDU_+{2>rql@#86xh}_CmGU&U81XAmad}^pJ(mePh z3lceC*_YX$*nt-P>czHTqdBO(AH!g6_ixCei5##mJIOM((r()fXRVizaAQXK)^8X zcd0~owAW$v3;UR+9e-Z$6eL>ZjBZDdn~9=Jspj3%IR%K2#p|0Xnj!P7+l!>UarF%6 zkxZ~=(5Hx;LSQ0Hl=?i%c;%v(PGEoJfa|RxUIGJpM8?o4wPu4R;{N2MZpNc?+3I^gOItu;-H)Sa^?IcTZ)O2S18Ry;G(ATE>M|nnlku0Jk}U5 zW1s4Dc@T)($m>Koae=o)_5m3hqqs6BzttieeT^1BDByiBMZ_P>IwgBiH98nLJ_oU1 zJJt+M1}*b_NT;K6L7!@V_AG*)qE}}{u-x&V=D(6#Cxzo|SC87%8d++;+E^SyL0?B^ z-?EAHu@YEtkC>a7I#1w8)X^dkXX#5zhINLQ>CPFnqe+Jpn$eA;pu@v@O2ip!C%I%c z0dT@HDzUlCehuAfOrDw{8e#sz{2Agd&zrd_rF}+Z&ZE-oN@7lfdBjJ-Z<)jpHvOAz z;DO$7?*j$%NXNbOvc`Z!R7#+jgB+pV!X|0m-ft?P-tb}_9`2C3zAR^nzB8AFa7izxwqi{ij@>_CLz=p7s%vkHYN94mxwoI_EP) zk%Ac%!0DT*V1b?ctl|Jj5br`X8g-%$M1yQ`(%TsD0dUE&flpKih9$@;v8WA$V>~Em zk}VLiTT0_-RWc*`iV}WU5h`kY@E;L+GoiIQ7z9?-``Os2NIwGb^ekm`M~%`~$Zg1w zD8~(h5pyVnQ)=H^o>0Z(LNANxLP)jo98P7n=tiGDu$lV*m|ZnWZQKX>(7gHGOmhU+ zU-o2-Eekt+@!6oj;x01S9%?g0ywT(~eK`g?W5bIIKw6A8kPeKG|q$&0!}qkVM?j0VfE^x->e5+rBHbz22GZI!H5H8E{f{#BzY=* zx2;#_SJ9S(BLyzp)Y>rt6$DS2*ByE7C0t`{J7;@4&u(bdt?{Xe7+&nVlH9z&OZ zf4MrhSmo~KDL#oM;@_QrOX`+8^Ch*VV_T;@%ZR3Roa2Aj&Tw^czgTZJ!P&7^!0Cz@ zl`uG22B}yHQzC~T2E&rIJ=_4qO zOyMPv4mw9kFw^niXQqEmtpA$SAN44Ud%AcnJ}5{AilmkVehnw;VL{fIUG-mif~c(|8OAK?sTVQW4-7QGXwzmmkt+Su1Y;iph+dXP#HyR20%l@s ze{N!D;P2Fisa`?xG(wu-c@?P<9dPbhtc{--@|g`g=(eOs*iXRBkwe!Mp{Xgw z&9G+#p}qT&L3)TO(g;_42cXD&6Tvr}oS-Sf@zfKQi-jrUme@p#UB%hjYHvW-1=dH? zb-laiIR7RMBb=#BvY$=rRuGOFvf7A+yz^R$b9JbrlFKvFY<7~ofyKzL5H zXp36}sB0H?_waVJ?n;Lg1z1kI{x)ipjL9R>@+i7o42-0dBD>j{av5*90E!@%DVl>z zs)jM`x2#w9cwG$0V*YmA+D!VvH;41bK&@j)Qa66Uc2+;o#>zSE=9;)LFO?UOO$(cz zpc4nV%AMIQ6Fb!n3>=S)+Tw^|s6;dOODBQ5u3a$uf@4yf$tfBpaxDJ1xgrt$zW**g zEPNF&Eon+(O8S4NA3;%h8q9pJ(n$#)kf2^y2ARw5oauTAtAxKTf{a8Xh7}Go zcL6=FS)Ol-d#wrP_siZohSt&o+UlPm8oJG$l*@A4w9 zjem#oJE22Qi&)#jpW9>pW}PIa^gC5UEd`S>mMB4nuu0G`u}!8rxO^G=0Z(406e1su zLs~v(b!j;41&H9ZkqP63@s+*zD;O9@$Iy&DEuO#sp$y#P^LKCQX}1S$vH&9C7ye$s z$H6shpccc}YLxJntIQ>_s$Z7BOXZ#|)0ZGOFhZ*Fc4diQ23fj%=1c}8QrhZUn>$J3t#>|xfgSXH5RZt0~AB*onbu{x7?e0H7VER1*o&x1u8 zN7jibeB=CPH7?T5B(Zj9g)mlimq!feh~c?v^!%%np}HnmP|Jkk#9oaEZi4r*d!Ap- z(Aj5a(?Hb-bPYG@6ucdetd>dcC}30PUfvYMHP_sbmq2-+M{<-Phc)8-=xPhDObQrg zx+c}G8LCRjiwmWyGr8oTBcj0E*u7vZdcKY;7w{&VW0yxDadGUs*Si;+;EC+mc38mEr#DnMk- z19OAe5;R@wSLq8okXEZAiw`R7RlG4H3|vO|;qNY-XI6r@%(>vGUd5KLu0tW%GZpIi z(`Sr$TccO@V=&u0>)d5Kq@CJ^Xcb!9bBRMJgVdKnq{nILV^t^PU&GU(176<}u4??JbP`WFf%|pwSLes=Pw|g-d|lv0 zIRRYp(oG`9t~u6Y%o4)d^PAMV8+6SG{_v8kYa4*uu$vW7Z;#%%CN zvsHDz^19)*-Z4>D!frz=+XJz*5j5QB%{X?$H`)if`fPi>`$; zxtGr^G>g|;3`K729k0?dHC-uMm9i(q;jyVj{>DEGEl9uU2ia+EuW5?ocZb_OD`syQ zMKQGdp}CodJ8h@m1h=_*BOXOtXn0q?b1f1-tgbtUE&t9QrTL$jLrJ|#pB~|{Ds}{S z7T_!R6X}TTr^>frB9H$q?v|9l?bN5BJfzpn=w0MB8)eU+{_;1-f2B)%t645I(>nhP zA~&5X|Cvttu-z^$PaR`L{qKKaZiiJrh0ujtsyx2724O^J318q$c}lpqY1-h`ixVl_ zONBHz;sFH5GFoX>9j2{K@(zrxP2AWcesXcMlW%G0S;l?FRCnuP72MYw`P6Z1F&hac zJHoiD`vN12Q~sf`*ssyJzz`z zURwOcMHDnZB)}kc@kZM&Vtn%dMKHmCWAmy*Ut0W8g$G9|gtUI<4=jcyW~ z+2fUy79~rheZPtkBj%w3BT2p^FUUT2Brp;;e}{PFFOwP+sO(mk1r(}Gb(6`H;4ByeM-;HzV~;30{YeeHYn5$UO%x+zU9;O%tFBI zV-=0d_obHHNM7!4rF&XDThrmxII8g@-UXIz5V!kS*%nv+K|SS}=WHIO zbft3VPxt(*E&8WcNTwqqZt!=pF8eH!oPy7z6Z?FxdO4|LV??g%N)(}ljPTHRshgAH ztLGN%aIAge+r4wk50YJ3vB@=W?Phw(4io1EnA6i2rUm z;^VD*sjPrHs{)R3wddms*G^l`#I6L_& zfmCYf<2N6DlwBbA@DWZwo=kmDg$3IgD}H0RWkDlygJr4hRoo>3dRrxRt8iytt-@c} z3m5y`+1(5oC0>s;wd{^~%W|j|g9dEpLOG|hP9ZD2Geu9!cxsTHTxVPZYK@^V(KLFy zq{>tnB`Yi6(x=4O*g?z2hEx2hx#jHcqYu4Fu(QG=pu$yr?~4NIPKvak(dB!*1C4rA z)hdp&-1W>mg#bBu2i#wm-;1L`w*om;)pe`Q&?M8uPdyZo9TFHDU}85+-V&M(-5Ief zo~FSaRm;W@S!Yi3+mnUvZfCm(+fq{?kX=cok5HRvdV9MT(<^9u$qDoX#u-w&Wk9i~ z>zE568-DEcY(MXR>beUC6)n4&T6o`gN*D)9cDFIv+naTsQ;CduJ6m_BZgxls@AJRg z8akUprP6C`mAMzA8Kqk|iy=HRTg?2dry}+-@s$l(o$H?M_cPnYgR^w5mq)hE!(G~$ zmMGVFXS(!$^zR&ROxd95rOYMvDhX5H$eP;~)3w2ue8-2Aum0^Cgrm$t$vgTgjIs#5SA z063XELmAfbF4DHzZT4=j?_bkIep=5orgS}WaMyWKG3OeO_CuMO$nZ}t_IF1;xe=BQ zoNKq|vxxX;7&N>n0Qsr%496xQymwMfFsj%|OvVQ%%p&SH>$Q75-Pvq5?ONZ^AN!Ih z%dA_YRQkS@p>LV4BMdg;0LveEGy|O3RQ)t=IK0y2&`6sf=kd7iDYa(O(HQw#$j!u+ z1d3!Jk(gcAg{>H+dU2d431=Cuiz=83JQ)%V%1bP30(5ptubPc3`y-6-P8A=s8;zc`e4=$p z?;03w*NS^(uQ^uZ*hO{7E#+|E;#v=@@Dp~wYv!M`6Ihn?`G_X>LcM0XR{b+chTg&P zuFBKvB%X|V*{E$`8)v>BzGpd{H7FH^$GbO-bOqB?$x4F;n{)T^9z>q@Yu{j(bo}5CtL& zZZa_=qlR_ly1EwNj;Piyk{m9?*@9K*SJa_5P{wif@!d@t$(6_XY7{@nUan^urFuXi z4m2&>eJezboyNo(*xv-zBZ24X@=S$epT)vl%*j>IXMULeamNqzwi+m`rkdcJ)p_4b z$x<-fx_%>0VK6nISa$#84@-=dj3lkIi^BMpm_aE_5{u8`#r{*~-TZ(v=+C?dIHH%B zF`(fUa*z~ur5BPC90(uKD94fq^zi#**@B!w3V2+PG$<}j3A2%N|I(-h+`uUQ4V-_Y{p013}3{H=3DKU&#!v*l+Vk(xM64M(V@(%nF^tV@jmpC#=2RQM)k>w(WK z@tSKn<1Gnq;C|s%=6hS9MSL5H|7l*A%A1Iat>G3a;ut^`i;)VR;ea9Z{0VrK>xjEE z|DYvNl3`&A_gY`;{CSVP0WHp?YZC9`9SNq@MjnU0XM;&}5b}q561BIO451>iQuq8- zyc6e0IG5sse-*41Hh!)c+k&Dc=h7ZyaBo271gN%EdJmypvF*T)!aJ^tL|K6UOQWOV z(o*96Ip`=gbo~$N|9Vat zW}kZnlOl0M*CB@z7$BxDTAS`7cq1XzK2{SX`qZOf2`$8c6=?x3zz=M3pvTT&1pF&e z$+|fpJ1!&#P-*FvKlD+`O!WEA4IetkXvXQ4#;3yK!@xKI5#@QLvUn&k9rV;?tqz1L zZogD$b5JGFnECNJik;-3Mmb^uS;F)g@-yDd(lcAmOe4rLt&?3;WK5O;Ej@)rxM1b0 zS#58qu~(UnC+}O1m{rfY#Tt@dq0K@wUs!gslfMt@Nh)Cj2;&eL!lkRU@4+H0 zu9UGYvDDUt!KG|z4Gn_=ypuZ_lw~2*_iCZtm+6I@%%v0NU}Q6K-xZ?<6)?t3(z2JB zkkX@h6!`}V2qHrkbnG)>+G(&{iMmyllYknQb(lNdrj2nFYR*5=F z`cxFBek~&(pDrU<_AJcNZ&1r53w$(=rSgnKTHY(?fcJjJzjb5l#6D%6kFN3@?T<0k zaaJueuSP?-*paV}P=AnIK#w{T;pr{>A2iBy&BXab?%=venDps^ZiQR?KqHN@hk}tV zx&I=nMOL3j8SEQV~|++z{7UnmJ> z$jWoL5BI{CG((Mi!kD8kpiI{^gLpN7iZ9AX%u2MA-TN)iQjJm;ve-b_JI~I`r<iwV_VW4R;2un(Kx z0bPyMl$*pk=!jiM6bhnr#Ct0T-Ns-=FwA1-33}^=6@(|3DM*g;5(WZuJPY+iPXTW* zSHPK`OA?1+(BhE#+~*;UQOt?2BOElB$ZpAHv+AFck|y#qjZBD%{~(VFfYollXh5Q` z@%$;16V9)g(FT}Z(0R)6v0Zy`5f-Q`5s9yhSKR@?G=3>9*%)$xLGszjXT1J`L$TRj?#5unO zP5OP4{zKZ>ipMoEERg<=0cQui!2;qM7??0lD-8Pp5->J)tN9-F5|-+l@u3Tx_*{1& zzWe+z2l=J^_9IazeoVF9bjsrY*H|ChA@rB{Qp04dV&MeJ$%eOc<{3O}5&Zf-qcbiR zYD{Ro>Q2)M6h#{(YJS~PKVRlrdkgesxOwMYVsbWSVoIeOKB9?rNGm$pVZDwo*D+ah znyeuMGDagtN8~c?n;hE@iEo%X3t~6!DP%}Gl;rN8M9C~G!*^SwWV(QF^j+toFvhXR zXbNAM7RV|7BM^IcXKU?}-+*7ieZ(4}k2LXf66>&exRmcE3J(S~nF!RX4uZ>aA~UIhye$>vy&ER+=$kK+BIH zO|KJ{7~p(7YXE7^N7^jiM%Y2OSc0fFuX{y_dno@3zEs1B9V-NosTBicql@AU(8B0h z*golRzi3>o+^Xv=G$iuH3*99AXoNn5kUc_SF=rlCTkr3_a16b$8O=l_dnJV_8BsQL zmN>F<=$95TW;a@>AwgK*HNc>s>xkiGItj}FDiqSuyL5>NGdk1IlxAT`oLnA@!DwPr zU@9%+^IpF|dB%;iEA=#xg(hlVPQ>>*-Ey7xW6wC$^NFcTTYY*>b9V-yj44UV5LIHZ zTaH8Qhe|Z&@qUytk3{Mr$)813QvC@nXCQLfhQl%zi3R;3yw0=W5!47)G;l5TE z!!6Njkw~nl!3uzJtA#m&Mg;h&uiCu%SgRK?{ko4Z$UEfcQTjeF5T79VuSjtm})RrCpTWLYdE>QizZwMd#ymo`ipG zK#1Mc+!~iE+NJN06Tf}E$;h3pJyGx#DIj;MJS>-h*gRe7W1k1*_NdTD!;frC0M|%U}(TbT4#A7>LaG;A&_C- zmFISCsqV?RZ#TL8|6=@mQrM@HI|U1}fMZU{Mc4pisoV+#Vp-Y8EZKL+iQBQ`Nb*J? zyeQwJ6Z}uQ+}SnV7fzljwmYR~f#8qyHxcYIOr&($U5zmNO9uhVmEgc+EB6 zI&RWXB|yK(vxg>euclU!S!i0aWK%);RXBC%TTMHBSb`G}U&$$TRbH50IckFr$_cHO zL$O)h+cxGvoxowDM|ecTFRShoTB*cu9SI#okzOUVja5ERsj-0c3?s))zt{j6b*M-- zPtc5>{;-W<(;Xel7|ieCE@s092QBXQe7>R3-W({boWgT*wdF`uF;u>w(FwTU$Yw1` zlHc!ldyFpBiR(=-Nf1H8t&qGc3m94J7h6GU^$_c0mF_iWMNVv_7I zOt6|K8Jy9jYKf%jbDzLPt_7Rw!#yyu*zg&b)&5w_16Pu{4|$7Xt4sWuat-*?-gzR{ zQw05>`fh11L(wQ8uK$PSS`(#IY~L<-YsWIhZ$0I)gI0i=0hj23SC?e`mMq!Ee@_~0 z;iKWa%vdupqd1nbXWm&iHg@e=)68^zCI8Uzs>&9zKMnp!gwX+MYtG53hZ z_$R(JhlClJjmK4gEWHVAuO4{LMAnFTVAImdQgQ|BQ;77E&Wwo?)AU#%iD z*MFKCDWEaU5YQ(pjr~Q1!w0dZqTRXTMRRK z$iUqY{$;5YS7T6#fYl_RUfjokS02z#;dq7Ram*Z4+wc$W$8WYOpGR300*SDa)V?1- zJ*J}rRS_hQNMuu$@&2KSdLT#0adIpOQ3J12su(gVj^YN^o?SMGHXRjifazLp0S5o4NUX; zdS>m=^Ygw@XWr;A7!QhoE1AV@;=WuWZ0_OwtcXZ4WwY5Y#uUpBDHrTQ2mpKfg9MFK z9UrA+-327E#?MQF88sgPy8@;VCh<%~+hVPVey~nQNvosb(b|E&5OF@M!7bcX ze4i*A^9au<4CA=J<^_6D*vguKX%AX+FH=)@(8WPgMWf|W{GQ~kt=C+3FCZH@BcZYn zOG~DFCUY96`Xq-wRTDWRBmSA4jV_jaB%Fx5I3djnZv|V!VfD&Mp+xBBdB~3X$RB&o z)Ua2Qos5{O=4Gbxl%sOJybsJo6}C+#q<<8G4nGhV;*PCxS*~|0gzm%B8TH79y^FZX zbUH0pBe&~LlRVLKp`#v(5L?W4g?jE$O%I%>KIi=2`qN*0(XQA8ls-NIKsX)e!vvW4aLrdeDI*d``;Y6J=$$?leutg=`Bo6nF^nvII2t{4w+VXa^)Ih z)`w%rH%YurQgZbdGDi5fho)(Hkf${ImuFO{MnqI0*e*D#kcy6m!Y3+qRTUtS@%UVi z`+~J3m>_P6q*iTk;GL-dX#K`)ZQX~bh&7a0k3P$oIxGV}O@kZ)l&SauBQF3SG@?Q) zOB;nK)1x5=xMa)-Hen~8Ax1ZM4i=Ok1xR_{k@P(Rbaua3aGKMPRvC1Nje19}R6FkR zclfZ>x7;JrqruvYvD-(h*(Ttl@A?;*qU}>+%>qnL(rhXEx5b8y9EpG8e9i=cXtTx?ry=|;pe>HdB1bQ zfA6|8t7pyh^i$ovckSw`+O@0Z%5|X}VlnDAJv+C9SAsb*?~}2CwyQz#(ggTDfK^BE z!Nl1Xl-T&_KN;Q(^mF;kB?a>{v$%Y3_Sy}^@cBhT{wdpFsd6SnBP-ucDmvY_+V8Gl z{0Cuu+;6VpgOrx}Jz>|35!#)>>#t!g`n2K}@+jTX>9Uj!mEc2mUxEaoH;B=KNNKH@ z5PItDzKz0>rvoV-t6Y$>Brxuq=wpw))`L!E$$46?_>+?_F8w6RFub~DHu!uUmjoi; zucg=$l55>qevOEe1$1$`3@6#%v$NK$b_BhJ7N2U#Kt0g5Nm#d0HV{o~-*yvTQte8l zDqEk_3OaKwh^VGjr(A?m!g#uo9cjK?>6rf9YpvNHf@zN6GaExV%Js>;>XtTM&(0J) zGL$7&zl_bh4AZu*u3Hfd6QpIZB~quCh88y{;)q;)v$@%WFaGHDR!C&M2b`Lv5G_=c-op^j5bq;f>I>ZkMMBlQfM4G-kRyTWIB`3{m@ zCxp>)XNeH)6K=io(jFC~^(T7mR@k?`^;i^>jw9-iLsjdXppzZ@ySeJ_E_!R*mvxfj zWN`gJgglen(WNku7eZ#Vjk_nU<5La8S^@ZyY+~FJTvh_`oT)%?tUXqw#cWwUS$Q%5 zKR8=5T>%|DuO80!7vpt2zLA_OZb!>KXx`?jOj{{nNeiNqcP=`JGfH6V)fnyHxw#t3 zKX(BWra^#i`4r3b7&jQV@ne~SL^LV8qv*lWk@?{Oi&A&NOw-VD$+8flGWJtU7M?R3 ze(vXmWBdl4GlN%?!ylcq4>BEioM*6QEl=9hW%m`K#_o2fvj(N?Wq3@vv1uOB*H)(p zqe~g{6#p9W`qc-)8Sz&8-~_a7(W_ji_SbgBqC)w?c^v|5C@+aCkx;T=Mf^hhD!&ql1Z<8NX5||y zoS2hC90${otO1v!f=F5^J{!QWmJK*CoYbZ`vbI2)DGlg%v`RRVv(KDsPzM<{AJwD4_QO}xabS^0@&Kf z=JVdf z9@**Pwn(}=6QmTXO(rUlDlkuaRMRp4rOXW3TRYT(PD%p|CdAJ;>(iobpfMx4Nd*Kq zFK))?QQ1u0T}D=r2W9<|K&G4NdnC`1sip^K2cbvmI~!?PwvuVVN#0s)(ic+e(A`1M zNhc{f(&0stkbConrJ#C=#nB_%AhR z%6|3lL2zx7N=K41-Gin#BVYqz2T!zg z?1We|XU08wc~Wm25=Y2Q;8B3ddc3(W@zLbpm5I6aQoWI(RA=Jxi=lWRSWeq9r& z3X>it;M&?aW}DO6{BV7Id$oCcLY67Nx~|aC-xW?-p9Z=lx5AHa=e3&ecQw4IKz>Uy zj9^^LSK3Q<4~yL&VyjUk^)hL7aMRC8i8{5eVHlHBBjsSuL!US)rxHk_-zW5B7qJ$t z-bGmF*w;lSXkIV&@Dz%)C+9X1X$r$#$1|v1sm^M`M_Af$SK+eiKMvjH$dGcws_7-cliD= z@iz3u>O~J%ARfzS-N>#|c$)=f+?!n%mst@v&jsLin;%Wdo>fCDjMv~jBH87cFsZT& z9!+4u`T~?p(Gg9a>nr-7B+ON-7*7M0jI#<3rY@8A-`4=YQ8N$63fd^C?yv0ZKXDe? zxABn6XJ&slj8A^BAEEK6pEYQAhhSu|lsRpqxLYG(KNNTZ{Y*k5jx=b|Bbb-mAl10t zI^oKtPwRx8dSAWt?T7+eEo3h|*yzx(YfF0lT^HckN;TyRQ2} zL$`(B<1SsHUmdt3_u`* zVzRM6^R`|_pNEy|5&aJ@8LJXMjB&r!{mrqkbcSoc^S-Wj<=4~lHLuenS@30tUtC@+ zVjW!MEZ&Cb{^2afXrcj!v~7V8)&I{p{LQ(r2c~sDF%A>%X(~sou%5G4USx;oPT?~Y zS$$b<$)8>--Yx1S{u~uqW)_&t_*X;)XUN~;RK;o7v*CcgW{xd6CCX?N&mU+_wJkOT zx@mEJ@2N*5M~dgXLVM*yjJL{BQ~8F?-~jqaW+jrF5e*(z+o_*hCWc7KKdh%YLS0qH zB7>Db?t?lECA8w0L?d#(_*Duj5>i8M@zg6HkmS>92soP z+nv?|8nNrIfkfZIE6v`N_gYRsGt!iGp{l&_`cl(PWx$*)0fHfO1zgQhD`c0&%T}RJ`&f zDKAq3VLl3F?^qsp7#h-|8`?l!65n!+BP{v_2d*|lTwE2iZ^q8T)@JtplX3^MN&F>c zEkOs>=>}OF{)tjyBrkLJV9=c1{6m3ZPW+8Y&M;P4Wul7ga zpDR+2?Vin~t!IJJ(K-FY4UX?^Sr=MR;F3Es}%fd5QrlyS%M zo$x)m(-Z;_5bl2y8vRd}r+=q4`cKBE(Zp5jGzO#q9dJ9F)()bw>JaK1(Vyx?=4^<% z=bg>4`17o=%LQkZskFJ~Le{2DERbU!29Z{cO%_AM?A}f=H{@xeH4H%M*@~R&{)o#_ z$DFM#Z4VFu=Z-8_S8J`iD|uX$0bvu~w z_?r&ny6!CJ*rFp$@!jr{C7){F!Wie3lD)~E85$E)C)S3K7#3hs{nq_47>U;zHge?H zy=XhNkhTyuOT)DZS_@dYd`s}Va#&df;Ro+{8RzgsWbji-1y34?sW!T+ezSkxT0jK= zPM{L-y2RLruPzEe+CqTc_ZN+_G*AK?n7u(Axq<5(0p^u!2Vjy9d6bKUdt zF_|t$Z3l-Jd~27G(P%c4Tu?cNGyo%3OynzpZ{o%+K76byOdbWs$!=;EL?&`xR!>|@ zPX6k2N!+eCZBcFRst2`asj{FaC0$nX2&Yz`V5^ZixnK)!cvD%e3K;`QBsk0~UH`5ew2d1WxA=pc2tA^p+j#`ex%+J7?7dd@lUA>X&pe zoxAqEWtd3u87I8mW=>c1okBdTaALN;L!tB`d#(NoQkyR33uX}R-m#3Aw6#}=KRN59 z6Ro3=k0BpPXfEW8-LT<7njYSH`UWVXcH^>lH#&VXwX|yzLN^t@=_1A|Hcy!q;7&f8xSVhPRa+AN=(W`Hr_SKX30a}0sB*2^jc!aji zdMo0$I8u({MxIx@Wvz zPXb5P)IHetgypflc;;c`F!FdoV2EE+4OvoATY-4NYZWv1rVKGo9<7FeN;NgW0S~dz zBw&k^z|r`|B&del1}#z#(ITBGqa3TORNAYHmZnFBBdeCaGkkQsR6D-Z$N84sRqlI( zuAO%)!Jy@+k@9I=2kW&v?^#7+AZ(p6jtx+SU4|e$6I<6X92F{Tv#KIvA1ohFAAO!R zyZS#3SI7A!)2C2VV-wJe@TfYu$~kb9x9kP%n4AONsJn6(7IS#_PYC|(Xb9_{{+;h4 zq#YXw=+l2Y+Sc%w|CK)(MC{-c^SQHVsTpk|IwYHFl15s-A~Z zN{!Q3k4s*5P4@KnEOiZ_ql6KGGy`rU0`PVuOarFf?#{81t->(-8E+if864p!2@x2z z+#ZLIFG@;ySJv}TnnU)2p^M0IDKl~b?cy;vU_kh#vO8D&ts;sC=!{{{LLNpE(Z6Ul zYuNeHV8?@jrWtUN9+G~mNqUW;>_HA*kxx;t0|aCUq9Rs;?QvmF<|qKx!Q(6nri2Q@ zI58UpreOoeRuM2cn&M1{YvGn56M7d&$k#8r_&K?@Nj6aYgOlF_wGlZ_C|~hW1$@y1 z9v(4<@so_hlUJri^EV_YXfi%uiPfgz(JyHDeO;o$JjRDxs)tKnA!IV_IUTf=Fb8K}jfICVLSy*tV@X;EvT{0z`!s|GM6Gd;_Qcg%+tKrSdlz-* zb#iuo=zl^G#VGZi)fr#+_^@L=+f~wjy$I7q4e2}-Tj7F>Nc~>FQrL1%`zDyH5FbPI zg>H=@Jn1%kYHC6zckx~Z9!FYWTHxm5wZTu`$qxG!>Z-JCD^IL&pqi=>`%9X4{*5g4 zg9VNL+v0ldlDMIlRb89wEgRjj{GyJ=l1EoeZL1_KF*jA=0lK0)+D&+WLNHpos@gZ7R`tdlxMq5>2Rozm+ zqcrHNO4O#9zYbr{r?d3Y<~s-*c=zFW9Rk0M?U{`A3sC*Ka0tWfA>velmS~=$0YdAL z(9`A88*%PdJ@KzvhGw>;2%nZtlH<}_$=CaAQjr()SRZ;N+qc-Xh86c3+Wdz2C%^N7 zFoEK|3$<%AARxs5^1FkhtL6X5vlA^1m*qnAAG{si!)JKwMolG$wEaaYHPRG=MXR@1 zgY0uc=$uewqtB1PT0g^SC&-kRSP|hZ`PSE-3~KljTc56;CQrEqj@1U54x(N$Z`~&t zC&%nh=^u6KkJ#Ma#_!GmYi>J>f!a~^&aDmi*CnATDxPXdtEnlO_mt|)7B@FHEn5~jW0 zGPI+JSBS1)PJL`pqGrLI?h!72BSN*7? zQ+@+z7T}G_L!%et6jbkoEoQva>wiv7tg*3}rP$}tIw@^cwuq9=g z+KjqSyHWe*AznCOzuu;gk=U9Q8^DI6#p`0XylKmUU0#9i=~@%0;J4*VJ4O*O&O-um z4!yNa1sjBr#re>=CPZ>E)iH`0B4$9@OH8nf(cNu?^h~D-q2@HnG+-DoOvr{G#i0de zqOKkD*{6nf-F7#+%az+WOH9HMM9u-NrZSO2JTi2WIH4ESc(SHffk+Fh?}xn&dHeD` zgd7Z^S&%?~I=dj5fA6-0&`-Hox!#MYCdrX%f|DKfCe&~XIxNWIbCT^N(xCuvV_{OP zqdwA2!<&4MIf>*7-NG4kUww@HhRXUbFY^+P znT%m?r;UhdJ?;5aIo*0kQ^W9##O6W$PvLP4qD!8I6hLIG8R-`k(QT-dh|kehoy3;u zEuWX&_A$-A`wJ7*wX&bimLwAP_psO)*cGQPf=O3XfX6$iYQ%C1A?CrnIozpw!VeAlTGUNTbm8^Y5V455LBdk5;$7X0_1BDMLu2(@(cr zIskET_U>|ujRYPYYU1ot=+UMFk^$4^)684Ls>$8k^;BP#b1M^ZNv=GZOn#-4J{P8) z=jgU0sTBPRGtm8(+_Nid$&{WDQ7-!9~!q#OZ1YmvIyQ3~3 zO>^RvEyl}H+1S@i&bX?7;CLGyM+!f$3Q0tWDPxvZG0t3L1-;2g_SxrP^GavD5SPK^ z0Muk~hHFwX+fTBRV03&YxhWUvQcvS@$f0!i{rmvc-G8s!F=&D`wG2De>n*BYQ=f7J@kHm*~Y%C+^a zEr#R<9k-}MUex(Lm&VFyn7Fle?Z#dojnmaI{)N`k`(&p(Tfz;cJ4gLcO9mN_JbM|9 zdtUv0(~7M*$Hn*&(FM~ zGbwv9>u3$72zk?aoNVxsdd84^5-LFF1HE0={d(#PVr#sXtii3G=%YQgeiAn1+BA~N z1E7{70^Qp4e4w;ujefx$D05O?>EOF7_OF&@<`MpE>>2b1p5@Ic;IRQ?zN;r^q(@%k zKhCRDqXSW?9#6MzmnKYe&etMHtar+&B*dkxkO3i?BJI{@)X1*sv!}h4N~G%*eQ4;8 zv2Lr>=@TZzD>zA2jiD!;9p-j*ild{l=$)#w0@oyi5_1Qq81m51wVcH=QN~kKQ5$Wf zhN>z~fZ@CuIw3Q)15DqvXWDy$-3>K^rN=oHU3(_F6AX7?V6j!OVU2mFkSRi)qWX}% zxaA?q;M5+z9zVxQ#>UXYerehsJ;|p&xJ1(jMLH_Xl~^f~jL+tCI{o~f3oB}y=zVoj z#JBe1jdD4KI|#N3!?c!*CO8);OntN<`qFWJQVRBac61G`IL4y|0F|u z@^Ke4c_aN{GV0IYWTFa*ljPK24=7LM6p~}yu{UdAEIb`umBi{!PN+G5#^{_`tF-0H zWI1OS$jywal1tfGZ}<8>5u(tIpxb2~97z_)aMF<~#1cF{`yuCyTCIg&2Rcd1pWrVE zrIukB-A%B+?uICTI**Q$f-x3#8G9&14|ekj*M8B|kJd=24ihIdmd<^v8khf(Q@NF3 z+JT5IWG(%LQ;sqMW*_a5-oqGUF*^t)fc>W|0k9=*H*2^2ap!^IcOJO)-YBgpphp_M z&V*Z}u6?7>d*)6I)Z0qCjfrO%OQK^TdB|%=sKPcJ2v4!Bm0$)6-!XpeWhf-%9ia)1 z0a{m*PUP%8BPZ{p$4Xb}8VeYH(VH7u?t*%2%=2FX`QXRID;#!r8z_>@&_tI)Qydc) zbzxl@^#^I6keSEW3D+|tVFI(vn%62}=0!2|^uoo+B1#|KV0|F)7TG%bfSHh~vKzn- zzKG-HT;%aS8oHk6+3P_>+q@g~5SUTFast1oaXPkW7K$jVM@Z1`#RaqJz$#aU*KQZD zOhx>Z4HJ^3z^se;RpHrBn~h9g0#ouVJzhL=rlU|8sa*%W2nP8=iNmgc{>}!73w#+tdd7|{ffe8SpxK5meU``ae7RbwI2gqpbq%1w4h58IoP%Q z4R}2_AF4oz(AEH}q5D%_t)%%f6P_lX>400z_@EEqvRCKhTzS5boxI`)jdkdC%&Qw_FH=C-CE&3N2! z4Q2itYAjAddn284rHq6Is`;oPUGaUto8K%VQcS4mGd_JFBxZ+92QNn7jm(h#U`E%B zfS<`x|HG#Wa!N%wO8Le5I!a?HcJQwOEu+bn)EsOBO)9UAD^9r@i5~6-f+Z6w&|h@^ zY()ZVP?W`YJ>2fy2L0ch+y*vQf2HL9kB1?BvMaQQ5D8*K1$s?knmbN7bp0r4)kKmoh*46D^UWz*U9vmfy z2)%E9maLqqI^3rX0Td`u1iK)}j${{Z887>jM9bU9V4EfnE$@0)_RYx({C%RE=&(Im%aa;%92651)&z}kLSNV0+> z@~IJ;kKl_$ZqjCPTnxnMgL<)zc3n`C?`zcPceE{iq%l+FKq=$+_+>g*5QXeTs5uB< zTueE=V^FafbQ!0rDGz7EkR)3dC#byAM7Ae;q>hAfSAq)PeV_HhTqmVeUShmDfc0iM z2P+a78lRc?7~C(cvMSfjk~CO+nXoUnvboDEJylNpeYxSqS3+$ViU~32Ja@tmNjyAd zD!G8lL0bCZG^zRUizkkbRIl_%tQ#F4a_&QsH^1+|*CG8KS+C%K@)Wi!Sw!$VPtCk< zf7L4Zr!Acv9Br)rYR&YqE|~Y$1e?%-ZfXd@7ZRV=?yU*>-Iklms#{IeLic!=5B0;l zUoWt~_J!taA4Kw35fa3@1d!~$!T!a8C)={I>a!({Utr1H(Uec$L_Uuc$%P(+=;b!g zRIwm9U^exBrEwh7Xw1|C6;c*0lNl=S#Vo$w-kG;xeN9Z8I6XUHY@I$WItBgn!Vxnt zKTRhoBw?kOD?A-eb+6;wqMDAj4XmbISVmRUA zsFcERgw{vgGHj|E|4(TKH4#7PRdh&A8t3Lhma5u_QpDQo`C{5OfGNIiG)8zY3MR0Q z`7P=nYDHDE?-gO-vmfzwV|D=~;C*d6HFWuptiM1MO4zqgp3{miIG0(*-|~%=gW;r+ z4%%-R-Q&GP`g?eG!$9=G+1t(hptvm(#i?!|>EUMn^o8aJ$@`pU5nFr7L=jp{SEqLA zYxgVgPW*FlN!n~SR>@k_pw2_AsWjblG7`*N*k{-9EkR!3Fot@*ov*?s3Pq<;?zJzLxVj0kxto9=hkl3DU9bSrq5RQ>{!U@6WE z&A1oO9=N%j4}Z(6bYX>~iGS{~Lk$A{R?b8eW^@nW ziP+nuZfeWY$YH^x=!7VYcE(B=I|L_6NR(y9A)@;^7+;j!GlMF$+q6+B_pIpWX!xn0 z83Y58${7>BTcdo+^pCbHEf&* zF#KCMME<8s(|NL3a6_$Co9rSlDB76uo;%NnA7XRyC3l`6 z2uRyW5Oh7whS)&hpYgVJmzYlBAoBu&8@;w&WD~*ctoSn#z_(`d@bcLh)MYyURKHK|UQqSx!q;%{yD=SoEHKZ$R(B^bDV^XDLw=B;qYkDw z-{&2nVTM@V9FHM+WiwJ}NHG?#gd$XKS*9n z2QnG>=HqWi%@d5P(oz;HnQ7G)V#H`hqkizZJ>MTp zR_Nl$aAz4U_;#_3of)F*^Kza)HOFckZ$!}-zcUEB0H|ay*4xV0cX4qx$W>gP5f|co7O%nvE z3r3Ka+5Q}Bris{uenJy^;!68T6}D;f0md*$ek!Z96NXJ+YzjTx*X*Y$tvHFb;P=eL z($tHhAE-m$`W~&C@#SY0$)>tCP{F@>e~%nPn)9TjG%6YX3mNV|4;W!HvjU)&2(+g`bWsn`b2*@LN3V%i}2CV z5ha9Z*h3WsAEg(L}DgNt2_q{)#E*({lL zs6?#-VOy(Fq~a%*MS?p8*+rmM9yFtJiAGgUn<;7z(5IGfI2B1K+YyiwxxH3`Ez%(! z$f9p2;?Tugn8$NhIN&@6LS0%o6twDi^_hwea)KL~^Nw}V3$lojZR`lzH>F$f6>+)R z_k`tGOu81C{e{jt(6HOU)e{Do7o4D=hg@cedUZ8)Qb^f{Ap5BZiGpD;$;~g-IOZB< zw5`5xf5wEwap~I6dy3cE872U<&qv<9TsQX>u`F+*lT>?JB~~-OeqUO`5BJp~wYU{l zai5&kcC0&cKS_elouml*F5FOLbEI7r&?MvdzDC*z=6zEqQ#+X z(>5ecywjqnQ4(J4Y(!FbWRcJov6S#YbYpFu`yL-l;YJ@={ewV){!B#g`KnSuOI0u* zHaY*79j+nh8EN;J*^1Sv^6#IEICw%eZqnP*avG`Digk4%gRv1RUENn`u2Nd;ROHoc zimhwx{XY}qc3U5@Q6L|b62UfP=b}PM8tnBJn8?9~o}lItcL85d;R%!9B_Nt5ne!FR zt??Ik&sphnqU~(RrUq|{;p+27I^B6f@!1|58*gr-8IbI-18x1Bf^AbGjV~H(4=Y!E0UTieV$s z;@(!g`njxZOrybFP+eA{{1$*y6!+R}EnVePqvvE(UUZsz7evr{A(1Rv5Uvjx%HLaT zjr!WaW=!QYN0v9*(&I3Fvuj+Hi+4SZXtwopR>gX|n{g@ep(==+f!H@uCUDZTOZRRk zpu^}zeI%Dvyqv$+cKEw4=ZX2eb2C}Z=C#DE_$=+0H0Qh-=d{pS7uuTnDuR4`Xz1~V zv;alW0|O@BAM5N`I(UBB{n;knKT%=mclO~!rMmE)^oP4>256KsjHNiq*xWqoGLcwspqU$K`M7F zG4F2K53NlhNJ!9I)v~laztaDy?2sJ#;H+~L6y#S#QW?nP;}6y_stcta;tMtGz%xISsa4ayp&Lpw5i}T**+>f6m&TVJn`PR!%kq$ z%5%73f+C~|*s?V;&zhtOS6bODSq00dG$hBDtXC3fA=E$Stjyj*xC@k@<9nJ-X(*k; zOr4)I1OWbrZJz7;XQ(=4l!zKm$O zq^)Ju*P2-xhzN3aol#{8R}aU{xi9p9W2vc=U#J%wXG$e13W!>mLBSoCOx9fB6{Ojz z85n2XKQVLoRlw-pzjthKYeQbD#KWoA8UuAqTQO5GM4*dt(R_^Q&aET&)xE#xjR6ez z4dhQ|_^GY)nEtL=4Zm-w|JATujPw=$WmsuN4*z8j3g7v@Ayqeod=?TXXe??WR^%nD zH^BMEM24cyyPk#9wd(~DWKxL2y literal 0 HcmV?d00001 diff --git a/docs/beta-1/history/station/pre-naming-2026-11/USER-MANUAL.html b/docs/beta-1/history/station/pre-naming-2026-11/USER-MANUAL.html new file mode 100644 index 0000000..7fc10be --- /dev/null +++ b/docs/beta-1/history/station/pre-naming-2026-11/USER-MANUAL.html @@ -0,0 +1,1601 @@ +Townlight Station +Manual | Townlight Beta 1

townlightTownlight Beta 1
+
Townlight Beta 1

Townlight +Station +Manual

Staff guide and technical reference

Documentation edition 30 October 2026
Existing component versions retained
Signed suite installer 1.6.0.1
Private beta documentation companion

+

Townlight Beta 1 — Station delivery update, 31 October +2026. Signed +Windows installer, source, documentation and acceptance. This +edition documents the Sandbox-tested Station delivery additions. +Existing component versions are retained. Earlier baseline results +remain identified as historical evidence; the new acceptance report +identifies the new installer.

+
+

Using this manual

+

Townlight Station helps station operators, clerks, records staff and +deployment administrators. Station adapts a pinned CivicCast media +implementation into an independent Townlight boundary. It captures +managed files or configured live UDP MPEG-TS, retains canonical +meeting/agenda context, and hands verified recording evidence to +Records. Scheduling, playout, approval and local playback have distinct +controls.

+

Staff should begin with First run and Daily workflow. Administrators +should also read Architecture, Technical specifications, Configuration, +Security and Recovery. Developers should use the exact API/data +dictionary and examples. The table of contents and alphabetical subject +index link to the relevant sections in the HTML edition; the PDF +preserves headings and searchable text. An editable Word edition is +included with the same documentation companion.

+

Beta identity

+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IdentityValue
Public documentation identityTownlight Beta 1
Installer version1.6.0.1
Product componenttownlight-station 0.3.0
Native desktop source version1.6.0-1
Candidate artifact identityStation delivery update; use the release SHA256SUMS.txt
Corresponding sourceUpdated Station delivery candidate source companion
Current owned software licenseAGPL-3.0-only
Supported acceptance profileWindows x64 fresh install; inspections-preview; separate Station +configuration
+

“Townlight Beta 1” identifies this coordinated beta delivery. It does +not renumber the installer, native binary, Python packages or historical +receipts. Component versions may differ. This edition accompanies the +newly packaged and signed MSI containing the Station delivery additions. +The native desktop and other native payload files retain their accepted +signed bytes. Historical release pages and manuals describe their own +versions and are not the download instructions for this Station delivery +candidate.

+

First run

+
    +
  1. Download the signed Windows installer and matching +source/documentation companions from the Station +delivery release. Use that release’s checksums and publisher +signature to identify the candidate.
  2. +
  3. On the intended fresh Windows test installation, verify the MSI hash +and publisher signature before installing. Preserve unrelated profiles +and recovery material. This candidate has fresh-install acceptance; +historical in-place upgrades are unverified.
  4. +
  5. Launch Townlight under the intended named Windows account. Choose +the storage folders. Select Townlight Inspections +candidate (inspections-preview) for all eight +desktop products. A narrower default selection will not expose all +workspaces.
  6. +
  7. Enter the city profile, time zone and contacts. Create the first +named local administrator, sign in and choose protected backup storage. +Continue without local AI is valid for the +deterministic workflows.
  8. +
  9. Run Health Check and wait for readiness. Open Townlight. In System +Health select Finish Records Migration to activate the +canonical Python/PostgreSQL runtime. Do not fabricate migration receipts +or seed accounts.
  10. +
  11. Create named staff through Settings. Import authorized sources using +each product’s source library. All examples in this package are +synthetic; they are not municipal authority.
  12. +
  13. Provision Station separately if it is part of the beta exercise. +Selecting the desktop composition does not start or configure Station. +Configure vision explicitly only if automatic photo drafting is +selected.
  14. +
+

Daily workflow

+

1. Prepare meeting context

+

Create and save the actual meeting and agenda in Meetings. Assign +each selected agenda item to that meeting. A recording request cannot +substitute an editable meeting label for the canonical records.

+

2. Open the operator

+

Sign in as authorized staff. Use the configured local operator +command with the explicit native profile root. It obtains a short-lived +one-use browser ticket; the native proof is not placed in the URL.

+

3. Choose the input

+

Select the meeting, assigned agenda and administrator-configured +live-source ID. For recorded-file work, place the source in the managed +ingest directory and optionally supply an SRT sidecar. Callers cannot +submit arbitrary pipelines or filesystem paths.

+

4. Capture and stop

+

Start capture and distinguish waiting for a signal from active +recording. Stop requests pipeline drain. Wait for completed status and +validated output; a partial, failed or interrupted attempt is not a +completed recording.

+

5. Review recording evidence

+

Inspect the media and retained context/hash. Retry is explicit for +failed/interrupted recorded-file jobs. A lost live signal cannot be +reconstructed: begin a new live recording and preserve the failed +attempt.

+

6. Hand off to Records

+

Choose an existing Records request and attach the reviewed recording. +The receiver checks bytes/hash and retains a locked private original. +Repeating the same handoff retains one canonical document.

+

7. Use playout deliberately

+

Scheduling, dry-run/commit playout, staff approval and local +publication are distinct API operations. Public playback only serves the +separately approved packaged output. Nothing in capture or Records +handoff automatically publishes it.

+

8. Close and recover

+

Sign out of the operator. Back up Station’s database and media +evidence together, separately from Core’s native profile backup. Restart +interrupted work deliberately; do not automatically re-air a lost +signal.

+

Working safely

+

Use your own named account and save before leaving a screen. A saved +draft is durable; unsaved form text may not be. If a write has an +unknown result, reopen its record before repeating it.

+

Read source jurisdiction, dates, citation, version and visibility. A +copied source hash identifies exact bytes, not their legal +applicability. If a source changes or permission is removed, resolve the +source problem rather than substituting stale cached content.

+

Keep originals and derivatives separate. Review the intended audience +before export. A public summary excludes private fields only through the +applicable copy contract and your review. A renamed private packet is +still private content.

+

Drafting, review, approval, attachment, export, fulfillment and +publication are separate operations. A Townlight workpaper does not +itself adopt law, issue a permit, impose a fine or release a records +response. The responsible staff member records the applicable +decision.

+

Connected workflows

+

Meetings → Station → Records is the accepted recording workflow. +Townlight owns current session authority; Station owns its database, +storage and media children. Standalone CivicCast remains separate, with +no shared configuration, service, data directory or automatic updater +fallback.

+ ++++ + + + + + + + + + + + + + + + + +
DirectionMaterial
InputA real Townlight staff session, saved Meetings records, a dedicated +Station database/data root, a managed ingest filename or configured +live-source ID, and optional supplied SRT captions for recorded-file +input.
OutputCompleted verified recording derivatives, retained original +inputs/provenance, separately approved local playback packages and +locked private Records evidence.
+

Product boundary

+

There is no Station first-run wizard or automatic activation by the +desktop composition. The accepted normal-profile path uses an explicitly +configured paired Townlight HTTP process. Physical encoder/network, +remote identity, SCM commissioning, CDN delivery and long-duration field +quality are not certified. Station does not perform automatic meeting +speech recognition.

+

Architecture

+

Townlight Station architecture and evidence flow

+

The drawing shows the principal staff/evidence path. Native commands +carry trusted identity to Python business services; PostgreSQL and +retained original files hold durable state. A downstream copy does not +silently transfer decision authority. Station has its own configured +authority/media boundary, database and mutable files. The +connected-workflow text supplies the drawing’s reading order and +accessibility alternative.

+

Scheduling playout and +recovery

+

Schedule a +recording and interpret its state

+

Use Schedules after saving the actual meeting/agenda +and placing a complete file in Station’s managed ingest +directory. Choose the meeting, Start time, +Source file in managed ingest, and optional SRT +Caption sidecar, then select Schedule. +The browser form schedules files. The service’s schedule API also +supports a configured live-source ID; this is not a second input +selector in that browser form.

+

The browser’s datetime input is interpreted in the operator +computer’s local timezone and converted to an ISO UTC instant. Verify +that computer’s timezone before entering a city meeting time. A direct +API client should send an explicit timezone offset or Z; a +timezone-less API datetime is interpreted as UTC. A synthetic +POST /v1/schedules body is:

+
{"meeting_id":"11111111-1111-4111-8111-111111111111","agenda_ids":[],"source_file":"synthetic-program.mp4","captions_file":"synthetic-captions.srt","start_at":"2026-11-05T18:00:00-07:00","idempotency_key":"synthetic-schedule-001"}
+

Use a real synthetic meeting ID and intended future exercise time, +with files already in managed ingest. The body selects exactly one file +or configured live source; a live source cannot use a sidecar. Reusing +an idempotency key with changed input/context is a conflict. The initial +response includes id, status: scheduled and +start_at; it does not mean recording has finished.

+

Refresh Schedules and inspect the returned identity/time. +Cancel schedule is available while it remains +scheduled; cancellation of an already dispatched or terminal entry is +refused. The worker claims due work once and creates the linked +recording. A start delayed by more than ten minutes is +missed, not replayed late. A start within that grace can +dispatch on the next worker pass. Inspect the linked recording for its +own queued/running/completed or failed state. Do not assume scheduling +also commits that recording to air.

+

Apply the caption profile

+

For a managed recorded file, an explicitly supplied SRT sidecar +replaces embedded captions for this profile; otherwise embedded captions +are retained where supported by the pinned media profile. Live capture +preserves the embedded-caption path and does not accept an SRT sidecar. +An absent caption stream is not automatic speech recognition. Check the +actual captured/packaged captions for the selected synthetic input.

+

Original files are limited to 2,147,483,647 bytes and sidecars to +5,000,000 bytes. After publication, browser playback uses the packaged +MP4 and a separate WebVTT track when produced. Preserve original inputs +and recorded caption provenance separately from those derivatives.

+

Check playout and commit +deliberately

+

Open a completed recording. Select Check +playout to queue mode: dry-run. Inspect its status +and retained errors; a successful check does not change on-air state. To +render and take that program to the scheduled on-air path, explicitly +select Commit to air, which uses +mode: commit. Wait for the playout to be +complete; failed rendering is not a successful switch.

+

Equivalent POST /v1/playouts input is:

+
{"recording_id":"22222222-2222-4222-8222-222222222222","mode":"dry-run","idempotency_key":"synthetic-playout-check-001"}
+

Replace the recording ID with completed synthetic evidence. A +separate deliberate commit uses mode: commit and a new key; +do not reuse the check’s key with a changed mode. Inspect the returned +playout id and read /v1/playouts/{id} until +terminal. The scheduled on-air program follows verified committed +output, not every dry-run or every recording. Keep the worker and air +roles distinct: one renders work, the other follows durable on-air state +and emits the local program.

+

Take a live override and +return

+

In On air, choose an administrator-configured live +input and enter a reason of at least three characters. Select +Take live override and inspect the on-air mode/source. +POST /v1/on-air/live uses live_source_id and +reason; callers cannot supply an arbitrary network +pipeline.

+

While live, select Return to schedule +(POST /v1/on-air/return-to-schedule with no payload). +Confirm the mode returns to scheduled program. The override supersedes +the scheduled output; it does not delete its committed material. If no +valid committed program is available, do not assume returning has +produced a usable broadcast. Read actual output/state and any error. +These are local synthetic on-air controls, not proof of a commissioned +cable headend, physical receiver or public CDN.

+

Approve and publish local +playback

+

In Playout and playback, wait for a completed +rendered playout. Review its actual media/context/captions, then enter +the approval note and approve it. The API accepts a note of 3–500 +characters at /v1/playouts/{id}/approve. Approval is +retained with the authenticated staff actor; it does not itself +publish.

+

Select Publish locally only for that reviewed +approved playout. /v1/playouts/{id}/publish packages local +MP4/WebVTT playback. The response and subsequent playout view retain the +publication details. Open the displayed local playback, verify it +advances with the expected picture/sound, and inspect the caption track +where supplied. Unpublished content is unavailable through the public +playback route; guessing its ID does not authorize access. Repeating a +completed publication returns the retained package rather than silently +publishing changed media.

+

The local playback route /v1/public/playback/{id} serves +the packaged program; /captions serves its available +WebVTT. This approval/publication is separate from Commit to +air, capture, attachment to Records and a Records release. +Internet commissioning remains outside this local procedure.

+

Recover without +replaying unknown work

+

After a worker/API/air interruption, inspect durable schedules, +recordings, attempts, playouts and on-air state before repeating any +write. The worker marks interrupted in-flight work accordingly. Eligible +failed/interrupted file recording retries are explicit; +live loss requires a new live capture. Retain the prior attempt/logs and +do not claim a missing live interval was reconstructed.

+

Future scheduled intent survives restart. A claimed/dispatched +schedule must not be duplicated; one beyond the ten-minute grace becomes +missed. Read its linked recording and create new future intent only when +deliberately required. On-air recovery preserves attribution and does +not automatically resume a stale live override as if the source had +remained valid. Check the actual on-air mode and available committed +program after restart before choosing a new override.

+

Visible failed/interrupted states and error text in the operator are +the existing alert mechanism for this beta. Preserve the private process +logs and attempt evidence. Reopen a normal operator ticket after API +restart; do not replay an old ticket or bypass current staff authority. +Restore Station’s database and its matching media as one recovery set, +separately from Core’s native backup. Recheck original/output hashes and +intended state after restoration. No automatic repair or database reset +is implied by restart.

+

Source contracts: townlight_station/operations.py, +worker.py, airplay.py, +operator.py, the pinned media profile and +station/operator-ui/src/operator.tsx. Service request +models are in the Station API companion. The three suite-side Station +paths in its OpenAPI download are not the full separate /v1 +service schema.

+

Technical specifications

+

Runtime and storage

+

The accepted package targets Windows x64 fresh +installation. Its native shell uses Rust 2021, Tauri 2 +and Microsoft WebView2; browser assets are JavaScript built +with Vite 8.1.6. This describes the native desktop +frontend; Station has a separate React operator, specified below or in +its product manual. Canonical business workflows use bundled +CPython 3.13.5, FastAPI, Pydantic, SQLAlchemy and +Alembic, with PostgreSQL 17 / PostGIS and +managed original files. The installed runtime tested here contains +FastAPI 0.162.0. Package minimum Python requirements can differ from the +bundled executable; the metadata reference preserves both. No stack +rewrite is implied by the beta label.

+

The native transport is fixed to loopback +127.0.0.1:15480; PostgreSQL uses the configured local +runtime port (default 15432). Optional local model service +defaults to 127.0.0.1:15434. Those are deployment defaults, +not internet endpoints. The runtime has health, module and readiness +endpoints; readiness is stronger than process existence. The task queue +is the existing local Core task infrastructure, not an assertion that a +separate Redis service is required for this desktop composition.

+

The default native profile is %LOCALAPPDATA%\CivicSuite; +the historical directory name remains part of compatibility. Do not +rename it to Townlight. A configured TOWNLIGHT_PROFILE_ROOT +must be absolute. Local configuration and secrets live under that +profile; protected managed files and database state must be backed up +coherently. Source/runtime identity is distinct from a product’s display +label.

+

Data and consistency

+

Configured live-source IDs; canonical meeting/agenda snapshots; +queued recordings and immutable attempts; input/output hashes; +schedules; playout jobs and approvals; durable on-air state; publication +packages; Records attachment provenance.

+

Versioned saves use expected prior revision identifiers where +defined. Reopen and reconcile on conflict. Exact exports and handoffs +use source IDs, current visibility, revision and SHA256. Review belongs +to the saved revision and does not transfer silently to edited text. +Database changes use the owning product’s migrations; a request or +readiness check is not an authorization to mutate schema.

+

Capacity and platform +statements

+

This beta has synthetic single-profile workflow evidence. It does not +have a published benchmark for concurrent staff capacity, minimum +RAM/CPU, large-source limits or a field SLA. Do not turn a developer +machine’s specification into a supported minimum. Installer size is +2,092,122,112 bytes before installation; allow additional disk for +extracted runtime, database, originals, exports, media and backups. +Select equipment/storage after sizing those actual workloads.

+

The exact runtime +payload lock records pinned files, sizes and hashes. The component metadata +records shipped dependency declarations. These references are more +precise than a manually copied dependency list. Third-party and +historical license notices must accompany their matching payloads.

+

Station operator and +media components

+

The native desktop frontend above is distinct from Station’s browser +operator. The pinned operator package +townlight-station-operator is version +0.1.0, using React/react-dom 19.1.1, +TypeScript 5.9.2, Vite 7.3.7 and the +React Vite plugin 5.0.2. Station serves its built assets through its own +operator API. Its Python control/API package remains +townlight-station 0.3.0, while its retained storage +identity remains 0.1.0. These identities have different +purposes and are not renumbered.

+

The separate pinned CivicCast-derived media engine uses Python/native +GStreamer processing and bounded media children. It is not the +standalone CivicCast application. Station’s control database, data root, +service/configuration and update identity remain independent. This +describes the current mixed stack; no runtime rewrite or CivicCast +migration is implied.

+

Station media and +lifecycle contract

+

The package/API version is 0.3.0. Its retained storage +identity has version 0.1.0; that is a separate storage +marker and must not be rewritten to match the package. Product/app IDs +are townlight-station and +org.townlight.station; service identity is +TownlightStation, virtual account +NT SERVICE\TownlightStation, credential namespace +townlight.station, database schema station, +and update-channel identity townlight-station. An identity +name or SCM entry point does not establish that a Windows service was +registered.

+

The control service is Python; its separate pinned CivicCast-derived +engine uses native GStreamer media processing. There is no launch of the +standalone CivicCast application. Default encoding is 1920×1080, 30 fps +and 6000 kbps; explicit validated configuration may change it. The +source lock is verified before use. Media children are isolated and +bounded; unfinished attempts become interrupted on recovery.

+

Recorded-file requests accept a managed ingest filename, optional SRT +sidecar and idempotency key. Live requests accept a configured source +ID, not a path. Select exactly one file or live source; live capture +cannot also supply a sidecar. Inputs are bounded by the configured +two-hour default timeout and a 2,147,483,647-byte file limit. Supplied +SRT sidecars are bounded to 5,000,000 bytes. The queue admits at most +100 pending/running jobs; live admission is further serialized. A +repeated idempotency key must identify the same source bytes, canonical +meeting context and encoding profile.

+

queued and running do not make content +available as completed. Completion requires the worker’s clean media +teardown and stream validation. Failed/interrupted file jobs may be +explicitly retried; a live gap requires a new capture. Records receives +verified bytes and canonical provenance as a locked private original. +Local publication is an explicit later operation on separately approved +playout; its MP4/WebVTT package is distinct from the retained recording +and from a Records release.

+

Configuration and +administration

+

Prepare the +normally activated synthetic profile

+

This procedure describes a future isolated beta installation. +Documentation generation does not execute it. Complete normal Townlight +Setup under the intended Windows account, select +inspections-preview, sign in, and use Finish +Records Migration. Keep the native database running and confirm +the canonical runtime is ready. Use that account’s actual profile path; +the default is %LOCALAPPDATA%\CivicSuite. Do not create +session files, seed accounts or force +domain_enabled=True.

+

Station needs its own database and initially empty absolute data +directory. It uses the same named Townlight staff authority through an +additional configured loopback suite process. It does not launch or +modify CivicCast. No SCM installation, registry edit or replacement of +the desktop’s fixed-origin service is needed.

+

The examples reserve suite port 15481, Station port +8756 and synthetic UDP input port +19000. Choose unused ports and change both configured +origins together if needed. Never point these instructions at a city’s +live profile or data. Use the actual installation directory if Townlight +was installed elsewhere.

+

Store the independent +test configuration

+

Run the following in a deployment PowerShell session under the same +Windows user. Keep this session for startup and shutdown. The dedicated +parent holds configuration/logs; its data child is +Station’s initially empty managed store.

+
$profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite'
+$control = Join-Path $profilePath 'runtime\python\python.exe'
+$payload = 'C:\Program Files\Townlight\_up_\runtime\payload\station'
+$stationRoot = Join-Path $env:LOCALAPPDATA 'TownlightStation-Synthetic'
+if (-not (Test-Path -LiteralPath $control)) { throw 'Complete normal Townlight setup first.' }
+if (Test-Path -LiteralPath $stationRoot) { throw 'Existing Station directory: inspect it; do not overwrite.' }
+New-Item -ItemType Directory -Path $stationRoot | Out-Null
+$account = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
+& icacls.exe $stationRoot /inheritance:r /grant:r "${account}:(OI)(CI)F" '*S-1-5-18:(OI)(CI)F' | Out-Null
+if ($LASTEXITCODE -ne 0) { throw 'Cannot protect Station configuration directory.' }
+New-Item -ItemType Directory -Path (Join-Path $stationRoot 'data'),(Join-Path $stationRoot 'logs') | Out-Null
+$rng = [System.Security.Cryptography.RandomNumberGenerator]::Create()
+$randomBytes = New-Object byte[] 32
+$rng.GetBytes($randomBytes)
+$rng.Dispose()
+$stationPassword = -join ($randomBytes | ForEach-Object { $_.ToString('x2') })
+$stationPassword | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString |
+  Set-Content -LiteralPath (Join-Path $stationRoot 'station-password.dpapi')
+Remove-Variable stationPassword,randomBytes
+

The password file uses the current Windows user’s DPAPI protection. +It is not portable to a different user or machine without an explicit +credential/recovery decision. Keep it out of source control, support +bundles and public documentation. Reuse this protected configuration on +restart rather than creating another database or password.

+

In the same session, establish the exact process environment. On a +later restart, set $profilePath, $control, +$payload and $stationRoot to these same +existing locations, then repeat this environment/start section, +not the first-time provisioning section.

+
$secret = Get-Content -LiteralPath (Join-Path $stationRoot 'station-password.dpapi') -Raw |
+  ConvertTo-SecureString
+$stationPassword = [System.Net.NetworkCredential]::new('', $secret).Password
+$nativePassword = (Get-Content -LiteralPath (Join-Path $profilePath 'config\secrets\postgres-password.txt') -Raw).Trim()
+$encodedNative = [uri]::EscapeDataString($nativePassword)
+$env:TOWNLIGHT_PROFILE_ROOT = $profilePath
+$env:CIVICSUITE_DATA_DIR = Join-Path $profilePath 'Data'
+$env:CIVICSUITE_FILE_STORAGE_DIR = Join-Path $profilePath 'Data\files'
+$env:DATABASE_URL = "postgresql+asyncpg://civicsuite:${encodedNative}@127.0.0.1:15432/civicsuite"
+$env:TOWNLIGHT_PRODUCT_PROFILE = 'inspections-preview'
+$env:PORTAL_MODE = 'private'
+$env:CIVICSUITE_RUNTIME_HOST = '127.0.0.1'
+$env:CIVICSUITE_RUNTIME_PORT = '15481'
+$env:TOWNLIGHT_STATION_URL = 'http://127.0.0.1:8756'
+$env:TOWNLIGHT_STATION_SUITE_URL = 'http://127.0.0.1:15481'
+$env:TOWNLIGHT_STATION_DATA_ROOT = Join-Path $stationRoot 'data'
+$env:TOWNLIGHT_STATION_DATABASE_URL = "postgresql+psycopg2://townlight_beta_station_app:${stationPassword}@127.0.0.1:15432/townlight_beta_station"
+$env:TOWNLIGHT_STATION_MEDIA_SOURCE = Join-Path $payload 'media-source'
+$env:TOWNLIGHT_STATION_MEDIA_PYTHON = Join-Path $payload 'runtime\python.exe'
+$env:TOWNLIGHT_STATION_MEDIA_RUNTIME = Join-Path $payload 'runtime'
+$env:TOWNLIGHT_STATION_FFPROBE = Join-Path $payload 'bin\ffprobe.exe'
+$env:PYTHONNOUSERSITE = '1'
+$env:PYTHONDONTWRITEBYTECODE = '1'
+Remove-Item Env:PYTHONPATH -ErrorAction SilentlyContinue
+Remove-Variable nativePassword,encodedNative,stationPassword,secret
+

Use the actual native PostgreSQL port/database/user if the deployment +differs from the accepted defaults. Environment changes here apply to +children of this shell, not the already running native supervisor. Keep +secrets out of command arguments and output. The paired runtime +deliberately uses normal verify_activation through its +standard module entry point.

+

Provision the Station +database once

+

This first-time step creates only the dedicated synthetic +role/database. Its role owns that database and its Station schema, with +no superuser/global administration grant. It connects to the normally +provisioned local database using the current profile’s protected +credential. Existing role/database names cause a refusal before +creation; do not drop or repurpose them automatically.

+
@'
+import os
+from pathlib import Path
+import psycopg2
+from psycopg2 import sql
+from sqlalchemy.engine import make_url
+
+url = make_url(os.environ['TOWNLIGHT_STATION_DATABASE_URL'])
+profile = Path(os.environ['TOWNLIGHT_PROFILE_ROOT'])
+password = (profile/'config/secrets/postgres-password.txt').read_text().strip()
+conn = psycopg2.connect(host='127.0.0.1', port=15432, user='civicsuite',
+                        password=password, dbname='postgres')
+conn.autocommit = True
+try:
+    with conn.cursor() as cur:
+        cur.execute('SELECT 1 FROM pg_roles WHERE rolname=%s', (url.username,))
+        role_exists = cur.fetchone() is not None
+        cur.execute('SELECT 1 FROM pg_database WHERE datname=%s', (url.database,))
+        if role_exists or cur.fetchone() is not None:
+            raise RuntimeError('Dedicated role/database already exists; inspect before continuing')
+        cur.execute(sql.SQL('CREATE ROLE {} LOGIN PASSWORD %s').format(
+            sql.Identifier(url.username)), (url.password,))
+        cur.execute(sql.SQL('CREATE DATABASE {} OWNER {}').format(
+            sql.Identifier(url.database), sql.Identifier(url.username)))
+finally:
+    conn.close()
+'@ | & $control -B -
+if ($LASTEXITCODE -ne 0) { throw 'Station database provisioning did not complete; inspect before retrying.' }
+& $control -B -m townlight_station.cli migrate
+if ($LASTEXITCODE -ne 0) { throw 'Station migration failed; retain logs and inspect the dedicated schema.' }
+

If database creation fails after the role was created, the operation +is partially complete: inspect that exact owned role/database before +resuming. Do not rerun against guessed names or remove unrelated +objects. On normal restarts, the database already exists; skip creation +and use the existing identity. migrate is explicit; API +requests do not substitute for schema migration.

+

Start and check the paired +processes

+

Use the same configured session. The standard suite entry point +verifies the existing native activation. Check readiness of that exact +paired origin, not only the desktop’s canonical port. Startup below +creates hidden children with private log files and records their +identities; it does not focus windows or install services.

+
$owned = @()
+function Start-StationRole([string]$name, [string[]]$arguments) {
+  $p = Start-Process -FilePath $control -ArgumentList $arguments -WindowStyle Hidden -PassThru `
+    -RedirectStandardOutput (Join-Path $stationRoot "logs\$name.out.log") `
+    -RedirectStandardError (Join-Path $stationRoot "logs\$name.err.log")
+  $script:owned += [pscustomobject]@{ Name=$name; Id=$p.Id; StartTime=$p.StartTime; Path=$p.Path }
+  $script:owned | ConvertTo-Json | Set-Content -LiteralPath (Join-Path $stationRoot 'owned-processes.json')
+  return $p
+}
+function Wait-StationReady([string]$url, $process) {
+  for ($attempt=0; $attempt -lt 40; $attempt++) {
+    if ($process.HasExited) { throw "Owned process exited; inspect logs for $url" }
+    try {
+      $response = Invoke-WebRequest -Uri $url -UseBasicParsing -TimeoutSec 2
+      if ($response.StatusCode -eq 200) { return }
+    } catch { }
+    Start-Sleep -Milliseconds 250
+  }
+  throw "Readiness not established: $url; inspect the owned logs"
+}
+$suite = Start-StationRole 'paired-suite' @('-B','-m','civicsuite_runtime.services')
+Wait-StationReady 'http://127.0.0.1:15481/ready' $suite
+$api = Start-StationRole 'station-api' @('-B','-m','townlight_station.cli','serve','--port','8756')
+Wait-StationReady 'http://127.0.0.1:8756/health' $api
+$worker = Start-StationRole 'station-worker' @('-B','-m','townlight_station.cli','worker')
+# Only for the on-air profile:
+$air = Start-StationRole 'station-air' @('-B','-m','townlight_station.cli','air')
+$owned | ConvertTo-Json | Set-Content -LiteralPath (Join-Path $stationRoot 'owned-processes.json')
+

Before launching, confirm ports 15481 and 8756 are unused. If +readiness fails, inspect the relevant logs and retained profile/schema +state; do not start another copy. A port that answers belongs to the +intended process only when its ownership is established. A single worker +owns a database. worker --once performs a bounded pass; it +is not the normal continuous worker. The air role follows +durable on-air state and emits the local program; it does not commission +a physical transmitter or CDN. Its currently configured local output is +under Station’s air directory. Back up the dedicated +database and media together; Core’s native backup does not cover +them.

+

Configure a live +input and open the operator

+

Create live-sources.json under the Station +data directory with the following fictional input. An +actual sender must supply UDP MPEG-TS to that receiver; this +configuration alone does not generate a signal.

+
[{"id":"synthetic-chamber","label":"Synthetic chamber feed","kind":"udp-mpegts","address":"127.0.0.1","port":19000}]
+

At most 32 rows are accepted. IDs are unique 1–64 +letters/digits/underscore/hyphen; labels have 1–100 characters; IPv4 and +ports 1024–65535 are validated. Each row has exactly the five shown +keys. Protect the source network; UDP is not authenticated. Then, under +the same signed-in native account:

+
& $control -B -m townlight_station.cli operator --profile-root $profilePath --port 8756
+

This normal operator command opens the operator for a future staff +exercise. It reads the native session and exchanges a one-use launch +ticket; it does not seed authority or put the native proof in a URL. +Ticket expiry is 60 seconds, operator cookie lifetime 900 seconds, with +at most 256 outstanding tickets/sessions each. Reopen normally after +expiration, API restart or sign-out. Changing database/configuration +identities does not repair a staff permission refusal.

+

Bounds and shutdown

+

Default encoding is 1920×1080, 30 fps, 6000 kbps. Optional Station +variables permit MAX_SECONDS 10–86400 (default 7200), even +WIDTH 320–3840 and HEIGHT 180–2160, +FPS 1–60 and BITRATE_KBPS 128–50000; each is +prefixed TOWNLIGHT_STATION_. The media source lock and +exclusive data identity are verified before use. The dedicated database +name must end in _station; unowned nonempty storage and +escaping/reparse paths are refused. The existing SCM entry point is not +a claim of installed service acceptance.

+

To finish an exercise, stop live capture from the operator and wait +for its completed or failed terminal state. Wait for any +recording/playout work to finish, cancel unwanted future schedules, sign +out and preserve the evidence/logs. The air role starts a separate media +child; force-stopping only its parent does not run Python cleanup. Stop +only the process trees you started, checking each root’s identity before +using a saved PID:

+
foreach ($entry in @($owned | Sort-Object StartTime -Descending)) {
+  $process = Get-Process -Id $entry.Id -ErrorAction SilentlyContinue
+  if ($process -and $process.StartTime -eq $entry.StartTime -and $process.Path -eq $entry.Path) {
+    & taskkill.exe /PID $process.Id /T /F | Out-Null
+    if ($LASTEXITCODE -ne 0) { throw 'Owned process tree did not stop; inspect before proceeding.' }
+    $process.WaitForExit()
+  }
+}
+

Retain the ownership file if the shell must close; parse and verify +its actual process paths/start times before acting. Do not terminate the +native database/supervisor or CivicCast. Interrupting a worker during a +job preserves an interrupted attempt, not completed media; recovery is +described in the Station operating procedure. Clear secret-bearing +environment values when closing the dedicated deployment shell. Do not +delete the database/data root to “reset” an uncertain result.

+

API and integration examples

+

Native command example

+

The following JavaScript belongs in the existing trusted Townlight +frontend/development environment with invoke imported from +@tauri-apps/api/core. It is not a command for an arbitrary +web page or an instruction for nontechnical staff. IDs must come from +records created in an isolated synthetic exercise.

+
import { invoke } from '@tauri-apps/api/core';
+const result = await invoke('meetings_domain_request', {request: {operation: 'get-meeting', id: meetingId}});
+console.log(result);
+

Trusted local HTTP example

+

An administrator/developer can inspect an already-configured isolated +runtime from a trusted local process. This PowerShell example reads the +signed-in synthetic profile’s existing proof into memory; it does not +create a user, seed a session, reveal the proof in output or bypass a +permission check. Do not use real city data in development examples. A +read response does not prove approval or publication.

+
Invoke-RestMethod -Uri 'http://127.0.0.1:8756/health'
+# Authenticated recording operations additionally require current native proof.
+

A synthetic write +with subsequent readback

+

This example demonstrates the existing Meetings HTTP contract in an +isolated exercise. It is intentionally fictional. It does not start a +service. Its authentication setup is included so it can be run +independently under the signed-in synthetic account. If a write times +out, inspect current records before repeating it.

+
$profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite'
+$sessionPath = Join-Path $profilePath 'config/local-session.json'
+$session = Get-Content -LiteralPath $sessionPath -Raw | ConvertFrom-Json
+$headers = @{ 'X-Townlight-Session' = $session.session_hash }
+$body = @{
+  title = 'Synthetic documentation exercise'
+  scheduled_start = '2026-11-05T18:00:00-07:00'
+  location = 'Synthetic room'
+  meeting_type = 'regular'
+} | ConvertTo-Json
+$meeting = Invoke-RestMethod -Method Post `
+  -Uri 'http://127.0.0.1:15480/desktop/v1/meetings/meetings' `
+  -Headers $headers -ContentType 'application/json' -Body $body
+Invoke-RestMethod `
+  -Uri ('http://127.0.0.1:15480/desktop/v1/meetings/meetings/' + $meeting.id) `
+  -Headers $headers
+Remove-Variable session, headers
+

This write requires Meetings to be enabled and the signed-in staff +role to permit it. It is a cross-suite integration example; for this +product’s request models, use the complete technical reference +below.

+

Recording and Records +handoff example

+

An authenticated local client sends +POST http://127.0.0.1:8756/v1/recordings with +X-Townlight-Session and this JSON, replacing the synthetic +UUIDs with saved synthetic meeting/agenda IDs. Configure +synthetic-chamber first.

+
{
+  "meeting_id": "11111111-1111-4111-8111-111111111111",
+  "agenda_ids": ["22222222-2222-4222-8222-222222222222"],
+  "live_source_id": "synthetic-chamber",
+  "idempotency_key": "synthetic-docs-capture-001"
+}
+

The initial response is 202 with a queued/running +identity rather than completed media. Read +/v1/recordings/{identity}, explicitly stop live capture +through /v1/recordings/{identity}/stop, and wait for +completed status before reading /content. Then the +authorized Records client calls +POST /desktop/v1/requests/{request_id}/station-recordings +on the paired Suite runtime with:

+
{
+  "recording_id": "33333333-3333-4333-8333-333333333333",
+  "expected_sha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+}
+

The shown hash is deliberately a placeholder. Use the actual +completed recording’s hash. A mismatched hash must fail. Repeating the +identical completed handoff is idempotent; it does not create a release +copy or fulfill a request.

+

Complete technical contract

+

Read the Station API reference for +every documented operation, request field, constraint, response +declaration and source supplement. Download the OpenAPI JSON for tools. For +Station this is the suite-side schema only; its separate service +contract is documented in the API supplement. The reference directory includes +configuration/source inventories, dependency declarations, native +command contracts, MCP signatures and candidate evidence.

+

MCP and automation boundary

+

No direct product MCP server is exposed by the accepted Townlight +desktop or Station boundary. Do not configure an invented +townlight mcp command or assume an AI client has staff +permissions. The integration surfaces for this beta are native IPC, the +documented HTTP APIs, source bundle imports, exact exports and the +existing Station CLI.

+

The bundled transcription code includes a TextFlowKit MCP +adapter as a separate source capability. It offers job-based +transcribe_media, get_transcript, +list_jobs, get_job_status and +export_transcript, and additional tools declared in that +adapter. It uses stdio first and optional Streamable HTTP, with the MCP +SDK as an optional extra. It is not automatically launched, +authenticated as Townlight staff or accepted as a Townlight product MCP +deployment. This documentation does not add such a service.

+

For a transcription client already provisioned separately, an +illustrative tool call is:

+
{"name":"get_job_status","arguments":{"job_id":"synthetic-existing-job-id"}}
+

Use a job ID returned by that transcription service. This example +does not create a Townlight record or bypass its review/Records handoff. +The exact optional adapter tool signatures are supplied in the MCP source reference. Station meeting +capture does not become live speech recognition because this optional +donor adapter exists.

+

Security and permissions

+

Use your own named account and save before leaving a screen. A saved +draft is durable; unsaved form text may not be. If a write has an +unknown result, reopen its record before repeating it.

+

Read source jurisdiction, dates, citation, version and visibility. A +copied source hash identifies exact bytes, not their legal +applicability. If a source changes or permission is removed, resolve the +source problem rather than substituting stale cached content.

+

Keep originals and derivatives separate. Review the intended audience +before export. A public summary excludes private fields only through the +applicable copy contract and your review. A renamed private packet is +still private content.

+

Drafting, review, approval, attachment, export, fulfillment and +publication are separate operations. A Townlight workpaper does not +itself adopt law, issue a permit, impose a fine or release a records +response. The responsible staff member records the applicable +decision.

+

The native session is validated and mapped to a persisted SQL +identity. An editable actor/reviewer label is not authentication. +Product/module permissions and source visibility apply at the server +boundary. Revoked/unavailable authority fails closed for new Station +operations; a previous permission result is not a perpetual +authorization.

+

Use protected local folders, account permissions and credential +storage. Never include the native session file, database passwords, +provider keys or unredacted support bundles in a public issue or +generated public documentation. A local public view is not automatically +a secured internet deployment. Keep network exposure and real equipment +acceptance specific to the chosen beta site.

+

Backup recovery and +maintenance

+

Save work and use Core’s canonical Backup Now before +maintenance. That operation stops writers. Preserve the coherent +profile/database/document backup and its receipt, then use +Start to resume. A source export is not a full +backup.

+

Use Restore Latest Backup through the supported +controls. If the result says Restore needs service +start, use Start, then Check, +and reopen a known record. Do not repeat restore merely because services +need to start. The fresh-profile acceptance verified that a fulfilled +request survived restore and a post-backup marker did not.

+

Keep Station’s dedicated database and media evidence together in its +own backup. Core’s native-profile backup must not be assumed to include +an external Station data directory. Stop writers during a coordinated +backup. Preserve failed media attempts and logs.

+

On failure, record the time, selected composition, +component/installer versions and exact message. Check System Health for +stopped, starting, ready or failed dependencies. Use the existing Retry +control after readiness; do not create duplicate business records to +refresh a stale view. Share only a redacted diagnostic bundle. Preserve +secrets, original evidence, recovery material and unrelated +installations.

+

Troubleshooting

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SymptomLikely meaningNext action
Workspace absentWrong product composition or unavailable canonical runtime.Check selected composition; activate through Finish Records +Migration; wait for readiness.
Cannot sign in / 401Missing or expired named account session.Sign in normally; reopen a Station launch ticket if applicable.
Permission denied / 403Account, module, source or browser-origin permission.Ask the authorized administrator to inspect the intended permission; +do not invent role headers.
Save conflict / 409The saved revision, expected source hash or lifecycle changed.Keep edits, reopen current state and reconcile deliberately.
Invalid input / 422Required field, format, geometry, source envelope or state is +invalid.Read the field detail and correct the input/source; preserve +originals.
Service unavailable / 503Database, schema, connected source or configuration +unavailable.Inspect System Health and the named dependency. Preserve work; retry +only after readiness.
Export refusedMissing exact review, approval, audience or source +authorization.Read the refusal and complete the owning product’s explicit +decision.
Restore needs service startThe snapshot was restored but services have not resumed.Use Start, then Check and verify a saved record; do not blindly +repeat restore.
Ticket expired or usedA launch is one-use and expires after 60 seconds.Reopen from the signed-in native session; do not replay the old +URL.
Recording interruptedInput/worker failed or a live signal was lost.Retain attempt/logs. Retry eligible file work explicitly; start a +new live capture for a live gap.
Recording not downloadableIt is not complete or its retained bytes failed validation.Inspect state and evidence; do not serve a partial attempt as +completed media.
+

Verified workflows and +limits

+ +++++ + + + + + + + + + + + + + + +
ProductRecorded resultPrecisely exercised
StationPASSActual native staff session and normally created meeting; headless +operator live start/stop, decoded generated audio/video, served hash, +private Records readback, idempotent locked original and logout.
+

The following baseline results come from the previously accepted +signed candidate’s fresh normal-profile Sandbox exercise: real native +IPC/HTTP/PostgreSQL and selected headless controls. All accounts, source +bundles and media were synthetic. The guest install/uninstall and +recovery passed, and the owned Sandbox stopped. No host installed +application or standalone CivicCast was changed. Those baseline receipts +are retained for unchanged workflows. The accompanying ACCEPTANCE.md +records the separate installed verification and exact identity of this +new Station delivery candidate.

+

The workflow matrix +identifies raw receipt filenames. The evidence index +retains their original hashes; raw receipts remain in the private beta +handoff rather than being silently republished with the documentation +site.

+

The limits remain: actual city field acceptance and equipment/network +commissioning; Station automatic provisioning/SCM commissioning; every +UI/role combination; field recognition accuracy; and historical in-place +upgrades are not certified. They are not five invented feature +requirements. Fresh-install controlled beta handoff remains the accepted +scope. This package makes no city-deployment, publication or +general-availability claim.

+

Terms of service and license

+

Scope and status

+

These terms describe the Townlight Beta 1 software and this +documentation package. This is a public beta software distribution. It +does not create a hosted-service subscription or a city deployment +agreement. No uptime commitment, support response time, indemnity, +data-processing agreement or paid service is created by these documents. +A separate signed agreement, if any, governs services it actually +provides.

+

Software license and rights

+

Current Townlight-owned distributions identified in this candidate +use AGPL-3.0-only. The full license is supplied with +this documentation and with the source companion. The license governs +rights to run, copy, modify and convey the covered software; these +operational terms do not add restrictions to those rights. Historical +grants and dependency licenses retain their own terms. CivicCast remains +a separate product and is not relicensed by this documentation work.

+

When conveying covered software, retain applicable notices and +provide the corresponding source and installation/build information +required by the license. For a modified version supporting remote +network interaction, follow section 13’s source-offer requirement. The +companion archive identifies the source for this candidate; a link to a +different public branch is not a substitute for the matching source. +Read the supplied license for the complete conditions. See the GNU license +reference and GNU licensing +FAQ.

+

Data ownership and access

+

Importing a document does not transfer its ownership or grant +permission to publish it. The operating organization controls its +accounts, access decisions, lawful source use, retention and +review/release policy. Keep resident information, credentials, private +notes and restricted evidence in their authorized locations. +Documentation examples contain fictional data. No real city account, +credential or record is required to exercise these examples in an +isolated test environment.

+

Local operation and +external processors

+

The accepted beta workflow is local and uses named staff accounts. +Station has separate storage and credentials. Configure backup +destinations and optional model/network providers deliberately. A +configured external provider may receive submitted prompts, images or +audio according to that configuration and provider’s terms; this +documentation does not promise that every optional configuration is +offline. An email outbox or local public view does not establish +external delivery or an internet deployment. This static documentation +site has no analytics, account collection or remote font dependency.

+

Staff decisions and +source applicability

+

Staff verify the jurisdiction, source currency, permissions, +citations and proposed audience. Model output and generated guidance +require review. No draft is automatically an official legal +interpretation, zoning determination, permit approval, fee assessment, +enforcement notice or records-release decision. Official permit fee +authority remains with the adopted source and responsible organization; +imported amounts do not become a new authoritative calculation.

+

Beta operation and recovery

+

Use the identified candidate in its supported fresh-install scope. +Preserve backups and original evidence. Test physical equipment and +chosen network/service configuration before relying on them. The +supplied acceptance describes selected synthetic workflows, not every +screen, vendor, field condition or upgrade. Operators decide whether a +particular deployment meets their own operational obligations.

+

Warranty and liability

+

The covered software’s warranty and liability conditions are those in +sections 15–17 of the supplied AGPL and any applicable separate written +undertaking. This documentation creates no additional warranty or +limitation beyond those terms. Third-party software is subject to its +retained license notices. Nothing here removes rights that applicable +law makes nonwaivable.

+

Support and incident +reporting

+

Use the project’s existing SUPPORT and SECURITY guidance for its +matching repository. Report reproducible behavior with the version, +operation and redacted logs. Do not put credentials, resident records or +unredacted evidence in a public issue. Coordinate sensitive reports +through the channel designated in SECURITY. No new support address or +service commitment is invented here.

+

Ending a beta +exercise and document changes

+

When an organization ends testing, it controls retention/export and +removes access according to its policy. Uninstall may retain data; back +up and inspect the selected removal options. Ending an exercise does not +revoke rights already granted by AGPL. Later software/documentation +versions must identify their changed candidate and scope; historical +receipts retain their original identities. These terms do not claim that +a city has accepted a contract merely by reading a manual.

+

Glossary

+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TermMeaning
ApprovalAn explicit authorized decision on the saved text/artifact. It is +separate from saving or attachment.
Canonical recordThe owning product’s retained identity and saved version, rather +than an editable copied label.
CompositionThe selected set of desktop modules; inspections-preview exposes the +eight staff products.
Corresponding sourceThe source/build material matching the delivered covered program, +subject to its license.
Derivative / Records copyA separately prepared document with its own intended audience and +hash.
Hash / SHA256A fingerprint of exact bytes. It detects change; it does not +establish legal authority.
IdempotencyRepeating the same identified request has the same intended effect; +changing its payload can be refused.
IPCThe native desktop command boundary between its browser interface +and Rust host.
MCPModel Context Protocol; no direct Townlight product server is +enabled by this beta.
OriginalRetained source bytes. A reviewed derivative does not replace +them.
ProvenanceSource, version, date, actor and relationship information retained +with evidence.
RevisionAn immutable saved version. Later edits do not inherit an earlier +review automatically.
SnapshotA fixed audience-specific copy tied to a source/reviewed +revision.
StationTownlight’s separate media boundary using a pinned CivicCast-derived +engine; standalone CivicCast remains separate.
+

Alphabetical subject index

+ + + +

Source and document control

+

This edition is authored from the immutable corresponding-source +companion, the generated installed-domain schema and the retained +workflow receipts. Component version numbers are retained. The private +MSI has its own new hash and signing receipt. Historical release tags +and their artifacts remain unchanged.

+

Workflow subject index

+ +

Completed +recordings on YouTube and live CivicCast coverage

+

This source extension adds only completed-recording YouTube uploads +and a live Station-to-CivicCast feed. It is not in the published +Beta 1 installer. Existing component versions are retained. New +Station code is AGPL-3.0-only. The pinned CivicCast source and +third-party licenses remain unchanged. Standalone CivicCast is a +separate product; no installer, account, database, service or default in +it is changed by Station.

+

Staff workflow

+

For live coverage, choose a meeting, its chamber input and the +administrator’s CivicCast live feed option, then start +recording. Choose Recording only to capture privately +without a network feed. A disconnected receiver does not stop the +recording. Station sends the live MPEG-TS bytes as the recording grows; +it does not wait for the completed file. The feed is available only +during that capture. The CivicCast/PEG operator selects that source and +controls when it is broadcast on local cable. Station does not +automatically put the PEG channel on air. sending means +transport bytes were sent, not proof of cable carriage.

+

After Station shows complete, use Upload +completed recording to YouTube. Review the title, select +private/unlisted/public visibility (default private), +and enter the approval note. Click Upload to YouTube. +This is an explicit external upload to the Station-configured OAuth +account. No upload occurs just because recording stopped, a playout was +committed or a Records attachment was made. Station does not create a +YouTube livestream.

+

The upload receipt shows +queued/running/uploaded/failed/needs-reconciliation, the chosen +visibility and returned video link. uploaded is the YouTube +upload acknowledgement; YouTube may still be processing the video. The +canonical recording remains private and byte-identical for the existing +Records handoff. The YouTube visibility is separate from local +playback/disclosure approval.

+

Architecture

+

Station live feed to separate CivicCast and completed recording upload to YouTube

+

The sender has bounded, leaky buffers and follows the live edge after +congestion. Its network sink shares no pipeline with the recorder. A +late join or connection loss can leave a live coverage gap, while the +private recording continues. H.264/AAC and existing MPEG-TS captions are +forwarded without another encode. The MP4 upload remux reuses +vod_job.py; it does not generate transcripts or captions, +and does not upload a separate caption track. Upload queue work runs in +a separate process so a long upload never monopolizes the capture +worker.

+

Administrator setup

+

Use Station’s existing dedicated data root and PostgreSQL database. +Stop Station writers for a coordinated backup, retain that backup, and +run the explicit townlight-station migrate before starting +this source version. Schema 4 adds +station.youtube_uploads, keeping existing +recording/schedule/playout evidence. The data identity marker and +component versions are unchanged. Old services expect schema 3; use a +matched source/runtime and preserve the backup for rollback.

+

Create civiccast-feeds.json in the private Station data +directory:

+
[
+  {
+    "id": "peg",
+    "label": "CivicCast council feed",
+    "address": "192.0.2.10",
+    "port": 10080,
+    "secret_env": "TOWNLIGHT_STATION_SRT_PEG"
+  }
+]
+

The address is a numeric IPv4 local interface bind address on +Station, not the CivicCast computer. 192.0.2.10 is +a documentation placeholder. Use the actual Station interface, an unused +port (1024–65535), and appropriate network access between those two +systems. Clients select an administrator-defined ID, never an arbitrary +destination or media pipeline. Keep configuration files private.

+

Set TOWNLIGHT_STATION_SRT_PEG in the capture worker’s +process environment to a 10–79 character SRT passphrase. Configure a +separate CivicCast SRT live source with the caller URI +srt://<Station-address>:10080?mode=caller&latency=200 +and the same passphrase through CivicCast’s existing credential control. +Do not put the passphrase in the URI. Station’s +listener uses 128-bit SRT encryption. Keep the two accounts and +configuration stores separate; matching this specific transport +credential is the deliberate pairing. Site-specific camera, headend and +firewall commissioning remain deployment work.

+

For completed uploads, configure these Station-only +environment variables in the upload worker process. Obtain OAuth +authorization for the intended Station YouTube channel/account through +the existing deployment’s Google configuration; no OAuth onboarding +framework is added here. Do not use CivicCast’s credentials implicitly +or copy its profile.

+
    +
  • TOWNLIGHT_STATION_YOUTUBE_CLIENT_ID
  • +
  • TOWNLIGHT_STATION_YOUTUBE_CLIENT_SECRET
  • +
  • TOWNLIGHT_STATION_YOUTUBE_REFRESH_TOKEN (authorized for +YouTube video uploads)
  • +
+

Run the existing serve and capture worker, +plus the separate upload consumer with the same Station settings and +dedicated database:

+
townlight-station migrate
+townlight-station serve
+# In separate managed processes with the same explicit Station configuration:
+townlight-station worker
+townlight-station uploads
+

These are deployment commands, not commands executed against +installed apps by this development task. Run only one capture +worker and one upload worker per database. Each holds a distinct +advisory lock; media children require the existing Windows job +containment. The recorder child gets no provider credentials; the SRT +child receives only its explicit transport passphrase plus the existing +runtime allowlist. The upload worker reads only the Station OAuth +variables. OAuth/upload HTTP is restricted to Google HTTPS hosts; +redirects are not followed. The pinned donor import is checked against +Station’s declared media source.

+

HTTP API and examples

+

All /v1 operations below require the existing current +Townlight staff session header (X-Townlight-Session) or the +existing same-origin operator session. Read roles can inspect receipts. +Starting live feed/upload/retry requires the existing Station +capture capability. No new login, role system or MCP server +is added.

+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Method and routePurpose
GET /v1/civiccast-feedsCapture-authorized list of configured IDs and labels; no transport +credentials
POST /v1/recordingsExisting capture contract plus optional +civiccast_feed_id, allowed only with +live_source_id
POST /v1/recordings/{recording_id}/youtubeQueue one explicit completed-recording upload
GET /v1/youtube-uploadsRead-authorized latest 100 durable upload receipts
POST /v1/youtube-uploads/{upload_id}/retryCapture-authorized retry of a preparation failure +only
+

Station’s generated /openapi.json includes the new +routes and request schemas. Example bodies (use real canonical IDs from +the selected deployment):

+
{
+  "meeting_id": "11111111-1111-4111-8111-111111111111",
+  "agenda_ids": [],
+  "live_source_id": "chamber",
+  "civiccast_feed_id": "peg",
+  "idempotency_key": "council-live-2026-10-30"
+}
+
{
+  "title": "City council meeting — 30 October 2026",
+  "privacy": "private",
+  "approval_note": "Reviewed completed recording for upload",
+  "idempotency_key": "council-vod-2026-10-30"
+}
+

Upload titles are 1–100 characters; control characters and angle +brackets are rejected. Visibility is private/unlisted/public; approval +note 3–500 characters; key 1–100 characters. Repeating the same key +returns the same intent, a changed request conflicts, and another key +cannot duplicate an existing recording upload. A +missing/uncompleted/tampered recording is rejected before upload +admission; the worker independently verifies the recording hash before +remuxing/sending. Retained receipts include approving actor, note/time, +recording hash, MP4 path/ hash/size, chosen title/privacy and provider +video ID/URL after acknowledgement. No OAuth token, passphrase or donor +credential pointer is stored in receipts.

+

Recovery and limits

+

A failed preparation (for example missing Station OAuth configuration +or failed remux) is failed; correct the cause and +explicitly call its retry route. The prior attempt files remain +retained. Once any external request begins, an error is conservatively +needs-reconciliation. A worker restart also moves +interrupted running uploads to that state. There is no +automatic retry that could create a duplicate YouTube video. Check +YouTube Studio and the retained job before a human chooses another +external action. This increment provides no automatic remote +reconciliation/delete/reupload control. A valid uploaded link is +retained even if the capture worker is restarted. The existing +recording/Records path does not depend on the external upload +succeeding.

+

Live sender state is in the recording’s +details.civiccast_delivery; its final byte count and +per-attempt status/log files stay with the private recording. On +capture-worker restart, an interrupted feed is marked interrupted rather +than left appearing to send. Stop/reap is bounded even if the network +child hangs. No feed is automatically re-aired after recovery.

+

Verification and release +status

+

tests/accept_deliveries.py exercises the real Station +API/store/media/remux, CivicCast’s pinned SRT source adapter and real +YouTube file-upload client using a disposable PostgreSQL cluster, +generated audio/video, synthetic staff authority and +httpx.MockTransport for Google. No city systems or external +publication are involved. tests/accept_delivery_ui.cjs +drives the actual compiled operator controls in headless Chromium with +synthetic API responses. Existing boundary/ operations checks and +TypeScript compilation also apply.

+

Example invocation from a development environment with existing +dependencies:

+
$env:PYTHONPATH = (Resolve-Path ./beta-1).Path
+$env:STATION_TEST_PG_BIN = 'C:/test-tools/postgres/bin'
+$env:STATION_TEST_MEDIA_RUNTIME = 'C:/test-tools/station-media-runtime'
+python -B ./beta-1/tests/accept_deliveries.py C:/test-output/station-deliveries-new
+

Use a new output directory; the script starts/stops +only its owned disposable cluster and children. See the task’s retained +acceptance receipts for actual results. This evidence establishes the +new source wiring synthetically. It does not replace CivicCast’s already +established real YouTube delivery evidence, nor claim a new real YouTube +upload, physical cable broadcast, signed installer or Sandbox acceptance +of this extension. Published Beta 1 artifacts stay unchanged.

+

Delivery subject index

+
    +
  • CivicCast +live feed
  • +
  • YouTube: explicit completed recording upload; visibility; receipt +and reconciliation.
  • +
  • Schema4: durable upload intent; existing evidence retained.
  • +
+ \ No newline at end of file diff --git a/docs/beta-1/history/station/pre-naming-2026-11/USER-MANUAL.md b/docs/beta-1/history/station/pre-naming-2026-11/USER-MANUAL.md new file mode 100644 index 0000000..59f2947 --- /dev/null +++ b/docs/beta-1/history/station/pre-naming-2026-11/USER-MANUAL.md @@ -0,0 +1,848 @@ +> **Private Station delivery beta candidate — 30 October 2026.** This documentation includes completed-recording YouTube uploads and a live Station-to-CivicCast feed. It accompanies the new private candidate, not the previously published installer. Existing versions are retained. Consult the accompanying candidate checksums and acceptance receipts; earlier published-candidate results below remain historical evidence. No public release or city deployment is implied. + +## Using this manual + +Townlight Station helps station operators, clerks, records staff and deployment administrators. Station adapts a pinned CivicCast media implementation into an independent Townlight boundary. It captures managed files or configured live UDP MPEG-TS, retains canonical meeting/agenda context, and hands verified recording evidence to Records. Scheduling, playout, approval and local playback have distinct controls. + +Staff should begin with First run and Daily workflow. Administrators should also read Architecture, Technical specifications, Configuration, Security and Recovery. Developers should use the exact API/data dictionary and examples. The table of contents and alphabetical subject index link to the relevant sections in the HTML edition; the PDF preserves headings and searchable text. An editable Word edition is included with the same documentation companion. + +## Beta identity + +| Identity | Value | +| --- | --- | +| Public documentation identity | Townlight Beta 1 | +| Installer version | 1.6.0.1 | +| Product component | townlight-station 0.3.0 | +| Native desktop source version | 1.6.0-1 | +| Candidate artifact identity | Private Station delivery candidate; use accompanying SHA256SUMS | +| Corresponding source | Updated private candidate source companion | +| Current owned software license | AGPL-3.0-only | +| Supported acceptance profile | Windows x64 fresh install; inspections-preview; separate Station configuration | + + +“Townlight Beta 1” identifies this coordinated beta delivery. It does not renumber the installer, native binary, Python packages or historical receipts. Component versions may differ. This edition accompanies a newly packaged and signed private MSI containing the Station delivery additions. The native desktop and other native payload files retain their accepted signed bytes. Historical release pages and manuals describe their own versions and are not the download instructions for this private candidate. + +## First run + +1. Obtain the identified signed private candidate and its corresponding-source companion from the beta coordinator. The landing pages in this documentation are not an installer download service. +2. On the intended fresh Windows test installation, verify the MSI hash and publisher signature before installing. Preserve unrelated profiles and recovery material. This candidate has fresh-install acceptance; historical in-place upgrades are unverified. +3. Launch Townlight under the intended named Windows account. Choose the storage folders. Select **Townlight Inspections candidate** (`inspections-preview`) for all eight desktop products. A narrower default selection will not expose all workspaces. +4. Enter the city profile, time zone and contacts. Create the first named local administrator, sign in and choose protected backup storage. **Continue without local AI** is valid for the deterministic workflows. +5. Run Health Check and wait for readiness. Open Townlight. In System Health select **Finish Records Migration** to activate the canonical Python/PostgreSQL runtime. Do not fabricate migration receipts or seed accounts. +6. Create named staff through Settings. Import authorized sources using each product’s source library. All examples in this package are synthetic; they are not municipal authority. +7. Provision Station separately if it is part of the beta exercise. Selecting the desktop composition does not start or configure Station. Configure vision explicitly only if automatic photo drafting is selected. + +## Daily workflow + +### 1. Prepare meeting context {#workflow-1} + +Create and save the actual meeting and agenda in Meetings. Assign each selected agenda item to that meeting. A recording request cannot substitute an editable meeting label for the canonical records. + +### 2. Open the operator {#workflow-2} + +Sign in as authorized staff. Use the configured local operator command with the explicit native profile root. It obtains a short-lived one-use browser ticket; the native proof is not placed in the URL. + +### 3. Choose the input {#workflow-3} + +Select the meeting, assigned agenda and administrator-configured live-source ID. For recorded-file work, place the source in the managed ingest directory and optionally supply an SRT sidecar. Callers cannot submit arbitrary pipelines or filesystem paths. + +### 4. Capture and stop {#workflow-4} + +Start capture and distinguish waiting for a signal from active recording. Stop requests pipeline drain. Wait for completed status and validated output; a partial, failed or interrupted attempt is not a completed recording. + +### 5. Review recording evidence {#workflow-5} + +Inspect the media and retained context/hash. Retry is explicit for failed/interrupted recorded-file jobs. A lost live signal cannot be reconstructed: begin a new live recording and preserve the failed attempt. + +### 6. Hand off to Records {#workflow-6} + +Choose an existing Records request and attach the reviewed recording. The receiver checks bytes/hash and retains a locked private original. Repeating the same handoff retains one canonical document. + +### 7. Use playout deliberately {#workflow-7} + +Scheduling, dry-run/commit playout, staff approval and local publication are distinct API operations. Public playback only serves the separately approved packaged output. Nothing in capture or Records handoff automatically publishes it. + +### 8. Close and recover {#workflow-8} + +Sign out of the operator. Back up Station’s database and media evidence together, separately from Core’s native profile backup. Restart interrupted work deliberately; do not automatically re-air a lost signal. + +### Working safely + +Use your own named account and save before leaving a screen. A saved draft is durable; unsaved form text may not be. If a write has an unknown result, reopen its record before repeating it. + +Read source jurisdiction, dates, citation, version and visibility. A copied source hash identifies exact bytes, not their legal applicability. If a source changes or permission is removed, resolve the source problem rather than substituting stale cached content. + +Keep originals and derivatives separate. Review the intended audience before export. A public summary excludes private fields only through the applicable copy contract and your review. A renamed private packet is still private content. + +Drafting, review, approval, attachment, export, fulfillment and publication are separate operations. A Townlight workpaper does not itself adopt law, issue a permit, impose a fine or release a records response. The responsible staff member records the applicable decision. + +## Connected workflows + +Meetings → Station → Records is the accepted recording workflow. Townlight owns current session authority; Station owns its database, storage and media children. Standalone CivicCast remains separate, with no shared configuration, service, data directory or automatic updater fallback. + + +| Direction | Material | +| --- | --- | +| Input | A real Townlight staff session, saved Meetings records, a dedicated Station database/data root, a managed ingest filename or configured live-source ID, and optional supplied SRT captions for recorded-file input. | +| Output | Completed verified recording derivatives, retained original inputs/provenance, separately approved local playback packages and locked private Records evidence. | + + +### Product boundary + +There is no Station first-run wizard or automatic activation by the desktop composition. The accepted normal-profile path uses an explicitly configured paired Townlight HTTP process. Physical encoder/network, remote identity, SCM commissioning, CDN delivery and long-duration field quality are not certified. Station does not perform automatic meeting speech recognition. + +## Architecture + +Townlight Station architecture and evidence flow + +The drawing shows the principal staff/evidence path. Native commands carry trusted identity to Python business services; PostgreSQL and retained original files hold durable state. A downstream copy does not silently transfer decision authority. Station has its own configured authority/media boundary, database and mutable files. The connected-workflow text supplies the drawing’s reading order and accessibility alternative. + +## Scheduling playout and recovery + +### Schedule a recording and interpret its state + +Use **Schedules** after saving the actual meeting/agenda and placing a complete file in Station's managed `ingest` directory. Choose the meeting, **Start** time, **Source file in managed ingest**, and optional SRT **Caption sidecar**, then select **Schedule**. The browser form schedules files. The service's schedule API also supports a configured live-source ID; this is not a second input selector in that browser form. + +The browser's datetime input is interpreted in the operator computer's local timezone and converted to an ISO UTC instant. Verify that computer's timezone before entering a city meeting time. A direct API client should send an explicit timezone offset or `Z`; a timezone-less API datetime is interpreted as UTC. A synthetic `POST /v1/schedules` body is: + +```json +{"meeting_id":"11111111-1111-4111-8111-111111111111","agenda_ids":[],"source_file":"synthetic-program.mp4","captions_file":"synthetic-captions.srt","start_at":"2026-11-05T18:00:00-07:00","idempotency_key":"synthetic-schedule-001"} +``` + +Use a real synthetic meeting ID and intended future exercise time, with files already in managed ingest. The body selects exactly one file or configured live source; a live source cannot use a sidecar. Reusing an idempotency key with changed input/context is a conflict. The initial response includes `id`, `status: scheduled` and `start_at`; it does not mean recording has finished. + +Refresh Schedules and inspect the returned identity/time. **Cancel schedule** is available while it remains scheduled; cancellation of an already dispatched or terminal entry is refused. The worker claims due work once and creates the linked recording. A start delayed by **more than ten minutes** is `missed`, not replayed late. A start within that grace can dispatch on the next worker pass. Inspect the linked recording for its own queued/running/completed or failed state. Do not assume scheduling also commits that recording to air. + +### Apply the caption profile + +For a managed recorded file, an explicitly supplied SRT sidecar replaces embedded captions for this profile; otherwise embedded captions are retained where supported by the pinned media profile. Live capture preserves the embedded-caption path and does not accept an SRT sidecar. An absent caption stream is not automatic speech recognition. Check the actual captured/packaged captions for the selected synthetic input. + +Original files are limited to 2,147,483,647 bytes and sidecars to 5,000,000 bytes. After publication, browser playback uses the packaged MP4 and a separate WebVTT track when produced. Preserve original inputs and recorded caption provenance separately from those derivatives. + +### Check playout and commit deliberately + +Open a **completed** recording. Select **Check playout** to queue `mode: dry-run`. Inspect its status and retained errors; a successful check does not change on-air state. To render and take that program to the scheduled on-air path, explicitly select **Commit to air**, which uses `mode: commit`. Wait for the playout to be `complete`; failed rendering is not a successful switch. + +Equivalent `POST /v1/playouts` input is: + +```json +{"recording_id":"22222222-2222-4222-8222-222222222222","mode":"dry-run","idempotency_key":"synthetic-playout-check-001"} +``` + +Replace the recording ID with completed synthetic evidence. A separate deliberate commit uses `mode: commit` and a new key; do not reuse the check's key with a changed mode. Inspect the returned playout `id` and read `/v1/playouts/{id}` until terminal. The scheduled on-air program follows verified committed output, not every dry-run or every recording. Keep the worker and air roles distinct: one renders work, the other follows durable on-air state and emits the local program. + +### Take a live override and return + +In **On air**, choose an administrator-configured live input and enter a reason of at least three characters. Select **Take live override** and inspect the on-air mode/source. `POST /v1/on-air/live` uses `live_source_id` and `reason`; callers cannot supply an arbitrary network pipeline. + +While live, select **Return to schedule** (`POST /v1/on-air/return-to-schedule` with no payload). Confirm the mode returns to scheduled program. The override supersedes the scheduled output; it does not delete its committed material. If no valid committed program is available, do not assume returning has produced a usable broadcast. Read actual output/state and any error. These are local synthetic on-air controls, not proof of a commissioned cable headend, physical receiver or public CDN. + +### Approve and publish local playback + +In **Playout and playback**, wait for a completed rendered playout. Review its actual media/context/captions, then enter the approval note and approve it. The API accepts a note of 3–500 characters at `/v1/playouts/{id}/approve`. Approval is retained with the authenticated staff actor; it does not itself publish. + +Select **Publish locally** only for that reviewed approved playout. `/v1/playouts/{id}/publish` packages local MP4/WebVTT playback. The response and subsequent playout view retain the publication details. Open the displayed local playback, verify it advances with the expected picture/sound, and inspect the caption track where supplied. Unpublished content is unavailable through the public playback route; guessing its ID does not authorize access. Repeating a completed publication returns the retained package rather than silently publishing changed media. + +The local playback route `/v1/public/playback/{id}` serves the packaged program; `/captions` serves its available WebVTT. This approval/publication is separate from **Commit to air**, capture, attachment to Records and a Records release. Internet commissioning remains outside this local procedure. + +### Recover without replaying unknown work + +After a worker/API/air interruption, inspect durable schedules, recordings, attempts, playouts and on-air state before repeating any write. The worker marks interrupted in-flight work accordingly. Eligible failed/interrupted **file** recording retries are explicit; live loss requires a new live capture. Retain the prior attempt/logs and do not claim a missing live interval was reconstructed. + +Future scheduled intent survives restart. A claimed/dispatched schedule must not be duplicated; one beyond the ten-minute grace becomes missed. Read its linked recording and create new future intent only when deliberately required. On-air recovery preserves attribution and does not automatically resume a stale live override as if the source had remained valid. Check the actual on-air mode and available committed program after restart before choosing a new override. + +Visible failed/interrupted states and error text in the operator are the existing alert mechanism for this beta. Preserve the private process logs and attempt evidence. Reopen a normal operator ticket after API restart; do not replay an old ticket or bypass current staff authority. Restore Station's database and its matching media as one recovery set, separately from Core's native backup. Recheck original/output hashes and intended state after restoration. No automatic repair or database reset is implied by restart. + +Source contracts: `townlight_station/operations.py`, `worker.py`, `airplay.py`, `operator.py`, the pinned media profile and `station/operator-ui/src/operator.tsx`. Service request models are in the Station API companion. The three suite-side Station paths in its OpenAPI download are not the full separate `/v1` service schema. + + +## Technical specifications +### Runtime and storage + +The accepted package targets **Windows x64 fresh installation**. Its native shell uses **Rust 2021, Tauri 2 and Microsoft WebView2**; browser assets are JavaScript built with **Vite 8.1.6**. This describes the native desktop frontend; Station has a separate React operator, specified below or in its product manual. Canonical business workflows use bundled **CPython 3.13.5, FastAPI, Pydantic, SQLAlchemy and Alembic**, with **PostgreSQL 17 / PostGIS** and managed original files. The installed runtime tested here contains FastAPI 0.162.0. Package minimum Python requirements can differ from the bundled executable; the metadata reference preserves both. No stack rewrite is implied by the beta label. + +The native transport is fixed to loopback `127.0.0.1:15480`; PostgreSQL uses the configured local runtime port (default `15432`). Optional local model service defaults to `127.0.0.1:15434`. Those are deployment defaults, not internet endpoints. The runtime has health, module and readiness endpoints; readiness is stronger than process existence. The task queue is the existing local Core task infrastructure, not an assertion that a separate Redis service is required for this desktop composition. + +The default native profile is `%LOCALAPPDATA%\CivicSuite`; the historical directory name remains part of compatibility. Do not rename it to Townlight. A configured `TOWNLIGHT_PROFILE_ROOT` must be absolute. Local configuration and secrets live under that profile; protected managed files and database state must be backed up coherently. Source/runtime identity is distinct from a product’s display label. + +### Data and consistency + +Configured live-source IDs; canonical meeting/agenda snapshots; queued recordings and immutable attempts; input/output hashes; schedules; playout jobs and approvals; durable on-air state; publication packages; Records attachment provenance. + +Versioned saves use expected prior revision identifiers where defined. Reopen and reconcile on conflict. Exact exports and handoffs use source IDs, current visibility, revision and SHA256. Review belongs to the saved revision and does not transfer silently to edited text. Database changes use the owning product’s migrations; a request or readiness check is not an authorization to mutate schema. + +### Capacity and platform statements + +This beta has synthetic single-profile workflow evidence. It does not have a published benchmark for concurrent staff capacity, minimum RAM/CPU, large-source limits or a field SLA. Do not turn a developer machine’s specification into a supported minimum. Installer size is 2,092,122,112 bytes before installation; allow additional disk for extracted runtime, database, originals, exports, media and backups. Select equipment/storage after sizing those actual workloads. + +The exact [runtime payload lock](docs/beta-1/reference/runtime-payload-lock.json) records pinned files, sizes and hashes. The [component metadata](docs/beta-1/reference/component-metadata.json) records shipped dependency declarations. These references are more precise than a manually copied dependency list. Third-party and historical license notices must accompany their matching payloads. + +### Station operator and media components + +The native desktop frontend above is distinct from Station's browser operator. The pinned operator package `townlight-station-operator` is version **0.1.0**, using **React/react-dom 19.1.1**, **TypeScript 5.9.2**, **Vite 7.3.7** and the React Vite plugin 5.0.2. Station serves its built assets through its own operator API. Its Python control/API package remains **townlight-station 0.3.0**, while its retained storage identity remains **0.1.0**. These identities have different purposes and are not renumbered. + +The separate pinned CivicCast-derived media engine uses Python/native GStreamer processing and bounded media children. It is not the standalone CivicCast application. Station's control database, data root, service/configuration and update identity remain independent. This describes the current mixed stack; no runtime rewrite or CivicCast migration is implied. + +### Station media and lifecycle contract + +The package/API version is `0.3.0`. Its retained storage identity has version `0.1.0`; that is a separate storage marker and must not be rewritten to match the package. Product/app IDs are `townlight-station` and `org.townlight.station`; service identity is `TownlightStation`, virtual account `NT SERVICE\TownlightStation`, credential namespace `townlight.station`, database schema `station`, and update-channel identity `townlight-station`. An identity name or SCM entry point does not establish that a Windows service was registered. + +The control service is Python; its separate pinned CivicCast-derived engine uses native GStreamer media processing. There is no launch of the standalone CivicCast application. Default encoding is 1920×1080, 30 fps and 6000 kbps; explicit validated configuration may change it. The source lock is verified before use. Media children are isolated and bounded; unfinished attempts become interrupted on recovery. + +Recorded-file requests accept a managed ingest filename, optional SRT sidecar and idempotency key. Live requests accept a configured source ID, not a path. Select exactly one file or live source; live capture cannot also supply a sidecar. Inputs are bounded by the configured two-hour default timeout and a 2,147,483,647-byte file limit. Supplied SRT sidecars are bounded to 5,000,000 bytes. The queue admits at most 100 pending/running jobs; live admission is further serialized. A repeated idempotency key must identify the same source bytes, canonical meeting context and encoding profile. + +`queued` and `running` do not make content available as completed. Completion requires the worker’s clean media teardown and stream validation. Failed/interrupted file jobs may be explicitly retried; a live gap requires a new capture. Records receives verified bytes and canonical provenance as a locked private original. Local publication is an explicit later operation on separately approved playout; its MP4/WebVTT package is distinct from the retained recording and from a Records release. + +## Configuration and administration +### Prepare the normally activated synthetic profile + +This procedure describes a future isolated beta installation. Documentation generation does not execute it. Complete normal Townlight Setup under the intended Windows account, select `inspections-preview`, sign in, and use **Finish Records Migration**. Keep the native database running and confirm the canonical runtime is ready. Use that account's actual profile path; the default is `%LOCALAPPDATA%\CivicSuite`. Do not create session files, seed accounts or force `domain_enabled=True`. + +Station needs its own database and initially empty absolute data directory. It uses the same named Townlight staff authority through an additional configured loopback suite process. It does not launch or modify CivicCast. No SCM installation, registry edit or replacement of the desktop's fixed-origin service is needed. + +The examples reserve suite port **15481**, Station port **8756** and synthetic UDP input port **19000**. Choose unused ports and change both configured origins together if needed. Never point these instructions at a city's live profile or data. Use the actual installation directory if Townlight was installed elsewhere. + +### Store the independent test configuration + +Run the following in a deployment PowerShell session under the same Windows user. Keep this session for startup and shutdown. The dedicated parent holds configuration/logs; its `data` child is Station's initially empty managed store. + +```powershell +$profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite' +$control = Join-Path $profilePath 'runtime\python\python.exe' +$payload = 'C:\Program Files\Townlight\_up_\runtime\payload\station' +$stationRoot = Join-Path $env:LOCALAPPDATA 'TownlightStation-Synthetic' +if (-not (Test-Path -LiteralPath $control)) { throw 'Complete normal Townlight setup first.' } +if (Test-Path -LiteralPath $stationRoot) { throw 'Existing Station directory: inspect it; do not overwrite.' } +New-Item -ItemType Directory -Path $stationRoot | Out-Null +$account = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name +& icacls.exe $stationRoot /inheritance:r /grant:r "${account}:(OI)(CI)F" '*S-1-5-18:(OI)(CI)F' | Out-Null +if ($LASTEXITCODE -ne 0) { throw 'Cannot protect Station configuration directory.' } +New-Item -ItemType Directory -Path (Join-Path $stationRoot 'data'),(Join-Path $stationRoot 'logs') | Out-Null +$rng = [System.Security.Cryptography.RandomNumberGenerator]::Create() +$randomBytes = New-Object byte[] 32 +$rng.GetBytes($randomBytes) +$rng.Dispose() +$stationPassword = -join ($randomBytes | ForEach-Object { $_.ToString('x2') }) +$stationPassword | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString | + Set-Content -LiteralPath (Join-Path $stationRoot 'station-password.dpapi') +Remove-Variable stationPassword,randomBytes +``` + +The password file uses the current Windows user's DPAPI protection. It is not portable to a different user or machine without an explicit credential/recovery decision. Keep it out of source control, support bundles and public documentation. Reuse this protected configuration on restart rather than creating another database or password. + +In the same session, establish the exact process environment. On a later restart, set `$profilePath`, `$control`, `$payload` and `$stationRoot` to these same existing locations, then repeat this environment/start section, **not** the first-time provisioning section. + +```powershell +$secret = Get-Content -LiteralPath (Join-Path $stationRoot 'station-password.dpapi') -Raw | + ConvertTo-SecureString +$stationPassword = [System.Net.NetworkCredential]::new('', $secret).Password +$nativePassword = (Get-Content -LiteralPath (Join-Path $profilePath 'config\secrets\postgres-password.txt') -Raw).Trim() +$encodedNative = [uri]::EscapeDataString($nativePassword) +$env:TOWNLIGHT_PROFILE_ROOT = $profilePath +$env:CIVICSUITE_DATA_DIR = Join-Path $profilePath 'Data' +$env:CIVICSUITE_FILE_STORAGE_DIR = Join-Path $profilePath 'Data\files' +$env:DATABASE_URL = "postgresql+asyncpg://civicsuite:${encodedNative}@127.0.0.1:15432/civicsuite" +$env:TOWNLIGHT_PRODUCT_PROFILE = 'inspections-preview' +$env:PORTAL_MODE = 'private' +$env:CIVICSUITE_RUNTIME_HOST = '127.0.0.1' +$env:CIVICSUITE_RUNTIME_PORT = '15481' +$env:TOWNLIGHT_STATION_URL = 'http://127.0.0.1:8756' +$env:TOWNLIGHT_STATION_SUITE_URL = 'http://127.0.0.1:15481' +$env:TOWNLIGHT_STATION_DATA_ROOT = Join-Path $stationRoot 'data' +$env:TOWNLIGHT_STATION_DATABASE_URL = "postgresql+psycopg2://townlight_beta_station_app:${stationPassword}@127.0.0.1:15432/townlight_beta_station" +$env:TOWNLIGHT_STATION_MEDIA_SOURCE = Join-Path $payload 'media-source' +$env:TOWNLIGHT_STATION_MEDIA_PYTHON = Join-Path $payload 'runtime\python.exe' +$env:TOWNLIGHT_STATION_MEDIA_RUNTIME = Join-Path $payload 'runtime' +$env:TOWNLIGHT_STATION_FFPROBE = Join-Path $payload 'bin\ffprobe.exe' +$env:PYTHONNOUSERSITE = '1' +$env:PYTHONDONTWRITEBYTECODE = '1' +Remove-Item Env:PYTHONPATH -ErrorAction SilentlyContinue +Remove-Variable nativePassword,encodedNative,stationPassword,secret +``` + +Use the actual native PostgreSQL port/database/user if the deployment differs from the accepted defaults. Environment changes here apply to children of this shell, not the already running native supervisor. Keep secrets out of command arguments and output. The paired runtime deliberately uses normal `verify_activation` through its standard module entry point. + +### Provision the Station database once + +This first-time step creates only the dedicated synthetic role/database. Its role owns that database and its Station schema, with no superuser/global administration grant. It connects to the normally provisioned local database using the current profile's protected credential. Existing role/database names cause a refusal before creation; do not drop or repurpose them automatically. + +```powershell +@' +import os +from pathlib import Path +import psycopg2 +from psycopg2 import sql +from sqlalchemy.engine import make_url + +url = make_url(os.environ['TOWNLIGHT_STATION_DATABASE_URL']) +profile = Path(os.environ['TOWNLIGHT_PROFILE_ROOT']) +password = (profile/'config/secrets/postgres-password.txt').read_text().strip() +conn = psycopg2.connect(host='127.0.0.1', port=15432, user='civicsuite', + password=password, dbname='postgres') +conn.autocommit = True +try: + with conn.cursor() as cur: + cur.execute('SELECT 1 FROM pg_roles WHERE rolname=%s', (url.username,)) + role_exists = cur.fetchone() is not None + cur.execute('SELECT 1 FROM pg_database WHERE datname=%s', (url.database,)) + if role_exists or cur.fetchone() is not None: + raise RuntimeError('Dedicated role/database already exists; inspect before continuing') + cur.execute(sql.SQL('CREATE ROLE {} LOGIN PASSWORD %s').format( + sql.Identifier(url.username)), (url.password,)) + cur.execute(sql.SQL('CREATE DATABASE {} OWNER {}').format( + sql.Identifier(url.database), sql.Identifier(url.username))) +finally: + conn.close() +'@ | & $control -B - +if ($LASTEXITCODE -ne 0) { throw 'Station database provisioning did not complete; inspect before retrying.' } +& $control -B -m townlight_station.cli migrate +if ($LASTEXITCODE -ne 0) { throw 'Station migration failed; retain logs and inspect the dedicated schema.' } +``` + +If database creation fails after the role was created, the operation is partially complete: inspect that exact owned role/database before resuming. Do not rerun against guessed names or remove unrelated objects. On normal restarts, the database already exists; skip creation and use the existing identity. `migrate` is explicit; API requests do not substitute for schema migration. + +### Start and check the paired processes + +Use the same configured session. The standard suite entry point verifies the existing native activation. Check readiness of that exact paired origin, not only the desktop's canonical port. Startup below creates hidden children with private log files and records their identities; it does not focus windows or install services. + +```powershell +$owned = @() +function Start-StationRole([string]$name, [string[]]$arguments) { + $p = Start-Process -FilePath $control -ArgumentList $arguments -WindowStyle Hidden -PassThru ` + -RedirectStandardOutput (Join-Path $stationRoot "logs\$name.out.log") ` + -RedirectStandardError (Join-Path $stationRoot "logs\$name.err.log") + $script:owned += [pscustomobject]@{ Name=$name; Id=$p.Id; StartTime=$p.StartTime; Path=$p.Path } + $script:owned | ConvertTo-Json | Set-Content -LiteralPath (Join-Path $stationRoot 'owned-processes.json') + return $p +} +function Wait-StationReady([string]$url, $process) { + for ($attempt=0; $attempt -lt 40; $attempt++) { + if ($process.HasExited) { throw "Owned process exited; inspect logs for $url" } + try { + $response = Invoke-WebRequest -Uri $url -UseBasicParsing -TimeoutSec 2 + if ($response.StatusCode -eq 200) { return } + } catch { } + Start-Sleep -Milliseconds 250 + } + throw "Readiness not established: $url; inspect the owned logs" +} +$suite = Start-StationRole 'paired-suite' @('-B','-m','civicsuite_runtime.services') +Wait-StationReady 'http://127.0.0.1:15481/ready' $suite +$api = Start-StationRole 'station-api' @('-B','-m','townlight_station.cli','serve','--port','8756') +Wait-StationReady 'http://127.0.0.1:8756/health' $api +$worker = Start-StationRole 'station-worker' @('-B','-m','townlight_station.cli','worker') +# Only for the on-air profile: +$air = Start-StationRole 'station-air' @('-B','-m','townlight_station.cli','air') +$owned | ConvertTo-Json | Set-Content -LiteralPath (Join-Path $stationRoot 'owned-processes.json') +``` + +Before launching, confirm ports 15481 and 8756 are unused. If readiness fails, inspect the relevant logs and retained profile/schema state; do not start another copy. A port that answers belongs to the intended process only when its ownership is established. A single worker owns a database. `worker --once` performs a bounded pass; it is not the normal continuous worker. The `air` role follows durable on-air state and emits the local program; it does not commission a physical transmitter or CDN. Its currently configured local output is under Station's `air` directory. Back up the dedicated database and media together; Core's native backup does not cover them. + +### Configure a live input and open the operator + +Create `live-sources.json` under the Station **data** directory with the following fictional input. An actual sender must supply UDP MPEG-TS to that receiver; this configuration alone does not generate a signal. + +```json +[{"id":"synthetic-chamber","label":"Synthetic chamber feed","kind":"udp-mpegts","address":"127.0.0.1","port":19000}] +``` + +At most 32 rows are accepted. IDs are unique 1–64 letters/digits/underscore/hyphen; labels have 1–100 characters; IPv4 and ports 1024–65535 are validated. Each row has exactly the five shown keys. Protect the source network; UDP is not authenticated. Then, under the same signed-in native account: + +```powershell +& $control -B -m townlight_station.cli operator --profile-root $profilePath --port 8756 +``` + +This normal operator command opens the operator for a future staff exercise. It reads the native session and exchanges a one-use launch ticket; it does not seed authority or put the native proof in a URL. Ticket expiry is 60 seconds, operator cookie lifetime 900 seconds, with at most 256 outstanding tickets/sessions each. Reopen normally after expiration, API restart or sign-out. Changing database/configuration identities does not repair a staff permission refusal. + +### Bounds and shutdown + +Default encoding is 1920×1080, 30 fps, 6000 kbps. Optional Station variables permit `MAX_SECONDS` 10–86400 (default 7200), even `WIDTH` 320–3840 and `HEIGHT` 180–2160, `FPS` 1–60 and `BITRATE_KBPS` 128–50000; each is prefixed `TOWNLIGHT_STATION_`. The media source lock and exclusive data identity are verified before use. The dedicated database name must end in `_station`; unowned nonempty storage and escaping/reparse paths are refused. The existing SCM entry point is not a claim of installed service acceptance. + +To finish an exercise, stop live capture from the operator and wait for its completed or failed terminal state. Wait for any recording/playout work to finish, cancel unwanted future schedules, sign out and preserve the evidence/logs. The air role starts a separate media child; force-stopping only its parent does not run Python cleanup. Stop only the process trees you started, checking each root's identity before using a saved PID: + +```powershell +foreach ($entry in @($owned | Sort-Object StartTime -Descending)) { + $process = Get-Process -Id $entry.Id -ErrorAction SilentlyContinue + if ($process -and $process.StartTime -eq $entry.StartTime -and $process.Path -eq $entry.Path) { + & taskkill.exe /PID $process.Id /T /F | Out-Null + if ($LASTEXITCODE -ne 0) { throw 'Owned process tree did not stop; inspect before proceeding.' } + $process.WaitForExit() + } +} +``` + +Retain the ownership file if the shell must close; parse and verify its actual process paths/start times before acting. Do not terminate the native database/supervisor or CivicCast. Interrupting a worker during a job preserves an interrupted attempt, not completed media; recovery is described in the Station operating procedure. Clear secret-bearing environment values when closing the dedicated deployment shell. Do not delete the database/data root to “reset” an uncertain result. + +## API and integration examples +### Native command example + +The following JavaScript belongs in the existing trusted Townlight frontend/development environment with `invoke` imported from `@tauri-apps/api/core`. It is not a command for an arbitrary web page or an instruction for nontechnical staff. IDs must come from records created in an isolated synthetic exercise. + +```javascript +import { invoke } from '@tauri-apps/api/core'; +const result = await invoke('meetings_domain_request', {request: {operation: 'get-meeting', id: meetingId}}); +console.log(result); +``` + +### Trusted local HTTP example + +An administrator/developer can inspect an already-configured isolated runtime from a trusted local process. This PowerShell example reads the signed-in synthetic profile’s existing proof into memory; it does not create a user, seed a session, reveal the proof in output or bypass a permission check. Do not use real city data in development examples. A read response does not prove approval or publication. + +```powershell +Invoke-RestMethod -Uri 'http://127.0.0.1:8756/health' +# Authenticated recording operations additionally require current native proof. +``` + +### A synthetic write with subsequent readback + +This example demonstrates the existing Meetings HTTP contract in an isolated exercise. It is intentionally fictional. It does not start a service. Its authentication setup is included so it can be run independently under the signed-in synthetic account. If a write times out, inspect current records before repeating it. + +```powershell +$profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite' +$sessionPath = Join-Path $profilePath 'config/local-session.json' +$session = Get-Content -LiteralPath $sessionPath -Raw | ConvertFrom-Json +$headers = @{ 'X-Townlight-Session' = $session.session_hash } +$body = @{ + title = 'Synthetic documentation exercise' + scheduled_start = '2026-11-05T18:00:00-07:00' + location = 'Synthetic room' + meeting_type = 'regular' +} | ConvertTo-Json +$meeting = Invoke-RestMethod -Method Post ` + -Uri 'http://127.0.0.1:15480/desktop/v1/meetings/meetings' ` + -Headers $headers -ContentType 'application/json' -Body $body +Invoke-RestMethod ` + -Uri ('http://127.0.0.1:15480/desktop/v1/meetings/meetings/' + $meeting.id) ` + -Headers $headers +Remove-Variable session, headers +``` + +This write requires Meetings to be enabled and the signed-in staff role to permit it. It is a cross-suite integration example; for this product’s request models, use the complete technical reference below. + +### Recording and Records handoff example + +An authenticated local client sends `POST http://127.0.0.1:8756/v1/recordings` with `X-Townlight-Session` and this JSON, replacing the synthetic UUIDs with saved synthetic meeting/agenda IDs. Configure `synthetic-chamber` first. + +```json +{ + "meeting_id": "11111111-1111-4111-8111-111111111111", + "agenda_ids": ["22222222-2222-4222-8222-222222222222"], + "live_source_id": "synthetic-chamber", + "idempotency_key": "synthetic-docs-capture-001" +} +``` + +The initial response is `202` with a queued/running identity rather than completed media. Read `/v1/recordings/{identity}`, explicitly stop live capture through `/v1/recordings/{identity}/stop`, and wait for completed status before reading `/content`. Then the authorized Records client calls `POST /desktop/v1/requests/{request_id}/station-recordings` on the paired Suite runtime with: + +```json +{ + "recording_id": "33333333-3333-4333-8333-333333333333", + "expected_sha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +} +``` + +The shown hash is deliberately a placeholder. Use the actual completed recording’s hash. A mismatched hash must fail. Repeating the identical completed handoff is idempotent; it does not create a release copy or fulfill a request. + +### Complete technical contract + +Read the [Station API reference](docs/beta-1/api/station.html) for every documented operation, request field, constraint, response declaration and source supplement. Download the [OpenAPI JSON](docs/beta-1/api/station-openapi.json) for tools. For Station this is the suite-side schema only; its separate service contract is documented in the API supplement. The [reference directory](docs/beta-1/reference/index.html) includes configuration/source inventories, dependency declarations, native command contracts, MCP signatures and candidate evidence. + +## MCP and automation boundary + +No direct product MCP server is exposed by the accepted Townlight desktop or Station boundary. Do not configure an invented `townlight mcp` command or assume an AI client has staff permissions. The integration surfaces for this beta are native IPC, the documented HTTP APIs, source bundle imports, exact exports and the existing Station CLI. + +The bundled transcription code includes a **TextFlowKit MCP adapter** as a separate source capability. It offers job-based `transcribe_media`, `get_transcript`, `list_jobs`, `get_job_status` and `export_transcript`, and additional tools declared in that adapter. It uses stdio first and optional Streamable HTTP, with the MCP SDK as an optional extra. It is not automatically launched, authenticated as Townlight staff or accepted as a Townlight product MCP deployment. This documentation does not add such a service. + +For a transcription client already provisioned separately, an illustrative tool call is: + +```json +{"name":"get_job_status","arguments":{"job_id":"synthetic-existing-job-id"}} +``` + +Use a job ID returned by that transcription service. This example does not create a Townlight record or bypass its review/Records handoff. The exact optional adapter tool signatures are supplied in the [MCP source reference](docs/beta-1/reference/mcp.html). Station meeting capture does not become live speech recognition because this optional donor adapter exists. + +## Security and permissions + + +Use your own named account and save before leaving a screen. A saved draft is durable; unsaved form text may not be. If a write has an unknown result, reopen its record before repeating it. + +Read source jurisdiction, dates, citation, version and visibility. A copied source hash identifies exact bytes, not their legal applicability. If a source changes or permission is removed, resolve the source problem rather than substituting stale cached content. + +Keep originals and derivatives separate. Review the intended audience before export. A public summary excludes private fields only through the applicable copy contract and your review. A renamed private packet is still private content. + +Drafting, review, approval, attachment, export, fulfillment and publication are separate operations. A Townlight workpaper does not itself adopt law, issue a permit, impose a fine or release a records response. The responsible staff member records the applicable decision. + +The native session is validated and mapped to a persisted SQL identity. An editable actor/reviewer label is not authentication. Product/module permissions and source visibility apply at the server boundary. Revoked/unavailable authority fails closed for new Station operations; a previous permission result is not a perpetual authorization. + +Use protected local folders, account permissions and credential storage. Never include the native session file, database passwords, provider keys or unredacted support bundles in a public issue or generated public documentation. A local public view is not automatically a secured internet deployment. Keep network exposure and real equipment acceptance specific to the chosen beta site. + +## Backup recovery and maintenance + +Save work and use Core’s canonical **Backup Now** before maintenance. That operation stops writers. Preserve the coherent profile/database/document backup and its receipt, then use **Start** to resume. A source export is not a full backup. + +Use **Restore Latest Backup** through the supported controls. If the result says **Restore needs service start**, use **Start**, then **Check**, and reopen a known record. Do not repeat restore merely because services need to start. The fresh-profile acceptance verified that a fulfilled request survived restore and a post-backup marker did not. + +Keep Station’s dedicated database and media evidence together in its own backup. Core’s native-profile backup must not be assumed to include an external Station data directory. Stop writers during a coordinated backup. Preserve failed media attempts and logs. + +On failure, record the time, selected composition, component/installer versions and exact message. Check System Health for stopped, starting, ready or failed dependencies. Use the existing Retry control after readiness; do not create duplicate business records to refresh a stale view. Share only a redacted diagnostic bundle. Preserve secrets, original evidence, recovery material and unrelated installations. + +## Troubleshooting + +| Symptom | Likely meaning | Next action | +| --- | --- | --- | +| Workspace absent | Wrong product composition or unavailable canonical runtime. | Check selected composition; activate through Finish Records Migration; wait for readiness. | +| Cannot sign in / 401 | Missing or expired named account session. | Sign in normally; reopen a Station launch ticket if applicable. | +| Permission denied / 403 | Account, module, source or browser-origin permission. | Ask the authorized administrator to inspect the intended permission; do not invent role headers. | +| Save conflict / 409 | The saved revision, expected source hash or lifecycle changed. | Keep edits, reopen current state and reconcile deliberately. | +| Invalid input / 422 | Required field, format, geometry, source envelope or state is invalid. | Read the field detail and correct the input/source; preserve originals. | +| Service unavailable / 503 | Database, schema, connected source or configuration unavailable. | Inspect System Health and the named dependency. Preserve work; retry only after readiness. | +| Export refused | Missing exact review, approval, audience or source authorization. | Read the refusal and complete the owning product’s explicit decision. | +| Restore needs service start | The snapshot was restored but services have not resumed. | Use Start, then Check and verify a saved record; do not blindly repeat restore. | +| Ticket expired or used | A launch is one-use and expires after 60 seconds. | Reopen from the signed-in native session; do not replay the old URL. | +| Recording interrupted | Input/worker failed or a live signal was lost. | Retain attempt/logs. Retry eligible file work explicitly; start a new live capture for a live gap. | +| Recording not downloadable | It is not complete or its retained bytes failed validation. | Inspect state and evidence; do not serve a partial attempt as completed media. | + + +## Verified workflows and limits + +| Product | Recorded result | Precisely exercised | +| --- | --- | --- | +| Station | PASS | Actual native staff session and normally created meeting; headless operator live start/stop, decoded generated audio/video, served hash, private Records readback, idempotent locked original and logout. | + + +The following baseline results come from the previously accepted signed candidate’s fresh normal-profile Sandbox exercise: real native IPC/HTTP/PostgreSQL and selected headless controls. All accounts, source bundles and media were synthetic. The guest install/uninstall and recovery passed, and the owned Sandbox stopped. No host installed application or standalone CivicCast was changed. Those baseline receipts are retained for unchanged workflows. The accompanying ACCEPTANCE.md records the separate installed verification and exact identity of this new Station delivery candidate. + +The [workflow matrix](docs/beta-1/reference/workflow-matrix.json) identifies raw receipt filenames. The [evidence index](docs/beta-1/reference/sandbox-evidence-index.json) retains their original hashes; raw receipts remain in the private beta handoff rather than being silently republished with the documentation site. + +The limits remain: actual city field acceptance and equipment/network commissioning; Station automatic provisioning/SCM commissioning; every UI/role combination; field recognition accuracy; and historical in-place upgrades are not certified. They are not five invented feature requirements. Fresh-install controlled beta handoff remains the accepted scope. This package makes no city-deployment, publication or general-availability claim. + +## Terms of service and license + +### Scope and status + +These terms describe the Townlight Beta 1 software and this documentation package. This is a locally prepared private beta, not a hosted-service subscription, a city deployment agreement or a public release. No uptime commitment, support response time, indemnity, data-processing agreement or paid service is created by these documents. A separate signed agreement, if any, governs services it actually provides. + +### Software license and rights + +Current Townlight-owned distributions identified in this candidate use **AGPL-3.0-only**. The full license is supplied with this documentation and with the source companion. The license governs rights to run, copy, modify and convey the covered software; these operational terms do not add restrictions to those rights. Historical grants and dependency licenses retain their own terms. CivicCast remains a separate product and is not relicensed by this documentation work. + +When conveying covered software, retain applicable notices and provide the corresponding source and installation/build information required by the license. For a modified version supporting remote network interaction, follow section 13’s source-offer requirement. The companion archive identifies the source for this candidate; a link to a different public branch is not a substitute for the matching source. Read the supplied license for the complete conditions. See the [GNU license reference](https://www.gnu.org/licenses/agpl-3.0.html) and [GNU licensing FAQ](https://www.gnu.org/licenses/gpl-faq.en.html). + +### Data ownership and access + +Importing a document does not transfer its ownership or grant permission to publish it. The operating organization controls its accounts, access decisions, lawful source use, retention and review/release policy. Keep resident information, credentials, private notes and restricted evidence in their authorized locations. Documentation examples contain fictional data. No real city account, credential or record is required to exercise these examples in an isolated test environment. + +### Local operation and external processors + +The accepted beta workflow is local and uses named staff accounts. Station has separate storage and credentials. Configure backup destinations and optional model/network providers deliberately. A configured external provider may receive submitted prompts, images or audio according to that configuration and provider’s terms; this documentation does not promise that every optional configuration is offline. An email outbox or local public view does not establish external delivery or an internet deployment. This static documentation site has no analytics, account collection or remote font dependency. + +### Staff decisions and source applicability + +Staff verify the jurisdiction, source currency, permissions, citations and proposed audience. Model output and generated guidance require review. No draft is automatically an official legal interpretation, zoning determination, permit approval, fee assessment, enforcement notice or records-release decision. Official permit fee authority remains with the adopted source and responsible organization; imported amounts do not become a new authoritative calculation. + +### Beta operation and recovery + +Use the identified candidate in its supported fresh-install scope. Preserve backups and original evidence. Test physical equipment and chosen network/service configuration before relying on them. The supplied acceptance describes selected synthetic workflows, not every screen, vendor, field condition or upgrade. Operators decide whether a particular deployment meets their own operational obligations. + +### Warranty and liability + +The covered software’s warranty and liability conditions are those in sections 15–17 of the supplied AGPL and any applicable separate written undertaking. This documentation creates no additional warranty or limitation beyond those terms. Third-party software is subject to its retained license notices. Nothing here removes rights that applicable law makes nonwaivable. + +### Support and incident reporting + +Use the project’s existing SUPPORT and SECURITY guidance for its matching repository. Report reproducible behavior with the version, operation and redacted logs. Do not put credentials, resident records or unredacted evidence in a public issue. Coordinate sensitive reports through the channel designated in SECURITY. No new support address or service commitment is invented here. + +### Ending a beta exercise and document changes + +When an organization ends testing, it controls retention/export and removes access according to its policy. Uninstall may retain data; back up and inspect the selected removal options. Ending an exercise does not revoke rights already granted by AGPL. Later software/documentation versions must identify their changed candidate and scope; historical receipts retain their original identities. These terms do not claim that a city has accepted a contract merely by reading a manual. + +## Glossary + +| Term | Meaning | +| --- | --- | +| Approval | An explicit authorized decision on the saved text/artifact. It is separate from saving or attachment. | +| Canonical record | The owning product’s retained identity and saved version, rather than an editable copied label. | +| Composition | The selected set of desktop modules; inspections-preview exposes the eight staff products. | +| Corresponding source | The source/build material matching the delivered covered program, subject to its license. | +| Derivative / Records copy | A separately prepared document with its own intended audience and hash. | +| Hash / SHA256 | A fingerprint of exact bytes. It detects change; it does not establish legal authority. | +| Idempotency | Repeating the same identified request has the same intended effect; changing its payload can be refused. | +| IPC | The native desktop command boundary between its browser interface and Rust host. | +| MCP | Model Context Protocol; no direct Townlight product server is enabled by this beta. | +| Original | Retained source bytes. A reviewed derivative does not replace them. | +| Provenance | Source, version, date, actor and relationship information retained with evidence. | +| Revision | An immutable saved version. Later edits do not inherit an earlier review automatically. | +| Snapshot | A fixed audience-specific copy tied to a source/reviewed revision. | +| Station | Townlight’s separate media boundary using a pinned CivicCast-derived engine; standalone CivicCast remains separate. | + + +## Alphabetical subject index + +- **Accounts and authentication** — [Security and permissions](#security-and-permissions). +- **AGPL and source** — [Terms of service and license](#terms-of-service-and-license). +- **API contracts** — [API and integration examples](#api-and-integration-examples). +- **Architecture** — [Architecture](#architecture). +- **Backup** — [Backup recovery and maintenance](#backup-recovery-and-maintenance). +- **Beta version** — [Beta identity](#beta-identity). +- **Configuration** — [Configuration and administration](#configuration-and-administration). +- **Evidence and acceptance** — [Verified workflows and limits](#verified-workflows-and-limits). +- **Fees and official decisions** — [Terms of service and license](#terms-of-service-and-license). +- **First run** — [First run](#first-run). +- **Handoffs and audience** — [Connected workflows](#connected-workflows). +- **MCP** — [MCP and automation boundary](#mcp-and-automation-boundary). +- **Originals and provenance** — [Security and permissions](#security-and-permissions). +- **Recovery** — [Backup recovery and maintenance](#backup-recovery-and-maintenance). +- **Staff procedures** — [Daily workflow](#daily-workflow). +- **Station configuration** — [Configuration and administration](#configuration-and-administration). +- **Technical stack** — [Technical specifications](#technical-specifications). +- **Troubleshooting** — [Troubleshooting](#troubleshooting). + +### Operating subject links + +- **Apply the caption profile** — [Apply the caption profile](#apply-the-caption-profile). +- **Approve and publish local playback** — [Approve and publish local playback](#approve-and-publish-local-playback). +- **Bounds and shutdown** — [Bounds and shutdown](#bounds-and-shutdown). +- **Check playout and commit deliberately** — [Check playout and commit deliberately](#check-playout-and-commit-deliberately). +- **Configure a live input and open the operator** — [Configure a live input and open the operator](#configure-a-live-input-and-open-the-operator). +- **Prepare the normally activated synthetic profile** — [Prepare the normally activated synthetic profile](#prepare-the-normally-activated-synthetic-profile). +- **Provision the Station database once** — [Provision the Station database once](#provision-the-station-database-once). +- **Recover without replaying unknown work** — [Recover without replaying unknown work](#recover-without-replaying-unknown-work). +- **Schedule a recording and interpret its state** — [Schedule a recording and interpret its state](#schedule-a-recording-and-interpret-its-state). +- **Scheduling playout and recovery** — [Scheduling playout and recovery](#scheduling-playout-and-recovery). +- **Start and check the paired processes** — [Start and check the paired processes](#start-and-check-the-paired-processes). +- **Store the independent test configuration** — [Store the independent test configuration](#store-the-independent-test-configuration). +- **Take a live override and return** — [Take a live override and return](#take-a-live-override-and-return). + +## Source and document control + +This edition is authored from the immutable corresponding-source companion, the generated installed-domain schema and the retained workflow receipts. Component version numbers are retained. The private MSI has its own new hash and signing receipt. Public historical pages remain unchanged. + +### Workflow subject index + +- **Capture and stop** — [Daily workflow, step 4](#workflow-4). +- **Choose the input** — [Daily workflow, step 3](#workflow-3). +- **Close and recover** — [Daily workflow, step 8](#workflow-8). +- **Hand off to Records** — [Daily workflow, step 6](#workflow-6). +- **Open the operator** — [Daily workflow, step 2](#workflow-2). +- **Prepare meeting context** — [Daily workflow, step 1](#workflow-1). +- **Review recording evidence** — [Daily workflow, step 5](#workflow-5). +- **Use playout deliberately** — [Daily workflow, step 7](#workflow-7). + +- [Source inventory and file hashes](docs/beta-1/reference/source-inventory.json) +- [All component metadata](docs/beta-1/reference/component-metadata.json) +- [Installed domain OpenAPI](docs/beta-1/reference/desktop-domain-openapi.json) +- [Workflow matrix](docs/beta-1/reference/workflow-matrix.json) +- [Full AGPL text](docs/beta-1/reference/AGPL-3.0.txt) + + +## Completed recordings on YouTube and live CivicCast coverage + +This source extension adds only completed-recording YouTube uploads and a live +Station-to-CivicCast feed. It is **not in the published Beta 1 installer**. Existing +component versions are retained. New Station code is AGPL-3.0-only. The pinned +CivicCast source and third-party licenses remain unchanged. Standalone CivicCast +is a separate product; no installer, account, database, service or default in it +is changed by Station. + +### Staff workflow + +For live coverage, choose a meeting, its chamber input and the administrator's +**CivicCast live feed** option, then start recording. Choose **Recording only** +to capture privately without a network feed. A disconnected receiver does not +stop the recording. Station sends the live MPEG-TS bytes as the recording grows; +it does not wait for the completed file. The feed is available only during that +capture. The CivicCast/PEG operator selects that source and controls when it is +broadcast on local cable. Station does not automatically put the PEG channel on +air. `sending` means transport bytes were sent, not proof of cable carriage. + +After Station shows **complete**, use **Upload completed recording to YouTube**. +Review the title, select private/unlisted/public visibility (default **private**), +and enter the approval note. Click **Upload to YouTube**. This is an explicit +external upload to the Station-configured OAuth account. No upload occurs just +because recording stopped, a playout was committed or a Records attachment was +made. Station does not create a YouTube livestream. + +The upload receipt shows queued/running/uploaded/failed/needs-reconciliation, +the chosen visibility and returned video link. `uploaded` is the YouTube upload +acknowledgement; YouTube may still be processing the video. The canonical +recording remains private and byte-identical for the existing Records handoff. +The YouTube visibility is separate from local playback/disclosure approval. + +### Architecture + +Station live feed to separate CivicCast and completed recording upload to YouTube + +The sender has bounded, leaky buffers and follows the live edge after congestion. +Its network sink shares no pipeline with the recorder. A late join or connection +loss can leave a live coverage gap, while the private recording continues. +H.264/AAC and existing MPEG-TS captions are forwarded without another encode. +The MP4 upload remux reuses `vod_job.py`; it does not generate transcripts or +captions, and does not upload a separate caption track. Upload queue work runs +in a separate process so a long upload never monopolizes the capture worker. + +### Administrator setup + +Use Station's existing dedicated data root and PostgreSQL database. Stop Station +writers for a coordinated backup, retain that backup, and run the explicit +`townlight-station migrate` before starting this source version. Schema **4** adds +`station.youtube_uploads`, keeping existing recording/schedule/playout evidence. +The data identity marker and component versions are unchanged. Old services +expect schema 3; use a matched source/runtime and preserve the backup for rollback. + +Create `civiccast-feeds.json` in the private Station data directory: + +```json +[ + { + "id": "peg", + "label": "CivicCast council feed", + "address": "192.0.2.10", + "port": 10080, + "secret_env": "TOWNLIGHT_STATION_SRT_PEG" + } +] +``` + +The address is a numeric IPv4 **local interface bind address on Station**, not the +CivicCast computer. `192.0.2.10` is a documentation placeholder. Use the actual +Station interface, an unused port (1024–65535), and appropriate network access +between those two systems. Clients select an administrator-defined ID, never an +arbitrary destination or media pipeline. Keep configuration files private. + +Set `TOWNLIGHT_STATION_SRT_PEG` in the capture worker's process environment to a +10–79 character SRT passphrase. Configure a separate CivicCast SRT live source +with the caller URI `srt://:10080?mode=caller&latency=200` and the +same passphrase through CivicCast's existing credential control. Do **not** put +the passphrase in the URI. Station's listener uses 128-bit SRT encryption. +Keep the two accounts and configuration stores separate; matching this specific +transport credential is the deliberate pairing. Site-specific camera, headend +and firewall commissioning remain deployment work. + +For completed uploads, configure these **Station-only** environment variables in +the upload worker process. Obtain OAuth authorization for the intended Station +YouTube channel/account through the existing deployment's Google configuration; +no OAuth onboarding framework is added here. Do not use CivicCast's credentials +implicitly or copy its profile. + +- `TOWNLIGHT_STATION_YOUTUBE_CLIENT_ID` +- `TOWNLIGHT_STATION_YOUTUBE_CLIENT_SECRET` +- `TOWNLIGHT_STATION_YOUTUBE_REFRESH_TOKEN` (authorized for YouTube video uploads) + +Run the existing `serve` and capture `worker`, plus the separate upload consumer +with the same Station settings and dedicated database: + +```powershell +townlight-station migrate +townlight-station serve +# In separate managed processes with the same explicit Station configuration: +townlight-station worker +townlight-station uploads +``` + +These are deployment commands, **not commands executed against installed apps +by this development task**. Run only one capture worker and one upload worker per +database. Each holds a distinct advisory lock; media children require the existing +Windows job containment. The recorder child gets no provider credentials; the +SRT child receives only its explicit transport passphrase plus the existing +runtime allowlist. The upload worker reads only the Station OAuth variables. +OAuth/upload HTTP is restricted to Google HTTPS hosts; redirects are not followed. +The pinned donor import is checked against Station's declared media source. + +### HTTP API and examples + +All `/v1` operations below require the existing current Townlight staff session +header (`X-Townlight-Session`) or the existing same-origin operator session. Read +roles can inspect receipts. Starting live feed/upload/retry requires the existing +Station `capture` capability. No new login, role system or MCP server is added. + +| Method and route | Purpose | +| --- | --- | +| GET `/v1/civiccast-feeds` | Capture-authorized list of configured IDs and labels; no transport credentials | +| POST `/v1/recordings` | Existing capture contract plus optional `civiccast_feed_id`, allowed only with `live_source_id` | +| POST `/v1/recordings/{recording_id}/youtube` | Queue one explicit completed-recording upload | +| GET `/v1/youtube-uploads` | Read-authorized latest 100 durable upload receipts | +| POST `/v1/youtube-uploads/{upload_id}/retry` | Capture-authorized retry of a **preparation** failure only | + +Station's generated `/openapi.json` includes the new routes and request schemas. +Example bodies (use real canonical IDs from the selected deployment): + +```json +{ + "meeting_id": "11111111-1111-4111-8111-111111111111", + "agenda_ids": [], + "live_source_id": "chamber", + "civiccast_feed_id": "peg", + "idempotency_key": "council-live-2026-10-30" +} +``` + +```json +{ + "title": "City council meeting — 30 October 2026", + "privacy": "private", + "approval_note": "Reviewed completed recording for upload", + "idempotency_key": "council-vod-2026-10-30" +} +``` + +Upload titles are 1–100 characters; control characters and angle brackets are +rejected. Visibility is private/unlisted/public; approval note 3–500 characters; +key 1–100 characters. Repeating the same key returns the same intent, a changed +request conflicts, and another key cannot duplicate an existing recording upload. +A missing/uncompleted/tampered recording is rejected before upload admission; +the worker independently verifies the recording hash before remuxing/sending. +Retained receipts include approving actor, note/time, recording hash, MP4 path/ +hash/size, chosen title/privacy and provider video ID/URL after acknowledgement. +No OAuth token, passphrase or donor credential pointer is stored in receipts. + +### Recovery and limits + +A failed preparation (for example missing Station OAuth configuration or failed +remux) is `failed`; correct the cause and explicitly call its retry route. The +prior attempt files remain retained. Once any external request begins, an error +is conservatively `needs-reconciliation`. A worker restart also moves interrupted +`running` uploads to that state. There is no automatic retry that could create a +duplicate YouTube video. Check YouTube Studio and the retained job before a human +chooses another external action. This increment provides no automatic remote +reconciliation/delete/reupload control. A valid uploaded link is retained even +if the capture worker is restarted. The existing recording/Records path does +not depend on the external upload succeeding. + +Live sender state is in the recording's `details.civiccast_delivery`; its final +byte count and per-attempt status/log files stay with the private recording. +On capture-worker restart, an interrupted feed is marked interrupted rather +than left appearing to send. Stop/reap is bounded even if the network child hangs. +No feed is automatically re-aired after recovery. + +### Verification and release status + +`tests/accept_deliveries.py` exercises the real Station API/store/media/remux, +CivicCast's pinned SRT source adapter and real YouTube file-upload client using a +disposable PostgreSQL cluster, generated audio/video, synthetic staff authority +and `httpx.MockTransport` for Google. No city systems or external publication +are involved. `tests/accept_delivery_ui.cjs` drives the actual compiled operator +controls in headless Chromium with synthetic API responses. Existing boundary/ +operations checks and TypeScript compilation also apply. + +Example invocation from a development environment with existing dependencies: + +```powershell +$env:PYTHONPATH = (Resolve-Path ./beta-1).Path +$env:STATION_TEST_PG_BIN = 'C:/test-tools/postgres/bin' +$env:STATION_TEST_MEDIA_RUNTIME = 'C:/test-tools/station-media-runtime' +python -B ./beta-1/tests/accept_deliveries.py C:/test-output/station-deliveries-new +``` + +Use a **new** output directory; the script starts/stops only its owned disposable +cluster and children. See the task's retained acceptance receipts for actual +results. This evidence establishes the new source wiring synthetically. It does +not replace CivicCast's already established real YouTube delivery evidence, nor +claim a new real YouTube upload, physical cable broadcast, signed installer or +Sandbox acceptance of this extension. Published Beta 1 artifacts stay unchanged. + + +## Delivery subject index + +- [CivicCast live feed](#completed-recordings-on-youtube-and-live-civiccast-coverage) +- YouTube: explicit completed recording upload; visibility; receipt and reconciliation. +- Schema4: durable upload intent; existing evidence retained. diff --git a/docs/beta-1/index.html b/docs/beta-1/index.html index ee41f73..faa792b 100644 --- a/docs/beta-1/index.html +++ b/docs/beta-1/index.html @@ -1 +1 @@ -Townlight Core | Townlight Beta 1
townlightTownlight Beta 1
Townlight Core · Townlight Beta 1

A shared foundation for accountable municipal work.

Core provides the shared contracts, ingestion, identity helpers, task infrastructure and recovery foundation used by Townlight. Staff encounter these capabilities through Setup, Settings and System Health. Business decisions stay with their owning product.

townlight-core 1.3.0.dev2AGPL-3.0-onlyPrivate beta · Windows fresh-install scope
For IT administrators and platform maintainers

What the workflow delivers

  1. Complete setup. Choose folders and the full product composition. Create the city profile and the first named administrator. Choose a protected backup location. Defer optional local AI if it is not needed.
  2. Activate the runtime. Run the first-run health check, wait for readiness and open Townlight. In System Health select Finish Records Migration to activate the canonical Python and PostgreSQL services. A running process alone is not a ready database.
  3. Create staff access. Use Settings to create named staff. Sign out and confirm that staff can sign in with their own account. Keep administrator privileges with people responsible for setup; ordinary staff cannot administer users.
  4. Import through the right product. Use the source library of Code, Zoning, Planning or Permitting. Inspect provenance and permissions there. Core ingestion helpers do not bypass the owning product’s source review.

Connected evidence

All products use selected Core contracts. Core does not create unrestricted access between products. Access and Notice provide the bounded staff workflows described in their current manuals; installed acceptance remains pending.

Know the beta boundary

Shared catalog, exemption and module-generator code exists in this private candidate. It is not a centrally hosted federation service. A business product still owns its decisions, identity mapping and permission checks. Historical placeholder ADRs are retained as history, rather than descriptions of the current implementation.

Architecture

Where the evidence goes

Townlight Core architecture and evidence flow

All products use selected Core contracts. Core does not create unrestricted access between products. Access and Notice provide the bounded staff workflows described in their current manuals; installed acceptance remains pending.

Evidence rather than promises

Candidate installed acceptance remains pending.

Earlier releases have their own first-run and synthetic Windows Sandbox evidence. This changed source candidate requires a new signed installer and installed acceptance. This is not a claim that every screen, vendor, upgrade or city equipment configuration has been certified.

Read the exact acceptance and limits →

Ready to evaluate?

Begin with the current manual; obtain this candidate only after its exact installer and acceptance are identified. Configure the chosen test site and have its staff review source applicability and run the existing workflows.

\ No newline at end of file +Townlight | Townlight Beta 1
townlightTownlight Beta 1
The connected municipal suite · Townlight Beta 1

Municipal work with a clear record.

Connected municipal products help staff prepare, review and retain municipal work. Start with a controlled private beta, keep original evidence, and make each official decision deliberately.

Suite candidate 1.7.0.1; installed acceptance pendingAGPL-3.0-onlyBeta evaluation · Windows fresh-install scope
The product family

The kept products and their connected workflows.

Designed around the record

Prepare, review, hand off.

Keep source versions and original hashes connected to staff work. Select the intended audience, review the saved revision, and explicitly attach the resulting evidence. Records retains the final response and release decisions.

A practical beta deployment

The selected Townlight desktop composition includes Access and Notice staff workspaces alongside the existing municipal workflows. Station is a separately configured capture and media service. Standalone CivicCast keeps its own product, installation and data.

The changed candidate still requires a new signed installer and exact installed acceptance before distribution. This documentation site does not provision a hosted city portal.

Architecture

The suite and its boundaries

Townlight architecture and evidence flow

Native staff workspaces use canonical Python/PostgreSQL services. Station has a separate database, media store and explicit Townlight authority.

Evidence rather than promises

Candidate installed acceptance remains pending.

Earlier releases have their own first-run and synthetic Windows Sandbox evidence. This changed source candidate requires a new signed installer and installed acceptance. This is not a claim that every screen, vendor, upgrade or city equipment configuration has been certified.

Read the exact acceptance and limits →

Ready to evaluate?

Begin with the current manual; obtain this candidate only after its exact installer and acceptance are identified. Configure the chosen test site and have its staff review source applicability and run the existing workflows.

Station delivery update

Live cable coverage and recorded video delivery

Station offers an encrypted live SRT feed to separate CivicCast while recording. The PEG operator controls cable broadcast. Completed recordings can be explicitly uploaded to YouTube with a reviewed title and chosen visibility. The private Records original stays intact.

Setup, staff steps and API examples

\ No newline at end of file diff --git a/docs/beta-1/manuals/access.html b/docs/beta-1/manuals/access.html new file mode 100644 index 0000000..bdfd729 --- /dev/null +++ b/docs/beta-1/manuals/access.html @@ -0,0 +1,528 @@ + + +Townlight Access Manual | Townlight candidate + +
Townlight +
+

Naming, Access and Notice source candidate · 2 November 2026

+

Prepared documentation. Build, signing, installed acceptance and publication remain pending.

+ + +

+

Townlight Access User Manual

+

Windows staff workflow — +0.5.0 candidate

+

This candidate is prepared; exact signed-installer acceptance is +pending. It supports a fresh profile only. Keep the previous release +with any existing unmarked profile. The compatibility profile directory +remains %LOCALAPPDATA%\CivicSuite; the new program refuses +to adopt existing unmarked city data.

+
    +
  1. Sign in with an account allowed to use Access and enable the Access +capability. Open Accessibility and enter the actual source title, text, +language and image-description information.
  2. +
  3. Save the review. Reopen it to inspect the source, deterministic +findings and any saved local-model advice, model identity and outcome. +Advice is not a certified accessibility finding or approval.
  4. +
  5. For plain-language or translation work, enter the actual source and +request a draft. The Windows path uses the suite’s configured local +model. Saved drafts retain source/output, language, model/outcome, staff +actor/time and the requirement for qualified human review. An +unavailable-model sample is labeled as a sample; it is not a translation +of the input.
  6. +
  7. Reopen saved drafts from Access, including after restarting the app. +Select Export record on the desired review or draft. The desktop writes +a Markdown record and verifies its content hash and companion manifest +before reporting completion. The fenced JSON is the complete record, +including source, output/advice and relevant provenance; ordinary HTML +rendering is unnecessary to read it.
  8. +
  9. To hand the record to Records, open the intended Records request, +attach the actual exported Markdown file using Records’ native file +picker, and read it back from that request. A successful Access export +alone does not attach evidence to a request or authorize disclosure. +Records permissions and review/release rules still apply.
  10. +
+

The complete review export includes reviewed source, findings, saved +advice/model/outcome where available, actor/time, relevant audit history +and advisory limits. Draft exports include the retained source/output +pair and review status. Back up the complete profile using System Health +and restore only a matching new-format backup. Preservation of these +additions on the actual installed candidate remains part of +acceptance.

+

No automated result certifies ADA compliance, creates an +accessible/tagged PDF, approves publication or replaces a qualified +translator or ADA coordinator.

+

Standalone support service

+

The separately run FastAPI service provides deterministic checks and +planning helpers. Its Spanish and Vietnamese responses are fixed +samples, not translations of the supplied source. Its +deterministic jargon substitutions are separate from the Windows model +workflow. A shared write token proves possession of that token; it does +not establish an individual staff identity. Standalone audit records use +shared-token-staff for that reason.

+

Standalone saved-review exports now return a complete Markdown +artifact with source, findings and relevant audit provenance, plus its +SHA-256. The staff page offers that actual artifact for download. Other +form, tagged-PDF, ADA and publishing helpers remain checklists. The +standalone service does not acquire Windows draft persistence or native +individual-account identity merely because it shares this package.

+

Version 0.5.0 · prepared candidate; installed acceptance +pending Townlight Access is the accessibility, plain-language, +multilingual, and ADA Title II review-support module for Townlight.

+

This manual has two parts. Read the one that fits your role:

+ +
+

Part 1 — For Civic Staff

+

+

What Townlight Access is for

+

Townlight Access helps your office put out public notices, forms, and +documents that everyone can read — and keep a clean +record proving you checked. It is a staff tool that gives advice and +does the busywork; you and your ADA coordinator always make the +final call.

+

What you can do with it

+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
You want to…Townlight Access gives you…
Know if a notice is hard to readA check that flags missing titles, images without descriptions, and +dense wording — each with a specific fix
Cut the jargonA plain-language rewrite (e.g. “remit payment prior to the deadline” +→ “pay before the deadline”)
Reach non-English readersWindows local-model drafts for qualified review; fixed standalone +samples do not translate input
Publish an accessible form or PDFA checklist of what an accessible form or tagged PDF needs
Handle an ADA Title II reviewA step-by-step review-support checklist
Answer a records requestA saved, exportable record of every review, with provenance +(individual staff identity in Windows; shared-token identity in the +standalone service)
+

How you’ll use it day to day

+

There are two places to work, and the difference matters:

+
    +
  • The public checker is for trying things out — it +forgets everything when you leave.
  • +
  • The staff workspace is for keeping a permanent, +official record you can produce later.
  • +
+

Your IT team will give you the link to each.

+
    +
  1. Open the public checker. Paste in a draft notice +and run the check. You’ll get a list of plain-language fixes — nothing +is saved, so it’s a safe place to experiment.
  2. +
  3. When you’re ready to keep a review on the record, open the +staff workspace and enter the staff password your IT +team gave you (a one-time setup). Save the review — it goes into your +Townlight records with a time-stamp of who saved it and when.
  4. +
  5. From the staff workspace, export a records-ready +package for any saved review — ready to hand to a +public-records request.
  6. +
+

+

What Townlight Access will +not do

+

Townlight Access is a tool for your staff, not a rubber +stamp. It does not:

+
    +
  • give legal advice,
  • +
  • certify ADA compliance,
  • +
  • issue official translations, or
  • +
  • publish anything on its own.
  • +
+

A qualified human — your staff, an ADA coordinator, a translator, +legal counsel — always reviews and approves before anything goes public. +Translations it drafts are starting points for a human +translator, never the final word.

+

Where it stands today

+

This is v0.5.0, an early release we’re being upfront +about. It’s solid enough to evaluate and pilot, but it is not a +finished 1.0 and not a compliance guarantee. (An earlier +v1.0.0 was published by mistake; we pulled it back to an +honest sub-1.0 label rather than overstate where the product is.)

+
+

Part 2 — For IT & Technical +Staff

+

Overview

+

Townlight Access is a deterministic FastAPI service, +written in Python and pinned to the published Townlight Core +1.3.0.dev2 release wheel. It performs rule-based accessibility +checks — no LLM/model calls, no network calls — so +output is reproducible and the service is cheap to run. It ships as one +module inside Townlight Windows Local, a Tauri/WebView2 +desktop application, and is also runnable standalone for +development.

+

Deployment architecture

+

In Townlight Windows Local, a Tauri supervisor +starts a bundled Python host (running Townlight Access alongside peer +modules) and a bundled PostgreSQL instance on +127.0.0.1:15432. The supervisor injects a +DATABASE_URL into each module service; Townlight Access +stores its data in a dedicated townlight_access schema in +that shared cluster. The supervisor’s backup copies the entire data +directory (including the Postgres cluster), so Townlight Access data is +captured with it.

+
flowchart TB
+  Resident["Resident<br/>(browser)"] -->|"public, read-only"| Pub["/townlight_access"]
+  Staff["City staff<br/>(browser)"] -->|"WebView2 UI"| StaffUI["/townlight_access/staff"]
+
+  subgraph Sup["Tauri supervisor — local machine only"]
+    CA["Townlight Access<br/>(FastAPI)"]
+    Peers["Peer modules<br/>Townlight Meetings · Townlight Code · Townlight Notice · …"]
+    PG[("Bundled PostgreSQL<br/>127.0.0.1:15432")]
+  end
+
+  Pub --> CA
+  StaffUI --> CA
+  CA -->|"DATABASE_URL → townlight_access schema"| PG
+  Peers --> PG
+  CA -->|"depends on"| Core["Townlight Core 1.3.0.dev2"]
+  CA -. "records-export hand-off" .-> Records["Townlight Records"]
+  Sup -. "wholesale backup of Data/ (incl. Data/postgres)" .-> Backup[("Backup folder")]
+

Request & trust model

+

There are two surfaces with deliberately different trust levels:

+
    +
  • Public (/townlight_access → +POST /api/v1/townlight_access/analyze): stateless. Anyone +can analyze content; nothing is persisted and no token is +required.
  • +
  • Staff (/townlight_access/staff → +POST .../review, +POST .../reviews/{id}/records-export): persistent. Every +write requires the trusted-write token.
  • +
+
sequenceDiagram
+  participant R as Resident (public)
+  participant S as City staff
+  participant CA as Townlight Access
+  participant DB as PostgreSQL (townlight_access schema)
+
+  R->>CA: POST /analyze (no token)
+  CA-->>R: findings + fixes (nothing saved)
+
+  S->>CA: POST /review + X-Townlight-Access-Write-Token
+  Note over CA: constant-time token check<br/>403 if invalid · 503 if unconfigured
+  CA->>DB: insert review + audit row (one transaction)
+  CA-->>S: saved review_id + findings
+
+  S->>CA: POST /reviews/{id}/records-export + token
+  CA->>DB: write audit_events row
+  CA-->>S: records-ready export
+

Persistence & configuration

+

Townlight Access resolves its review store in this order:

+
    +
  1. TOWNLIGHT_ACCESS_REVIEW_DB_URL — explicit override (a +dev SQLite path or a pre-built Postgres URL).
  2. +
  3. DATABASE_URL — the supervisor-injected async URL +(postgresql+asyncpg://…:15432/…), converted to a +synchronous psycopg2 URL. This is the default under the desktop +runtime.
  4. +
  5. SQLite dev fallback — +data/townlight_access-reviews.db under +TOWNLIGHT_ACCESS_DATA_DIR (default: ./data), +used only when neither variable is set.
  6. +
+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + +
VariablePurpose
DATABASE_URLShared Townlight Core PostgreSQL (set by the supervisor) — the +production default
TOWNLIGHT_ACCESS_REVIEW_DB_URLExplicit SQLAlchemy URL override
TOWNLIGHT_ACCESS_DATA_DIRDirectory for the SQLite dev fallback
TOWNLIGHT_ACCESS_TRUSTED_WRITE_TOKENRequired server secret for persistent writes
+

townlight_access-db-status (console script) preflights a +database with an explicit URL.

+

Data model

+

Three tables live in the townlight_access schema +(translated to the default schema on SQLite). Schema setup is +non-destructive (CREATE SCHEMA IF NOT EXISTS + +metadata.create_all); the applied migration id is +townlight_access-windows-local-state-v1.

+
erDiagram
+  accessibility_review_records {
+    string   review_id PK
+    string   title
+    text     body
+    bool     has_alt_text
+    string   language
+    string   status
+    json     findings
+    text     disclaimer
+    datetime created_at
+  }
+  audit_events {
+    string   event_id PK
+    string   action
+    string   subject_id "soft ref → review_id"
+    string   actor
+    datetime created_at
+  }
+  schema_migrations {
+    string   schema_version PK
+    datetime applied_at
+  }
+

HTTP API

+ ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Method & pathAuthPersists?Purpose
GET /—noModule status and boundaries
GET /health—noPackage + Townlight Core version
GET /ready, +GET /api/v1/townlight_access/readiness—noPersistence readiness gate
GET /townlight_access—noPublic accessibility checker (UI)
GET /townlight_access/staff—noStaff workspace (UI; never embeds the token)
POST /api/v1/townlight_access/analyze—noStateless accessibility analysis
POST /api/v1/townlight_access/reviewtokenyesSave a review record (+ audit)
GET /api/v1/townlight_access/reviews—noList saved reviews
GET /api/v1/townlight_access/reviews/{id}—noRetrieve a saved review
POST /api/v1/townlight_access/reviews/{id}/records-exporttokenyes (audit)Records-ready export (+ audit)
GET /api/v1/townlight_access/integration-contracts—noPublished integration contracts
POST /api/v1/townlight_access/plain-language—noDeterministic plain-language rewrite
POST /api/v1/townlight_access/language-variant—noMultilingual draft variant (human-review flagged)
POST /api/v1/townlight_access/forms—noAccessible form publication checks
POST /api/v1/townlight_access/publishing-workflow—noStaff publication workflow steps/blockers
POST /api/v1/townlight_access/ada-title-ii—noADA Title II review-support checklist
POST /api/v1/townlight_access/tagged-pdf—noTagged-PDF heading expectations
POST /api/v1/townlight_access/export—noRecords-ready export checklist (stateless)
+

Token-guarded writes require the +X-Townlight-Access-Write-Token header matching +TOWNLIGHT_ACCESS_TRUSTED_WRITE_TOKEN (compared in constant +time). Missing/invalid → 403; guard not configured → +503 (fails closed). The server token is never embedded in +served HTML — the staff page provides a field where an operator pastes +it; it is kept only in the browser session.

+

Security

+
    +
  • Authentication boundary: persistence-write routes +require the trusted-write token; read and stateless-analysis routes are +open. The desktop supervisor binds the service to the local +machine.
  • +
  • Audit trail: every persistent write/export writes +an audit_events row (action, subject, actor, timestamp). +review.create is committed atomically with the review +record.
  • +
  • Determinism: no model/LLM calls and no outbound +network calls; checks are pure functions.
  • +
  • Backups: review and audit data live in the shared +Postgres cluster, captured by the supervisor’s wholesale +Data/ backup. Durability is covered by the test suite (a +Postgres reconnect round-trip for the default store; a SQLite file +backup/restore round-trip for the dev fallback).
  • +
+

Operations

+

Readiness: poll GET /ready (or +/api/v1/townlight_access/readiness) — ready +when the schema can be created and verified.

+

Local verification (mirrors CI; the release gate requires a real +PostgreSQL):

+
python -m pip install https://github.com/townlight/core/releases/download/v1.2.0/townlight_core-1.2.0-py3-none-any.whl
+python -m pip install -e ".[dev]"
+# Release gate (requires Postgres):
+export TOWNLIGHT_ACCESS_POSTGRES_TEST_URL="postgresql+psycopg2://USER:PW@HOST:PORT/DB"
+bash scripts/verify-release.sh
+

Integration

+

Townlight Access depends on Townlight Core; +Townlight Core does not depend on Townlight Access. It publishes +integration contracts at +/api/v1/townlight_access/integration-contracts, hands +records exports to Townlight Records, and provides +accessibility support to downstream publishers (zone, plan, permit, +inspect, grants, procure).

+

Release status

+

v0.5.0 is an early release. Probe gaps #1–#4 (clean +install, staff/public authz, audit logging, backup/restore durability) +are closed with evidence (see PROBE-PROGRESS.md). City-core +membership (desktop registry record + 6-module profile) and a clean-VM +accessibility acceptance pass are later phases. The earlier +v1.0.0 tag was published in error and is retained only as +historical evidence.

+
Townlight · AGPL-3.0-only · Candidate evidence applies only to its identified artifacts.
\ No newline at end of file diff --git a/docs/beta-1/manuals/code.html b/docs/beta-1/manuals/code.html new file mode 100644 index 0000000..d806f1b --- /dev/null +++ b/docs/beta-1/manuals/code.html @@ -0,0 +1,1003 @@ + + +Townlight Code Manual | Townlight candidate + +
Townlight +
+

Naming, Access and Notice source candidate · 2 November 2026

+

Prepared documentation. Build, signing, installed acceptance and publication remain pending.

+ + +

Townlight Code Manual

+

Townlight Beta 1 · Naming candidate documentation +edition 2 November 2026

+

Contents

+ +

Using this manual

+

Townlight Code helps code custodians, clerks, legal reviewers and +staff seeking cited authority. Code imports and preserves municipal code +sources, supplies exact citations and version history, and connects +proposed legislation to Meetings. Authorized staff separately record +adoption evidence and codification.

+

Staff should begin with First run and Daily workflow. Administrators +should also read Architecture, Technical specifications, Configuration, +Security and Recovery. Developers should use the exact API/data +dictionary and examples. The table of contents and alphabetical subject +index link to the relevant sections in the HTML edition; the PDF +preserves headings and searchable text. An editable Word edition is +included with the same documentation companion.

+

Beta identity

+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IdentityValue
DocumentationTownlight Beta 1 naming, Access and Notice candidate
Intended installer version1.7.0.1; build and acceptance pending
Product componenttownlight-code 1.0.9
Principal import packagetownlight_code
Native desktop source version1.7.0-1
Candidate hashesPending candidate build, signing and installed acceptance
Current owned software licenseAGPL-3.0-only
Acceptance compositionFresh Windows x64 profile; inspections-preview; Station configured +separately
+

The naming change advances this package’s version and requires a new +signed installer and installed acceptance. Those steps and publication +remain pending. Historical tags, receipts and archived manuals keep +their original names and certify only their identified artifacts. Use an +empty database and fresh profile; no in-place legacy upgrade is +supported. The approved Windows profile path remains +%LOCALAPPDATA%\CivicSuite. Preserve existing profiles, data +and recovery material.

+

First run

+
    +
  1. Obtain the identified signed private candidate and its +corresponding-source companion from the beta coordinator. The landing +pages in this documentation are not an installer download service.
  2. +
  3. On the intended fresh Windows test installation, verify the MSI hash +and publisher signature before installing. Preserve unrelated profiles +and recovery material. Installed acceptance for this source candidate +remains pending; no in-place legacy upgrade is supported.
  4. +
  5. Launch Townlight under the intended named Windows account. Choose +the storage folders. Select Townlight Inspections +candidate (inspections-preview) for the bounded +desktop composition, including Access and Notice. A narrower default +selection will not expose all workspaces.
  6. +
  7. Enter the city profile, time zone and contacts. Create the first +named local administrator, sign in and choose protected backup storage. +Continue without local AI is valid for the +deterministic workflows.
  8. +
  9. Run Health Check and wait for readiness. Open Townlight. In System +Health select Finish Records Migration to activate the +canonical Python/PostgreSQL runtime. Do not fabricate migration receipts +or seed accounts.
  10. +
  11. Create named staff through Settings. Import authorized sources using +each product’s source library. All examples in this package are +synthetic; they are not municipal authority.
  12. +
  13. Provision Station separately if it is part of the beta exercise. +Selecting the desktop composition does not start or configure Station. +Configure vision explicitly only if automatic photo drafting is +selected.
  14. +
+

Daily workflow

+

+

1. Import a source

+

Inspect the complete bundle JSON for jurisdiction, section +identifiers, source/effective dates, original name and hashes before +selecting Import. Import submits directly; inspect the saved import and +provenance afterward. There is no separate preview/confirmation +step.

+

+

2. Find the exact section

+

Search the topic and open the cited section. Check the requested +as-of date and version. Keep explanatory wording separate from the +retained source text.

+

+

3. Inspect provenance

+

Read import history, original source and section history. Export the +exact cited source when it is needed for a staff workpaper or Records +evidence.

+

+

4. Connect a proposal

+

Create the existing Code–Meetings connection for the actual proposal +and agenda context. Retain the connection identifier and keep pending +text distinct from adopted code.

+

+

5. Record adoption

+

Record the actual authorized meeting decision with its adoption +context. An unrelated motion, packet or draft minutes does not establish +that the proposal was adopted.

+

+

6. Codify separately

+

Review the adopted text and affected sections, then record the +distinct codification closeout. Preserve prior versions and the link to +adoption evidence.

+

+

7. Share the right version

+

Select permitted source evidence downstream. If visibility or source +content changes, resolve the mismatch and select current evidence rather +than accepting a stale cached citation.

+

Working safely

+

Use your own named account and save before leaving a screen. A saved +draft is durable; unsaved form text may not be. If a write has an +unknown result, reopen its record before repeating it.

+

Read source jurisdiction, dates, citation, version and visibility. A +copied source hash identifies exact bytes, not their legal +applicability. If a source changes or permission is removed, resolve the +source problem rather than substituting stale cached content.

+

Keep originals and derivatives separate. Review the intended audience +before export. A public summary excludes private fields only through the +applicable copy contract and your review. A renamed private packet is +still private content.

+

Drafting, review, approval, attachment, export, fulfillment and +publication are separate operations. A Townlight workpaper does not +itself adopt law, issue a permit, impose a fine or release a records +response. The responsible staff member records the applicable +decision.

+

Connected workflows

+

Receives Meetings decision evidence. Supplies permitted cited +material to Records, Zoning, Permitting and Inspections. Planning’s +selected installed evidence providers are Meetings and Zoning; no +separate direct Code connection is implied.

+ ++++ + + + + + + + + + + + + + + + + +
DirectionMaterial
InputA complete supported source bundle, source and effective dates, +original file hashes and actual meeting adoption evidence.
OutputCited code text and history, exact exports, staff explanations with +source references and an explicit adoption/codification trail.
+

Product boundary

+

An imported document is not automatically adopted law. Local imports +and orchestration do not establish a live agreement with every +commercial codifier. Human approval and authoritative source +applicability remain necessary.

+

Architecture

+
+ + +
+

The drawing shows the principal staff/evidence path. Native commands +carry trusted identity to Python business services; PostgreSQL and +retained original files hold durable state. A downstream copy does not +silently transfer decision authority. Station has its own configured +authority/media boundary, database and mutable files. The +connected-workflow text supplies the drawing’s reading order and +accessibility alternative.

+

Cited +questions summaries and local synchronization

+

Ask against an actual +retained section

+

Import and inspect the complete source bundle first. Import +submits directly; there is no separate preview/confirmation +screen in this Code UI. Check the JSON source envelope before pressing +Import, then inspect its saved import/provenance result.

+

Use the existing question control or authenticated +POST /desktop/v1/code/questions. A synthetic body is:

+
{"question":"What does the retained synthetic section require?","section_number":"18.20.050","as_of":null}
+

The section number must resolve in the imported source, and an +optional as_of must be the intended effective date. Read +the answer and cited retained version together. Missing or ambiguous +authority is a review issue, not permission to invent a section. Save +staff interpretation notes separately from official section text.

+

Draft and approve an +explanatory summary

+

Obtain the actual section ID and version ID from lookup/history. Use +POST /desktop/v1/code/sections/{section_id}/summaries with +section_version_id, summary_text, optional +language_code (default en) and draft status. +For example:

+
{"section_version_id":"synthetic-replace-with-retained-version","summary_text":"Synthetic explanatory draft for staff review.","language_code":"en","status":"draft"}
+

Reopen the section’s summaries, compare the draft with the cited +version, and use the separate +/desktop/v1/code/summaries/{summary_id}/approve operation +only after review. The summary is explanatory material, not a change to +adopted code. An approved summary does not record legislative adoption +or complete codification.

+

Operate the +existing local codifier contract

+

The local synchronization orchestrator exists in the +standalone Code application source. Its +/api/v1/townlight_code/staff/sync/... routes and +/staff/sync page are not mounted merely because the +Townlight desktop Code workspace is enabled. Use them only in an already +configured standalone deployment with genuine staff access. The +role/actor headers in its source are a trusted deployment boundary, not +credentials for an arbitrary client to invent. This guide does not ask +you to deploy another server for the desktop beta.

+
    +
  1. Register the actual official source through that application’s +source registry, preserving its vendor, official URL and source +identity. Retain the returned source_id.
  2. +
  3. Configure +/api/v1/townlight_code/staff/sync/codifier-sources with +that ID, sync_schedule and reviewed +allowlisted_hosts. Use a standard five-field cron +expression no more frequent than every 15 minutes; for example +0 3 * * *. A synthetic configure body is +{"source_id":"replace-with-registered-synthetic-id","sync_schedule":"0 3 * * *","allowlisted_hosts":[]}. +A reviewed intended on-prem host needs its explicit source-specific +allowlist; this does not bypass URL safety.
  4. +
  5. Read the configured source list and /staff/sync. Check +host validation, circuit-breaker state, delta/cursor readiness and +recorded run history. A configured source is not proof of a vendor +network connection.
  6. +
  7. Submit a local complete import payload to +/api/v1/townlight_code/staff/sync/codifier-sources/{source_id}/run. +The body is +{"payload": <complete ImportBundleCreate>, "changed_since": null}. +Use the full synthetic code-bundle example in the reference directory as +the payload, replacing source identity only with a registered synthetic +source from this exercise.
  8. +
  9. Retain the run/import identity, inspect import status, sections, +source hash and recorded cursor/history, and resolve circuit/readiness +refusals before another run. An unknown result requires readback, not +blind resubmission. This operation does not itself fetch every +commercial codifier or automatically codify an ordinance.
  10. +
+

Source contracts: townlight_runtime/code_bridge.py, +townlight_code/main.py, codifier_sync.py and +staff_sync.py. Standalone request signatures and refusals +remain in the Code API source supplement.

+

Technical specifications

+

Runtime and storage

+

The accepted package targets Windows x64 fresh +installation. Its native shell uses Rust 2021, Tauri 2 +and Microsoft WebView2; browser assets are JavaScript built +with Vite 8.1.6. This describes the native desktop +frontend; Station has a separate React operator, specified below or in +its product manual. Canonical business workflows use bundled +CPython 3.13.5, FastAPI, Pydantic, SQLAlchemy and +Alembic, with PostgreSQL 17 / PostGIS and +managed original files. The installed runtime tested here contains +FastAPI 0.162.0. Package minimum Python requirements can differ from the +bundled executable; the metadata reference preserves both. No stack +rewrite is implied by the beta label.

+

The native transport is fixed to loopback +127.0.0.1:15480; PostgreSQL uses the configured local +runtime port (default 15432). Optional local model service +defaults to 127.0.0.1:15434. Those are deployment defaults, +not internet endpoints. The runtime has health, module and readiness +endpoints; readiness is stronger than process existence. The task queue +is the existing local Core task infrastructure, not an assertion that a +separate Redis service is required for this desktop composition.

+

The default native profile is %LOCALAPPDATA%\CivicSuite; +the historical directory name remains part of compatibility. Do not +rename it to Townlight. A configured TOWNLIGHT_PROFILE_ROOT +must be absolute. Local configuration and secrets live under that +profile; protected managed files and database state must be backed up +coherently. Source/runtime identity is distinct from a product’s display +label.

+

Data and consistency

+

Source registry entries; import jobs and originals; sections and +versions; effective-date citations; questions, notes and summaries; +Meetings connections; adoption and codification closeout.

+

Versioned saves use expected prior revision identifiers where +defined. Reopen and reconcile on conflict. Exact exports and handoffs +use source IDs, current visibility, revision and SHA256. Review belongs +to the saved revision and does not transfer silently to edited text. +Database changes use the owning product’s migrations; a request or +readiness check is not an authorization to mutate schema.

+

Capacity and platform +statements

+

This beta has synthetic single-profile workflow evidence. It does not +have a published benchmark for concurrent staff capacity, minimum +RAM/CPU, large-source limits or a field SLA. Do not turn a developer +machine’s specification into a supported minimum. The new installer size +remains pending its build; allow additional disk for extracted runtime, +database, originals, exports, media and backups. Select +equipment/storage after sizing those actual workloads.

+

The exact runtime payload +lock records pinned files, sizes and hashes. The component +metadata records shipped dependency declarations. These references +are more precise than a manually copied dependency list. Third-party and +historical license notices must accompany their matching payloads.

+

Configuration and +administration

+

Native deployment +configuration

+

Use Setup, Settings and System Health for supported staff operation. +Administrators provision folders, backup storage, named accounts and the +city profile. Select inspections-preview for the bounded +desktop composition, including Access and Notice. Station remains a +separate service boundary. Do not use a standalone product’s demo server +as a substitute for the installed workspace.

+

Technical deployments use TOWNLIGHT_PRODUCT_PROFILE, +TOWNLIGHT_PROFILE_ROOT, DATABASE_URL, +TOWNLIGHT_RUNTIME_PORT, PORTAL_MODE and the +runtime-managed secret files. Treat database URLs and native session +proofs as secrets. The installed native domain runtime explicitly +refuses non-loopback binding. PORTAL_MODE=private is the +accepted posture; changing it does not by itself commission an internet +portal, authentication provider or reverse proxy.

+

The isolated documentation exporter sets a fictional profile and +unusable synthetic database origin only to read schemas; those values +are not deployment configuration. Keep deployment values in the intended +process/account scope. An already-running process does not automatically +inherit later environment edits.

+

API and integration examples

+

Native command example

+

The following JavaScript belongs in the existing trusted Townlight +frontend/development environment with invoke imported from +@tauri-apps/api/core. It is not a command for an arbitrary +web page or an instruction for nontechnical staff. IDs must come from +records created in an isolated synthetic exercise.

+
import { invoke } from '@tauri-apps/api/core';
+const result = await invoke('code_domain_request', {request: {operation: 'citation', section_number: '18.20.050', as_of: null}});
+console.log(result);
+

Trusted local HTTP example

+

An administrator/developer can inspect an already-configured isolated +runtime from a trusted local process. This PowerShell example reads the +signed-in synthetic profile’s existing proof into memory; it does not +create a user, seed a session, reveal the proof in output or bypass a +permission check. Do not use real city data in development examples. A +read response does not prove approval or publication.

+
$profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite'
+$sessionPath = Join-Path $profilePath 'config\local-session.json'
+$session = Get-Content -LiteralPath $sessionPath -Raw | ConvertFrom-Json
+$headers = @{ 'X-Townlight-Session' = $session.session_hash }
+Invoke-RestMethod -Uri 'http://127.0.0.1:15480/desktop/v1/code/sources' -Headers $headers
+Remove-Variable session, headers
+

Complete synthetic source +bundle

+

The synthetic +Code bundle is the retained fixture used by the beta staff exercise. +It includes the complete supported source envelope rather than a +shortened pseudo-payload. Keep its fictional source labels. For +Planning, wrap it as +{"bundle": BUNDLE, "expected_previous_revision": null}; for +Permitting use +{"bundle": BUNDLE, "expected_revision": null}. Code and +Zoning take their own complete import envelopes. Replace null with the +current expected revision when revising an existing source, as the +applicable schema requires. These are import examples, not legal +authority or permission to load them into a live city profile.

+

A synthetic write +with subsequent readback

+

This example demonstrates the existing Meetings HTTP contract in an +isolated exercise. It is intentionally fictional. It does not start a +service. Its authentication setup is included so it can be run +independently under the signed-in synthetic account. If a write times +out, inspect current records before repeating it.

+
$profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite'
+$sessionPath = Join-Path $profilePath 'config/local-session.json'
+$session = Get-Content -LiteralPath $sessionPath -Raw | ConvertFrom-Json
+$headers = @{ 'X-Townlight-Session' = $session.session_hash }
+$body = @{
+  title = 'Synthetic documentation exercise'
+  scheduled_start = '2026-11-05T18:00:00-07:00'
+  location = 'Synthetic room'
+  meeting_type = 'regular'
+} | ConvertTo-Json
+$meeting = Invoke-RestMethod -Method Post `
+  -Uri 'http://127.0.0.1:15480/desktop/v1/meetings/meetings' `
+  -Headers $headers -ContentType 'application/json' -Body $body
+Invoke-RestMethod `
+  -Uri ('http://127.0.0.1:15480/desktop/v1/meetings/meetings/' + $meeting.id) `
+  -Headers $headers
+Remove-Variable session, headers
+

This write requires Meetings to be enabled and the signed-in staff +role to permit it. It is a cross-suite integration example; for this +product’s request models, use the complete technical reference +below.

+

Complete technical contract

+

Read the Code API reference +for every documented operation, request field, constraint, response +declaration and source supplement. Download the OpenAPI JSON for tools. For +Station this is the suite-side schema only; its separate service +contract is documented in the API supplement. The reference directory includes +configuration/source inventories, dependency declarations, native +command contracts, MCP signatures and candidate evidence.

+

MCP and automation boundary

+

No direct product MCP server is exposed by the accepted Townlight +desktop or Station boundary. Do not configure an invented +townlight mcp command or assume an AI client has staff +permissions. The integration surfaces for this beta are native IPC, the +documented HTTP APIs, source bundle imports, exact exports and the +existing Station CLI.

+

The bundled transcription code includes a TextFlowKit MCP +adapter as a separate source capability. It offers job-based +transcribe_media, get_transcript, +list_jobs, get_job_status and +export_transcript, and additional tools declared in that +adapter. It uses stdio first and optional Streamable HTTP, with the MCP +SDK as an optional extra. It is not automatically launched, +authenticated as Townlight staff or accepted as a Townlight product MCP +deployment. This documentation does not add such a service.

+

For a transcription client already provisioned separately, an +illustrative tool call is:

+
{"name":"get_job_status","arguments":{"job_id":"synthetic-existing-job-id"}}
+

Use a job ID returned by that transcription service. This example +does not create a Townlight record or bypass its review/Records handoff. +The exact optional adapter tool signatures are supplied in the MCP source reference. Station +meeting capture does not become live speech recognition because this +optional donor adapter exists.

+

Security and permissions

+

Use your own named account and save before leaving a screen. A saved +draft is durable; unsaved form text may not be. If a write has an +unknown result, reopen its record before repeating it.

+

Read source jurisdiction, dates, citation, version and visibility. A +copied source hash identifies exact bytes, not their legal +applicability. If a source changes or permission is removed, resolve the +source problem rather than substituting stale cached content.

+

Keep originals and derivatives separate. Review the intended audience +before export. A public summary excludes private fields only through the +applicable copy contract and your review. A renamed private packet is +still private content.

+

Drafting, review, approval, attachment, export, fulfillment and +publication are separate operations. A Townlight workpaper does not +itself adopt law, issue a permit, impose a fine or release a records +response. The responsible staff member records the applicable +decision.

+

The native session is validated and mapped to a persisted SQL +identity. An editable actor/reviewer label is not authentication. +Product/module permissions and source visibility apply at the server +boundary. Revoked/unavailable authority fails closed for new Station +operations; a previous permission result is not a perpetual +authorization.

+

Use protected local folders, account permissions and credential +storage. Never include the native session file, database passwords, +provider keys or unredacted support bundles in a public issue or +generated public documentation. A local public view is not automatically +a secured internet deployment. Keep network exposure and real equipment +acceptance specific to the chosen beta site.

+

Backup recovery and +maintenance

+

Save work and use Core’s canonical Backup Now before +maintenance. That operation stops writers. Preserve the coherent +profile/database/document backup and its receipt, then use +Start to resume. A source export is not a full +backup.

+

Use Restore Latest Backup through the supported +controls. If the result says Restore needs service +start, use Start, then Check, +and reopen a known record. Do not repeat restore merely because services +need to start. The fresh-profile acceptance verified that a fulfilled +request survived restore and a post-backup marker did not.

+

Keep Station’s dedicated database and media evidence together in its +own backup. Core’s native-profile backup must not be assumed to include +an external Station data directory. Stop writers during a coordinated +backup. Preserve failed media attempts and logs.

+

On failure, record the time, selected composition, +component/installer versions and exact message. Check System Health for +stopped, starting, ready or failed dependencies. Use the existing Retry +control after readiness; do not create duplicate business records to +refresh a stale view. Share only a redacted diagnostic bundle. Preserve +secrets, original evidence, recovery material and unrelated +installations.

+

Troubleshooting

+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SymptomLikely meaningNext action
Workspace absentWrong product composition or unavailable canonical runtime.Check selected composition; activate through Finish Records +Migration; wait for readiness.
Cannot sign in / 401Missing or expired named account session.Sign in normally; reopen a Station launch ticket if applicable.
Permission denied / 403Account, module, source or browser-origin permission.Ask the authorized administrator to inspect the intended permission; +do not invent role headers.
Save conflict / 409The saved revision, expected source hash or lifecycle changed.Keep edits, reopen current state and reconcile deliberately.
Invalid input / 422Required field, format, geometry, source envelope or state is +invalid.Read the field detail and correct the input/source; preserve +originals.
Service unavailable / 503Database, schema, connected source or configuration +unavailable.Inspect System Health and the named dependency. Preserve work; retry +only after readiness.
Export refusedMissing exact review, approval, audience or source +authorization.Read the refusal and complete the owning product’s explicit +decision.
Restore needs service startThe snapshot was restored but services have not resumed.Use Start, then Check and verify a saved record; do not blindly +repeat restore.
+

Verified workflows and +limits

+ +++++ + + + + + + + + + + + + + + +
ProductRecorded resultPrecisely exercised
CodePASSSynthetic official source import, exact citation/history/export; +proposal into Meetings, recorded adoption and separately codified +version; native connection readback.
+

These results come from the identified signed candidate’s fresh +normal-profile Sandbox exercise: real native IPC/HTTP/PostgreSQL and +selected headless controls. All accounts, source bundles and media were +synthetic. The guest install/uninstall and recovery passed, and the +owned Sandbox stopped. No host installed application or standalone +CivicCast was changed. This documentation task reuses those receipts; it +does not claim a new software acceptance run.

+

The workflow +matrix identifies raw receipt filenames. The evidence +index retains their original hashes; raw receipts remain in the +private beta handoff rather than being silently republished with the +documentation site.

+

The limits remain: actual city field acceptance and equipment/network +commissioning; Station automatic provisioning/SCM commissioning; every +UI/role combination; field recognition accuracy; and historical in-place +upgrades are not certified. They are not five invented feature +requirements. Fresh-install controlled beta handoff remains the accepted +scope. This package makes no city-deployment, publication or +general-availability claim.

+

Terms of service and license

+

Scope and status

+

These terms describe the Townlight Beta 1 software and this +documentation package. This is a locally prepared private beta, not a +hosted-service subscription, a city deployment agreement or a public +release. No uptime commitment, support response time, indemnity, +data-processing agreement or paid service is created by these documents. +A separate signed agreement, if any, governs services it actually +provides.

+

Software license and rights

+

Current Townlight-owned distributions identified in this candidate +use AGPL-3.0-only. The full license is supplied with +this documentation and with the source companion. The license governs +rights to run, copy, modify and convey the covered software; these +operational terms do not add restrictions to those rights. Historical +grants and dependency licenses retain their own terms. CivicCast remains +a separate product and is not relicensed by this documentation work.

+

When conveying covered software, retain applicable notices and +provide the corresponding source and installation/build information +required by the license. For a modified version supporting remote +network interaction, follow section 13’s source-offer requirement. The +companion archive identifies the source for this candidate; a link to a +different public branch is not a substitute for the matching source. +Read the supplied license for the complete conditions. See the GNU license +reference and GNU licensing +FAQ.

+

Data ownership and access

+

Importing a document does not transfer its ownership or grant +permission to publish it. The operating organization controls its +accounts, access decisions, lawful source use, retention and +review/release policy. Keep resident information, credentials, private +notes and restricted evidence in their authorized locations. +Documentation examples contain fictional data. No real city account, +credential or record is required to exercise these examples in an +isolated test environment.

+

Local operation and +external processors

+

The accepted beta workflow is local and uses named staff accounts. +Station has separate storage and credentials. Configure backup +destinations and optional model/network providers deliberately. A +configured external provider may receive submitted prompts, images or +audio according to that configuration and provider’s terms; this +documentation does not promise that every optional configuration is +offline. An email outbox or local public view does not establish +external delivery or an internet deployment. This static documentation +site has no analytics, account collection or remote font dependency.

+

Staff decisions and +source applicability

+

Staff verify the jurisdiction, source currency, permissions, +citations and proposed audience. Model output and generated guidance +require review. No draft is automatically an official legal +interpretation, zoning determination, permit approval, fee assessment, +enforcement notice or records-release decision. Official permit fee +authority remains with the adopted source and responsible organization; +imported amounts do not become a new authoritative calculation.

+

Beta operation and recovery

+

Use the identified candidate in its supported fresh-install scope. +Preserve backups and original evidence. Test physical equipment and +chosen network/service configuration before relying on them. The +supplied acceptance describes selected synthetic workflows, not every +screen, vendor, field condition or upgrade. Operators decide whether a +particular deployment meets their own operational obligations.

+

Warranty and liability

+

The covered software’s warranty and liability conditions are those in +sections 15–17 of the supplied AGPL and any applicable separate written +undertaking. This documentation creates no additional warranty or +limitation beyond those terms. Third-party software is subject to its +retained license notices. Nothing here removes rights that applicable +law makes nonwaivable.

+

Support and incident +reporting

+

Use the project’s existing SUPPORT and SECURITY guidance for its +matching repository. Report reproducible behavior with the version, +operation and redacted logs. Do not put credentials, resident records or +unredacted evidence in a public issue. Coordinate sensitive reports +through the channel designated in SECURITY. No new support address or +service commitment is invented here.

+

Ending a beta +exercise and document changes

+

When an organization ends testing, it controls retention/export and +removes access according to its policy. Uninstall may retain data; back +up and inspect the selected removal options. Ending an exercise does not +revoke rights already granted by AGPL. Later software/documentation +versions must identify their changed candidate and scope; historical +receipts retain their original identities. These terms do not claim that +a city has accepted a contract merely by reading a manual.

+

Glossary

+ ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TermMeaning
ApprovalAn explicit authorized decision on the saved text/artifact. It is +separate from saving or attachment.
Canonical recordThe owning product’s retained identity and saved version, rather +than an editable copied label.
CompositionThe selected set of desktop modules; inspections-preview exposes the +eight staff products.
Corresponding sourceThe source/build material matching the delivered covered program, +subject to its license.
Derivative / Records copyA separately prepared document with its own intended audience and +hash.
Hash / SHA256A fingerprint of exact bytes. It detects change; it does not +establish legal authority.
IdempotencyRepeating the same identified request has the same intended effect; +changing its payload can be refused.
IPCThe native desktop command boundary between its browser interface +and Rust host.
MCPModel Context Protocol; no direct Townlight product server is +enabled by this beta.
OriginalRetained source bytes. A reviewed derivative does not replace +them.
ProvenanceSource, version, date, actor and relationship information retained +with evidence.
RevisionAn immutable saved version. Later edits do not inherit an earlier +review automatically.
SnapshotA fixed audience-specific copy tied to a source/reviewed +revision.
StationTownlight’s separate media boundary using a pinned CivicCast-derived +engine; standalone CivicCast remains separate.
+

Alphabetical subject index

+ + + +

Source and document control

+

This edition is authored from the immutable corresponding-source +companion, the generated installed-domain schema and the retained +workflow receipts. The current software versions and signed artifacts +are unchanged. Public historical pages are not synchronized or published +by this local documentation task.

+

Workflow subject index

+ +
Townlight · AGPL-3.0-only · Candidate evidence applies only to its identified artifacts.
\ No newline at end of file diff --git a/docs/beta-1/manuals/core.html b/docs/beta-1/manuals/core.html index 8d3c331..0c54b0e 100644 --- a/docs/beta-1/manuals/core.html +++ b/docs/beta-1/manuals/core.html @@ -473,9 +473,9 @@

Capacity and platform database, originals, exports, media and backups. Select equipment/storage after sizing those actual workloads.

The exact runtime payload +href="../reference/runtime-payload-lock.json">runtime payload lock records pinned files, sizes and hashes. The component +href="../reference/component-metadata.json">component metadata records shipped dependency declarations. These references are more precise than a manually copied dependency list. Third-party and historical license notices must accompany their matching payloads.

@@ -557,13 +557,13 @@

A synthetic write product’s request models, use the complete technical reference below.

Complete technical contract

-

Read the Core API reference +

Read the Core API reference for every documented operation, request field, constraint, response declaration and source supplement. Download the OpenAPI JSON for tools. For +href="../api/core-openapi.json">OpenAPI JSON for tools. For Station this is the suite-side schema only; its separate service contract is documented in the API supplement. The reference directory includes +href="../reference/index.html">reference directory includes configuration/source inventories, dependency declarations, native command contracts, MCP signatures and candidate evidence.

MCP and automation boundary

@@ -589,7 +589,7 @@

MCP and automation boundary

Use a job ID returned by that transcription service. This example does not create a Townlight record or bypass its review/Records handoff. The exact optional adapter tool signatures are supplied in the MCP source reference. Station +href="../reference/mcp.html">MCP source reference. Station meeting capture does not become live speech recognition because this optional donor adapter exists.

Security and permissions

@@ -743,9 +743,9 @@

Verified workflows and owned Sandbox stopped. No host installed application or standalone CivicCast was changed. This documentation task reuses those receipts; it does not claim a new software acceptance run.

-

The workflow +

The workflow matrix identifies raw receipt filenames. The evidence +href="../reference/sandbox-evidence-index.json">evidence index retains their original hashes; raw receipts remain in the private beta handoff rather than being silently republished with the documentation site.

@@ -1012,16 +1012,16 @@

Workflow subject index

href="#workflow-5">Daily workflow, step 5.

  • Restore and verify — Daily workflow, step 6.

  • -
  • Source +

  • Source inventory and file hashes

  • -
  • All +

  • All component metadata

  • Installed +href="../reference/desktop-domain-openapi.json">Installed domain OpenAPI

  • -
  • Workflow +

  • Workflow matrix

  • -
  • Full AGPL +

  • Full AGPL text

  • Townlight · AGPL-3.0-only · Candidate evidence applies only to its identified artifacts.
    \ No newline at end of file diff --git a/docs/beta-1/manuals/inspections.html b/docs/beta-1/manuals/inspections.html new file mode 100644 index 0000000..b2a81e5 --- /dev/null +++ b/docs/beta-1/manuals/inspections.html @@ -0,0 +1,1046 @@ + + +Townlight Inspections Manual | Townlight candidate + +
    Townlight +
    +

    Naming, Access and Notice source candidate · 2 November 2026

    +

    Prepared documentation. Build, signing, installed acceptance and publication remain pending.

    + + +

    Townlight Inspections Manual

    +

    Townlight Beta 1 · Naming candidate documentation +edition 2 November 2026

    +

    Contents

    + +

    Using this manual

    +

    Townlight Inspections helps inspectors and authorized reviewing +staff. Inspections retains original evidence, supplied observations and +optional configured photo/audio analysis, then supports reviewed case +workpapers and a separate Records copy. Automatic output is a draft for +inspector review.

    +

    Staff should begin with First run and Daily workflow. Administrators +should also read Architecture, Technical specifications, Configuration, +Security and Recovery. Developers should use the exact API/data +dictionary and examples. The table of contents and alphabetical subject +index link to the relevant sections in the HTML edition; the PDF +preserves headings and searchable text. An editable Word edition is +included with the same documentation companion.

    +

    Beta identity

    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    IdentityValue
    DocumentationTownlight Beta 1 naming, Access and Notice candidate
    Intended installer version1.7.0.1; build and acceptance pending
    Product componenttownlight-inspections 0.3.0+dev.2
    Principal import packagetownlight_inspections
    Native desktop source version1.7.0-1
    Candidate hashesPending candidate build, signing and installed acceptance
    Current owned software licenseAGPL-3.0-only
    Acceptance compositionFresh Windows x64 profile; inspections-preview; Station configured +separately
    +

    The naming change advances this package’s version and requires a new +signed installer and installed acceptance. Those steps and publication +remain pending. Historical tags, receipts and archived manuals keep +their original names and certify only their identified artifacts. Use an +empty database and fresh profile; no in-place legacy upgrade is +supported. The approved Windows profile path remains +%LOCALAPPDATA%\CivicSuite. Preserve existing profiles, data +and recovery material.

    +

    First run

    +
      +
    1. Obtain the identified signed private candidate and its +corresponding-source companion from the beta coordinator. The landing +pages in this documentation are not an installer download service.
    2. +
    3. On the intended fresh Windows test installation, verify the MSI hash +and publisher signature before installing. Preserve unrelated profiles +and recovery material. Installed acceptance for this source candidate +remains pending; no in-place legacy upgrade is supported.
    4. +
    5. Launch Townlight under the intended named Windows account. Choose +the storage folders. Select Townlight Inspections +candidate (inspections-preview) for the bounded +desktop composition, including Access and Notice. A narrower default +selection will not expose all workspaces.
    6. +
    7. Enter the city profile, time zone and contacts. Create the first +named local administrator, sign in and choose protected backup storage. +Continue without local AI is valid for the +deterministic workflows.
    8. +
    9. Run Health Check and wait for readiness. Open Townlight. In System +Health select Finish Records Migration to activate the +canonical Python/PostgreSQL runtime. Do not fabricate migration receipts +or seed accounts.
    10. +
    11. Create named staff through Settings. Import authorized sources using +each product’s source library. All examples in this package are +synthetic; they are not municipal authority.
    12. +
    13. Provision Station separately if it is part of the beta exercise. +Selecting the desktop composition does not start or configure Station. +Configure vision explicitly only if automatic photo drafting is +selected.
    14. +
    +

    Daily workflow

    +

    +

    1. Create the case

    +

    Enter the property/case context and inspector observations. Keep +staff-only notes and identifiers in their intended fields. Save before +moving away from the workspace.

    +

    +

    2. Retain originals

    +

    Add original supported files using the existing evidence control. +Inspect the filename, size and retained hash. Preserve originals +separately from any derivative draft.

    +

    +

    3. Choose supplied or +automatic text

    +

    Use supplied photo observations and a supplied voice summary for +deterministic work. If configured, Analyse originals calls the +image-capable provider and bundled audio transcriber. Read +unavailable/failed results as such; do not label supplied text +automatic.

    +

    +

    4. Review the analysis and +citations

    +

    Compare automatic wording to the original evidence. Correct errors, +uncertainty and Code citations. A model output is neither an official +finding nor a notice.

    +

    +

    5. Save and record review

    +

    Save the case and explicitly record inspector/staff review of that +revision. Later edits create a draft requiring renewed review. Retain +the case history.

    +

    +

    6. Prepare the Records copy

    +

    Separately edit and review the public summary. Preview the Records +copy and confirm that private observations, property/address detail and +staff notes are excluded according to its contract.

    +

    +

    7. Hand off exact bytes

    +

    Attach the reviewed copy to an existing Records request. Inspect its +attachment/hash in Records. Attachment does not issue an enforcement +action or approve a public-records response.

    +

    Working safely

    +

    Use your own named account and save before leaving a screen. A saved +draft is durable; unsaved form text may not be. If a write has an +unknown result, reopen its record before repeating it.

    +

    Read source jurisdiction, dates, citation, version and visibility. A +copied source hash identifies exact bytes, not their legal +applicability. If a source changes or permission is removed, resolve the +source problem rather than substituting stale cached content.

    +

    Keep originals and derivatives separate. Review the intended audience +before export. A public summary excludes private fields only through the +applicable copy contract and your review. A renamed private packet is +still private content.

    +

    Drafting, review, approval, attachment, export, fulfillment and +publication are separate operations. A Townlight workpaper does not +itself adopt law, issue a permit, impose a fine or release a records +response. The responsible staff member records the applicable +decision.

    +

    Connected workflows

    +

    Consumes cited Code and Core contracts; supplies a reviewed copy to +Records. It does not imply an automatic permit-system or +enforcement-system writeback.

    + ++++ + + + + + + + + + + + + + + + + +
    DirectionMaterial
    InputInspector-supplied text, original supported photographs or audio, a +configured image-capable provider when photo analysis is selected, and +permitted Code authority.
    OutputRetained evidence with provenance, editable automatic drafts where +configured, reviewed cases and exact audience-specific packets.
    +

    Product boundary

    +

    The bundled Whistle CPU engine executes raw-audio transcription. +Automatic photo analysis requires explicit vision configuration; missing +configuration reports unavailable. Synthetic execution proves that +adapters run, not field recognition accuracy. No official citation/fine +issuance, inspection scheduling or enforcement-system writeback is +provided.

    +

    Architecture

    +
    + + +
    +

    The drawing shows the principal staff/evidence path. Native commands +carry trusted identity to Python business services; PostgreSQL and +retained original files hold durable state. A downstream copy does not +silently transfer decision authority. Station has its own configured +authority/media boundary, database and mutable files. The +connected-workflow text supplies the drawing’s reading order and +accessibility alternative.

    +

    Evidence limits +outlines and previous cases

    +

    Select supported original +files

    +

    The retained-original contract accepts the following MIME types, up +to 10,000,000 bytes per original. This is a decimal +byte limit, not 10 MiB. An unsupported type or oversized file is +refused; preserve the original outside the import and choose a supported +derivative deliberately rather than changing its filename to disguise +the type.

    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + +
    MaterialAccepted MIME types
    Photographsimage/jpeg, image/png, +image/webp
    Audioaudio/webm, audio/ogg, +audio/wav, audio/mpeg, +audio/mp4
    Plain texttext/plain
    Documentapplication/pdf
    +

    The case input bounds evidence to ten items; the browser’s +upload-body guard can be more restrictive when encoding/combining files. +Read the actual refusal and reduce the selected batch rather than +assuming the per-file limit guarantees the entire request will fit. +Accepted retention of text/PDF does not promise photo analysis of that +format. Configure an image-capable vision model for photographs. Whistle +handles supported raw audio when provisioned; TextFlowKit is a +separately configured alternative. Missing configuration is unavailable, +not a fabricated successful analysis.

    +

    Retain the original filename, MIME type, byte count and SHA256. +Compare generated observations/transcript with the evidence, correct the +draft and record review of the saved case revision. Supplied photo +observations or a supplied voice summary must remain labeled supplied +text.

    +

    Find earlier retained cases

    +

    Use the existing repeat-case lookup or authenticated +POST /desktop/v1/inspections/repeat-cases with:

    +
    {"property_reference":"Synthetic parcel A"}
    +

    Use the same property reference as the saved synthetic case. The +mounted implementation matches the normalized property reference against +saved case heads, verifies each revision hash and returns up to 50 +entries with entity/revision identity, title and review state, plus +sample_data: false. Empty results mean no matching retained +cases in this store. This is separate from the lower-level +townlight_inspections.case_lookup.lookup_repeat_cases +helper, which returns sample context and is not the mounted saved-case +query. Neither route queries an external enforcement system. Keep any +real prior case identity and facts separate from a model’s proposed +narrative. No GIS capture or external enforcement-system connection is +implied.

    +

    Prepare an outline for +review

    +

    The mounted POST /desktop/v1/inspections/notice-draft +accepts the same InspectionInput shape as the saved +workflow, not an arbitrary notice recipient or enforcement command. For +example:

    +
    {"title":"Synthetic review","property_reference":"Synthetic parcel A","inspection_reference":"SYN-001","dataset_kind":"fictional","inspector_notes":"Synthetic loose panel observed","photo_observations":["Synthetic panel appears loose"],"voice_notes":"Inspector supplied summary"}
    +

    Inspect the returned draft/outline and its limitations. The +lower-level townlight_inspections.notice_draft.draft_notice +takes case identity, property reference, violation type and supplied +observations. This source helper supplies a reviewable outline; it does +not issue a citation, serve notice, choose an official fine or make an +enforcement determination. Where no native button exists, technical +staff use the current authenticated API rather than an invented +screen.

    +

    Revise the saved case’s notice_draft only after checking +the actual evidence and applicable Code source. Save and record review +again; a new revision does not inherit the previous review. The staff +packet and separately reviewed Records copy retain their existing +audience/exclusion rules. A drafted outline is neither a Records release +nor proof that a notice was delivered.

    +

    Source contracts: +townlight_inspections/media_analysis.py, +case_lookup.py, notice_draft.py, workflow +models and townlight_runtime/inspections_bridge.py.

    +

    Technical specifications

    +

    Runtime and storage

    +

    The accepted package targets Windows x64 fresh +installation. Its native shell uses Rust 2021, Tauri 2 +and Microsoft WebView2; browser assets are JavaScript built +with Vite 8.1.6. This describes the native desktop +frontend; Station has a separate React operator, specified below or in +its product manual. Canonical business workflows use bundled +CPython 3.13.5, FastAPI, Pydantic, SQLAlchemy and +Alembic, with PostgreSQL 17 / PostGIS and +managed original files. The installed runtime tested here contains +FastAPI 0.162.0. Package minimum Python requirements can differ from the +bundled executable; the metadata reference preserves both. No stack +rewrite is implied by the beta label.

    +

    The native transport is fixed to loopback +127.0.0.1:15480; PostgreSQL uses the configured local +runtime port (default 15432). Optional local model service +defaults to 127.0.0.1:15434. Those are deployment defaults, +not internet endpoints. The runtime has health, module and readiness +endpoints; readiness is stronger than process existence. The task queue +is the existing local Core task infrastructure, not an assertion that a +separate Redis service is required for this desktop composition.

    +

    The default native profile is %LOCALAPPDATA%\CivicSuite; +the historical directory name remains part of compatibility. Do not +rename it to Townlight. A configured TOWNLIGHT_PROFILE_ROOT +must be absolute. Local configuration and secrets live under that +profile; protected managed files and database state must be backed up +coherently. Source/runtime identity is distinct from a product’s display +label.

    +

    Data and consistency

    +

    Original evidence files and hashes; media analysis records; +observations and voice summaries; Code citations; case revisions; review +records; private packets and separately edited Records copies.

    +

    Versioned saves use expected prior revision identifiers where +defined. Reopen and reconcile on conflict. Exact exports and handoffs +use source IDs, current visibility, revision and SHA256. Review belongs +to the saved revision and does not transfer silently to edited text. +Database changes use the owning product’s migrations; a request or +readiness check is not an authorization to mutate schema.

    +

    Capacity and platform +statements

    +

    This beta has synthetic single-profile workflow evidence. It does not +have a published benchmark for concurrent staff capacity, minimum +RAM/CPU, large-source limits or a field SLA. Do not turn a developer +machine’s specification into a supported minimum. The new installer size +remains pending its build; allow additional disk for extracted runtime, +database, originals, exports, media and backups. Select +equipment/storage after sizing those actual workloads.

    +

    The exact runtime payload +lock records pinned files, sizes and hashes. The component +metadata records shipped dependency declarations. These references +are more precise than a manually copied dependency list. Third-party and +historical license notices must accompany their matching payloads.

    +

    Configuration and +administration

    +

    Native deployment +configuration

    +

    Use Setup, Settings and System Health for supported staff operation. +Administrators provision folders, backup storage, named accounts and the +city profile. Select inspections-preview for the bounded +desktop composition, including Access and Notice. Station remains a +separate service boundary. Do not use a standalone product’s demo server +as a substitute for the installed workspace.

    +

    Technical deployments use TOWNLIGHT_PRODUCT_PROFILE, +TOWNLIGHT_PROFILE_ROOT, DATABASE_URL, +TOWNLIGHT_RUNTIME_PORT, PORTAL_MODE and the +runtime-managed secret files. Treat database URLs and native session +proofs as secrets. The installed native domain runtime explicitly +refuses non-loopback binding. PORTAL_MODE=private is the +accepted posture; changing it does not by itself commission an internet +portal, authentication provider or reverse proxy.

    +

    The isolated documentation exporter sets a fictional profile and +unusable synthetic database origin only to read schemas; those values +are not deployment configuration. Keep deployment values in the intended +process/account scope. An already-running process does not automatically +inherit later environment edits.

    +

    Optional media analysis +configuration

    +

    TOWNLIGHT_INSPECTIONS_VISION_PROVIDER accepts +ollama, openai or anthropic. +Select an actually image-capable model through +TOWNLIGHT_INSPECTIONS_VISION_MODEL; an Ollama endpoint may +use TOWNLIGHT_INSPECTIONS_VISION_BASE_URL. +TOWNLIGHT_INSPECTIONS_VISION_THINK accepts +true/false/low/medium/high where that configured adapter uses it. Keep +provider credentials in protected deployment configuration, never in a +source bundle. Missing vision configuration returns unavailable rather +than invented observations.

    +

    TOWNLIGHT_INSPECTIONS_TRANSCRIBER selects +whistle or textflowkit; the installed +candidate provisions the bundled Whistle CPU path. The owning +transcriber assets and retained notices must stay with it. A provider +result remains an editable draft with original evidence retained. The +separate TextFlowKit MCP adapter is not an automatically enabled +Townlight server.

    +

    API and integration examples

    +

    Native command example

    +

    The following JavaScript belongs in the existing trusted Townlight +frontend/development environment with invoke imported from +@tauri-apps/api/core. It is not a command for an arbitrary +web page or an instruction for nontechnical staff. IDs must come from +records created in an isolated synthetic exercise.

    +
    import { invoke } from '@tauri-apps/api/core';
    +const result = await invoke('inspections_domain_request', {request: {operation: 'cases', offset: 0}});
    +console.log(result);
    +

    Trusted local HTTP example

    +

    An administrator/developer can inspect an already-configured isolated +runtime from a trusted local process. This PowerShell example reads the +signed-in synthetic profile’s existing proof into memory; it does not +create a user, seed a session, reveal the proof in output or bypass a +permission check. Do not use real city data in development examples. A +read response does not prove approval or publication.

    +
    $profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite'
    +$sessionPath = Join-Path $profilePath 'config\local-session.json'
    +$session = Get-Content -LiteralPath $sessionPath -Raw | ConvertFrom-Json
    +$headers = @{ 'X-Townlight-Session' = $session.session_hash }
    +Invoke-RestMethod -Uri 'http://127.0.0.1:15480/desktop/v1/inspections/evidence/supported-types' -Headers $headers
    +Remove-Variable session, headers
    +

    A synthetic write +with subsequent readback

    +

    This example demonstrates the existing Meetings HTTP contract in an +isolated exercise. It is intentionally fictional. It does not start a +service. Its authentication setup is included so it can be run +independently under the signed-in synthetic account. If a write times +out, inspect current records before repeating it.

    +
    $profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite'
    +$sessionPath = Join-Path $profilePath 'config/local-session.json'
    +$session = Get-Content -LiteralPath $sessionPath -Raw | ConvertFrom-Json
    +$headers = @{ 'X-Townlight-Session' = $session.session_hash }
    +$body = @{
    +  title = 'Synthetic documentation exercise'
    +  scheduled_start = '2026-11-05T18:00:00-07:00'
    +  location = 'Synthetic room'
    +  meeting_type = 'regular'
    +} | ConvertTo-Json
    +$meeting = Invoke-RestMethod -Method Post `
    +  -Uri 'http://127.0.0.1:15480/desktop/v1/meetings/meetings' `
    +  -Headers $headers -ContentType 'application/json' -Body $body
    +Invoke-RestMethod `
    +  -Uri ('http://127.0.0.1:15480/desktop/v1/meetings/meetings/' + $meeting.id) `
    +  -Headers $headers
    +Remove-Variable session, headers
    +

    This write requires Meetings to be enabled and the signed-in staff +role to permit it. It is a cross-suite integration example; for this +product’s request models, use the complete technical reference +below.

    +

    Complete technical contract

    +

    Read the Inspections API +reference for every documented operation, request field, constraint, +response declaration and source supplement. Download the OpenAPI JSON for +tools. For Station this is the suite-side schema only; its separate +service contract is documented in the API supplement. The reference directory includes +configuration/source inventories, dependency declarations, native +command contracts, MCP signatures and candidate evidence.

    +

    MCP and automation boundary

    +

    No direct product MCP server is exposed by the accepted Townlight +desktop or Station boundary. Do not configure an invented +townlight mcp command or assume an AI client has staff +permissions. The integration surfaces for this beta are native IPC, the +documented HTTP APIs, source bundle imports, exact exports and the +existing Station CLI.

    +

    The bundled transcription code includes a TextFlowKit MCP +adapter as a separate source capability. It offers job-based +transcribe_media, get_transcript, +list_jobs, get_job_status and +export_transcript, and additional tools declared in that +adapter. It uses stdio first and optional Streamable HTTP, with the MCP +SDK as an optional extra. It is not automatically launched, +authenticated as Townlight staff or accepted as a Townlight product MCP +deployment. This documentation does not add such a service.

    +

    For a transcription client already provisioned separately, an +illustrative tool call is:

    +
    {"name":"get_job_status","arguments":{"job_id":"synthetic-existing-job-id"}}
    +

    Use a job ID returned by that transcription service. This example +does not create a Townlight record or bypass its review/Records handoff. +The exact optional adapter tool signatures are supplied in the MCP source reference. Station +meeting capture does not become live speech recognition because this +optional donor adapter exists.

    +

    Security and permissions

    +

    Use your own named account and save before leaving a screen. A saved +draft is durable; unsaved form text may not be. If a write has an +unknown result, reopen its record before repeating it.

    +

    Read source jurisdiction, dates, citation, version and visibility. A +copied source hash identifies exact bytes, not their legal +applicability. If a source changes or permission is removed, resolve the +source problem rather than substituting stale cached content.

    +

    Keep originals and derivatives separate. Review the intended audience +before export. A public summary excludes private fields only through the +applicable copy contract and your review. A renamed private packet is +still private content.

    +

    Drafting, review, approval, attachment, export, fulfillment and +publication are separate operations. A Townlight workpaper does not +itself adopt law, issue a permit, impose a fine or release a records +response. The responsible staff member records the applicable +decision.

    +

    The native session is validated and mapped to a persisted SQL +identity. An editable actor/reviewer label is not authentication. +Product/module permissions and source visibility apply at the server +boundary. Revoked/unavailable authority fails closed for new Station +operations; a previous permission result is not a perpetual +authorization.

    +

    Use protected local folders, account permissions and credential +storage. Never include the native session file, database passwords, +provider keys or unredacted support bundles in a public issue or +generated public documentation. A local public view is not automatically +a secured internet deployment. Keep network exposure and real equipment +acceptance specific to the chosen beta site.

    +

    Backup recovery and +maintenance

    +

    Save work and use Core’s canonical Backup Now before +maintenance. That operation stops writers. Preserve the coherent +profile/database/document backup and its receipt, then use +Start to resume. A source export is not a full +backup.

    +

    Use Restore Latest Backup through the supported +controls. If the result says Restore needs service +start, use Start, then Check, +and reopen a known record. Do not repeat restore merely because services +need to start. The fresh-profile acceptance verified that a fulfilled +request survived restore and a post-backup marker did not.

    +

    Keep Station’s dedicated database and media evidence together in its +own backup. Core’s native-profile backup must not be assumed to include +an external Station data directory. Stop writers during a coordinated +backup. Preserve failed media attempts and logs.

    +

    On failure, record the time, selected composition, +component/installer versions and exact message. Check System Health for +stopped, starting, ready or failed dependencies. Use the existing Retry +control after readiness; do not create duplicate business records to +refresh a stale view. Share only a redacted diagnostic bundle. Preserve +secrets, original evidence, recovery material and unrelated +installations.

    +

    Troubleshooting

    + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    SymptomLikely meaningNext action
    Workspace absentWrong product composition or unavailable canonical runtime.Check selected composition; activate through Finish Records +Migration; wait for readiness.
    Cannot sign in / 401Missing or expired named account session.Sign in normally; reopen a Station launch ticket if applicable.
    Permission denied / 403Account, module, source or browser-origin permission.Ask the authorized administrator to inspect the intended permission; +do not invent role headers.
    Save conflict / 409The saved revision, expected source hash or lifecycle changed.Keep edits, reopen current state and reconcile deliberately.
    Invalid input / 422Required field, format, geometry, source envelope or state is +invalid.Read the field detail and correct the input/source; preserve +originals.
    Service unavailable / 503Database, schema, connected source or configuration +unavailable.Inspect System Health and the named dependency. Preserve work; retry +only after readiness.
    Export refusedMissing exact review, approval, audience or source +authorization.Read the refusal and complete the owning product’s explicit +decision.
    Restore needs service startThe snapshot was restored but services have not resumed.Use Start, then Check and verify a saved record; do not blindly +repeat restore.
    Photo analysis unavailableNo configured image-capable vision service.Use supplied observations or have an administrator configure the +existing adapter.
    Automatic text is incorrectModel recognition is uncertain or wrong.Compare original evidence, edit and record inspector review before +any official use.
    +

    Verified workflows and +limits

    + +++++ + + + + + + + + + + + + + + +
    ProductRecorded resultPrecisely exercised
    InspectionsPASSRetained original/hash, supplied observations and voice summary, +saved/reviewed case/readback, separate exact Records copy and private +handoff; address exclusion; native workspace.
    +

    These results come from the identified signed candidate’s fresh +normal-profile Sandbox exercise: real native IPC/HTTP/PostgreSQL and +selected headless controls. All accounts, source bundles and media were +synthetic. The guest install/uninstall and recovery passed, and the +owned Sandbox stopped. No host installed application or standalone +CivicCast was changed. This documentation task reuses those receipts; it +does not claim a new software acceptance run.

    +

    The workflow +matrix identifies raw receipt filenames. The evidence +index retains their original hashes; raw receipts remain in the +private beta handoff rather than being silently republished with the +documentation site.

    +

    The limits remain: actual city field acceptance and equipment/network +commissioning; Station automatic provisioning/SCM commissioning; every +UI/role combination; field recognition accuracy; and historical in-place +upgrades are not certified. They are not five invented feature +requirements. Fresh-install controlled beta handoff remains the accepted +scope. This package makes no city-deployment, publication or +general-availability claim.

    +

    Terms of service and license

    +

    Scope and status

    +

    These terms describe the Townlight Beta 1 software and this +documentation package. This is a locally prepared private beta, not a +hosted-service subscription, a city deployment agreement or a public +release. No uptime commitment, support response time, indemnity, +data-processing agreement or paid service is created by these documents. +A separate signed agreement, if any, governs services it actually +provides.

    +

    Software license and rights

    +

    Current Townlight-owned distributions identified in this candidate +use AGPL-3.0-only. The full license is supplied with +this documentation and with the source companion. The license governs +rights to run, copy, modify and convey the covered software; these +operational terms do not add restrictions to those rights. Historical +grants and dependency licenses retain their own terms. CivicCast remains +a separate product and is not relicensed by this documentation work.

    +

    When conveying covered software, retain applicable notices and +provide the corresponding source and installation/build information +required by the license. For a modified version supporting remote +network interaction, follow section 13’s source-offer requirement. The +companion archive identifies the source for this candidate; a link to a +different public branch is not a substitute for the matching source. +Read the supplied license for the complete conditions. See the GNU license +reference and GNU licensing +FAQ.

    +

    Data ownership and access

    +

    Importing a document does not transfer its ownership or grant +permission to publish it. The operating organization controls its +accounts, access decisions, lawful source use, retention and +review/release policy. Keep resident information, credentials, private +notes and restricted evidence in their authorized locations. +Documentation examples contain fictional data. No real city account, +credential or record is required to exercise these examples in an +isolated test environment.

    +

    Local operation and +external processors

    +

    The accepted beta workflow is local and uses named staff accounts. +Station has separate storage and credentials. Configure backup +destinations and optional model/network providers deliberately. A +configured external provider may receive submitted prompts, images or +audio according to that configuration and provider’s terms; this +documentation does not promise that every optional configuration is +offline. An email outbox or local public view does not establish +external delivery or an internet deployment. This static documentation +site has no analytics, account collection or remote font dependency.

    +

    Staff decisions and +source applicability

    +

    Staff verify the jurisdiction, source currency, permissions, +citations and proposed audience. Model output and generated guidance +require review. No draft is automatically an official legal +interpretation, zoning determination, permit approval, fee assessment, +enforcement notice or records-release decision. Official permit fee +authority remains with the adopted source and responsible organization; +imported amounts do not become a new authoritative calculation.

    +

    Beta operation and recovery

    +

    Use the identified candidate in its supported fresh-install scope. +Preserve backups and original evidence. Test physical equipment and +chosen network/service configuration before relying on them. The +supplied acceptance describes selected synthetic workflows, not every +screen, vendor, field condition or upgrade. Operators decide whether a +particular deployment meets their own operational obligations.

    +

    Warranty and liability

    +

    The covered software’s warranty and liability conditions are those in +sections 15–17 of the supplied AGPL and any applicable separate written +undertaking. This documentation creates no additional warranty or +limitation beyond those terms. Third-party software is subject to its +retained license notices. Nothing here removes rights that applicable +law makes nonwaivable.

    +

    Support and incident +reporting

    +

    Use the project’s existing SUPPORT and SECURITY guidance for its +matching repository. Report reproducible behavior with the version, +operation and redacted logs. Do not put credentials, resident records or +unredacted evidence in a public issue. Coordinate sensitive reports +through the channel designated in SECURITY. No new support address or +service commitment is invented here.

    +

    Ending a beta +exercise and document changes

    +

    When an organization ends testing, it controls retention/export and +removes access according to its policy. Uninstall may retain data; back +up and inspect the selected removal options. Ending an exercise does not +revoke rights already granted by AGPL. Later software/documentation +versions must identify their changed candidate and scope; historical +receipts retain their original identities. These terms do not claim that +a city has accepted a contract merely by reading a manual.

    +

    Glossary

    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TermMeaning
    ApprovalAn explicit authorized decision on the saved text/artifact. It is +separate from saving or attachment.
    Canonical recordThe owning product’s retained identity and saved version, rather +than an editable copied label.
    CompositionThe selected set of desktop modules; inspections-preview exposes the +eight staff products.
    Corresponding sourceThe source/build material matching the delivered covered program, +subject to its license.
    Derivative / Records copyA separately prepared document with its own intended audience and +hash.
    Hash / SHA256A fingerprint of exact bytes. It detects change; it does not +establish legal authority.
    IdempotencyRepeating the same identified request has the same intended effect; +changing its payload can be refused.
    IPCThe native desktop command boundary between its browser interface +and Rust host.
    MCPModel Context Protocol; no direct Townlight product server is +enabled by this beta.
    OriginalRetained source bytes. A reviewed derivative does not replace +them.
    ProvenanceSource, version, date, actor and relationship information retained +with evidence.
    RevisionAn immutable saved version. Later edits do not inherit an earlier +review automatically.
    SnapshotA fixed audience-specific copy tied to a source/reviewed +revision.
    StationTownlight’s separate media boundary using a pinned CivicCast-derived +engine; standalone CivicCast remains separate.
    +

    Alphabetical subject index

    + + + +

    Source and document control

    +

    This edition is authored from the immutable corresponding-source +companion, the generated installed-domain schema and the retained +workflow receipts. The current software versions and signed artifacts +are unchanged. Public historical pages are not synchronized or published +by this local documentation task.

    +

    Workflow subject index

    + +
    Townlight · AGPL-3.0-only · Candidate evidence applies only to its identified artifacts.
    \ No newline at end of file diff --git a/docs/beta-1/manuals/meetings.html b/docs/beta-1/manuals/meetings.html new file mode 100644 index 0000000..7b64a59 --- /dev/null +++ b/docs/beta-1/manuals/meetings.html @@ -0,0 +1,969 @@ + + +Townlight Meetings Manual | Townlight candidate + +
    Townlight +
    +

    Naming, Access and Notice source candidate · 2 November 2026

    +

    Prepared documentation. Build, signing, installed acceptance and publication remain pending.

    + + +

    Townlight Meetings Manual

    +

    Townlight Beta 1 · Naming candidate documentation +edition 2 November 2026

    +

    Contents

    + +

    Using this manual

    +

    Townlight Meetings helps clerks, meeting coordinators and authorized +reviewers. Meetings supports clerk preparation and the retained +proceedings of a meeting: agenda items, packets, motions, votes, +supplied transcript material, minutes decisions and archives. It +supplies canonical meeting and agenda context to Station.

    +

    Staff should begin with First run and Daily workflow. Administrators +should also read Architecture, Technical specifications, Configuration, +Security and Recovery. Developers should use the exact API/data +dictionary and examples. The table of contents and alphabetical subject +index link to the relevant sections in the HTML edition; the PDF +preserves headings and searchable text. An editable Word edition is +included with the same documentation companion.

    +

    Beta identity

    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    IdentityValue
    Public documentation identityTownlight Beta 1
    Intended installer version1.7.0.1; build and acceptance pending
    Product componenttownlight-meetings 1.0.5
    Principal import packagetownlight_meetings
    Native desktop source version1.7.0-1
    Candidate MSI SHA256Pending build, signing and installed acceptance
    Corresponding-source SHA256Pending candidate source assembly
    Current owned software licenseAGPL-3.0-only
    Supported acceptance profileWindows x64 fresh install; inspections-preview; separate Station +configuration
    +

    This source candidate renames the distribution, principal import +package and active schema to Townlight identities and advances Meetings +to 1.0.5. Build, signing, installed acceptance and publication remain +pending. Historical tags and receipts keep their original identities and +certify only their identified bytes. Use a fresh profile and empty +database; this candidate provides no in-place legacy upgrade. The +approved profile path remains %LOCALAPPDATA%\CivicSuite. +Preserve existing profiles, data and backups.

    +

    First run

    +
      +
    1. Obtain the identified signed private candidate and its +corresponding-source companion from the beta coordinator. The landing +pages in this documentation are not an installer download service.
    2. +
    3. On the intended fresh Windows test installation, verify the +identified candidate MSI hash and publisher signature before installing. +Preserve unrelated profiles and recovery material. Installed acceptance +for this source candidate remains pending.
    4. +
    5. Launch Townlight under the intended named Windows account. Choose +the storage folders. Select Townlight Inspections +candidate (inspections-preview) for the bounded +desktop composition, including Access and Notice. A narrower selection +will not expose all workspaces.
    6. +
    7. Enter the city profile, time zone and contacts. Create the first +named local administrator, sign in and choose protected backup storage. +Continue without local AI is valid for the +deterministic workflows.
    8. +
    9. Run Health Check and wait for readiness. Open Townlight. In System +Health select Finish Records Migration to activate the +canonical Python/PostgreSQL runtime. Do not fabricate migration receipts +or seed accounts.
    10. +
    11. Create named staff through Settings. Import authorized sources using +each product’s source library. All examples in this package are +synthetic; they are not municipal authority.
    12. +
    13. Provision Station separately if it is part of the beta exercise. +Selecting the desktop composition does not start or configure Station. +Configure vision explicitly only if automatic photo drafting is +selected.
    14. +
    +

    Daily workflow

    +

    +

    1. Create the meeting

    +

    Enter its title, date/time including the intended time zone, location +and meeting type. Save and reopen it before adding downstream +evidence.

    +

    +

    2. Prepare the agenda and +packet

    +

    Create agenda items, assign them to the actual meeting and record +review. Assemble a packet from the selected items and source documents. +Check the saved assembly’s packet identifier before using it for an +archive or delivery.

    +

    +

    3. Record notice work

    +

    Use the existing notice checklist, template and posting-proof +controls where applicable. A calculated checklist is evidence for clerk +review; staff verify the jurisdiction’s notice requirements and actual +posting.

    +

    +

    4. Record proceedings

    +

    Capture the actual motion, seconder and votes. Record corrections as +corrections, preserving the earlier event. Retain supplied transcript +text with its source label.

    +

    +

    5. Review minutes

    +

    Draft from identified source material. Check the citations and +wording. Record the explicit minutes decision; a draft or a motion is +not adopted minutes.

    +

    +

    6. Record legislation evidence

    +

    When an ordinance or resolution is adopted, record the actual Code +connection decision. Code staff separately perform codification; meeting +adoption does not silently rewrite the code.

    +

    +

    7. Archive and hand off

    +

    Choose the appropriate visibility and saved packet/minutes. Inspect +the resulting proceedings and permitted archive. Use Station’s operator +for capture and Records for a separate response/release.

    +

    Working safely

    +

    Use your own named account and save before leaving a screen. A saved +draft is durable; unsaved form text may not be. If a write has an +unknown result, reopen its record before repeating it.

    +

    Read source jurisdiction, dates, citation, version and visibility. A +copied source hash identifies exact bytes, not their legal +applicability. If a source changes or permission is removed, resolve the +source problem rather than substituting stale cached content.

    +

    Keep originals and derivatives separate. Review the intended audience +before export. A public summary excludes private fields only through the +applicable copy contract and your review. A renamed private packet is +still private content.

    +

    Drafting, review, approval, attachment, export, fulfillment and +publication are separate operations. A Townlight workpaper does not +itself adopt law, issue a permit, impose a fine or release a records +response. The responsible staff member records the applicable +decision.

    +

    Connected workflows

    +

    Provides evidence to Records, Code, Zoning and Planning, and meeting +identity to Station. Code adoption and codification remain separate. +Supporting Notice and Access do not replace clerk review.

    + ++++ + + + + + + + + + + + + + + + + +
    DirectionMaterial
    InputA meeting schedule, staff agenda material, source documents, +recorded clerk decisions and supplied transcript text.
    OutputVersioned meeting evidence, packets, proceedings, reviewed minutes +and permitted archive documents. Station receives the selected meeting +and agenda snapshot.
    +

    Product boundary

    +

    Supplied transcript handling is not automatic audio transcription. +Station adds capture; it does not imply a Meetings livestream hosting +service. Vendor sync code and adapters are not proof that every vendor +is configured or live.

    +

    Architecture

    +
    + + +
    +

    The drawing shows the principal staff/evidence path. Native commands +carry trusted identity to Python business services; PostgreSQL and +retained original files hold durable state. A downstream copy does not +silently transfer decision authority. Station has its own configured +authority/media boundary, database and mutable files. The +connected-workflow text supplies the drawing’s reading order and +accessibility alternative.

    +

    Transcript corrections +and action items

    +

    Preserve supplied +transcript history

    +
      +
    1. Save the actual meeting first. Retain the supplied text’s source +label and confirm that the material belongs to that meeting. Supplied +text is not automatic audio transcription.
    2. +
    3. Use the transcript capture operation. The installed route is +POST /desktop/v1/meetings/meetings/{meeting_id}/transcripts. +It requires source_label and transcript_text; +the server attributes the signed-in actor.
    4. +
    5. Read the meeting’s proceedings and retain the returned transcript +id. If text needs correction, submit a new +capture for the same meeting with correction_of_id +set to that original ID. Do not replace the original row or silently +edit its audit history.
    6. +
    7. Read proceedings again and confirm both entries, their source +labels, actor/time and correction link. A correction referencing an +entry from another meeting is refused. Reconcile the corrected text +before using it in reviewed minutes.
    8. +
    +

    For an already saved synthetic meeting, an initial request body +is:

    +
    {"source_label":"Synthetic clerk text v1","transcript_text":"The synthetic meeting opened at 18:00."}
    +

    A subsequent correction body is:

    +
    {"source_label":"Synthetic clerk correction v2","transcript_text":"The synthetic meeting opened at 18:05.","correction_of_id":"11111111-1111-4111-8111-111111111111"}
    +

    Replace the example UUID with the ID returned by the first capture. +An HTTP client must use the existing authenticated native proof as +described in the technical reference. Readback uses +GET /desktop/v1/meetings/meetings/{meeting_id}/proceedings; +its transcripts collection preserves the append-only +entries. Correcting a transcript does not automatically revise adopted +minutes or publish the material.

    +

    Retain action items +with the proceedings

    +

    Use +POST /desktop/v1/meetings/meetings/{meeting_id}/action-items +with a description, optional assignee and optional saved source motion +ID. For example:

    +
    {"description":"Prepare the synthetic follow-up report","assigned_to":"Synthetic staff","source_motion_id":null}
    +

    If linking a motion, obtain its actual saved identity and keep the +item in its meeting context. Inspect the returned identity and the +action_items collection in proceedings. This captures a +retained action item; it does not send an email, enforce a task deadline +or turn a note into adopted legislation. Where a native screen does not +expose this field, technical staff use the existing authenticated API +rather than an invented button.

    +

    Source contracts: townlight_meetings/transcripts.py, +townlight_meetings/motion_vote.py and +townlight_runtime/meetings_bridge.py. The exact motion +repository filename and all mounted route models are retained in the +source inventory/API companion.

    +

    Technical specifications

    +

    Runtime and storage

    +

    The accepted package targets Windows x64 fresh +installation. Its native shell uses Rust 2021, Tauri 2 +and Microsoft WebView2; browser assets are JavaScript built +with Vite 8.1.6. This describes the native desktop +frontend; Station has a separate React operator, specified below or in +its product manual. Canonical business workflows use bundled +CPython 3.13.5, FastAPI, Pydantic, SQLAlchemy and +Alembic, with PostgreSQL 17 / PostGIS and +managed original files. The installed runtime tested here contains +FastAPI 0.162.0. Package minimum Python requirements can differ from the +bundled executable; the metadata reference preserves both. No stack +rewrite is implied by the beta label.

    +

    The native transport is fixed to loopback +127.0.0.1:15480; PostgreSQL uses the configured local +runtime port (default 15432). Optional local model service +defaults to 127.0.0.1:15434. Those are deployment defaults, +not internet endpoints. The runtime has health, module and readiness +endpoints; readiness is stronger than process existence. The task queue +is the existing local Core task infrastructure, not an assertion that a +separate Redis service is required for this desktop composition.

    +

    The default native profile is %LOCALAPPDATA%\CivicSuite; +the historical directory name remains part of compatibility. Do not +rename it to Townlight. A configured TOWNLIGHT_PROFILE_ROOT +must be absolute. Local configuration and secrets live under that +profile; protected managed files and database state must be backed up +coherently. Source/runtime identity is distinct from a product’s display +label.

    +

    Data and consistency

    +

    Meetings and stages; agenda items and assignments; packet snapshots +and deliveries; notices and posting proof; motions and corrections; +votes; transcript records; minutes drafts and decisions; archives.

    +

    Versioned saves use expected prior revision identifiers where +defined. Reopen and reconcile on conflict. Exact exports and handoffs +use source IDs, current visibility, revision and SHA256. Review belongs +to the saved revision and does not transfer silently to edited text. +Database changes use the owning product’s migrations; a request or +readiness check is not an authorization to mutate schema.

    +

    Capacity and platform +statements

    +

    This beta has synthetic single-profile workflow evidence. It does not +have a published benchmark for concurrent staff capacity, minimum +RAM/CPU, large-source limits or a field SLA. Do not turn a developer +machine’s specification into a supported minimum. The new installer size +remains pending its build; allow additional disk for extracted runtime, +database, originals, exports, media and backups. Select +equipment/storage after sizing those actual workloads.

    +

    The exact runtime payload +lock records pinned files, sizes and hashes. The component +metadata records shipped dependency declarations. These references +are more precise than a manually copied dependency list. Third-party and +historical license notices must accompany their matching payloads.

    +

    Configuration and +administration

    +

    Native deployment +configuration

    +

    Use Setup, Settings and System Health for supported staff operation. +Administrators provision folders, backup storage, named accounts and the +city profile. Select inspections-preview for the bounded +desktop composition, including Access and Notice. Station remains a +separate service boundary. Do not use a standalone product’s demo server +as a substitute for the installed workspace.

    +

    Technical deployments use TOWNLIGHT_PRODUCT_PROFILE, +TOWNLIGHT_PROFILE_ROOT, DATABASE_URL, +TOWNLIGHT_RUNTIME_PORT, PORTAL_MODE and the +runtime-managed secret files. Treat database URLs and native session +proofs as secrets. The installed native domain runtime explicitly +refuses non-loopback binding. PORTAL_MODE=private is the +accepted posture; changing it does not by itself commission an internet +portal, authentication provider or reverse proxy.

    +

    The isolated documentation exporter sets a fictional profile and +unusable synthetic database origin only to read schemas; those values +are not deployment configuration. Keep deployment values in the intended +process/account scope. An already-running process does not automatically +inherit later environment edits.

    +

    API and integration examples

    +

    Native command example

    +

    The following JavaScript belongs in the existing trusted Townlight +frontend/development environment with invoke imported from +@tauri-apps/api/core. It is not a command for an arbitrary +web page or an instruction for nontechnical staff. IDs must come from +records created in an isolated synthetic exercise.

    +
    import { invoke } from '@tauri-apps/api/core';
    +const result = await invoke('meetings_domain_request', {request: {operation: 'get-proceedings', id: meetingId}});
    +console.log(result);
    +

    Trusted local HTTP example

    +

    An administrator/developer can inspect an already-configured isolated +runtime from a trusted local process. This PowerShell example reads the +signed-in synthetic profile’s existing proof into memory; it does not +create a user, seed a session, reveal the proof in output or bypass a +permission check. Do not use real city data in development examples. A +read response does not prove approval or publication.

    +
    $profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite'
    +$sessionPath = Join-Path $profilePath 'config\local-session.json'
    +$session = Get-Content -LiteralPath $sessionPath -Raw | ConvertFrom-Json
    +$headers = @{ 'X-Townlight-Session' = $session.session_hash }
    +Invoke-RestMethod -Uri 'http://127.0.0.1:15480/desktop/v1/meetings/station/catalog' -Headers $headers
    +Remove-Variable session, headers
    +

    A synthetic write +with subsequent readback

    +

    This example demonstrates the existing Meetings HTTP contract in an +isolated exercise. It is intentionally fictional. It does not start a +service. Its authentication setup is included so it can be run +independently under the signed-in synthetic account. If a write times +out, inspect current records before repeating it.

    +
    $profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite'
    +$sessionPath = Join-Path $profilePath 'config/local-session.json'
    +$session = Get-Content -LiteralPath $sessionPath -Raw | ConvertFrom-Json
    +$headers = @{ 'X-Townlight-Session' = $session.session_hash }
    +$body = @{
    +  title = 'Synthetic documentation exercise'
    +  scheduled_start = '2026-11-05T18:00:00-07:00'
    +  location = 'Synthetic room'
    +  meeting_type = 'regular'
    +} | ConvertTo-Json
    +$meeting = Invoke-RestMethod -Method Post `
    +  -Uri 'http://127.0.0.1:15480/desktop/v1/meetings/meetings' `
    +  -Headers $headers -ContentType 'application/json' -Body $body
    +Invoke-RestMethod `
    +  -Uri ('http://127.0.0.1:15480/desktop/v1/meetings/meetings/' + $meeting.id) `
    +  -Headers $headers
    +Remove-Variable session, headers
    +

    This write requires Meetings to be enabled and the signed-in staff +role to permit it. It is a cross-suite integration example; for this +product’s request models, use the complete technical reference +below.

    +

    Complete technical contract

    +

    Read the Meetings API +reference for every documented operation, request field, constraint, +response declaration and source supplement. Download the OpenAPI JSON for tools. +For Station this is the suite-side schema only; its separate service +contract is documented in the API supplement. The reference directory includes +configuration/source inventories, dependency declarations, native +command contracts, MCP signatures and candidate evidence.

    +

    MCP and automation boundary

    +

    No direct product MCP server is exposed by the accepted Townlight +desktop or Station boundary. Do not configure an invented +townlight mcp command or assume an AI client has staff +permissions. The integration surfaces for this beta are native IPC, the +documented HTTP APIs, source bundle imports, exact exports and the +existing Station CLI.

    +

    The bundled transcription code includes a TextFlowKit MCP +adapter as a separate source capability. It offers job-based +transcribe_media, get_transcript, +list_jobs, get_job_status and +export_transcript, and additional tools declared in that +adapter. It uses stdio first and optional Streamable HTTP, with the MCP +SDK as an optional extra. It is not automatically launched, +authenticated as Townlight staff or accepted as a Townlight product MCP +deployment. This documentation does not add such a service.

    +

    For a transcription client already provisioned separately, an +illustrative tool call is:

    +
    {"name":"get_job_status","arguments":{"job_id":"synthetic-existing-job-id"}}
    +

    Use a job ID returned by that transcription service. This example +does not create a Townlight record or bypass its review/Records handoff. +The exact optional adapter tool signatures are supplied in the MCP source reference. Station +meeting capture does not become live speech recognition because this +optional donor adapter exists.

    +

    Security and permissions

    +

    Use your own named account and save before leaving a screen. A saved +draft is durable; unsaved form text may not be. If a write has an +unknown result, reopen its record before repeating it.

    +

    Read source jurisdiction, dates, citation, version and visibility. A +copied source hash identifies exact bytes, not their legal +applicability. If a source changes or permission is removed, resolve the +source problem rather than substituting stale cached content.

    +

    Keep originals and derivatives separate. Review the intended audience +before export. A public summary excludes private fields only through the +applicable copy contract and your review. A renamed private packet is +still private content.

    +

    Drafting, review, approval, attachment, export, fulfillment and +publication are separate operations. A Townlight workpaper does not +itself adopt law, issue a permit, impose a fine or release a records +response. The responsible staff member records the applicable +decision.

    +

    The native session is validated and mapped to a persisted SQL +identity. An editable actor/reviewer label is not authentication. +Product/module permissions and source visibility apply at the server +boundary. Revoked/unavailable authority fails closed for new Station +operations; a previous permission result is not a perpetual +authorization.

    +

    Use protected local folders, account permissions and credential +storage. Never include the native session file, database passwords, +provider keys or unredacted support bundles in a public issue or +generated public documentation. A local public view is not automatically +a secured internet deployment. Keep network exposure and real equipment +acceptance specific to the chosen beta site.

    +

    Backup recovery and +maintenance

    +

    Save work and use Core’s canonical Backup Now before +maintenance. That operation stops writers. Preserve the coherent +profile/database/document backup and its receipt, then use +Start to resume. A source export is not a full +backup.

    +

    Use Restore Latest Backup through the supported +controls. If the result says Restore needs service +start, use Start, then Check, +and reopen a known record. Do not repeat restore merely because services +need to start. The fresh-profile acceptance verified that a fulfilled +request survived restore and a post-backup marker did not.

    +

    Keep Station’s dedicated database and media evidence together in its +own backup. Core’s native-profile backup must not be assumed to include +an external Station data directory. Stop writers during a coordinated +backup. Preserve failed media attempts and logs.

    +

    On failure, record the time, selected composition, +component/installer versions and exact message. Check System Health for +stopped, starting, ready or failed dependencies. Use the existing Retry +control after readiness; do not create duplicate business records to +refresh a stale view. Share only a redacted diagnostic bundle. Preserve +secrets, original evidence, recovery material and unrelated +installations.

    +

    Troubleshooting

    + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    SymptomLikely meaningNext action
    Workspace absentWrong product composition or unavailable canonical runtime.Check selected composition; activate through Finish Records +Migration; wait for readiness.
    Cannot sign in / 401Missing or expired named account session.Sign in normally; reopen a Station launch ticket if applicable.
    Permission denied / 403Account, module, source or browser-origin permission.Ask the authorized administrator to inspect the intended permission; +do not invent role headers.
    Save conflict / 409The saved revision, expected source hash or lifecycle changed.Keep edits, reopen current state and reconcile deliberately.
    Invalid input / 422Required field, format, geometry, source envelope or state is +invalid.Read the field detail and correct the input/source; preserve +originals.
    Service unavailable / 503Database, schema, connected source or configuration +unavailable.Inspect System Health and the named dependency. Preserve work; retry +only after readiness.
    Export refusedMissing exact review, approval, audience or source +authorization.Read the refusal and complete the owning product’s explicit +decision.
    Restore needs service startThe snapshot was restored but services have not resumed.Use Start, then Check and verify a saved record; do not blindly +repeat restore.
    +

    Verified workflows and +limits

    + +++++ + + + + + + + + + + + + + + +
    ProductRecorded resultPrecisely exercised
    MeetingsPASSMeeting/agenda, packet assembly, motion/vote, supplied transcript, +reviewed/adopted minutes, restricted local archive and proceedings +readback; Code decision integration.
    +

    These results come from the identified signed candidate’s fresh +normal-profile Sandbox exercise: real native IPC/HTTP/PostgreSQL and +selected headless controls. All accounts, source bundles and media were +synthetic. The guest install/uninstall and recovery passed, and the +owned Sandbox stopped. No host installed application or standalone +CivicCast was changed. This documentation task reuses those receipts; it +does not claim a new software acceptance run.

    +

    The workflow +matrix identifies raw receipt filenames. The evidence +index retains their original hashes; raw receipts remain in the +private beta handoff rather than being silently republished with the +documentation site.

    +

    The limits remain: actual city field acceptance and equipment/network +commissioning; Station automatic provisioning/SCM commissioning; every +UI/role combination; field recognition accuracy; and historical in-place +upgrades are not certified. They are not five invented feature +requirements. Fresh-install controlled beta handoff remains the accepted +scope. This package makes no city-deployment, publication or +general-availability claim.

    +

    Terms of service and license

    +

    Scope and status

    +

    These terms describe the Townlight Beta 1 software and this +documentation package. This is a locally prepared private beta, not a +hosted-service subscription, a city deployment agreement or a public +release. No uptime commitment, support response time, indemnity, +data-processing agreement or paid service is created by these documents. +A separate signed agreement, if any, governs services it actually +provides.

    +

    Software license and rights

    +

    Current Townlight-owned distributions identified in this candidate +use AGPL-3.0-only. The full license is supplied with +this documentation and with the source companion. The license governs +rights to run, copy, modify and convey the covered software; these +operational terms do not add restrictions to those rights. Historical +grants and dependency licenses retain their own terms. CivicCast remains +a separate product and is not relicensed by this documentation work.

    +

    When conveying covered software, retain applicable notices and +provide the corresponding source and installation/build information +required by the license. For a modified version supporting remote +network interaction, follow section 13’s source-offer requirement. The +companion archive identifies the source for this candidate; a link to a +different public branch is not a substitute for the matching source. +Read the supplied license for the complete conditions. See the GNU license +reference and GNU licensing +FAQ.

    +

    Data ownership and access

    +

    Importing a document does not transfer its ownership or grant +permission to publish it. The operating organization controls its +accounts, access decisions, lawful source use, retention and +review/release policy. Keep resident information, credentials, private +notes and restricted evidence in their authorized locations. +Documentation examples contain fictional data. No real city account, +credential or record is required to exercise these examples in an +isolated test environment.

    +

    Local operation and +external processors

    +

    The accepted beta workflow is local and uses named staff accounts. +Station has separate storage and credentials. Configure backup +destinations and optional model/network providers deliberately. A +configured external provider may receive submitted prompts, images or +audio according to that configuration and provider’s terms; this +documentation does not promise that every optional configuration is +offline. An email outbox or local public view does not establish +external delivery or an internet deployment. This static documentation +site has no analytics, account collection or remote font dependency.

    +

    Staff decisions and +source applicability

    +

    Staff verify the jurisdiction, source currency, permissions, +citations and proposed audience. Model output and generated guidance +require review. No draft is automatically an official legal +interpretation, zoning determination, permit approval, fee assessment, +enforcement notice or records-release decision. Official permit fee +authority remains with the adopted source and responsible organization; +imported amounts do not become a new authoritative calculation.

    +

    Beta operation and recovery

    +

    Use the identified candidate in its supported fresh-install scope. +Preserve backups and original evidence. Test physical equipment and +chosen network/service configuration before relying on them. The +supplied acceptance describes selected synthetic workflows, not every +screen, vendor, field condition or upgrade. Operators decide whether a +particular deployment meets their own operational obligations.

    +

    Warranty and liability

    +

    The covered software’s warranty and liability conditions are those in +sections 15–17 of the supplied AGPL and any applicable separate written +undertaking. This documentation creates no additional warranty or +limitation beyond those terms. Third-party software is subject to its +retained license notices. Nothing here removes rights that applicable +law makes nonwaivable.

    +

    Support and incident +reporting

    +

    Use the project’s existing SUPPORT and SECURITY guidance for its +matching repository. Report reproducible behavior with the version, +operation and redacted logs. Do not put credentials, resident records or +unredacted evidence in a public issue. Coordinate sensitive reports +through the channel designated in SECURITY. No new support address or +service commitment is invented here.

    +

    Ending a beta +exercise and document changes

    +

    When an organization ends testing, it controls retention/export and +removes access according to its policy. Uninstall may retain data; back +up and inspect the selected removal options. Ending an exercise does not +revoke rights already granted by AGPL. Later software/documentation +versions must identify their changed candidate and scope; historical +receipts retain their original identities. These terms do not claim that +a city has accepted a contract merely by reading a manual.

    +

    Glossary

    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TermMeaning
    ApprovalAn explicit authorized decision on the saved text/artifact. It is +separate from saving or attachment.
    Canonical recordThe owning product’s retained identity and saved version, rather +than an editable copied label.
    CompositionThe selected set of desktop modules; inspections-preview exposes the +eight staff products.
    Corresponding sourceThe source/build material matching the delivered covered program, +subject to its license.
    Derivative / Records copyA separately prepared document with its own intended audience and +hash.
    Hash / SHA256A fingerprint of exact bytes. It detects change; it does not +establish legal authority.
    IdempotencyRepeating the same identified request has the same intended effect; +changing its payload can be refused.
    IPCThe native desktop command boundary between its browser interface +and Rust host.
    MCPModel Context Protocol; no direct Townlight product server is +enabled by this beta.
    OriginalRetained source bytes. A reviewed derivative does not replace +them.
    ProvenanceSource, version, date, actor and relationship information retained +with evidence.
    RevisionAn immutable saved version. Later edits do not inherit an earlier +review automatically.
    SnapshotA fixed audience-specific copy tied to a source/reviewed +revision.
    StationTownlight’s separate media boundary using a pinned CivicCast-derived +engine; standalone CivicCast remains separate.
    +

    Alphabetical subject index

    + + + +

    Source and document control

    +

    This edition is authored from the immutable corresponding-source +companion, the generated installed-domain schema and the retained +workflow receipts. The current software versions and signed artifacts +are unchanged. Public historical pages are not synchronized or published +by this local documentation task.

    +

    Workflow subject index

    + +
    Townlight · AGPL-3.0-only · Candidate evidence applies only to its identified artifacts.
    \ No newline at end of file diff --git a/docs/beta-1/manuals/notice.html b/docs/beta-1/manuals/notice.html new file mode 100644 index 0000000..376638c --- /dev/null +++ b/docs/beta-1/manuals/notice.html @@ -0,0 +1,198 @@ + + +Townlight Notice Manual | Townlight candidate + +
    Townlight +
    +

    Naming, Access and Notice source candidate · 2 November 2026

    +

    Prepared documentation. Build, signing, installed acceptance and publication remain pending.

    + + +

    +

    Townlight Notice User Manual

    +

    Windows staff workflow — +0.3.0 candidate

    +

    This candidate is prepared; exact signed-installer acceptance is +pending. It supports a fresh profile, not an in-place upgrade of an +unmarked legacy database. The existing compatibility profile path is +retained and existing data is refused before initialization.

    +
      +
    1. Sign in with an account allowed to use Notice and open Public +Notices. Create a draft with title, actual notice text, type, event +date, staff-selected calendar lead days and staff-verified statutory +basis. Save it. Its deadline workpaper uses the shared Core reminder +helper; it does not establish legal sufficiency.
    2. +
    3. Select the saved notice, read the deadline workpaper and source, +enter review notes, then record staff review. Approve that saved +revision only after the responsible staff member has checked the law, +timing, content and channels. Mechanical rule success never removes the +staff-review requirement.
    4. +
    5. Perform official publication outside Townlight. Retain the actual +proof file (up to 5 MB each and 10 MB total for the current approved +content), posting location and actual posting date/time including time +zone. A filename, target system name or checklist alone is not posting +proof.
    6. +
    7. Create the archive after approval and proof. The archive contains +the actual notice, retained proof bytes, review/approval history and a +per-file SHA-256/size manifest. Write and verify the ZIP export to +preserve a usable file. ZIP entry timestamps are fixed for deterministic +packaging; the record contains the recorded posting and audit +times.
    8. +
    9. For a Records handoff, enter the intended Records request UUID and +select Attach archive to Records. This requires Records authority as +well as Notice authority. Townlight retains an exact managed copy, +verifies its hash, attaches it through the canonical Records writer and +reports the request/archive identity and hash. Repeating the same +handoff does not create a duplicate attachment. Open the request in +Records and read back the attached archive. Disclosure still requires +Records review/release authority.
    10. +
    +

    Saved notices and history can be reopened from Public Notices. A +content edit clears the prior review, approval and current proof +selection; historical events/proof/archives remain retained. A stale +open revision is rejected so staff must refresh and review the saved +content. Missing review, approval or actual proof blocks the +corresponding step. Back up/restore the matching complete new-format +profile through System Health; installed restart/recovery acceptance +remains required for this candidate.

    +

    This replaces the disconnected standalone Public Notices controls. +The separate Meetings notice/template/proof workflow remains available +for meeting-specific records; it does not silently approve a different +Notice draft. Staff remain responsible for legal sufficiency, official +publication and the official record. No subscriber message or official +notice is sent automatically.

    +

    Standalone package boundary

    +

    The standalone FastAPI routes below remain registry/deadline/proof +workpapers and deterministic planning helpers. The Windows authenticated +lifecycle above is provided by the suite runtime using Notice’s durable +workflow store; it is not a claim that every standalone helper performs +an archive or Records transfer. Fixed rule packs are review aids and are +not administered jurisdiction/effective-date legal rules. +Subscriber/channel/accessibility/export helpers retain their documented +planning boundaries.

    +

    For Non-Technical Users

    +

    Townlight Notice helps city staff organize public hearing notices, +legal notices, bid notices, vacancy notices, publication deadlines, +channel planning notes, accessibility and language-readiness checks, +proof requirements, subscriber delivery plans, archive/handoff packets, +and export manifests. It can create a sample notice registry stub, build +publication deadline reminders, check a draft packet against +deterministic staff-review rules, create a staff-editable notice +template, retrieve saved registry/deadline/publication-proof workpapers +when IT enables persistence, assemble publication-readiness checklists, +summarize channel planning, build +accessibility/plain-language/translation readiness packets, build +subscriber delivery plans, assemble archive/handoff packets, and +assemble a notice/records export checklist.

    +

    Release state: 0.3.0 is the prepared naming/lifecycle candidate, +paired with Townlight Core 1.3.0.dev2. No new standalone release or +installed acceptance is claimed here.

    +

    For IT and Technical Staff

    +

    Townlight Notice is a FastAPI Python package pinned to the +townlight-core 1.3.0.dev2 release wheel. The current +runtime exposes:

    +

    Set TOWNLIGHT_NOTICE_WORKPAPER_DB_URL to enable +SQLAlchemy-backed notice registry, deadline-plan, and publication-proof +records. Leave it unset for deterministic stateless operation: registry +and deadline POST requests return transient payloads, persisted GET +routes return actionable 503 responses, and publication-proof storage is +unavailable. When persistence is enabled, set +TOWNLIGHT_NOTICE_TRUSTED_WRITE_TOKEN and send the matching +X-Townlight-Notice-Write-Token header for durable write +routes.

    +
      +
    • GET /
    • +
    • GET /health
    • +
    • GET /townlight_notice
    • +
    • GET /docs
    • +
    • GET /openapi.json
    • +
    • POST /api/v1/townlight_notice/registry
    • +
    • GET /api/v1/townlight_notice/registry/{record_id}
    • +
    • POST /api/v1/townlight_notice/deadlines
    • +
    • GET /api/v1/townlight_notice/deadlines/{plan_id}
    • +
    • POST /api/v1/townlight_notice/rule-check
    • +
    • POST /api/v1/townlight_notice/templates
    • +
    • POST /api/v1/townlight_notice/publication-proof
    • +
    • GET /api/v1/townlight_notice/publication-proof/{proof_id}
    • +
    • POST /api/v1/townlight_notice/publication-check
    • +
    • POST /api/v1/townlight_notice/accessibility-review
    • +
    • POST /api/v1/townlight_notice/channels
    • +
    • POST /api/v1/townlight_notice/subscribers/plan
    • +
    • POST /api/v1/townlight_notice/archive-packet
    • +
    • POST /api/v1/townlight_notice/export
    • +
    +

    +

    Start and Smoke-Check +Townlight Notice

    +

    A fresh user can reach the core stateless API and public sample UI +without a database, model server, account, or API key. Start the ASGI +app target townlight_notice.main:app, then confirm +/health reports Townlight Notice 0.3.0 and +Townlight Core 1.2.0.

    +

    Minimal smoke-check workflow:

    +
      +
    1. Create a transient registry stub with +/api/v1/townlight_notice/registry.
    2. +
    3. Open /docs or /openapi.json to inspect +accepted fields, then create a deterministic rule check with +/api/v1/townlight_notice/rule-check. Unsupported notice +types return supported choices instead of silently falling back to a +generic rule.
    4. +
    5. Open /townlight_notice and confirm it is a static +public sample with boundary copy.
    6. +
    7. If durable workpapers are enabled, confirm the trusted write token +is configured before testing persistence-backed writes.
    8. +
    +

    Run:

    +
    python -m pip install -e ".[dev]"
    +python -m pytest -q
    +bash scripts/verify-release.sh
    +

    Architecture

    +
    flowchart LR
    +  Staff["Clerk / communications / purchasing staff"] --> Townlight Notice["Townlight Notice"]
    +  Townlight Notice --> Townlight Core["Townlight Core 1.3.0.dev2"]
    +  Townlight Notice -. future handoff .-> Townlight Meetings["Townlight Meetings v0.1.0"]
    +  Townlight Notice -. future handoff .-> CivicProcure["CivicProcure v0.1.1"]
    +  Townlight Notice --> Export["Notice and records export checklist"]
    +

    Townlight Notice depends on Townlight Core. Townlight Core does not +depend on Townlight Notice. Townlight Notice v0.3.0 uses the shared +Townlight Core notice deadline helper plus deterministic sample notice +data, staff-review rule packs, notice templates, accessibility and +language-readiness packets, subscriber delivery plans, archive/handoff +packets, and optional publication-proof workpapers only; live +agenda/procurement handoffs, legal sufficiency decisions, legal advice, +official notice publication, publication-system write-back, and +production notice-system integrations are future work.

    +
    Townlight · AGPL-3.0-only · Candidate evidence applies only to its identified artifacts.
    \ No newline at end of file diff --git a/docs/beta-1/manuals/permitting.html b/docs/beta-1/manuals/permitting.html new file mode 100644 index 0000000..cbcf4b7 --- /dev/null +++ b/docs/beta-1/manuals/permitting.html @@ -0,0 +1,981 @@ + + +Townlight Permitting Manual | Townlight candidate + +
    Townlight +
    +

    Naming, Access and Notice source candidate · 2 November 2026

    +

    Prepared documentation. Build, signing, installed acceptance and publication remain pending.

    + + +

    Townlight Permitting Manual

    +

    Townlight Beta 1 · Naming candidate documentation +edition 2 November 2026

    +

    Contents

    + +

    Using this manual

    +

    Townlight Permitting helps permit intake staff and development-review +coordinators. Permitting supports pre-application and development-review +intake. It imports retained requirements, produces source-grounded +material/pathway guidance, saves reviewed cases and prepares a separate +Records copy.

    +

    Staff should begin with First run and Daily workflow. Administrators +should also read Architecture, Technical specifications, Configuration, +Security and Recovery. Developers should use the exact API/data +dictionary and examples. The table of contents and alphabetical subject +index link to the relevant sections in the HTML edition; the PDF +preserves headings and searchable text. An editable Word edition is +included with the same documentation companion.

    +

    Beta identity

    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    IdentityValue
    DocumentationTownlight Beta 1 naming, Access and Notice candidate
    Intended installer version1.7.0.1; build and acceptance pending
    Product componenttownlight-permitting 0.3.0+dev.2
    Principal import packagetownlight_permitting
    Native desktop source version1.7.0-1
    Candidate hashesPending candidate build, signing and installed acceptance
    Current owned software licenseAGPL-3.0-only
    Acceptance compositionFresh Windows x64 profile; inspections-preview; Station configured +separately
    +

    The naming change advances this package’s version and requires a new +signed installer and installed acceptance. Those steps and publication +remain pending. Historical tags, receipts and archived manuals keep +their original names and certify only their identified artifacts. Use an +empty database and fresh profile; no in-place legacy upgrade is +supported. The approved Windows profile path remains +%LOCALAPPDATA%\CivicSuite. Preserve existing profiles, data +and recovery material.

    +

    First run

    +
      +
    1. Obtain the identified signed private candidate and its +corresponding-source companion from the beta coordinator. The landing +pages in this documentation are not an installer download service.
    2. +
    3. On the intended fresh Windows test installation, verify the MSI hash +and publisher signature before installing. Preserve unrelated profiles +and recovery material. Installed acceptance for this source candidate +remains pending; no in-place legacy upgrade is supported.
    4. +
    5. Launch Townlight under the intended named Windows account. Choose +the storage folders. Select Townlight Inspections +candidate (inspections-preview) for the bounded +desktop composition, including Access and Notice. A narrower default +selection will not expose all workspaces.
    6. +
    7. Enter the city profile, time zone and contacts. Create the first +named local administrator, sign in and choose protected backup storage. +Continue without local AI is valid for the +deterministic workflows.
    8. +
    9. Run Health Check and wait for readiness. Open Townlight. In System +Health select Finish Records Migration to activate the +canonical Python/PostgreSQL runtime. Do not fabricate migration receipts +or seed accounts.
    10. +
    11. Create named staff through Settings. Import authorized sources using +each product’s source library. All examples in this package are +synthetic; they are not municipal authority.
    12. +
    13. Provision Station separately if it is part of the beta exercise. +Selecting the desktop composition does not start or configure Station. +Configure vision explicitly only if automatic photo drafting is +selected.
    14. +
    +

    Daily workflow

    +

    +

    1. Import requirements

    +

    Open Requirement library and select the complete JSON +RequirementBundle. Inspect jurisdiction, project type, effective/source +dates, original filename/hash and material citations. Later revisions +require the current revision and preserve history.

    +

    +

    2. Read pathway guidance

    +

    Choose the retained requirement revision and matching project type. +Inspect material requirements, pathway steps and source-backed +timing/fee text. If authority is absent, seek the source; do not invent +a requirement, date or fee.

    +

    +

    3. Prepare intake

    +

    Create the case with project, location, applicant contact and staff +assignment. Assess materials as not reviewed, provided, missing or +unclear. Keep private notes and the proposal separate from the public +summary.

    +

    +

    4. Select cited context

    +

    Search Code and Zoning and choose the exact permitted versions. +Source availability and expected hashes are checked during search, save +and export.

    +

    +

    5. Save and review

    +

    Save the intake, reopen it and reconcile revision conflicts. Record +staff review with review notes. The trusted staff path derives the +reviewer; later edits require a new review.

    +

    +

    6. Inspect each audience

    +

    A staff packet can contain private detail. A Records copy uses the +separately reviewed public summary and excludes applicant contact, +location, proposal, material notes and private staff notes. Preview it +before creating it.

    +

    +

    7. Attach and verify

    +

    Attach the exact hash-checked copy to an existing Records request. +Reopen Records and inspect it. Records retains its separate release, +approval and fulfillment controls.

    +

    Working safely

    +

    Use your own named account and save before leaving a screen. A saved +draft is durable; unsaved form text may not be. If a write has an +unknown result, reopen its record before repeating it.

    +

    Read source jurisdiction, dates, citation, version and visibility. A +copied source hash identifies exact bytes, not their legal +applicability. If a source changes or permission is removed, resolve the +source problem rather than substituting stale cached content.

    +

    Keep originals and derivatives separate. Review the intended audience +before export. A public summary excludes private fields only through the +applicable copy contract and your review. A renamed private packet is +still private content.

    +

    Drafting, review, approval, attachment, export, fulfillment and +publication are separate operations. A Townlight workpaper does not +itself adopt law, issue a permit, impose a fine or release a records +response. The responsible staff member records the applicable +decision.

    +

    Connected workflows

    +

    Consumes Code and Zoning evidence and hands a reviewed Records copy +to an existing request. There is no automatic creation of an Inspections +case.

    + ++++ + + + + + + + + + + + + + + + + +
    DirectionMaterial
    InputA complete RequirementBundle with jurisdiction, project type, source +dates, originals and citations; proposal/contact details; permitted +Code/Zoning sources.
    OutputSource-grounded guidance, saved reviewed intake workpapers and an +exact audience-specific packet or Records handoff.
    +

    Product boundary

    +

    Does not issue permits, collect money, calculate authoritative permit +fees, schedule inspections or write decisions to a commercial permit +system. Imported official fee amounts or fee-source wording are +information from their source, not a new authoritative calculation. +Universal vendor status mirroring and an internet applicant portal are +outside this beta scope.

    +

    Architecture

    +
    + + +
    +

    The drawing shows the principal staff/evidence path. Native commands +carry trusted identity to Python business services; PostgreSQL and +retained original files hold durable state. A downstream copy does not +silently transfer decision authority. Station has its own configured +authority/media boundary, database and mutable files. The +connected-workflow text supplies the drawing’s reading order and +accessibility alternative.

    +

    Describe a +project and read source grounded guidance

    +
      +
    1. Import and verify the complete requirement bundle in +Requirement library. Retain its actual revision and +matching project type. A bundle for a different project type is not +interchangeable authority.
    2. +
    3. Open Describe your project. Enter the +project type, retained requirement +revision, your proposal and location +context. The proposal explains the contemplated work; location +context helps staff understand applicability. Keep private applicant +contact and staff notes in their intended intake fields rather than a +public explanation.
    4. +
    5. Request the existing pathway. Read required materials, cited steps +and any source-backed timing or fee information together with the +retained sources.
    6. +
    7. Inspect the unavailable items. The application can +return useful cited material and also explicitly lack authority for a +fee, duration or stage. Obtain an applicable source or leave it +unavailable; do not turn a blank into zero or a guessed deadline.
    8. +
    9. If preparing a case, save the intake separately, select actual +Code/Zoning authority, record staff review and inspect the public copy +before the Records handoff. Requesting guidance is not issuance or +approval.
    10. +
    +

    An authenticated request to +POST /desktop/v1/permitting/pathway can use:

    +
    {"project_type":"synthetic-deck","requirement_revision":"11111111-1111-4111-8111-111111111111","proposal":"Replace a synthetic residential deck","location_context":"Fictional test parcel"}
    +

    Replace the revision and project type with the matching retained +synthetic bundle. The API’s optional fee_link is an exact +permitted source link when the client can supply one; it is not a fee +formula or arbitrary amount. The native Describe your project form does +not become a fee-authority editor. Imported official amounts and +explanatory estimates retain their source and informational status. No +authoritative fee calculation, payment collection, live-model call, +vendor status mirror or new portal is added by this workflow.

    +

    Expected readback is the source-grounded guidance together with +citations and explicitly unavailable items. Check actual source +identity/hash and review-required/informational indicators, rather than +treating a successful HTTP response as proof of complete or +authoritative guidance. Read the full returned shape in the API +reference and preserve a copy only through the existing +saved-case/review contracts.

    +

    Source contracts: townlight_permitting/pathway.py, +requirement source models, +townlight_runtime/permitting_bridge.py and the Permitting +view.

    +

    Technical specifications

    +

    Runtime and storage

    +

    The accepted package targets Windows x64 fresh +installation. Its native shell uses Rust 2021, Tauri 2 +and Microsoft WebView2; browser assets are JavaScript built +with Vite 8.1.6. This describes the native desktop +frontend; Station has a separate React operator, specified below or in +its product manual. Canonical business workflows use bundled +CPython 3.13.5, FastAPI, Pydantic, SQLAlchemy and +Alembic, with PostgreSQL 17 / PostGIS and +managed original files. The installed runtime tested here contains +FastAPI 0.162.0. Package minimum Python requirements can differ from the +bundled executable; the metadata reference preserves both. No stack +rewrite is implied by the beta label.

    +

    The native transport is fixed to loopback +127.0.0.1:15480; PostgreSQL uses the configured local +runtime port (default 15432). Optional local model service +defaults to 127.0.0.1:15434. Those are deployment defaults, +not internet endpoints. The runtime has health, module and readiness +endpoints; readiness is stronger than process existence. The task queue +is the existing local Core task infrastructure, not an assertion that a +separate Redis service is required for this desktop composition.

    +

    The default native profile is %LOCALAPPDATA%\CivicSuite; +the historical directory name remains part of compatibility. Do not +rename it to Townlight. A configured TOWNLIGHT_PROFILE_ROOT +must be absolute. Local configuration and secrets live under that +profile; protected managed files and database state must be backed up +coherently. Source/runtime identity is distinct from a product’s display +label.

    +

    Data and consistency

    +

    Requirement bundles and immutable revisions; cited materials and +pathway steps; source timing and fee information; intake cases and +revisions; material assessments; reviews; staff and Records packets.

    +

    Versioned saves use expected prior revision identifiers where +defined. Reopen and reconcile on conflict. Exact exports and handoffs +use source IDs, current visibility, revision and SHA256. Review belongs +to the saved revision and does not transfer silently to edited text. +Database changes use the owning product’s migrations; a request or +readiness check is not an authorization to mutate schema.

    +

    Capacity and platform +statements

    +

    This beta has synthetic single-profile workflow evidence. It does not +have a published benchmark for concurrent staff capacity, minimum +RAM/CPU, large-source limits or a field SLA. Do not turn a developer +machine’s specification into a supported minimum. The new installer size +remains pending its build; allow additional disk for extracted runtime, +database, originals, exports, media and backups. Select +equipment/storage after sizing those actual workloads.

    +

    The exact runtime payload +lock records pinned files, sizes and hashes. The component +metadata records shipped dependency declarations. These references +are more precise than a manually copied dependency list. Third-party and +historical license notices must accompany their matching payloads.

    +

    Configuration and +administration

    +

    Native deployment +configuration

    +

    Use Setup, Settings and System Health for supported staff operation. +Administrators provision folders, backup storage, named accounts and the +city profile. Select inspections-preview for the bounded +desktop composition, including Access and Notice. Station remains a +separate service boundary. Do not use a standalone product’s demo server +as a substitute for the installed workspace.

    +

    Technical deployments use TOWNLIGHT_PRODUCT_PROFILE, +TOWNLIGHT_PROFILE_ROOT, DATABASE_URL, +TOWNLIGHT_RUNTIME_PORT, PORTAL_MODE and the +runtime-managed secret files. Treat database URLs and native session +proofs as secrets. The installed native domain runtime explicitly +refuses non-loopback binding. PORTAL_MODE=private is the +accepted posture; changing it does not by itself commission an internet +portal, authentication provider or reverse proxy.

    +

    The isolated documentation exporter sets a fictional profile and +unusable synthetic database origin only to read schemas; those values +are not deployment configuration. Keep deployment values in the intended +process/account scope. An already-running process does not automatically +inherit later environment edits.

    +

    Requirement source +configuration

    +

    The supported requirement source is a complete versioned JSON bundle, +not an editable label pointing to an absent file. It retains project +type, source/effective dates, original name/hash and citations. Import a +later revision against the current expected revision. Pathway dates and +fee text must be tied to that retained authority. No official fee engine +or commercial permitting writeback is configured by this manual.

    +

    API and integration examples

    +

    Native command example

    +

    The following JavaScript belongs in the existing trusted Townlight +frontend/development environment with invoke imported from +@tauri-apps/api/core. It is not a command for an arbitrary +web page or an instruction for nontechnical staff. IDs must come from +records created in an isolated synthetic exercise.

    +
    import { invoke } from '@tauri-apps/api/core';
    +const result = await invoke('permitting_domain_request', {request: {operation: 'requirements', offset: 0}});
    +console.log(result);
    +

    Trusted local HTTP example

    +

    An administrator/developer can inspect an already-configured isolated +runtime from a trusted local process. This PowerShell example reads the +signed-in synthetic profile’s existing proof into memory; it does not +create a user, seed a session, reveal the proof in output or bypass a +permission check. Do not use real city data in development examples. A +read response does not prove approval or publication.

    +
    $profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite'
    +$sessionPath = Join-Path $profilePath 'config\local-session.json'
    +$session = Get-Content -LiteralPath $sessionPath -Raw | ConvertFrom-Json
    +$headers = @{ 'X-Townlight-Session' = $session.session_hash }
    +Invoke-RestMethod -Uri 'http://127.0.0.1:15480/desktop/v1/permitting/requirements' -Headers $headers
    +Remove-Variable session, headers
    +

    Complete synthetic source +bundle

    +

    The synthetic +Permitting bundle is the retained fixture used by the beta staff +exercise. It includes the complete supported source envelope rather than +a shortened pseudo-payload. Keep its fictional source labels. For +Planning, wrap it as +{"bundle": BUNDLE, "expected_previous_revision": null}; for +Permitting use +{"bundle": BUNDLE, "expected_revision": null}. Code and +Zoning take their own complete import envelopes. Replace null with the +current expected revision when revising an existing source, as the +applicable schema requires. These are import examples, not legal +authority or permission to load them into a live city profile.

    +

    A synthetic write +with subsequent readback

    +

    This example demonstrates the existing Meetings HTTP contract in an +isolated exercise. It is intentionally fictional. It does not start a +service. Its authentication setup is included so it can be run +independently under the signed-in synthetic account. If a write times +out, inspect current records before repeating it.

    +
    $profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite'
    +$sessionPath = Join-Path $profilePath 'config/local-session.json'
    +$session = Get-Content -LiteralPath $sessionPath -Raw | ConvertFrom-Json
    +$headers = @{ 'X-Townlight-Session' = $session.session_hash }
    +$body = @{
    +  title = 'Synthetic documentation exercise'
    +  scheduled_start = '2026-11-05T18:00:00-07:00'
    +  location = 'Synthetic room'
    +  meeting_type = 'regular'
    +} | ConvertTo-Json
    +$meeting = Invoke-RestMethod -Method Post `
    +  -Uri 'http://127.0.0.1:15480/desktop/v1/meetings/meetings' `
    +  -Headers $headers -ContentType 'application/json' -Body $body
    +Invoke-RestMethod `
    +  -Uri ('http://127.0.0.1:15480/desktop/v1/meetings/meetings/' + $meeting.id) `
    +  -Headers $headers
    +Remove-Variable session, headers
    +

    This write requires Meetings to be enabled and the signed-in staff +role to permit it. It is a cross-suite integration example; for this +product’s request models, use the complete technical reference +below.

    +

    Complete technical contract

    +

    Read the Permitting API +reference for every documented operation, request field, constraint, +response declaration and source supplement. Download the OpenAPI JSON for +tools. For Station this is the suite-side schema only; its separate +service contract is documented in the API supplement. The reference directory includes +configuration/source inventories, dependency declarations, native +command contracts, MCP signatures and candidate evidence.

    +

    MCP and automation boundary

    +

    No direct product MCP server is exposed by the accepted Townlight +desktop or Station boundary. Do not configure an invented +townlight mcp command or assume an AI client has staff +permissions. The integration surfaces for this beta are native IPC, the +documented HTTP APIs, source bundle imports, exact exports and the +existing Station CLI.

    +

    The bundled transcription code includes a TextFlowKit MCP +adapter as a separate source capability. It offers job-based +transcribe_media, get_transcript, +list_jobs, get_job_status and +export_transcript, and additional tools declared in that +adapter. It uses stdio first and optional Streamable HTTP, with the MCP +SDK as an optional extra. It is not automatically launched, +authenticated as Townlight staff or accepted as a Townlight product MCP +deployment. This documentation does not add such a service.

    +

    For a transcription client already provisioned separately, an +illustrative tool call is:

    +
    {"name":"get_job_status","arguments":{"job_id":"synthetic-existing-job-id"}}
    +

    Use a job ID returned by that transcription service. This example +does not create a Townlight record or bypass its review/Records handoff. +The exact optional adapter tool signatures are supplied in the MCP source reference. Station +meeting capture does not become live speech recognition because this +optional donor adapter exists.

    +

    Security and permissions

    +

    Use your own named account and save before leaving a screen. A saved +draft is durable; unsaved form text may not be. If a write has an +unknown result, reopen its record before repeating it.

    +

    Read source jurisdiction, dates, citation, version and visibility. A +copied source hash identifies exact bytes, not their legal +applicability. If a source changes or permission is removed, resolve the +source problem rather than substituting stale cached content.

    +

    Keep originals and derivatives separate. Review the intended audience +before export. A public summary excludes private fields only through the +applicable copy contract and your review. A renamed private packet is +still private content.

    +

    Drafting, review, approval, attachment, export, fulfillment and +publication are separate operations. A Townlight workpaper does not +itself adopt law, issue a permit, impose a fine or release a records +response. The responsible staff member records the applicable +decision.

    +

    The native session is validated and mapped to a persisted SQL +identity. An editable actor/reviewer label is not authentication. +Product/module permissions and source visibility apply at the server +boundary. Revoked/unavailable authority fails closed for new Station +operations; a previous permission result is not a perpetual +authorization.

    +

    Use protected local folders, account permissions and credential +storage. Never include the native session file, database passwords, +provider keys or unredacted support bundles in a public issue or +generated public documentation. A local public view is not automatically +a secured internet deployment. Keep network exposure and real equipment +acceptance specific to the chosen beta site.

    +

    Backup recovery and +maintenance

    +

    Save work and use Core’s canonical Backup Now before +maintenance. That operation stops writers. Preserve the coherent +profile/database/document backup and its receipt, then use +Start to resume. A source export is not a full +backup.

    +

    Use Restore Latest Backup through the supported +controls. If the result says Restore needs service +start, use Start, then Check, +and reopen a known record. Do not repeat restore merely because services +need to start. The fresh-profile acceptance verified that a fulfilled +request survived restore and a post-backup marker did not.

    +

    Keep Station’s dedicated database and media evidence together in its +own backup. Core’s native-profile backup must not be assumed to include +an external Station data directory. Stop writers during a coordinated +backup. Preserve failed media attempts and logs.

    +

    On failure, record the time, selected composition, +component/installer versions and exact message. Check System Health for +stopped, starting, ready or failed dependencies. Use the existing Retry +control after readiness; do not create duplicate business records to +refresh a stale view. Share only a redacted diagnostic bundle. Preserve +secrets, original evidence, recovery material and unrelated +installations.

    +

    Troubleshooting

    + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    SymptomLikely meaningNext action
    Workspace absentWrong product composition or unavailable canonical runtime.Check selected composition; activate through Finish Records +Migration; wait for readiness.
    Cannot sign in / 401Missing or expired named account session.Sign in normally; reopen a Station launch ticket if applicable.
    Permission denied / 403Account, module, source or browser-origin permission.Ask the authorized administrator to inspect the intended permission; +do not invent role headers.
    Save conflict / 409The saved revision, expected source hash or lifecycle changed.Keep edits, reopen current state and reconcile deliberately.
    Invalid input / 422Required field, format, geometry, source envelope or state is +invalid.Read the field detail and correct the input/source; preserve +originals.
    Service unavailable / 503Database, schema, connected source or configuration +unavailable.Inspect System Health and the named dependency. Preserve work; retry +only after readiness.
    Export refusedMissing exact review, approval, audience or source +authorization.Read the refusal and complete the owning product’s explicit +decision.
    Restore needs service startThe snapshot was restored but services have not resumed.Use Start, then Check and verify a saved record; do not blindly +repeat restore.
    +

    Verified workflows and +limits

    + +++++ + + + + + + + + + + + + + + +
    ProductRecorded resultPrecisely exercised
    PermittingPASSRetained requirement import, source-grounded +materials/pathway/timing, saved intake/review, separate hash-checked +Records copy and private handoff; contact exclusion; native +workspace.
    +

    These results come from the identified signed candidate’s fresh +normal-profile Sandbox exercise: real native IPC/HTTP/PostgreSQL and +selected headless controls. All accounts, source bundles and media were +synthetic. The guest install/uninstall and recovery passed, and the +owned Sandbox stopped. No host installed application or standalone +CivicCast was changed. This documentation task reuses those receipts; it +does not claim a new software acceptance run.

    +

    The workflow +matrix identifies raw receipt filenames. The evidence +index retains their original hashes; raw receipts remain in the +private beta handoff rather than being silently republished with the +documentation site.

    +

    The limits remain: actual city field acceptance and equipment/network +commissioning; Station automatic provisioning/SCM commissioning; every +UI/role combination; field recognition accuracy; and historical in-place +upgrades are not certified. They are not five invented feature +requirements. Fresh-install controlled beta handoff remains the accepted +scope. This package makes no city-deployment, publication or +general-availability claim.

    +

    Terms of service and license

    +

    Scope and status

    +

    These terms describe the Townlight Beta 1 software and this +documentation package. This is a locally prepared private beta, not a +hosted-service subscription, a city deployment agreement or a public +release. No uptime commitment, support response time, indemnity, +data-processing agreement or paid service is created by these documents. +A separate signed agreement, if any, governs services it actually +provides.

    +

    Software license and rights

    +

    Current Townlight-owned distributions identified in this candidate +use AGPL-3.0-only. The full license is supplied with +this documentation and with the source companion. The license governs +rights to run, copy, modify and convey the covered software; these +operational terms do not add restrictions to those rights. Historical +grants and dependency licenses retain their own terms. CivicCast remains +a separate product and is not relicensed by this documentation work.

    +

    When conveying covered software, retain applicable notices and +provide the corresponding source and installation/build information +required by the license. For a modified version supporting remote +network interaction, follow section 13’s source-offer requirement. The +companion archive identifies the source for this candidate; a link to a +different public branch is not a substitute for the matching source. +Read the supplied license for the complete conditions. See the GNU license +reference and GNU licensing +FAQ.

    +

    Data ownership and access

    +

    Importing a document does not transfer its ownership or grant +permission to publish it. The operating organization controls its +accounts, access decisions, lawful source use, retention and +review/release policy. Keep resident information, credentials, private +notes and restricted evidence in their authorized locations. +Documentation examples contain fictional data. No real city account, +credential or record is required to exercise these examples in an +isolated test environment.

    +

    Local operation and +external processors

    +

    The accepted beta workflow is local and uses named staff accounts. +Station has separate storage and credentials. Configure backup +destinations and optional model/network providers deliberately. A +configured external provider may receive submitted prompts, images or +audio according to that configuration and provider’s terms; this +documentation does not promise that every optional configuration is +offline. An email outbox or local public view does not establish +external delivery or an internet deployment. This static documentation +site has no analytics, account collection or remote font dependency.

    +

    Staff decisions and +source applicability

    +

    Staff verify the jurisdiction, source currency, permissions, +citations and proposed audience. Model output and generated guidance +require review. No draft is automatically an official legal +interpretation, zoning determination, permit approval, fee assessment, +enforcement notice or records-release decision. Official permit fee +authority remains with the adopted source and responsible organization; +imported amounts do not become a new authoritative calculation.

    +

    Beta operation and recovery

    +

    Use the identified candidate in its supported fresh-install scope. +Preserve backups and original evidence. Test physical equipment and +chosen network/service configuration before relying on them. The +supplied acceptance describes selected synthetic workflows, not every +screen, vendor, field condition or upgrade. Operators decide whether a +particular deployment meets their own operational obligations.

    +

    Warranty and liability

    +

    The covered software’s warranty and liability conditions are those in +sections 15–17 of the supplied AGPL and any applicable separate written +undertaking. This documentation creates no additional warranty or +limitation beyond those terms. Third-party software is subject to its +retained license notices. Nothing here removes rights that applicable +law makes nonwaivable.

    +

    Support and incident +reporting

    +

    Use the project’s existing SUPPORT and SECURITY guidance for its +matching repository. Report reproducible behavior with the version, +operation and redacted logs. Do not put credentials, resident records or +unredacted evidence in a public issue. Coordinate sensitive reports +through the channel designated in SECURITY. No new support address or +service commitment is invented here.

    +

    Ending a beta +exercise and document changes

    +

    When an organization ends testing, it controls retention/export and +removes access according to its policy. Uninstall may retain data; back +up and inspect the selected removal options. Ending an exercise does not +revoke rights already granted by AGPL. Later software/documentation +versions must identify their changed candidate and scope; historical +receipts retain their original identities. These terms do not claim that +a city has accepted a contract merely by reading a manual.

    +

    Glossary

    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TermMeaning
    ApprovalAn explicit authorized decision on the saved text/artifact. It is +separate from saving or attachment.
    Canonical recordThe owning product’s retained identity and saved version, rather +than an editable copied label.
    CompositionThe selected set of desktop modules; inspections-preview exposes the +eight staff products.
    Corresponding sourceThe source/build material matching the delivered covered program, +subject to its license.
    Derivative / Records copyA separately prepared document with its own intended audience and +hash.
    Hash / SHA256A fingerprint of exact bytes. It detects change; it does not +establish legal authority.
    IdempotencyRepeating the same identified request has the same intended effect; +changing its payload can be refused.
    IPCThe native desktop command boundary between its browser interface +and Rust host.
    MCPModel Context Protocol; no direct Townlight product server is +enabled by this beta.
    OriginalRetained source bytes. A reviewed derivative does not replace +them.
    ProvenanceSource, version, date, actor and relationship information retained +with evidence.
    RevisionAn immutable saved version. Later edits do not inherit an earlier +review automatically.
    SnapshotA fixed audience-specific copy tied to a source/reviewed +revision.
    StationTownlight’s separate media boundary using a pinned CivicCast-derived +engine; standalone CivicCast remains separate.
    +

    Alphabetical subject index

    + + + +

    Source and document control

    +

    This edition is authored from the immutable corresponding-source +companion, the generated installed-domain schema and the retained +workflow receipts. The current software versions and signed artifacts +are unchanged. Public historical pages are not synchronized or published +by this local documentation task.

    +

    Workflow subject index

    + +
    Townlight · AGPL-3.0-only · Candidate evidence applies only to its identified artifacts.
    \ No newline at end of file diff --git a/docs/beta-1/manuals/planning.html b/docs/beta-1/manuals/planning.html new file mode 100644 index 0000000..d6066c9 --- /dev/null +++ b/docs/beta-1/manuals/planning.html @@ -0,0 +1,1013 @@ + + +Townlight Planning Manual | Townlight candidate + +
    Townlight +
    +

    Naming, Access and Notice source candidate · 2 November 2026

    +

    Prepared documentation. Build, signing, installed acceptance and publication remain pending.

    + + +

    Townlight Planning Manual

    +

    Townlight Beta 1 · Naming candidate documentation +edition 2 November 2026

    +

    Contents

    + +

    Using this manual

    +

    Townlight Planning helps planning staff, municipal policy reviewers +and authorized administrators. Planning retains adopted policy imports +and neighborhood applicability, saved staff analyses, reviewed +snapshots, municipal initiatives and amendment history. An analysis or +amendment draft does not adopt policy.

    +

    Staff should begin with First run and Daily workflow. Administrators +should also read Architecture, Technical specifications, Configuration, +Security and Recovery. Developers should use the exact API/data +dictionary and examples. The table of contents and alphabetical subject +index link to the relevant sections in the HTML edition; the PDF +preserves headings and searchable text. An editable Word edition is +included with the same documentation companion.

    +

    Beta identity

    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    IdentityValue
    DocumentationTownlight Beta 1 naming, Access and Notice candidate
    Intended installer version1.7.0.1; build and acceptance pending
    Product componenttownlight-planning 0.4.0.dev2
    Principal import packagetownlight_planning
    Native desktop source version1.7.0-1
    Candidate hashesPending candidate build, signing and installed acceptance
    Current owned software licenseAGPL-3.0-only
    Acceptance compositionFresh Windows x64 profile; inspections-preview; Station configured +separately
    +

    The naming change advances this package’s version and requires a new +signed installer and installed acceptance. Those steps and publication +remain pending. Historical tags, receipts and archived manuals keep +their original names and certify only their identified artifacts. Use an +empty database and fresh profile; no in-place legacy upgrade is +supported. The approved Windows profile path remains +%LOCALAPPDATA%\CivicSuite. Preserve existing profiles, data +and recovery material.

    +

    First run

    +
      +
    1. Obtain the identified signed private candidate and its +corresponding-source companion from the beta coordinator. The landing +pages in this documentation are not an installer download service.
    2. +
    3. On the intended fresh Windows test installation, verify the MSI hash +and publisher signature before installing. Preserve unrelated profiles +and recovery material. Installed acceptance for this source candidate +remains pending; no in-place legacy upgrade is supported.
    4. +
    5. Launch Townlight under the intended named Windows account. Choose +the storage folders. Select Townlight Inspections +candidate (inspections-preview) for the bounded +desktop composition, including Access and Notice. A narrower default +selection will not expose all workspaces.
    6. +
    7. Enter the city profile, time zone and contacts. Create the first +named local administrator, sign in and choose protected backup storage. +Continue without local AI is valid for the +deterministic workflows.
    8. +
    9. Run Health Check and wait for readiness. Open Townlight. In System +Health select Finish Records Migration to activate the +canonical Python/PostgreSQL runtime. Do not fabricate migration receipts +or seed accounts.
    10. +
    11. Create named staff through Settings. Import authorized sources using +each product’s source library. All examples in this package are +synthetic; they are not municipal authority.
    12. +
    13. Provision Station separately if it is part of the beta exercise. +Selecting the desktop composition does not start or configure Station. +Configure vision explicitly only if automatic photo drafting is +selected.
    14. +
    +

    Daily workflow

    +

    +

    1. Import adopted policy

    +

    Open Policy library. Preview jurisdiction, adoption/source dates, +policy IDs, neighborhood applicability and originals, then confirm the +complete source bundle. Retain the previous revision.

    +

    +

    2. Create or reopen an +analysis

    +

    Open Analyses and select the project. Use Next page when the loaded +page does not contain the saved work. Enter the proposal, analysis and +private staff notes.

    +

    +

    3. Select policies and +evidence

    +

    In Policies & evidence select exact policy revisions and +applicable neighborhood context. Record supporting, conflicting or +uncertain considerations. Select permitted Meetings or Zoning evidence +with its expected hash.

    +

    +

    4. Save and reconcile

    +

    Use Save draft before navigating or signing out. When another +revision exists, reopen it and reconcile your edits. Do not resubmit +against a guessed revision identifier.

    +

    +

    5. Review the saved revision

    +

    In Review & export check the audience, public summary and review +notes. Save, then Record review of saved draft. The trusted staff path +derives identity/date. Editing later produces a new revision requiring +review.

    +

    +

    6. Create and export a +snapshot

    +

    Preview the reviewed saved revision, inspect the returned content, +then create the snapshot. Public copies exclude staff notes and full +staff analysis under the public contract. Export verifies the expected +SHA256.

    +

    +

    7. Track initiatives and +amendments

    +

    Create and revise municipal initiative status, responsibility, +targets, milestones and measurements using the existing controls. Retain +history. Draft and review amendments separately; adoption must identify +the actual adopted source revision.

    +

    +

    8. Share deliberately

    +

    Select a permitted snapshot in Records. Creating a snapshot does not +publish it, release a request or adopt policy.

    +

    Working safely

    +

    Use your own named account and save before leaving a screen. A saved +draft is durable; unsaved form text may not be. If a write has an +unknown result, reopen its record before repeating it.

    +

    Read source jurisdiction, dates, citation, version and visibility. A +copied source hash identifies exact bytes, not their legal +applicability. If a source changes or permission is removed, resolve the +source problem rather than substituting stale cached content.

    +

    Keep originals and derivatives separate. Review the intended audience +before export. A public summary excludes private fields only through the +applicable copy contract and your review. A renamed private packet is +still private content.

    +

    Drafting, review, approval, attachment, export, fulfillment and +publication are separate operations. A Townlight workpaper does not +itself adopt law, issue a permit, impose a fine or release a records +response. The responsible staff member records the applicable +decision.

    +

    Connected workflows

    +

    Selects Meetings and Zoning evidence. Provides permitted reviewed +snapshots to Records. Source selection is permission- and hash-checked +and is not automatic writeback.

    + ++++ + + + + + + + + + + + + + + + + +
    DirectionMaterial
    InputComplete adopted policy source bundles, proposal context, versioned +policy selections, permitted Meetings/Zoning evidence and staff progress +updates.
    OutputCited analyses, audience-specific reviewed snapshots, durable +initiative/history records and amendment lifecycle records.
    +

    Product boundary

    +

    Existing initiative/amendment persistence is included. A draft +amendment does not change an adopted source revision. Historical +standalone sample pages are not the installed staff workspace. Analysis +lists and project filters operate on loaded pages; use pagination to +reach additional records.

    +

    Architecture

    +
    + + +
    +

    The drawing shows the principal staff/evidence path. Native commands +carry trusted identity to Python business services; PostgreSQL and +retained original files hold durable state. A downstream copy does not +silently transfer decision authority. Station has its own configured +authority/media boundary, database and mutable files. The +connected-workflow text supplies the drawing’s reading order and +accessibility alternative.

    +

    Exploration initiatives +and amendments

    +

    Explore adopted plans

    +

    Open Policy library and find Explore adopted +plans. Enter a topic and/or choose the supplied goal, +neighborhood and plan-type filters. These are separate facets; keyword +search is not a substitute for neighborhood applicability. Run +exploration and inspect each returned plan, adopted/source dates, exact +policy references and permitted original material. Empty results can +mean no matching permitted adopted source, not an error or an invented +plan.

    +

    The existing public exploration transport is +planning_public_request, separate from staff +planning_domain_request. Technical clients use its +documented plan-explore operation or the mounted public +route in the API companion. A native operation fragment is:

    +
    {"operation":"plan-explore","payload":{"topic":"synthetic mobility","neighborhood":"Synthetic North","goal":"","plan_type":""}}
    +

    Only public-permitted adopted sources belong in this result. Private +staff analyses, selected restricted evidence and staff notes do not +become public through exploration. The output includes matching +plans/facets and an informational disclaimer; no cross-plan AI synthesis +or internet portal commissioning is implied.

    +

    Track a municipal initiative

    +

    Open Implementation & amendments. Choose an +actual retained policy selection, title, responsible staff, target, +unit, due date and explanatory note. Save a planned/active initiative +and reopen its current revision/history. Add milestones and measurements +with their dates and evidence. Each change uses the latest +expected_revision; reconcile a conflict by reopening the +current state rather than guessing a revision.

    +

    The initiative statuses are planned, +active, completed and cancelled. +A completed initiative requires measurement evidence and every supplied +milestone completed. A milestone completion needs supporting evidence +and a completion date that is not in the future. Numerical progress +without its source/evidence is not a completed municipal outcome.

    +

    For a synthetic exercise, create an active initiative with a +fictional policy selection, target 3, unit +synthetic reviews, an intended future due date and a note +explaining the test. Add one evidence-backed measurement, then complete +each milestone before requesting completed status. Read the saved +initiative/history after every accepted revision. No external project +system is updated by this save.

    +

    Retain an amendment +lifecycle

    +

    An amendment has its own proposal and history; changing an analysis +does not adopt an amendment. In Implementation & +amendments, select the actual policy, enter proposal text, +title, responsible staff and a note, then save draft. The +allowed amendment statuses are draft, review, +adopted and withdrawn.

    +

    Moving to review or adopted requires a +recorded review_note. Before recording +adopted, import and verify the actual adopted policy +revision, then supply its adoption_revision identity. Only +an adopted amendment may carry that field; draft/review/withdrawn +records must omit it or use null. The proposal’s existing policy +reference and newly imported adoption revision have distinct roles. +Staff record the authorized decision; a status choice does not itself +enact policy.

    +

    Use the latest expected_revision when revising. Reopen +the amendment and municipal history, confirm status, review note and +adoption link, and retain prior revisions. Public exploration changes +only when its permitted adopted sources actually change, not merely +because staff created a proposal.

    +

    Source contracts: townlight_planning/public_explore.py, +municipal.py, +townlight_runtime/planning_bridge.py and the Planning view. +The API dictionary carries InitiativeInput, +Milestone, Measurement, +AmendmentInput and the exact policy-selection fields; +conditional completion/adoption checks above also apply beyond simple +field validation.

    +

    Technical specifications

    +

    Runtime and storage

    +

    The accepted package targets Windows x64 fresh +installation. Its native shell uses Rust 2021, Tauri 2 +and Microsoft WebView2; browser assets are JavaScript built +with Vite 8.1.6. This describes the native desktop +frontend; Station has a separate React operator, specified below or in +its product manual. Canonical business workflows use bundled +CPython 3.13.5, FastAPI, Pydantic, SQLAlchemy and +Alembic, with PostgreSQL 17 / PostGIS and +managed original files. The installed runtime tested here contains +FastAPI 0.162.0. Package minimum Python requirements can differ from the +bundled executable; the metadata reference preserves both. No stack +rewrite is implied by the beta label.

    +

    The native transport is fixed to loopback +127.0.0.1:15480; PostgreSQL uses the configured local +runtime port (default 15432). Optional local model service +defaults to 127.0.0.1:15434. Those are deployment defaults, +not internet endpoints. The runtime has health, module and readiness +endpoints; readiness is stronger than process existence. The task queue +is the existing local Core task infrastructure, not an assertion that a +separate Redis service is required for this desktop composition.

    +

    The default native profile is %LOCALAPPDATA%\CivicSuite; +the historical directory name remains part of compatibility. Do not +rename it to Townlight. A configured TOWNLIGHT_PROFILE_ROOT +must be absolute. Local configuration and secrets live under that +profile; protected managed files and database state must be backed up +coherently. Source/runtime identity is distinct from a product’s display +label.

    +

    Data and consistency

    +

    Plan bundles and revisions; original documents; versioned policy +selections and neighborhood applicability; analysis revisions; reviews +and snapshots; initiatives, milestones and measurements; amendment +revisions.

    +

    Versioned saves use expected prior revision identifiers where +defined. Reopen and reconcile on conflict. Exact exports and handoffs +use source IDs, current visibility, revision and SHA256. Review belongs +to the saved revision and does not transfer silently to edited text. +Database changes use the owning product’s migrations; a request or +readiness check is not an authorization to mutate schema.

    +

    Capacity and platform +statements

    +

    This beta has synthetic single-profile workflow evidence. It does not +have a published benchmark for concurrent staff capacity, minimum +RAM/CPU, large-source limits or a field SLA. Do not turn a developer +machine’s specification into a supported minimum. The new installer size +remains pending its build; allow additional disk for extracted runtime, +database, originals, exports, media and backups. Select +equipment/storage after sizing those actual workloads.

    +

    The exact runtime payload +lock records pinned files, sizes and hashes. The component +metadata records shipped dependency declarations. These references +are more precise than a manually copied dependency list. Third-party and +historical license notices must accompany their matching payloads.

    +

    Configuration and +administration

    +

    Native deployment +configuration

    +

    Use Setup, Settings and System Health for supported staff operation. +Administrators provision folders, backup storage, named accounts and the +city profile. Select inspections-preview for the bounded +desktop composition, including Access and Notice. Station remains a +separate service boundary. Do not use a standalone product’s demo server +as a substitute for the installed workspace.

    +

    Technical deployments use TOWNLIGHT_PRODUCT_PROFILE, +TOWNLIGHT_PROFILE_ROOT, DATABASE_URL, +TOWNLIGHT_RUNTIME_PORT, PORTAL_MODE and the +runtime-managed secret files. Treat database URLs and native session +proofs as secrets. The installed native domain runtime explicitly +refuses non-loopback binding. PORTAL_MODE=private is the +accepted posture; changing it does not by itself commission an internet +portal, authentication provider or reverse proxy.

    +

    The isolated documentation exporter sets a fictional profile and +unusable synthetic database origin only to read schemas; those values +are not deployment configuration. Keep deployment values in the intended +process/account scope. An already-running process does not automatically +inherit later environment edits.

    +

    API and integration examples

    +

    Native command example

    +

    The following JavaScript belongs in the existing trusted Townlight +frontend/development environment with invoke imported from +@tauri-apps/api/core. It is not a command for an arbitrary +web page or an instruction for nontechnical staff. IDs must come from +records created in an isolated synthetic exercise.

    +
    import { invoke } from '@tauri-apps/api/core';
    +const result = await invoke('planning_domain_request', {request: {operation: 'sources', offset: 0}});
    +console.log(result);
    +

    Trusted local HTTP example

    +

    An administrator/developer can inspect an already-configured isolated +runtime from a trusted local process. This PowerShell example reads the +signed-in synthetic profile’s existing proof into memory; it does not +create a user, seed a session, reveal the proof in output or bypass a +permission check. Do not use real city data in development examples. A +read response does not prove approval or publication.

    +
    $profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite'
    +$sessionPath = Join-Path $profilePath 'config\local-session.json'
    +$session = Get-Content -LiteralPath $sessionPath -Raw | ConvertFrom-Json
    +$headers = @{ 'X-Townlight-Session' = $session.session_hash }
    +Invoke-RestMethod -Uri 'http://127.0.0.1:15480/desktop/v1/planning/sources' -Headers $headers
    +Remove-Variable session, headers
    +

    Complete synthetic source +bundle

    +

    The synthetic +Planning bundle is the retained fixture used by the beta staff +exercise. It includes the complete supported source envelope rather than +a shortened pseudo-payload. Keep its fictional source labels. For +Planning, wrap it as +{"bundle": BUNDLE, "expected_previous_revision": null}; for +Permitting use +{"bundle": BUNDLE, "expected_revision": null}. Code and +Zoning take their own complete import envelopes. Replace null with the +current expected revision when revising an existing source, as the +applicable schema requires. These are import examples, not legal +authority or permission to load them into a live city profile.

    +

    A synthetic write +with subsequent readback

    +

    This example demonstrates the existing Meetings HTTP contract in an +isolated exercise. It is intentionally fictional. It does not start a +service. Its authentication setup is included so it can be run +independently under the signed-in synthetic account. If a write times +out, inspect current records before repeating it.

    +
    $profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite'
    +$sessionPath = Join-Path $profilePath 'config/local-session.json'
    +$session = Get-Content -LiteralPath $sessionPath -Raw | ConvertFrom-Json
    +$headers = @{ 'X-Townlight-Session' = $session.session_hash }
    +$body = @{
    +  title = 'Synthetic documentation exercise'
    +  scheduled_start = '2026-11-05T18:00:00-07:00'
    +  location = 'Synthetic room'
    +  meeting_type = 'regular'
    +} | ConvertTo-Json
    +$meeting = Invoke-RestMethod -Method Post `
    +  -Uri 'http://127.0.0.1:15480/desktop/v1/meetings/meetings' `
    +  -Headers $headers -ContentType 'application/json' -Body $body
    +Invoke-RestMethod `
    +  -Uri ('http://127.0.0.1:15480/desktop/v1/meetings/meetings/' + $meeting.id) `
    +  -Headers $headers
    +Remove-Variable session, headers
    +

    This write requires Meetings to be enabled and the signed-in staff +role to permit it. It is a cross-suite integration example; for this +product’s request models, use the complete technical reference +below.

    +

    Complete technical contract

    +

    Read the Planning API +reference for every documented operation, request field, constraint, +response declaration and source supplement. Download the OpenAPI JSON for tools. +For Station this is the suite-side schema only; its separate service +contract is documented in the API supplement. The reference directory includes +configuration/source inventories, dependency declarations, native +command contracts, MCP signatures and candidate evidence.

    +

    MCP and automation boundary

    +

    No direct product MCP server is exposed by the accepted Townlight +desktop or Station boundary. Do not configure an invented +townlight mcp command or assume an AI client has staff +permissions. The integration surfaces for this beta are native IPC, the +documented HTTP APIs, source bundle imports, exact exports and the +existing Station CLI.

    +

    The bundled transcription code includes a TextFlowKit MCP +adapter as a separate source capability. It offers job-based +transcribe_media, get_transcript, +list_jobs, get_job_status and +export_transcript, and additional tools declared in that +adapter. It uses stdio first and optional Streamable HTTP, with the MCP +SDK as an optional extra. It is not automatically launched, +authenticated as Townlight staff or accepted as a Townlight product MCP +deployment. This documentation does not add such a service.

    +

    For a transcription client already provisioned separately, an +illustrative tool call is:

    +
    {"name":"get_job_status","arguments":{"job_id":"synthetic-existing-job-id"}}
    +

    Use a job ID returned by that transcription service. This example +does not create a Townlight record or bypass its review/Records handoff. +The exact optional adapter tool signatures are supplied in the MCP source reference. Station +meeting capture does not become live speech recognition because this +optional donor adapter exists.

    +

    Security and permissions

    +

    Use your own named account and save before leaving a screen. A saved +draft is durable; unsaved form text may not be. If a write has an +unknown result, reopen its record before repeating it.

    +

    Read source jurisdiction, dates, citation, version and visibility. A +copied source hash identifies exact bytes, not their legal +applicability. If a source changes or permission is removed, resolve the +source problem rather than substituting stale cached content.

    +

    Keep originals and derivatives separate. Review the intended audience +before export. A public summary excludes private fields only through the +applicable copy contract and your review. A renamed private packet is +still private content.

    +

    Drafting, review, approval, attachment, export, fulfillment and +publication are separate operations. A Townlight workpaper does not +itself adopt law, issue a permit, impose a fine or release a records +response. The responsible staff member records the applicable +decision.

    +

    The native session is validated and mapped to a persisted SQL +identity. An editable actor/reviewer label is not authentication. +Product/module permissions and source visibility apply at the server +boundary. Revoked/unavailable authority fails closed for new Station +operations; a previous permission result is not a perpetual +authorization.

    +

    Use protected local folders, account permissions and credential +storage. Never include the native session file, database passwords, +provider keys or unredacted support bundles in a public issue or +generated public documentation. A local public view is not automatically +a secured internet deployment. Keep network exposure and real equipment +acceptance specific to the chosen beta site.

    +

    Backup recovery and +maintenance

    +

    Save work and use Core’s canonical Backup Now before +maintenance. That operation stops writers. Preserve the coherent +profile/database/document backup and its receipt, then use +Start to resume. A source export is not a full +backup.

    +

    Use Restore Latest Backup through the supported +controls. If the result says Restore needs service +start, use Start, then Check, +and reopen a known record. Do not repeat restore merely because services +need to start. The fresh-profile acceptance verified that a fulfilled +request survived restore and a post-backup marker did not.

    +

    Keep Station’s dedicated database and media evidence together in its +own backup. Core’s native-profile backup must not be assumed to include +an external Station data directory. Stop writers during a coordinated +backup. Preserve failed media attempts and logs.

    +

    On failure, record the time, selected composition, +component/installer versions and exact message. Check System Health for +stopped, starting, ready or failed dependencies. Use the existing Retry +control after readiness; do not create duplicate business records to +refresh a stale view. Share only a redacted diagnostic bundle. Preserve +secrets, original evidence, recovery material and unrelated +installations.

    +

    Troubleshooting

    + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    SymptomLikely meaningNext action
    Workspace absentWrong product composition or unavailable canonical runtime.Check selected composition; activate through Finish Records +Migration; wait for readiness.
    Cannot sign in / 401Missing or expired named account session.Sign in normally; reopen a Station launch ticket if applicable.
    Permission denied / 403Account, module, source or browser-origin permission.Ask the authorized administrator to inspect the intended permission; +do not invent role headers.
    Save conflict / 409The saved revision, expected source hash or lifecycle changed.Keep edits, reopen current state and reconcile deliberately.
    Invalid input / 422Required field, format, geometry, source envelope or state is +invalid.Read the field detail and correct the input/source; preserve +originals.
    Service unavailable / 503Database, schema, connected source or configuration +unavailable.Inspect System Health and the named dependency. Preserve work; retry +only after readiness.
    Export refusedMissing exact review, approval, audience or source +authorization.Read the refusal and complete the owning product’s explicit +decision.
    Restore needs service startThe snapshot was restored but services have not resumed.Use Start, then Check and verify a saved record; do not blindly +repeat restore.
    +

    Verified workflows and +limits

    + +++++ + + + + + + + + + + + + + + +
    ProductRecorded resultPrecisely exercised
    PlanningPASSAdopted source import with neighborhood, saved/reviewed analysis and +snapshot, persisted initiative/history and draft amendment, public +explorer neighborhood readback and native workspace.
    +

    These results come from the identified signed candidate’s fresh +normal-profile Sandbox exercise: real native IPC/HTTP/PostgreSQL and +selected headless controls. All accounts, source bundles and media were +synthetic. The guest install/uninstall and recovery passed, and the +owned Sandbox stopped. No host installed application or standalone +CivicCast was changed. This documentation task reuses those receipts; it +does not claim a new software acceptance run.

    +

    The workflow +matrix identifies raw receipt filenames. The evidence +index retains their original hashes; raw receipts remain in the +private beta handoff rather than being silently republished with the +documentation site.

    +

    The limits remain: actual city field acceptance and equipment/network +commissioning; Station automatic provisioning/SCM commissioning; every +UI/role combination; field recognition accuracy; and historical in-place +upgrades are not certified. They are not five invented feature +requirements. Fresh-install controlled beta handoff remains the accepted +scope. This package makes no city-deployment, publication or +general-availability claim.

    +

    Terms of service and license

    +

    Scope and status

    +

    These terms describe the Townlight Beta 1 software and this +documentation package. This is a locally prepared private beta, not a +hosted-service subscription, a city deployment agreement or a public +release. No uptime commitment, support response time, indemnity, +data-processing agreement or paid service is created by these documents. +A separate signed agreement, if any, governs services it actually +provides.

    +

    Software license and rights

    +

    Current Townlight-owned distributions identified in this candidate +use AGPL-3.0-only. The full license is supplied with +this documentation and with the source companion. The license governs +rights to run, copy, modify and convey the covered software; these +operational terms do not add restrictions to those rights. Historical +grants and dependency licenses retain their own terms. CivicCast remains +a separate product and is not relicensed by this documentation work.

    +

    When conveying covered software, retain applicable notices and +provide the corresponding source and installation/build information +required by the license. For a modified version supporting remote +network interaction, follow section 13’s source-offer requirement. The +companion archive identifies the source for this candidate; a link to a +different public branch is not a substitute for the matching source. +Read the supplied license for the complete conditions. See the GNU license +reference and GNU licensing +FAQ.

    +

    Data ownership and access

    +

    Importing a document does not transfer its ownership or grant +permission to publish it. The operating organization controls its +accounts, access decisions, lawful source use, retention and +review/release policy. Keep resident information, credentials, private +notes and restricted evidence in their authorized locations. +Documentation examples contain fictional data. No real city account, +credential or record is required to exercise these examples in an +isolated test environment.

    +

    Local operation and +external processors

    +

    The accepted beta workflow is local and uses named staff accounts. +Station has separate storage and credentials. Configure backup +destinations and optional model/network providers deliberately. A +configured external provider may receive submitted prompts, images or +audio according to that configuration and provider’s terms; this +documentation does not promise that every optional configuration is +offline. An email outbox or local public view does not establish +external delivery or an internet deployment. This static documentation +site has no analytics, account collection or remote font dependency.

    +

    Staff decisions and +source applicability

    +

    Staff verify the jurisdiction, source currency, permissions, +citations and proposed audience. Model output and generated guidance +require review. No draft is automatically an official legal +interpretation, zoning determination, permit approval, fee assessment, +enforcement notice or records-release decision. Official permit fee +authority remains with the adopted source and responsible organization; +imported amounts do not become a new authoritative calculation.

    +

    Beta operation and recovery

    +

    Use the identified candidate in its supported fresh-install scope. +Preserve backups and original evidence. Test physical equipment and +chosen network/service configuration before relying on them. The +supplied acceptance describes selected synthetic workflows, not every +screen, vendor, field condition or upgrade. Operators decide whether a +particular deployment meets their own operational obligations.

    +

    Warranty and liability

    +

    The covered software’s warranty and liability conditions are those in +sections 15–17 of the supplied AGPL and any applicable separate written +undertaking. This documentation creates no additional warranty or +limitation beyond those terms. Third-party software is subject to its +retained license notices. Nothing here removes rights that applicable +law makes nonwaivable.

    +

    Support and incident +reporting

    +

    Use the project’s existing SUPPORT and SECURITY guidance for its +matching repository. Report reproducible behavior with the version, +operation and redacted logs. Do not put credentials, resident records or +unredacted evidence in a public issue. Coordinate sensitive reports +through the channel designated in SECURITY. No new support address or +service commitment is invented here.

    +

    Ending a beta +exercise and document changes

    +

    When an organization ends testing, it controls retention/export and +removes access according to its policy. Uninstall may retain data; back +up and inspect the selected removal options. Ending an exercise does not +revoke rights already granted by AGPL. Later software/documentation +versions must identify their changed candidate and scope; historical +receipts retain their original identities. These terms do not claim that +a city has accepted a contract merely by reading a manual.

    +

    Glossary

    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TermMeaning
    ApprovalAn explicit authorized decision on the saved text/artifact. It is +separate from saving or attachment.
    Canonical recordThe owning product’s retained identity and saved version, rather +than an editable copied label.
    CompositionThe selected set of desktop modules; inspections-preview exposes the +eight staff products.
    Corresponding sourceThe source/build material matching the delivered covered program, +subject to its license.
    Derivative / Records copyA separately prepared document with its own intended audience and +hash.
    Hash / SHA256A fingerprint of exact bytes. It detects change; it does not +establish legal authority.
    IdempotencyRepeating the same identified request has the same intended effect; +changing its payload can be refused.
    IPCThe native desktop command boundary between its browser interface +and Rust host.
    MCPModel Context Protocol; no direct Townlight product server is +enabled by this beta.
    OriginalRetained source bytes. A reviewed derivative does not replace +them.
    ProvenanceSource, version, date, actor and relationship information retained +with evidence.
    RevisionAn immutable saved version. Later edits do not inherit an earlier +review automatically.
    SnapshotA fixed audience-specific copy tied to a source/reviewed +revision.
    StationTownlight’s separate media boundary using a pinned CivicCast-derived +engine; standalone CivicCast remains separate.
    +

    Alphabetical subject index

    + + + +

    Source and document control

    +

    This edition is authored from the immutable corresponding-source +companion, the generated installed-domain schema and the retained +workflow receipts. The current software versions and signed artifacts +are unchanged. Public historical pages are not synchronized or published +by this local documentation task.

    +

    Workflow subject index

    + +
    Townlight · AGPL-3.0-only · Candidate evidence applies only to its identified artifacts.
    \ No newline at end of file diff --git a/docs/beta-1/manuals/records.html b/docs/beta-1/manuals/records.html new file mode 100644 index 0000000..31905a3 --- /dev/null +++ b/docs/beta-1/manuals/records.html @@ -0,0 +1,1027 @@ + + +Townlight Records Manual | Townlight candidate + +
    Townlight +
    +

    Naming, Access and Notice source candidate · 2 November 2026

    +

    Prepared documentation. Build, signing, installed acceptance and publication remain pending.

    + + +

    Townlight Records Manual

    +

    Townlight Beta 1 · Naming candidate documentation +edition 2 November 2026

    +

    Contents

    + +

    Using this manual

    +

    Townlight Records helps records officers, clerks and authorized +reviewers. Records manages request intake, responsive evidence, review +and the final response. Material received from another Townlight product +is evidence for a request. Records separately controls release +decisions, response approval, exports and fulfillment.

    +

    Staff should begin with First run and Daily workflow. Administrators +should also read Architecture, Technical specifications, Configuration, +Security and Recovery. Developers should use the exact API/data +dictionary and examples. The table of contents and alphabetical subject +index link to the relevant sections in the HTML edition; the PDF +preserves headings and searchable text. An editable Word edition is +included with the same documentation companion.

    +

    Beta identity

    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    IdentityValue
    DocumentationTownlight Beta 1 naming, Access and Notice candidate
    Intended installer version1.7.0.1; build and acceptance pending
    Product componenttownlight-records 1.8.0.dev2
    Principal import packagetownlight_records
    Native desktop source version1.7.0-1
    Candidate hashesPending candidate build, signing and installed acceptance
    Current owned software licenseAGPL-3.0-only
    Acceptance compositionFresh Windows x64 profile; inspections-preview; Station configured +separately
    +

    The naming change advances this package’s version and requires a new +signed installer and installed acceptance. Those steps and publication +remain pending. Historical tags, receipts and archived manuals keep +their original names and certify only their identified artifacts. Use an +empty database and fresh profile; no in-place legacy upgrade is +supported. The approved Windows profile path remains +%LOCALAPPDATA%\CivicSuite. Preserve existing profiles, data +and recovery material.

    +

    First run

    +
      +
    1. Obtain the identified signed private candidate and its +corresponding-source companion from the beta coordinator. The landing +pages in this documentation are not an installer download service.
    2. +
    3. On the intended fresh Windows test installation, verify the MSI hash +and publisher signature before installing. Preserve unrelated profiles +and recovery material. Installed acceptance for this source candidate +remains pending; no in-place legacy upgrade is supported.
    4. +
    5. Launch Townlight under the intended named Windows account. Choose +the storage folders. Select Townlight Inspections +candidate (inspections-preview) for the bounded +desktop composition, including Access and Notice. A narrower default +selection will not expose all workspaces.
    6. +
    7. Enter the city profile, time zone and contacts. Create the first +named local administrator, sign in and choose protected backup storage. +Continue without local AI is valid for the +deterministic workflows.
    8. +
    9. Run Health Check and wait for readiness. Open Townlight. In System +Health select Finish Records Migration to activate the +canonical Python/PostgreSQL runtime. Do not fabricate migration receipts +or seed accounts.
    10. +
    11. Create named staff through Settings. Import authorized sources using +each product’s source library. All examples in this package are +synthetic; they are not municipal authority.
    12. +
    13. Provision Station separately if it is part of the beta exercise. +Selecting the desktop composition does not start or configure Station. +Configure vision explicitly only if automatic photo drafting is +selected.
    14. +
    +

    Daily workflow

    +

    +

    1. Receive and identify the +request

    +

    Create the request with its requester, description and recorded +deadline basis. Save it and retain the request identifier. Record +assignment, clarification and work in the request history.

    +

    +

    2. Find responsive evidence

    +

    Search only the permitted sources. Inspect the source title, date, +citation, visibility and version before attaching responsive material. +Open the saved attachment to confirm that it is the intended +evidence.

    +

    +

    3. Preserve the original

    +

    Keep original bytes and their hash. Add a separately reviewed +release-ready or redacted copy when needed. Renaming a private file does +not remove private content.

    +

    +

    4. Record each release +decision

    +

    Explicitly record release, redact or exempt for the relevant +document, with the applicable reason and source. Do not treat an AI +suggestion or another product’s review as the Records legal +decision.

    +

    +

    5. Draft and approve

    +

    Draft the response and review the selected attachments. Record +approval of the exact response text. Editing that text changes its hash +and requires a new approval.

    +

    +

    6. Export both artifacts

    +

    Export the approved response and the release package. If release is +refused, inspect the missing decision, approval or source-permission +message. Resolve that condition before trying again.

    +

    +

    7. Fulfill and retain

    +

    Use the explicit fulfillment action only after checking the outgoing +artifacts. Retain the response, package and history. A preview, +attachment or export by itself does not fulfill the request.

    +

    Working safely

    +

    Use your own named account and save before leaving a screen. A saved +draft is durable; unsaved form text may not be. If a write has an +unknown result, reopen its record before repeating it.

    +

    Read source jurisdiction, dates, citation, version and visibility. A +copied source hash identifies exact bytes, not their legal +applicability. If a source changes or permission is removed, resolve the +source problem rather than substituting stale cached content.

    +

    Keep originals and derivatives separate. Review the intended audience +before export. A public summary excludes private fields only through the +applicable copy contract and your review. A renamed private packet is +still private content.

    +

    Drafting, review, approval, attachment, export, fulfillment and +publication are separate operations. A Townlight workpaper does not +itself adopt law, issue a permit, impose a fine or release a records +response. The responsible staff member records the applicable +decision.

    +

    Connected workflows

    +

    Receives selected evidence from Meetings, Code, Zoning, Planning, +Permitting, Inspections and Station. Station originals are locked +private evidence. A product’s public copy remains subject to the Records +response workflow.

    + ++++ + + + + + + + + + + + + + + + + +
    DirectionMaterial
    InputA request description and requester, authorized source documents, +explicit cross-product evidence selections and a reviewer’s +decisions.
    OutputA retained request history, reviewed attachments, approved response +text and a release package after the applicable release checks.
    +

    Product boundary

    +

    The selected staff workflow is accepted. A resident internet +deployment, every jurisdiction’s requirements, complete federation and +exhaustive redaction/accessibility behavior are not certified by that +acceptance. SMTP code exists; logging a message or outbox entry does not +establish email delivery.

    +

    Architecture

    +
    + + +
    +

    The drawing shows the principal staff/evidence path. Native commands +carry trusted identity to Python business services; PostgreSQL and +retained original files hold durable state. A downstream copy does not +silently transfer decision authority. Station has its own configured +authority/media boundary, database and mutable files. The +connected-workflow text supplies the drawing’s reading order and +accessibility alternative.

    +

    Fees messages +notifications and local intake

    +

    Record a fee line or waiver

    +

    Open the saved request’s existing fee controls. Enter the +description, adopted schedule/source basis and exact amount in dollars +and cents. For example, a synthetic line can use description “Synthetic +reproduction,” basis “Fictional test schedule” and amount +12.50. Save and reopen the request. Inspect +fee_line_items, fee_status and the resulting +estimate. The native line validator accepts positive exact cents; +additional fractional cents, negative values and a zero line are +refused.

    +

    To waive the request fee, record the actual waiver reason and save +through the waiver control. Reopen the request and confirm waived status +and the zero-dollar waiver explanation. Adding a later line preserves +the waiver in the current workflow; do not assume it reinstates a +payable balance. These are Records workflow amounts and decisions, not +an official permit-fee calculator or payment service.

    +

    A trusted native client uses records_domain_request with +operation: 'apply', the real request_id, and +action/payload fields from the fragments below +at the same level as operation and request_id. +Examples of command payloads follow; IDs and permissions still come from +the signed-in synthetic account.

    +
    {"action":"add-records-fee-line","payload":{"feeLineDescription":"Synthetic reproduction","feeScheduleBasis":"Fictional test schedule","feeLineAmount":"12.50"}}
    +
    {"action":"waive-records-fee","payload":{"feeWaiverReason":"Synthetic public-interest exercise"}}
    +

    Use the exact outer apply contract in the API reference rather than +sending these command fragments to an arbitrary URL. After either +operation, read the request again; a saved amount does not approve or +fulfill the response.

    +

    Save staff and requester +messages

    +

    In the saved request, enter a message and use its explicit send/save +action. The native add-records-message command’s payload +uses requestMessageBody, for example “Synthetic +clarification received.” Inspect the retained message/timeline and +intended audience before repeating the action. A persisted staff message +or locally queued notification does not prove an email reached a +requester. For a clarification requiring a response, retain the +clarification note and keep the request’s actual status distinct from +completion.

    +

    Configure templates +and inspect the outbox

    +

    Administrators use the existing /notifications/templates +create/list/update API under the application’s real authenticated +authority. A template supplies event_type, +channel (default email), +subject_template and body_template. Use the +event name actually produced by the selected workflow and the variables +it supplies; template existence alone does not cause that event to be +emitted. Staff inspect /notifications/log for recipient, +rendered content, status and error information.

    +

    The existing delivery function is +app.notifications.smtp_delivery.deliver_queued_notifications(session). +A technical operator invokes it only in the matching configured +application environment, with an application-owned async session. It +processes queued email entries, commits +sent or failed status, and returns counts. +Missing SMTP configuration returns +reason: smtp_not_configured. Missing rendered subject/body +or recipient is a failure, not delivery.

    +

    SMTP settings are SMTP_HOST, SMTP_PORT, +SMTP_USERNAME, SMTP_PASSWORD, +SMTP_FROM_EMAIL and SMTP_USE_TLS. Keep secrets +in protected process configuration. Inspect the actual setting +names/defaults in that reference before selecting a mail server. This +beta has no automatic failed-entry retry or native “Retry email” button: +failed rows are not selected by the queued-only delivery loop. Preserve +errors and resolve the cause through the owning deployment’s supported +process; do not invent a retry or reset database rows by hand. The +native notification “sent” acknowledgement is not an SMTP transmission +receipt. External mail remains a separately selected deployment +configuration, not a requirement to send email during synthetic +development.

    +

    Exercise +existing local public intake and tracking

    +

    This is the existing local contract, not a new internet portal +deployment. Under the application’s configured portal posture, a +synthetic client can submit +POST /desktop/v1/public/requests with:

    +
    {"requester":"Synthetic resident","requesterContact":"synthetic@example.invalid","summary":"Synthetic minutes request","deadline":""}
    +

    Retain the returned tracking information privately. +POST /desktop/v1/public/lookup requires +both trackingNumber and matching +requesterContact; it returns the permitted public status +rather than staff notes. /desktop/v1/public/messages +additionally requires publicRequestMessage. Read the +status/response detail and treat a portal-mode or identity refusal as a +refusal. Do not remove that gate, expose tracking/contact values in logs +or assume that changing PORTAL_MODE commissions a public +website. Named staff still use their own authenticated workspace.

    +

    Source contracts: app/desktop_bridge/schemas.py, +app/requests/workflow.py, notification service/router/SMTP +delivery, and the public desktop bridge routes. Full outer command +shapes and endpoint authentication remain in the Records API +reference.

    +

    Technical specifications

    +

    Runtime and storage

    +

    The accepted package targets Windows x64 fresh +installation. Its native shell uses Rust 2021, Tauri 2 +and Microsoft WebView2; browser assets are JavaScript built +with Vite 8.1.6. This describes the native desktop +frontend; Station has a separate React operator, specified below or in +its product manual. Canonical business workflows use bundled +CPython 3.13.5, FastAPI, Pydantic, SQLAlchemy and +Alembic, with PostgreSQL 17 / PostGIS and +managed original files. The installed runtime tested here contains +FastAPI 0.162.0. Package minimum Python requirements can differ from the +bundled executable; the metadata reference preserves both. No stack +rewrite is implied by the beta label.

    +

    The native transport is fixed to loopback +127.0.0.1:15480; PostgreSQL uses the configured local +runtime port (default 15432). Optional local model service +defaults to 127.0.0.1:15434. Those are deployment defaults, +not internet endpoints. The runtime has health, module and readiness +endpoints; readiness is stronger than process existence. The task queue +is the existing local Core task infrastructure, not an assertion that a +separate Redis service is required for this desktop composition.

    +

    The default native profile is %LOCALAPPDATA%\CivicSuite; +the historical directory name remains part of compatibility. Do not +rename it to Townlight. A configured TOWNLIGHT_PROFILE_ROOT +must be absolute. Local configuration and secrets live under that +profile; protected managed files and database state must be backed up +coherently. Source/runtime identity is distinct from a product’s display +label.

    +

    Data and consistency

    +

    Requests; assignments and deadlines; search sessions; evidence +attachments and original hashes; release copies; exemption decisions; +messages; fee line items; response approvals; export artifacts and audit +events.

    +

    Versioned saves use expected prior revision identifiers where +defined. Reopen and reconcile on conflict. Exact exports and handoffs +use source IDs, current visibility, revision and SHA256. Review belongs +to the saved revision and does not transfer silently to edited text. +Database changes use the owning product’s migrations; a request or +readiness check is not an authorization to mutate schema.

    +

    Capacity and platform +statements

    +

    This beta has synthetic single-profile workflow evidence. It does not +have a published benchmark for concurrent staff capacity, minimum +RAM/CPU, large-source limits or a field SLA. Do not turn a developer +machine’s specification into a supported minimum. The new installer size +remains pending its build; allow additional disk for extracted runtime, +database, originals, exports, media and backups. Select +equipment/storage after sizing those actual workloads.

    +

    The exact runtime payload +lock records pinned files, sizes and hashes. The component +metadata records shipped dependency declarations. These references +are more precise than a manually copied dependency list. Third-party and +historical license notices must accompany their matching payloads.

    +

    Configuration and +administration

    +

    Native deployment +configuration

    +

    Use Setup, Settings and System Health for supported staff operation. +Administrators provision folders, backup storage, named accounts and the +city profile. Select inspections-preview for the bounded +desktop composition, including Access and Notice. Station remains a +separate service boundary. Do not use a standalone product’s demo server +as a substitute for the installed workspace.

    +

    Technical deployments use TOWNLIGHT_PRODUCT_PROFILE, +TOWNLIGHT_PROFILE_ROOT, DATABASE_URL, +TOWNLIGHT_RUNTIME_PORT, PORTAL_MODE and the +runtime-managed secret files. Treat database URLs and native session +proofs as secrets. The installed native domain runtime explicitly +refuses non-loopback binding. PORTAL_MODE=private is the +accepted posture; changing it does not by itself commission an internet +portal, authentication provider or reverse proxy.

    +

    The isolated documentation exporter sets a fictional profile and +unusable synthetic database origin only to read schemas; those values +are not deployment configuration. Keep deployment values in the intended +process/account scope. An already-running process does not automatically +inherit later environment edits.

    +

    Communications and +review configuration

    +

    SMTP settings include host, port, username/password, sender address +and TLS choice. Configure and verify actual delivery only for a +deployment that selects external mail. Connector host allowlists and +encrypted data-source configuration are separate controls. Records fee +schedules concern the records workflow; they do not authorize Permitting +to calculate an official permit fee. Keep resident portal posture and +self-registration separate from named local staff setup.

    +

    API and integration examples

    +

    Native command example

    +

    The following JavaScript belongs in the existing trusted Townlight +frontend/development environment with invoke imported from +@tauri-apps/api/core. It is not a command for an arbitrary +web page or an instruction for nontechnical staff. IDs must come from +records created in an isolated synthetic exercise.

    +
    import { invoke } from '@tauri-apps/api/core';
    +const result = await invoke('records_domain_request', {request: {operation: 'view', request_id: requestId}});
    +console.log(result);
    +

    Trusted local HTTP example

    +

    An administrator/developer can inspect an already-configured isolated +runtime from a trusted local process. This PowerShell example reads the +signed-in synthetic profile’s existing proof into memory; it does not +create a user, seed a session, reveal the proof in output or bypass a +permission check. Do not use real city data in development examples. A +read response does not prove approval or publication.

    +
    $profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite'
    +$sessionPath = Join-Path $profilePath 'config\local-session.json'
    +$session = Get-Content -LiteralPath $sessionPath -Raw | ConvertFrom-Json
    +$headers = @{ 'X-Townlight-Session' = $session.session_hash }
    +Invoke-RestMethod -Uri 'http://127.0.0.1:15480/desktop/v1/records-state' -Headers $headers
    +Remove-Variable session, headers
    +

    A synthetic write +with subsequent readback

    +

    This example demonstrates the existing Meetings HTTP contract in an +isolated exercise. It is intentionally fictional. It does not start a +service. Its authentication setup is included so it can be run +independently under the signed-in synthetic account. If a write times +out, inspect current records before repeating it.

    +
    $profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite'
    +$sessionPath = Join-Path $profilePath 'config/local-session.json'
    +$session = Get-Content -LiteralPath $sessionPath -Raw | ConvertFrom-Json
    +$headers = @{ 'X-Townlight-Session' = $session.session_hash }
    +$body = @{
    +  title = 'Synthetic documentation exercise'
    +  scheduled_start = '2026-11-05T18:00:00-07:00'
    +  location = 'Synthetic room'
    +  meeting_type = 'regular'
    +} | ConvertTo-Json
    +$meeting = Invoke-RestMethod -Method Post `
    +  -Uri 'http://127.0.0.1:15480/desktop/v1/meetings/meetings' `
    +  -Headers $headers -ContentType 'application/json' -Body $body
    +Invoke-RestMethod `
    +  -Uri ('http://127.0.0.1:15480/desktop/v1/meetings/meetings/' + $meeting.id) `
    +  -Headers $headers
    +Remove-Variable session, headers
    +

    This write requires Meetings to be enabled and the signed-in staff +role to permit it. It is a cross-suite integration example; for this +product’s request models, use the complete technical reference +below.

    +

    Complete technical contract

    +

    Read the Records API +reference for every documented operation, request field, constraint, +response declaration and source supplement. Download the OpenAPI JSON for tools. +For Station this is the suite-side schema only; its separate service +contract is documented in the API supplement. The reference directory includes +configuration/source inventories, dependency declarations, native +command contracts, MCP signatures and candidate evidence.

    +

    MCP and automation boundary

    +

    No direct product MCP server is exposed by the accepted Townlight +desktop or Station boundary. Do not configure an invented +townlight mcp command or assume an AI client has staff +permissions. The integration surfaces for this beta are native IPC, the +documented HTTP APIs, source bundle imports, exact exports and the +existing Station CLI.

    +

    The bundled transcription code includes a TextFlowKit MCP +adapter as a separate source capability. It offers job-based +transcribe_media, get_transcript, +list_jobs, get_job_status and +export_transcript, and additional tools declared in that +adapter. It uses stdio first and optional Streamable HTTP, with the MCP +SDK as an optional extra. It is not automatically launched, +authenticated as Townlight staff or accepted as a Townlight product MCP +deployment. This documentation does not add such a service.

    +

    For a transcription client already provisioned separately, an +illustrative tool call is:

    +
    {"name":"get_job_status","arguments":{"job_id":"synthetic-existing-job-id"}}
    +

    Use a job ID returned by that transcription service. This example +does not create a Townlight record or bypass its review/Records handoff. +The exact optional adapter tool signatures are supplied in the MCP source reference. Station +meeting capture does not become live speech recognition because this +optional donor adapter exists.

    +

    Security and permissions

    +

    Use your own named account and save before leaving a screen. A saved +draft is durable; unsaved form text may not be. If a write has an +unknown result, reopen its record before repeating it.

    +

    Read source jurisdiction, dates, citation, version and visibility. A +copied source hash identifies exact bytes, not their legal +applicability. If a source changes or permission is removed, resolve the +source problem rather than substituting stale cached content.

    +

    Keep originals and derivatives separate. Review the intended audience +before export. A public summary excludes private fields only through the +applicable copy contract and your review. A renamed private packet is +still private content.

    +

    Drafting, review, approval, attachment, export, fulfillment and +publication are separate operations. A Townlight workpaper does not +itself adopt law, issue a permit, impose a fine or release a records +response. The responsible staff member records the applicable +decision.

    +

    The native session is validated and mapped to a persisted SQL +identity. An editable actor/reviewer label is not authentication. +Product/module permissions and source visibility apply at the server +boundary. Revoked/unavailable authority fails closed for new Station +operations; a previous permission result is not a perpetual +authorization.

    +

    Use protected local folders, account permissions and credential +storage. Never include the native session file, database passwords, +provider keys or unredacted support bundles in a public issue or +generated public documentation. A local public view is not automatically +a secured internet deployment. Keep network exposure and real equipment +acceptance specific to the chosen beta site.

    +

    Backup recovery and +maintenance

    +

    Save work and use Core’s canonical Backup Now before +maintenance. That operation stops writers. Preserve the coherent +profile/database/document backup and its receipt, then use +Start to resume. A source export is not a full +backup.

    +

    Use Restore Latest Backup through the supported +controls. If the result says Restore needs service +start, use Start, then Check, +and reopen a known record. Do not repeat restore merely because services +need to start. The fresh-profile acceptance verified that a fulfilled +request survived restore and a post-backup marker did not.

    +

    Keep Station’s dedicated database and media evidence together in its +own backup. Core’s native-profile backup must not be assumed to include +an external Station data directory. Stop writers during a coordinated +backup. Preserve failed media attempts and logs.

    +

    On failure, record the time, selected composition, +component/installer versions and exact message. Check System Health for +stopped, starting, ready or failed dependencies. Use the existing Retry +control after readiness; do not create duplicate business records to +refresh a stale view. Share only a redacted diagnostic bundle. Preserve +secrets, original evidence, recovery material and unrelated +installations.

    +

    Troubleshooting

    + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    SymptomLikely meaningNext action
    Workspace absentWrong product composition or unavailable canonical runtime.Check selected composition; activate through Finish Records +Migration; wait for readiness.
    Cannot sign in / 401Missing or expired named account session.Sign in normally; reopen a Station launch ticket if applicable.
    Permission denied / 403Account, module, source or browser-origin permission.Ask the authorized administrator to inspect the intended permission; +do not invent role headers.
    Save conflict / 409The saved revision, expected source hash or lifecycle changed.Keep edits, reopen current state and reconcile deliberately.
    Invalid input / 422Required field, format, geometry, source envelope or state is +invalid.Read the field detail and correct the input/source; preserve +originals.
    Service unavailable / 503Database, schema, connected source or configuration +unavailable.Inspect System Health and the named dependency. Preserve work; retry +only after readiness.
    Export refusedMissing exact review, approval, audience or source +authorization.Read the refusal and complete the owning product’s explicit +decision.
    Restore needs service startThe snapshot was restored but services have not resumed.Use Start, then Check and verify a saved record; do not blindly +repeat restore.
    +

    Verified workflows and +limits

    + +++++ + + + + + + + + + + + + + + +
    ProductRecorded resultPrecisely exercised
    RecordsPASSIntake, note, original attachment/readback, separate release copy, +explicit release decision, draft/approval, approved response and release +package exports, fulfillment/readback and native workspace.
    +

    These results come from the identified signed candidate’s fresh +normal-profile Sandbox exercise: real native IPC/HTTP/PostgreSQL and +selected headless controls. All accounts, source bundles and media were +synthetic. The guest install/uninstall and recovery passed, and the +owned Sandbox stopped. No host installed application or standalone +CivicCast was changed. This documentation task reuses those receipts; it +does not claim a new software acceptance run.

    +

    The workflow +matrix identifies raw receipt filenames. The evidence +index retains their original hashes; raw receipts remain in the +private beta handoff rather than being silently republished with the +documentation site.

    +

    The limits remain: actual city field acceptance and equipment/network +commissioning; Station automatic provisioning/SCM commissioning; every +UI/role combination; field recognition accuracy; and historical in-place +upgrades are not certified. They are not five invented feature +requirements. Fresh-install controlled beta handoff remains the accepted +scope. This package makes no city-deployment, publication or +general-availability claim.

    +

    Terms of service and license

    +

    Scope and status

    +

    These terms describe the Townlight Beta 1 software and this +documentation package. This is a locally prepared private beta, not a +hosted-service subscription, a city deployment agreement or a public +release. No uptime commitment, support response time, indemnity, +data-processing agreement or paid service is created by these documents. +A separate signed agreement, if any, governs services it actually +provides.

    +

    Software license and rights

    +

    Current Townlight-owned distributions identified in this candidate +use AGPL-3.0-only. The full license is supplied with +this documentation and with the source companion. The license governs +rights to run, copy, modify and convey the covered software; these +operational terms do not add restrictions to those rights. Historical +grants and dependency licenses retain their own terms. CivicCast remains +a separate product and is not relicensed by this documentation work.

    +

    When conveying covered software, retain applicable notices and +provide the corresponding source and installation/build information +required by the license. For a modified version supporting remote +network interaction, follow section 13’s source-offer requirement. The +companion archive identifies the source for this candidate; a link to a +different public branch is not a substitute for the matching source. +Read the supplied license for the complete conditions. See the GNU license +reference and GNU licensing +FAQ.

    +

    Data ownership and access

    +

    Importing a document does not transfer its ownership or grant +permission to publish it. The operating organization controls its +accounts, access decisions, lawful source use, retention and +review/release policy. Keep resident information, credentials, private +notes and restricted evidence in their authorized locations. +Documentation examples contain fictional data. No real city account, +credential or record is required to exercise these examples in an +isolated test environment.

    +

    Local operation and +external processors

    +

    The accepted beta workflow is local and uses named staff accounts. +Station has separate storage and credentials. Configure backup +destinations and optional model/network providers deliberately. A +configured external provider may receive submitted prompts, images or +audio according to that configuration and provider’s terms; this +documentation does not promise that every optional configuration is +offline. An email outbox or local public view does not establish +external delivery or an internet deployment. This static documentation +site has no analytics, account collection or remote font dependency.

    +

    Staff decisions and +source applicability

    +

    Staff verify the jurisdiction, source currency, permissions, +citations and proposed audience. Model output and generated guidance +require review. No draft is automatically an official legal +interpretation, zoning determination, permit approval, fee assessment, +enforcement notice or records-release decision. Official permit fee +authority remains with the adopted source and responsible organization; +imported amounts do not become a new authoritative calculation.

    +

    Beta operation and recovery

    +

    Use the identified candidate in its supported fresh-install scope. +Preserve backups and original evidence. Test physical equipment and +chosen network/service configuration before relying on them. The +supplied acceptance describes selected synthetic workflows, not every +screen, vendor, field condition or upgrade. Operators decide whether a +particular deployment meets their own operational obligations.

    +

    Warranty and liability

    +

    The covered software’s warranty and liability conditions are those in +sections 15–17 of the supplied AGPL and any applicable separate written +undertaking. This documentation creates no additional warranty or +limitation beyond those terms. Third-party software is subject to its +retained license notices. Nothing here removes rights that applicable +law makes nonwaivable.

    +

    Support and incident +reporting

    +

    Use the project’s existing SUPPORT and SECURITY guidance for its +matching repository. Report reproducible behavior with the version, +operation and redacted logs. Do not put credentials, resident records or +unredacted evidence in a public issue. Coordinate sensitive reports +through the channel designated in SECURITY. No new support address or +service commitment is invented here.

    +

    Ending a beta +exercise and document changes

    +

    When an organization ends testing, it controls retention/export and +removes access according to its policy. Uninstall may retain data; back +up and inspect the selected removal options. Ending an exercise does not +revoke rights already granted by AGPL. Later software/documentation +versions must identify their changed candidate and scope; historical +receipts retain their original identities. These terms do not claim that +a city has accepted a contract merely by reading a manual.

    +

    Glossary

    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TermMeaning
    ApprovalAn explicit authorized decision on the saved text/artifact. It is +separate from saving or attachment.
    Canonical recordThe owning product’s retained identity and saved version, rather +than an editable copied label.
    CompositionThe selected set of desktop modules; inspections-preview exposes the +eight staff products.
    Corresponding sourceThe source/build material matching the delivered covered program, +subject to its license.
    Derivative / Records copyA separately prepared document with its own intended audience and +hash.
    Hash / SHA256A fingerprint of exact bytes. It detects change; it does not +establish legal authority.
    IdempotencyRepeating the same identified request has the same intended effect; +changing its payload can be refused.
    IPCThe native desktop command boundary between its browser interface +and Rust host.
    MCPModel Context Protocol; no direct Townlight product server is +enabled by this beta.
    OriginalRetained source bytes. A reviewed derivative does not replace +them.
    ProvenanceSource, version, date, actor and relationship information retained +with evidence.
    RevisionAn immutable saved version. Later edits do not inherit an earlier +review automatically.
    SnapshotA fixed audience-specific copy tied to a source/reviewed +revision.
    StationTownlight’s separate media boundary using a pinned CivicCast-derived +engine; standalone CivicCast remains separate.
    +

    Alphabetical subject index

    + + + +

    Source and document control

    +

    This edition is authored from the immutable corresponding-source +companion, the generated installed-domain schema and the retained +workflow receipts. The current software versions and signed artifacts +are unchanged. Public historical pages are not synchronized or published +by this local documentation task.

    +

    Workflow subject index

    + +
    Townlight · AGPL-3.0-only · Candidate evidence applies only to its identified artifacts.
    \ No newline at end of file diff --git a/docs/beta-1/manuals/station.html b/docs/beta-1/manuals/station.html new file mode 100644 index 0000000..546a049 --- /dev/null +++ b/docs/beta-1/manuals/station.html @@ -0,0 +1,1588 @@ + + +Townlight Station Manual | Townlight candidate + +
    Townlight +
    +

    Naming, Access and Notice source candidate · 2 November 2026

    +

    Prepared documentation. Build, signing, installed acceptance and publication remain pending.

    + + +

    Townlight Station Manual

    +

    Prepared naming, Access and Notice candidate — 2 November 2026. +Station’s existing Beta 1 Python service remains +townlight-station 0.3.0 / townlight_station. +Its separate Rust development line and standalone CivicCast are outside +this migration. Exact signed Windows installed acceptance and +publication for the coordinated candidate remain pending.

    +

    Using this manual

    +

    Townlight Station helps station operators, clerks, records staff and +deployment administrators. Station adapts a pinned CivicCast media +implementation into an independent Townlight boundary. It captures +managed files or configured live UDP MPEG-TS, retains canonical +meeting/agenda context, and hands verified recording evidence to +Records. Scheduling, playout, approval and local playback have distinct +controls.

    +

    Staff should begin with First run and Daily workflow. Administrators +should also read Architecture, Technical specifications, Configuration, +Security and Recovery. Developers should use the exact API/data +dictionary and examples. The table of contents and alphabetical subject +index link to the relevant sections in the HTML edition; the PDF +preserves headings and searchable text. An editable Word edition is +included with the same documentation companion.

    +

    Beta identity

    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    IdentityValue
    DocumentationTownlight naming, Access and Notice candidate
    Intended installer1.7.0.1; build and installed acceptance pending
    Desktop source1.7.0-1
    Runtime distributiontownlight-runtime 0.2.0
    Station distribution/importtownlight-station 0.3.0 / townlight_station
    Acceptance compositionFresh Windows x64; inspections-preview; Station configured +separately
    Candidate hashes/signaturePending new build and signing
    Owned software licenseAGPL-3.0-only
    +

    This edition updates the paired-runtime instructions for the naming +candidate. It does not rename historical Station artifacts or claim new +Station software features. Use an empty database and fresh profile; no +in-place legacy upgrade or old import shim is supported. Preserve +existing city data and the prior release. The approved profile path +remains %LOCALAPPDATA%\CivicSuite for that path only.

    +

    First run

    +
      +
    1. When the identified new signed candidate and corresponding-source +companion are available, verify their exact release identity with the +beta coordinator. The landing pages in this documentation are not an +installer download service.
    2. +
    3. On the intended fresh Windows test installation, verify the MSI hash +and publisher signature before installing. Preserve unrelated profiles +and recovery material. Installed acceptance for this naming candidate +remains pending; no in-place legacy upgrade is supported.
    4. +
    5. Launch Townlight under the intended named Windows account. Choose +the storage folders. Select Townlight Inspections +candidate (inspections-preview) for the bounded +desktop composition, including Access and Notice. A narrower default +selection will not expose all workspaces.
    6. +
    7. Enter the city profile, time zone and contacts. Create the first +named local administrator, sign in and choose protected backup storage. +Continue without local AI is valid for the +deterministic workflows.
    8. +
    9. Run Health Check and wait for readiness. Open Townlight. In System +Health select Finish Records Migration to activate the +canonical Python/PostgreSQL runtime. Do not fabricate migration receipts +or seed accounts.
    10. +
    11. Create named staff through Settings. Import authorized sources using +each product’s source library. All examples in this package are +synthetic; they are not municipal authority.
    12. +
    13. Provision Station separately if it is part of the beta exercise. +Selecting the desktop composition does not start or configure Station. +Configure vision explicitly only if automatic photo drafting is +selected.
    14. +
    +

    Daily workflow

    +

    1. Prepare meeting context

    +

    Create and save the actual meeting and agenda in Meetings. Assign +each selected agenda item to that meeting. A recording request cannot +substitute an editable meeting label for the canonical records.

    +

    2. Open the operator

    +

    Sign in as authorized staff. Use the configured local operator +command with the explicit native profile root. It obtains a short-lived +one-use browser ticket; the native proof is not placed in the URL.

    +

    3. Choose the input

    +

    Select the meeting, assigned agenda and administrator-configured +live-source ID. For recorded-file work, place the source in the managed +ingest directory and optionally supply an SRT sidecar. Callers cannot +submit arbitrary pipelines or filesystem paths.

    +

    4. Capture and stop

    +

    Start capture and distinguish waiting for a signal from active +recording. Stop requests pipeline drain. Wait for completed status and +validated output; a partial, failed or interrupted attempt is not a +completed recording.

    +

    5. Review recording evidence

    +

    Inspect the media and retained context/hash. Retry is explicit for +failed/interrupted recorded-file jobs. A lost live signal cannot be +reconstructed: begin a new live recording and preserve the failed +attempt.

    +

    6. Hand off to Records

    +

    Choose an existing Records request and attach the reviewed recording. +The receiver checks bytes/hash and retains a locked private original. +Repeating the same handoff retains one canonical document.

    +

    7. Use playout deliberately

    +

    Scheduling, dry-run/commit playout, staff approval and local +publication are distinct API operations. Public playback only serves the +separately approved packaged output. Nothing in capture or Records +handoff automatically publishes it.

    +

    8. Close and recover

    +

    Sign out of the operator. Back up Station’s database and media +evidence together, separately from Core’s native profile backup. Restart +interrupted work deliberately; do not automatically re-air a lost +signal.

    +

    Working safely

    +

    Use your own named account and save before leaving a screen. A saved +draft is durable; unsaved form text may not be. If a write has an +unknown result, reopen its record before repeating it.

    +

    Read source jurisdiction, dates, citation, version and visibility. A +copied source hash identifies exact bytes, not their legal +applicability. If a source changes or permission is removed, resolve the +source problem rather than substituting stale cached content.

    +

    Keep originals and derivatives separate. Review the intended audience +before export. A public summary excludes private fields only through the +applicable copy contract and your review. A renamed private packet is +still private content.

    +

    Drafting, review, approval, attachment, export, fulfillment and +publication are separate operations. A Townlight workpaper does not +itself adopt law, issue a permit, impose a fine or release a records +response. The responsible staff member records the applicable +decision.

    +

    Connected workflows

    +

    Meetings → Station → Records is the accepted recording workflow. +Townlight owns current session authority; Station owns its database, +storage and media children. Standalone CivicCast remains separate, with +no shared configuration, service, data directory or automatic updater +fallback.

    + ++++ + + + + + + + + + + + + + + + + +
    DirectionMaterial
    InputA real Townlight staff session, saved Meetings records, a dedicated +Station database/data root, a managed ingest filename or configured +live-source ID, and optional supplied SRT captions for recorded-file +input.
    OutputCompleted verified recording derivatives, retained original +inputs/provenance, separately approved local playback packages and +locked private Records evidence.
    +

    Product boundary

    +

    There is no Station first-run wizard or automatic activation by the +desktop composition. The accepted normal-profile path uses an explicitly +configured paired Townlight HTTP process. Physical encoder/network, +remote identity, SCM commissioning, CDN delivery and long-duration field +quality are not certified. Station does not perform automatic meeting +speech recognition.

    +

    Architecture

    +

    Townlight Station architecture and evidence flow

    +

    The drawing shows the principal staff/evidence path. Native commands +carry trusted identity to Python business services; PostgreSQL and +retained original files hold durable state. A downstream copy does not +silently transfer decision authority. Station has its own configured +authority/media boundary, database and mutable files. The +connected-workflow text supplies the drawing’s reading order and +accessibility alternative.

    +

    Scheduling playout and +recovery

    +

    Schedule a +recording and interpret its state

    +

    Use Schedules after saving the actual meeting/agenda +and placing a complete file in Station’s managed ingest +directory. Choose the meeting, Start time, +Source file in managed ingest, and optional SRT +Caption sidecar, then select Schedule. +The browser form schedules files. The service’s schedule API also +supports a configured live-source ID; this is not a second input +selector in that browser form.

    +

    The browser’s datetime input is interpreted in the operator +computer’s local timezone and converted to an ISO UTC instant. Verify +that computer’s timezone before entering a city meeting time. A direct +API client should send an explicit timezone offset or Z; a +timezone-less API datetime is interpreted as UTC. A synthetic +POST /v1/schedules body is:

    +
    {"meeting_id":"11111111-1111-4111-8111-111111111111","agenda_ids":[],"source_file":"synthetic-program.mp4","captions_file":"synthetic-captions.srt","start_at":"2026-11-05T18:00:00-07:00","idempotency_key":"synthetic-schedule-001"}
    +

    Use a real synthetic meeting ID and intended future exercise time, +with files already in managed ingest. The body selects exactly one file +or configured live source; a live source cannot use a sidecar. Reusing +an idempotency key with changed input/context is a conflict. The initial +response includes id, status: scheduled and +start_at; it does not mean recording has finished.

    +

    Refresh Schedules and inspect the returned identity/time. +Cancel schedule is available while it remains +scheduled; cancellation of an already dispatched or terminal entry is +refused. The worker claims due work once and creates the linked +recording. A start delayed by more than ten minutes is +missed, not replayed late. A start within that grace can +dispatch on the next worker pass. Inspect the linked recording for its +own queued/running/completed or failed state. Do not assume scheduling +also commits that recording to air.

    +

    Apply the caption profile

    +

    For a managed recorded file, an explicitly supplied SRT sidecar +replaces embedded captions for this profile; otherwise embedded captions +are retained where supported by the pinned media profile. Live capture +preserves the embedded-caption path and does not accept an SRT sidecar. +An absent caption stream is not automatic speech recognition. Check the +actual captured/packaged captions for the selected synthetic input.

    +

    Original files are limited to 2,147,483,647 bytes and sidecars to +5,000,000 bytes. After publication, browser playback uses the packaged +MP4 and a separate WebVTT track when produced. Preserve original inputs +and recorded caption provenance separately from those derivatives.

    +

    Check playout and commit +deliberately

    +

    Open a completed recording. Select Check +playout to queue mode: dry-run. Inspect its status +and retained errors; a successful check does not change on-air state. To +render and take that program to the scheduled on-air path, explicitly +select Commit to air, which uses +mode: commit. Wait for the playout to be +complete; failed rendering is not a successful switch.

    +

    Equivalent POST /v1/playouts input is:

    +
    {"recording_id":"22222222-2222-4222-8222-222222222222","mode":"dry-run","idempotency_key":"synthetic-playout-check-001"}
    +

    Replace the recording ID with completed synthetic evidence. A +separate deliberate commit uses mode: commit and a new key; +do not reuse the check’s key with a changed mode. Inspect the returned +playout id and read /v1/playouts/{id} until +terminal. The scheduled on-air program follows verified committed +output, not every dry-run or every recording. Keep the worker and air +roles distinct: one renders work, the other follows durable on-air state +and emits the local program.

    +

    Take a live override and +return

    +

    In On air, choose an administrator-configured live +input and enter a reason of at least three characters. Select +Take live override and inspect the on-air mode/source. +POST /v1/on-air/live uses live_source_id and +reason; callers cannot supply an arbitrary network +pipeline.

    +

    While live, select Return to schedule +(POST /v1/on-air/return-to-schedule with no payload). +Confirm the mode returns to scheduled program. The override supersedes +the scheduled output; it does not delete its committed material. If no +valid committed program is available, do not assume returning has +produced a usable broadcast. Read actual output/state and any error. +These are local synthetic on-air controls, not proof of a commissioned +cable headend, physical receiver or public CDN.

    +

    Approve and publish local +playback

    +

    In Playout and playback, wait for a completed +rendered playout. Review its actual media/context/captions, then enter +the approval note and approve it. The API accepts a note of 3–500 +characters at /v1/playouts/{id}/approve. Approval is +retained with the authenticated staff actor; it does not itself +publish.

    +

    Select Publish locally only for that reviewed +approved playout. /v1/playouts/{id}/publish packages local +MP4/WebVTT playback. The response and subsequent playout view retain the +publication details. Open the displayed local playback, verify it +advances with the expected picture/sound, and inspect the caption track +where supplied. Unpublished content is unavailable through the public +playback route; guessing its ID does not authorize access. Repeating a +completed publication returns the retained package rather than silently +publishing changed media.

    +

    The local playback route /v1/public/playback/{id} serves +the packaged program; /captions serves its available +WebVTT. This approval/publication is separate from Commit to +air, capture, attachment to Records and a Records release. +Internet commissioning remains outside this local procedure.

    +

    Recover without +replaying unknown work

    +

    After a worker/API/air interruption, inspect durable schedules, +recordings, attempts, playouts and on-air state before repeating any +write. The worker marks interrupted in-flight work accordingly. Eligible +failed/interrupted file recording retries are explicit; +live loss requires a new live capture. Retain the prior attempt/logs and +do not claim a missing live interval was reconstructed.

    +

    Future scheduled intent survives restart. A claimed/dispatched +schedule must not be duplicated; one beyond the ten-minute grace becomes +missed. Read its linked recording and create new future intent only when +deliberately required. On-air recovery preserves attribution and does +not automatically resume a stale live override as if the source had +remained valid. Check the actual on-air mode and available committed +program after restart before choosing a new override.

    +

    Visible failed/interrupted states and error text in the operator are +the existing alert mechanism for this beta. Preserve the private process +logs and attempt evidence. Reopen a normal operator ticket after API +restart; do not replay an old ticket or bypass current staff authority. +Restore Station’s database and its matching media as one recovery set, +separately from Core’s native backup. Recheck original/output hashes and +intended state after restoration. No automatic repair or database reset +is implied by restart.

    +

    Source contracts: townlight_station/operations.py, +worker.py, airplay.py, +operator.py, the pinned media profile and +station/operator-ui/src/operator.tsx. Service request +models are in the Station API companion. The three suite-side Station +paths in its OpenAPI download are not the full separate /v1 +service schema.

    +

    Technical specifications

    +

    Runtime and storage

    +

    The accepted package targets Windows x64 fresh +installation. Its native shell uses Rust 2021, Tauri 2 +and Microsoft WebView2; browser assets are JavaScript built +with Vite 8.1.6. This describes the native desktop +frontend; Station has a separate React operator, specified below or in +its product manual. Canonical business workflows use bundled +CPython 3.13.5, FastAPI, Pydantic, SQLAlchemy and +Alembic, with PostgreSQL 17 / PostGIS and +managed original files. The installed runtime tested here contains +FastAPI 0.162.0. Package minimum Python requirements can differ from the +bundled executable; the metadata reference preserves both. No stack +rewrite is implied by the beta label.

    +

    The native transport is fixed to loopback +127.0.0.1:15480; PostgreSQL uses the configured local +runtime port (default 15432). Optional local model service +defaults to 127.0.0.1:15434. Those are deployment defaults, +not internet endpoints. The runtime has health, module and readiness +endpoints; readiness is stronger than process existence. The task queue +is the existing local Core task infrastructure, not an assertion that a +separate Redis service is required for this desktop composition.

    +

    The default native profile is %LOCALAPPDATA%\CivicSuite; +the historical directory name remains part of compatibility. Do not +rename it to Townlight. A configured TOWNLIGHT_PROFILE_ROOT +must be absolute. Local configuration and secrets live under that +profile; protected managed files and database state must be backed up +coherently. Source/runtime identity is distinct from a product’s display +label.

    +

    Data and consistency

    +

    Configured live-source IDs; canonical meeting/agenda snapshots; +queued recordings and immutable attempts; input/output hashes; +schedules; playout jobs and approvals; durable on-air state; publication +packages; Records attachment provenance.

    +

    Versioned saves use expected prior revision identifiers where +defined. Reopen and reconcile on conflict. Exact exports and handoffs +use source IDs, current visibility, revision and SHA256. Review belongs +to the saved revision and does not transfer silently to edited text. +Database changes use the owning product’s migrations; a request or +readiness check is not an authorization to mutate schema.

    +

    Capacity and platform +statements

    +

    This beta has synthetic single-profile workflow evidence. It does not +have a published benchmark for concurrent staff capacity, minimum +RAM/CPU, large-source limits or a field SLA. Do not turn a developer +machine’s specification into a supported minimum. Installer size is +2,092,122,112 bytes before installation; allow additional disk for +extracted runtime, database, originals, exports, media and backups. +Select equipment/storage after sizing those actual workloads.

    +

    The exact runtime payload +lock records pinned files, sizes and hashes. The component +metadata records shipped dependency declarations. These references +are more precise than a manually copied dependency list. Third-party and +historical license notices must accompany their matching payloads.

    +

    Station operator and +media components

    +

    The native desktop frontend above is distinct from Station’s browser +operator. The pinned operator package +townlight-station-operator is version +0.1.0, using React/react-dom 19.1.1, +TypeScript 5.9.2, Vite 7.3.7 and the +React Vite plugin 5.0.2. Station serves its built assets through its own +operator API. Its Python control/API package remains +townlight-station 0.3.0, while its retained storage +identity remains 0.1.0. These identities have different +purposes and are not renumbered.

    +

    The separate pinned CivicCast-derived media engine uses Python/native +GStreamer processing and bounded media children. It is not the +standalone CivicCast application. Station’s control database, data root, +service/configuration and update identity remain independent. This +describes the current mixed stack; no runtime rewrite or CivicCast +migration is implied.

    +

    Station media and +lifecycle contract

    +

    The package/API version is 0.3.0. Its retained storage +identity has version 0.1.0; that is a separate storage +marker and must not be rewritten to match the package. Product/app IDs +are townlight-station and +org.townlight.station; service identity is +TownlightStation, virtual account +NT SERVICE\TownlightStation, credential namespace +townlight.station, database schema station, +and update-channel identity townlight-station. An identity +name or SCM entry point does not establish that a Windows service was +registered.

    +

    The control service is Python; its separate pinned CivicCast-derived +engine uses native GStreamer media processing. There is no launch of the +standalone CivicCast application. Default encoding is 1920×1080, 30 fps +and 6000 kbps; explicit validated configuration may change it. The +source lock is verified before use. Media children are isolated and +bounded; unfinished attempts become interrupted on recovery.

    +

    Recorded-file requests accept a managed ingest filename, optional SRT +sidecar and idempotency key. Live requests accept a configured source +ID, not a path. Select exactly one file or live source; live capture +cannot also supply a sidecar. Inputs are bounded by the configured +two-hour default timeout and a 2,147,483,647-byte file limit. Supplied +SRT sidecars are bounded to 5,000,000 bytes. The queue admits at most +100 pending/running jobs; live admission is further serialized. A +repeated idempotency key must identify the same source bytes, canonical +meeting context and encoding profile.

    +

    queued and running do not make content +available as completed. Completion requires the worker’s clean media +teardown and stream validation. Failed/interrupted file jobs may be +explicitly retried; a live gap requires a new capture. Records receives +verified bytes and canonical provenance as a locked private original. +Local publication is an explicit later operation on separately approved +playout; its MP4/WebVTT package is distinct from the retained recording +and from a Records release.

    +

    Configuration and +administration

    +

    Prepare the +normally activated synthetic profile

    +

    This procedure describes a future isolated beta installation. +Documentation generation does not execute it. Complete normal Townlight +Setup under the intended Windows account, select +inspections-preview, sign in, and use Finish +Records Migration. Keep the native database running and confirm +the canonical runtime is ready. Use that account’s actual profile path; +the default is %LOCALAPPDATA%\CivicSuite. Do not create +session files, seed accounts or force +domain_enabled=True.

    +

    Station needs its own database and initially empty absolute data +directory. It uses the same named Townlight staff authority through an +additional configured loopback suite process. It does not launch or +modify CivicCast. No SCM installation, registry edit or replacement of +the desktop’s fixed-origin service is needed.

    +

    The examples reserve suite port 15481, Station port +8756 and synthetic UDP input port +19000. Choose unused ports and change both configured +origins together if needed. Never point these instructions at a city’s +live profile or data. Use the actual installation directory if Townlight +was installed elsewhere.

    +

    Store the independent +test configuration

    +

    Run the following in a deployment PowerShell session under the same +Windows user. Keep this session for startup and shutdown. The dedicated +parent holds configuration/logs; its data child is +Station’s initially empty managed store.

    +
    $profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite'
    +$control = Join-Path $profilePath 'runtime\python\python.exe'
    +$payload = 'C:\Program Files\Townlight\_up_\runtime\payload\station'
    +$stationRoot = Join-Path $env:LOCALAPPDATA 'TownlightStation-Synthetic'
    +if (-not (Test-Path -LiteralPath $control)) { throw 'Complete normal Townlight setup first.' }
    +if (Test-Path -LiteralPath $stationRoot) { throw 'Existing Station directory: inspect it; do not overwrite.' }
    +New-Item -ItemType Directory -Path $stationRoot | Out-Null
    +$account = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
    +& icacls.exe $stationRoot /inheritance:r /grant:r "${account}:(OI)(CI)F" '*S-1-5-18:(OI)(CI)F' | Out-Null
    +if ($LASTEXITCODE -ne 0) { throw 'Cannot protect Station configuration directory.' }
    +New-Item -ItemType Directory -Path (Join-Path $stationRoot 'data'),(Join-Path $stationRoot 'logs') | Out-Null
    +$rng = [System.Security.Cryptography.RandomNumberGenerator]::Create()
    +$randomBytes = New-Object byte[] 32
    +$rng.GetBytes($randomBytes)
    +$rng.Dispose()
    +$stationPassword = -join ($randomBytes | ForEach-Object { $_.ToString('x2') })
    +$stationPassword | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString |
    +  Set-Content -LiteralPath (Join-Path $stationRoot 'station-password.dpapi')
    +Remove-Variable stationPassword,randomBytes
    +

    The password file uses the current Windows user’s DPAPI protection. +It is not portable to a different user or machine without an explicit +credential/recovery decision. Keep it out of source control, support +bundles and public documentation. Reuse this protected configuration on +restart rather than creating another database or password.

    +

    In the same session, establish the exact process environment. On a +later restart, set $profilePath, $control, +$payload and $stationRoot to these same +existing locations, then repeat this environment/start section, +not the first-time provisioning section.

    +
    $secret = Get-Content -LiteralPath (Join-Path $stationRoot 'station-password.dpapi') -Raw |
    +  ConvertTo-SecureString
    +$stationPassword = [System.Net.NetworkCredential]::new('', $secret).Password
    +$nativePassword = (Get-Content -LiteralPath (Join-Path $profilePath 'config\secrets\postgres-password.txt') -Raw).Trim()
    +$encodedNative = [uri]::EscapeDataString($nativePassword)
    +$env:TOWNLIGHT_PROFILE_ROOT = $profilePath
    +$env:TOWNLIGHT_DATA_DIR = Join-Path $profilePath 'Data'
    +$env:TOWNLIGHT_FILE_STORAGE_DIR = Join-Path $profilePath 'Data\files'
    +$env:DATABASE_URL = "postgresql+asyncpg://townlight:${encodedNative}@127.0.0.1:15432/townlight"
    +$env:TOWNLIGHT_PRODUCT_PROFILE = 'inspections-preview'
    +$env:PORTAL_MODE = 'private'
    +$env:TOWNLIGHT_RUNTIME_HOST = '127.0.0.1'
    +$env:TOWNLIGHT_RUNTIME_PORT = '15481'
    +$env:TOWNLIGHT_STATION_URL = 'http://127.0.0.1:8756'
    +$env:TOWNLIGHT_STATION_SUITE_URL = 'http://127.0.0.1:15481'
    +$env:TOWNLIGHT_STATION_DATA_ROOT = Join-Path $stationRoot 'data'
    +$env:TOWNLIGHT_STATION_DATABASE_URL = "postgresql+psycopg2://townlight_beta_station_app:${stationPassword}@127.0.0.1:15432/townlight_beta_station"
    +$env:TOWNLIGHT_STATION_MEDIA_SOURCE = Join-Path $payload 'media-source'
    +$env:TOWNLIGHT_STATION_MEDIA_PYTHON = Join-Path $payload 'runtime\python.exe'
    +$env:TOWNLIGHT_STATION_MEDIA_RUNTIME = Join-Path $payload 'runtime'
    +$env:TOWNLIGHT_STATION_FFPROBE = Join-Path $payload 'bin\ffprobe.exe'
    +$env:PYTHONNOUSERSITE = '1'
    +$env:PYTHONDONTWRITEBYTECODE = '1'
    +Remove-Item Env:PYTHONPATH -ErrorAction SilentlyContinue
    +Remove-Variable nativePassword,encodedNative,stationPassword,secret
    +

    Use the actual native PostgreSQL port/database/user if the deployment +differs from the accepted defaults. Environment changes here apply to +children of this shell, not the already running native supervisor. Keep +secrets out of command arguments and output. The paired runtime +deliberately uses normal verify_activation through its +standard module entry point.

    +

    Provision the Station +database once

    +

    This first-time step creates only the dedicated synthetic +role/database. Its role owns that database and its Station schema, with +no superuser/global administration grant. It connects to the normally +provisioned local database using the current profile’s protected +credential. Existing role/database names cause a refusal before +creation; do not drop or repurpose them automatically.

    +
    @'
    +import os
    +from pathlib import Path
    +import psycopg2
    +from psycopg2 import sql
    +from sqlalchemy.engine import make_url
    +
    +url = make_url(os.environ['TOWNLIGHT_STATION_DATABASE_URL'])
    +profile = Path(os.environ['TOWNLIGHT_PROFILE_ROOT'])
    +password = (profile/'config/secrets/postgres-password.txt').read_text().strip()
    +conn = psycopg2.connect(host='127.0.0.1', port=15432, user='townlight',
    +                        password=password, dbname='postgres')
    +conn.autocommit = True
    +try:
    +    with conn.cursor() as cur:
    +        cur.execute('SELECT 1 FROM pg_roles WHERE rolname=%s', (url.username,))
    +        role_exists = cur.fetchone() is not None
    +        cur.execute('SELECT 1 FROM pg_database WHERE datname=%s', (url.database,))
    +        if role_exists or cur.fetchone() is not None:
    +            raise RuntimeError('Dedicated role/database already exists; inspect before continuing')
    +        cur.execute(sql.SQL('CREATE ROLE {} LOGIN PASSWORD %s').format(
    +            sql.Identifier(url.username)), (url.password,))
    +        cur.execute(sql.SQL('CREATE DATABASE {} OWNER {}').format(
    +            sql.Identifier(url.database), sql.Identifier(url.username)))
    +finally:
    +    conn.close()
    +'@ | & $control -B -
    +if ($LASTEXITCODE -ne 0) { throw 'Station database provisioning did not complete; inspect before retrying.' }
    +& $control -B -m townlight_station.cli migrate
    +if ($LASTEXITCODE -ne 0) { throw 'Station migration failed; retain logs and inspect the dedicated schema.' }
    +

    If database creation fails after the role was created, the operation +is partially complete: inspect that exact owned role/database before +resuming. Do not rerun against guessed names or remove unrelated +objects. On normal restarts, the database already exists; skip creation +and use the existing identity. migrate is explicit; API +requests do not substitute for schema migration.

    +

    Start and check the paired +processes

    +

    Use the same configured session. The standard suite entry point +verifies the existing native activation. Check readiness of that exact +paired origin, not only the desktop’s canonical port. Startup below +creates hidden children with private log files and records their +identities; it does not focus windows or install services.

    +
    $owned = @()
    +function Start-StationRole([string]$name, [string[]]$arguments) {
    +  $p = Start-Process -FilePath $control -ArgumentList $arguments -WindowStyle Hidden -PassThru `
    +    -RedirectStandardOutput (Join-Path $stationRoot "logs\$name.out.log") `
    +    -RedirectStandardError (Join-Path $stationRoot "logs\$name.err.log")
    +  $script:owned += [pscustomobject]@{ Name=$name; Id=$p.Id; StartTime=$p.StartTime; Path=$p.Path }
    +  $script:owned | ConvertTo-Json | Set-Content -LiteralPath (Join-Path $stationRoot 'owned-processes.json')
    +  return $p
    +}
    +function Wait-StationReady([string]$url, $process) {
    +  for ($attempt=0; $attempt -lt 40; $attempt++) {
    +    if ($process.HasExited) { throw "Owned process exited; inspect logs for $url" }
    +    try {
    +      $response = Invoke-WebRequest -Uri $url -UseBasicParsing -TimeoutSec 2
    +      if ($response.StatusCode -eq 200) { return }
    +    } catch { }
    +    Start-Sleep -Milliseconds 250
    +  }
    +  throw "Readiness not established: $url; inspect the owned logs"
    +}
    +$suite = Start-StationRole 'paired-suite' @('-B','-m','townlight_runtime.services')
    +Wait-StationReady 'http://127.0.0.1:15481/ready' $suite
    +$api = Start-StationRole 'station-api' @('-B','-m','townlight_station.cli','serve','--port','8756')
    +Wait-StationReady 'http://127.0.0.1:8756/health' $api
    +$worker = Start-StationRole 'station-worker' @('-B','-m','townlight_station.cli','worker')
    +# Only for the on-air profile:
    +$air = Start-StationRole 'station-air' @('-B','-m','townlight_station.cli','air')
    +$owned | ConvertTo-Json | Set-Content -LiteralPath (Join-Path $stationRoot 'owned-processes.json')
    +

    Before launching, confirm ports 15481 and 8756 are unused. If +readiness fails, inspect the relevant logs and retained profile/schema +state; do not start another copy. A port that answers belongs to the +intended process only when its ownership is established. A single worker +owns a database. worker --once performs a bounded pass; it +is not the normal continuous worker. The air role follows +durable on-air state and emits the local program; it does not commission +a physical transmitter or CDN. Its currently configured local output is +under Station’s air directory. Back up the dedicated +database and media together; Core’s native backup does not cover +them.

    +

    Configure a live +input and open the operator

    +

    Create live-sources.json under the Station +data directory with the following fictional input. An +actual sender must supply UDP MPEG-TS to that receiver; this +configuration alone does not generate a signal.

    +
    [{"id":"synthetic-chamber","label":"Synthetic chamber feed","kind":"udp-mpegts","address":"127.0.0.1","port":19000}]
    +

    At most 32 rows are accepted. IDs are unique 1–64 +letters/digits/underscore/hyphen; labels have 1–100 characters; IPv4 and +ports 1024–65535 are validated. Each row has exactly the five shown +keys. Protect the source network; UDP is not authenticated. Then, under +the same signed-in native account:

    +
    & $control -B -m townlight_station.cli operator --profile-root $profilePath --port 8756
    +

    This normal operator command opens the operator for a future staff +exercise. It reads the native session and exchanges a one-use launch +ticket; it does not seed authority or put the native proof in a URL. +Ticket expiry is 60 seconds, operator cookie lifetime 900 seconds, with +at most 256 outstanding tickets/sessions each. Reopen normally after +expiration, API restart or sign-out. Changing database/configuration +identities does not repair a staff permission refusal.

    +

    Bounds and shutdown

    +

    Default encoding is 1920×1080, 30 fps, 6000 kbps. Optional Station +variables permit MAX_SECONDS 10–86400 (default 7200), even +WIDTH 320–3840 and HEIGHT 180–2160, +FPS 1–60 and BITRATE_KBPS 128–50000; each is +prefixed TOWNLIGHT_STATION_. The media source lock and +exclusive data identity are verified before use. The dedicated database +name must end in _station; unowned nonempty storage and +escaping/reparse paths are refused. The existing SCM entry point is not +a claim of installed service acceptance.

    +

    To finish an exercise, stop live capture from the operator and wait +for its completed or failed terminal state. Wait for any +recording/playout work to finish, cancel unwanted future schedules, sign +out and preserve the evidence/logs. The air role starts a separate media +child; force-stopping only its parent does not run Python cleanup. Stop +only the process trees you started, checking each root’s identity before +using a saved PID:

    +
    foreach ($entry in @($owned | Sort-Object StartTime -Descending)) {
    +  $process = Get-Process -Id $entry.Id -ErrorAction SilentlyContinue
    +  if ($process -and $process.StartTime -eq $entry.StartTime -and $process.Path -eq $entry.Path) {
    +    & taskkill.exe /PID $process.Id /T /F | Out-Null
    +    if ($LASTEXITCODE -ne 0) { throw 'Owned process tree did not stop; inspect before proceeding.' }
    +    $process.WaitForExit()
    +  }
    +}
    +

    Retain the ownership file if the shell must close; parse and verify +its actual process paths/start times before acting. Do not terminate the +native database/supervisor or CivicCast. Interrupting a worker during a +job preserves an interrupted attempt, not completed media; recovery is +described in the Station operating procedure. Clear secret-bearing +environment values when closing the dedicated deployment shell. Do not +delete the database/data root to “reset” an uncertain result.

    +

    API and integration examples

    +

    Native command example

    +

    The following JavaScript belongs in the existing trusted Townlight +frontend/development environment with invoke imported from +@tauri-apps/api/core. It is not a command for an arbitrary +web page or an instruction for nontechnical staff. IDs must come from +records created in an isolated synthetic exercise.

    +
    import { invoke } from '@tauri-apps/api/core';
    +const result = await invoke('meetings_domain_request', {request: {operation: 'get-meeting', id: meetingId}});
    +console.log(result);
    +

    Trusted local HTTP example

    +

    An administrator/developer can inspect an already-configured isolated +runtime from a trusted local process. This PowerShell example reads the +signed-in synthetic profile’s existing proof into memory; it does not +create a user, seed a session, reveal the proof in output or bypass a +permission check. Do not use real city data in development examples. A +read response does not prove approval or publication.

    +
    Invoke-RestMethod -Uri 'http://127.0.0.1:8756/health'
    +# Authenticated recording operations additionally require current native proof.
    +

    A synthetic write +with subsequent readback

    +

    This example demonstrates the existing Meetings HTTP contract in an +isolated exercise. It is intentionally fictional. It does not start a +service. Its authentication setup is included so it can be run +independently under the signed-in synthetic account. If a write times +out, inspect current records before repeating it.

    +
    $profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite'
    +$sessionPath = Join-Path $profilePath 'config/local-session.json'
    +$session = Get-Content -LiteralPath $sessionPath -Raw | ConvertFrom-Json
    +$headers = @{ 'X-Townlight-Session' = $session.session_hash }
    +$body = @{
    +  title = 'Synthetic documentation exercise'
    +  scheduled_start = '2026-11-05T18:00:00-07:00'
    +  location = 'Synthetic room'
    +  meeting_type = 'regular'
    +} | ConvertTo-Json
    +$meeting = Invoke-RestMethod -Method Post `
    +  -Uri 'http://127.0.0.1:15480/desktop/v1/meetings/meetings' `
    +  -Headers $headers -ContentType 'application/json' -Body $body
    +Invoke-RestMethod `
    +  -Uri ('http://127.0.0.1:15480/desktop/v1/meetings/meetings/' + $meeting.id) `
    +  -Headers $headers
    +Remove-Variable session, headers
    +

    This write requires Meetings to be enabled and the signed-in staff +role to permit it. It is a cross-suite integration example; for this +product’s request models, use the complete technical reference +below.

    +

    Recording and Records +handoff example

    +

    An authenticated local client sends +POST http://127.0.0.1:8756/v1/recordings with +X-Townlight-Session and this JSON, replacing the synthetic +UUIDs with saved synthetic meeting/agenda IDs. Configure +synthetic-chamber first.

    +
    {
    +  "meeting_id": "11111111-1111-4111-8111-111111111111",
    +  "agenda_ids": ["22222222-2222-4222-8222-222222222222"],
    +  "live_source_id": "synthetic-chamber",
    +  "idempotency_key": "synthetic-docs-capture-001"
    +}
    +

    The initial response is 202 with a queued/running +identity rather than completed media. Read +/v1/recordings/{identity}, explicitly stop live capture +through /v1/recordings/{identity}/stop, and wait for +completed status before reading /content. Then the +authorized Records client calls +POST /desktop/v1/requests/{request_id}/station-recordings +on the paired Suite runtime with:

    +
    {
    +  "recording_id": "33333333-3333-4333-8333-333333333333",
    +  "expected_sha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
    +}
    +

    The shown hash is deliberately a placeholder. Use the actual +completed recording’s hash. A mismatched hash must fail. Repeating the +identical completed handoff is idempotent; it does not create a release +copy or fulfill a request.

    +

    Complete technical contract

    +

    Read the Station API +reference for every documented operation, request field, constraint, +response declaration and source supplement. Download the OpenAPI JSON for tools. +For Station this is the suite-side schema only; its separate service +contract is documented in the API supplement. The reference directory includes +configuration/source inventories, dependency declarations, native +command contracts, MCP signatures and candidate evidence.

    +

    MCP and automation boundary

    +

    No direct product MCP server is exposed by the accepted Townlight +desktop or Station boundary. Do not configure an invented +townlight mcp command or assume an AI client has staff +permissions. The integration surfaces for this beta are native IPC, the +documented HTTP APIs, source bundle imports, exact exports and the +existing Station CLI.

    +

    The bundled transcription code includes a TextFlowKit MCP +adapter as a separate source capability. It offers job-based +transcribe_media, get_transcript, +list_jobs, get_job_status and +export_transcript, and additional tools declared in that +adapter. It uses stdio first and optional Streamable HTTP, with the MCP +SDK as an optional extra. It is not automatically launched, +authenticated as Townlight staff or accepted as a Townlight product MCP +deployment. This documentation does not add such a service.

    +

    For a transcription client already provisioned separately, an +illustrative tool call is:

    +
    {"name":"get_job_status","arguments":{"job_id":"synthetic-existing-job-id"}}
    +

    Use a job ID returned by that transcription service. This example +does not create a Townlight record or bypass its review/Records handoff. +The exact optional adapter tool signatures are supplied in the MCP source reference. Station +meeting capture does not become live speech recognition because this +optional donor adapter exists.

    +

    Security and permissions

    +

    Use your own named account and save before leaving a screen. A saved +draft is durable; unsaved form text may not be. If a write has an +unknown result, reopen its record before repeating it.

    +

    Read source jurisdiction, dates, citation, version and visibility. A +copied source hash identifies exact bytes, not their legal +applicability. If a source changes or permission is removed, resolve the +source problem rather than substituting stale cached content.

    +

    Keep originals and derivatives separate. Review the intended audience +before export. A public summary excludes private fields only through the +applicable copy contract and your review. A renamed private packet is +still private content.

    +

    Drafting, review, approval, attachment, export, fulfillment and +publication are separate operations. A Townlight workpaper does not +itself adopt law, issue a permit, impose a fine or release a records +response. The responsible staff member records the applicable +decision.

    +

    The native session is validated and mapped to a persisted SQL +identity. An editable actor/reviewer label is not authentication. +Product/module permissions and source visibility apply at the server +boundary. Revoked/unavailable authority fails closed for new Station +operations; a previous permission result is not a perpetual +authorization.

    +

    Use protected local folders, account permissions and credential +storage. Never include the native session file, database passwords, +provider keys or unredacted support bundles in a public issue or +generated public documentation. A local public view is not automatically +a secured internet deployment. Keep network exposure and real equipment +acceptance specific to the chosen beta site.

    +

    Backup recovery and +maintenance

    +

    Save work and use Core’s canonical Backup Now before +maintenance. That operation stops writers. Preserve the coherent +profile/database/document backup and its receipt, then use +Start to resume. A source export is not a full +backup.

    +

    Use Restore Latest Backup through the supported +controls. If the result says Restore needs service +start, use Start, then Check, +and reopen a known record. Do not repeat restore merely because services +need to start. The prior accepted profile exercise verified +request/marker recovery for its identified artifact. Repeat the required +recovery proof for this changed signed candidate before calling it +accepted.

    +

    Keep Station’s dedicated database and media evidence together in its +own backup. Core’s native-profile backup must not be assumed to include +an external Station data directory. Stop writers during a coordinated +backup. Preserve failed media attempts and logs.

    +

    On failure, record the time, selected composition, +component/installer versions and exact message. Check System Health for +stopped, starting, ready or failed dependencies. Use the existing Retry +control after readiness; do not create duplicate business records to +refresh a stale view. Share only a redacted diagnostic bundle. Preserve +secrets, original evidence, recovery material and unrelated +installations.

    +

    Troubleshooting

    + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    SymptomLikely meaningNext action
    Workspace absentWrong product composition or unavailable canonical runtime.Check selected composition; activate through Finish Records +Migration; wait for readiness.
    Cannot sign in / 401Missing or expired named account session.Sign in normally; reopen a Station launch ticket if applicable.
    Permission denied / 403Account, module, source or browser-origin permission.Ask the authorized administrator to inspect the intended permission; +do not invent role headers.
    Save conflict / 409The saved revision, expected source hash or lifecycle changed.Keep edits, reopen current state and reconcile deliberately.
    Invalid input / 422Required field, format, geometry, source envelope or state is +invalid.Read the field detail and correct the input/source; preserve +originals.
    Service unavailable / 503Database, schema, connected source or configuration +unavailable.Inspect System Health and the named dependency. Preserve work; retry +only after readiness.
    Export refusedMissing exact review, approval, audience or source +authorization.Read the refusal and complete the owning product’s explicit +decision.
    Restore needs service startThe snapshot was restored but services have not resumed.Use Start, then Check and verify a saved record; do not blindly +repeat restore.
    Ticket expired or usedA launch is one-use and expires after 60 seconds.Reopen from the signed-in native session; do not replay the old +URL.
    Recording interruptedInput/worker failed or a live signal was lost.Retain attempt/logs. Retry eligible file work explicitly; start a +new live capture for a live gap.
    Recording not downloadableIt is not complete or its retained bytes failed validation.Inspect state and evidence; do not serve a partial attempt as +completed media.
    +

    Verified workflows and +limits

    +

    The original accepted Station manual and its workflow claims are +preserved byte +for byte. Those results identify earlier artifacts; they are not +installed signoff for this naming candidate. The current package retains +the same Beta Python service and pinned CivicCast donor. Source presence +and a successful wheel import do not establish the required Windows +Meetings → Station → Records handoff.

    +

    The new candidate must verify actual saved meeting/agenda context, +authorized Station capture and stop, completed media/hash readback, +private Records handoff, idempotency, authorization/logout, persistence +and the agreed recovery path. Its ACCEPTANCE.md must distinguish new +proof from justified reused evidence. This source documentation does not +certify a signed MSI, live YouTube upload, physical PEG broadcast, city +deployment or long-duration commissioning.

    +

    The separate provisioning/service boundary and existing +external-service limits remain as described below. Staff remain +responsible for official release and publication decisions. No +additional provider or selected-model change is made.

    +

    Terms of service and license

    +

    Scope and status

    +

    These terms describe the Townlight Beta 1 software and this +documentation package. This is a locally prepared private beta, not a +hosted-service subscription, a city deployment agreement or a public +release. No uptime commitment, support response time, indemnity, +data-processing agreement or paid service is created by these documents. +A separate signed agreement, if any, governs services it actually +provides.

    +

    Software license and rights

    +

    Current Townlight-owned distributions identified in this candidate +use AGPL-3.0-only. The full license is supplied with +this documentation and with the source companion. The license governs +rights to run, copy, modify and convey the covered software; these +operational terms do not add restrictions to those rights. Historical +grants and dependency licenses retain their own terms. CivicCast remains +a separate product and is not relicensed by this documentation work.

    +

    When conveying covered software, retain applicable notices and +provide the corresponding source and installation/build information +required by the license. For a modified version supporting remote +network interaction, follow section 13’s source-offer requirement. The +companion archive identifies the source for this candidate; a link to a +different public branch is not a substitute for the matching source. +Read the supplied license for the complete conditions. See the GNU license +reference and GNU licensing +FAQ.

    +

    Data ownership and access

    +

    Importing a document does not transfer its ownership or grant +permission to publish it. The operating organization controls its +accounts, access decisions, lawful source use, retention and +review/release policy. Keep resident information, credentials, private +notes and restricted evidence in their authorized locations. +Documentation examples contain fictional data. No real city account, +credential or record is required to exercise these examples in an +isolated test environment.

    +

    Local operation and +external processors

    +

    The bounded beta workflow uses named staff accounts; current +installed acceptance is pending. Station has separate storage and +credentials. Configure backup destinations and optional model/network +providers deliberately. A configured external provider may receive +submitted prompts, images or audio according to that configuration and +provider’s terms; this documentation does not promise that every +optional configuration is offline. An email outbox or local public view +does not establish external delivery or an internet deployment. This +static documentation site has no analytics, account collection or remote +font dependency.

    +

    Staff decisions and +source applicability

    +

    Staff verify the jurisdiction, source currency, permissions, +citations and proposed audience. Model output and generated guidance +require review. No draft is automatically an official legal +interpretation, zoning determination, permit approval, fee assessment, +enforcement notice or records-release decision. Official permit fee +authority remains with the adopted source and responsible organization; +imported amounts do not become a new authoritative calculation.

    +

    Beta operation and recovery

    +

    Use the identified candidate in its supported fresh-install scope. +Preserve backups and original evidence. Test physical equipment and +chosen network/service configuration before relying on them. The +supplied acceptance describes selected synthetic workflows, not every +screen, vendor, field condition or upgrade. Operators decide whether a +particular deployment meets their own operational obligations.

    +

    Warranty and liability

    +

    The covered software’s warranty and liability conditions are those in +sections 15–17 of the supplied AGPL and any applicable separate written +undertaking. This documentation creates no additional warranty or +limitation beyond those terms. Third-party software is subject to its +retained license notices. Nothing here removes rights that applicable +law makes nonwaivable.

    +

    Support and incident +reporting

    +

    Use the project’s existing SUPPORT and SECURITY guidance for its +matching repository. Report reproducible behavior with the version, +operation and redacted logs. Do not put credentials, resident records or +unredacted evidence in a public issue. Coordinate sensitive reports +through the channel designated in SECURITY. No new support address or +service commitment is invented here.

    +

    Ending a beta +exercise and document changes

    +

    When an organization ends testing, it controls retention/export and +removes access according to its policy. Uninstall may retain data; back +up and inspect the selected removal options. Ending an exercise does not +revoke rights already granted by AGPL. Later software/documentation +versions must identify their changed candidate and scope; historical +receipts retain their original identities. These terms do not claim that +a city has accepted a contract merely by reading a manual.

    +

    Glossary

    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TermMeaning
    ApprovalAn explicit authorized decision on the saved text/artifact. It is +separate from saving or attachment.
    Canonical recordThe owning product’s retained identity and saved version, rather +than an editable copied label.
    CompositionThe selected set of desktop modules; inspections-preview exposes the +eight staff products.
    Corresponding sourceThe source/build material matching the delivered covered program, +subject to its license.
    Derivative / Records copyA separately prepared document with its own intended audience and +hash.
    Hash / SHA256A fingerprint of exact bytes. It detects change; it does not +establish legal authority.
    IdempotencyRepeating the same identified request has the same intended effect; +changing its payload can be refused.
    IPCThe native desktop command boundary between its browser interface +and Rust host.
    MCPModel Context Protocol; no direct Townlight product server is +enabled by this beta.
    OriginalRetained source bytes. A reviewed derivative does not replace +them.
    ProvenanceSource, version, date, actor and relationship information retained +with evidence.
    RevisionAn immutable saved version. Later edits do not inherit an earlier +review automatically.
    SnapshotA fixed audience-specific copy tied to a source/reviewed +revision.
    StationTownlight’s separate media boundary using a pinned CivicCast-derived +engine; standalone CivicCast remains separate.
    +

    Alphabetical subject index

    + + + +

    Source and document control

    +

    This edition carries forward the accepted Station operating +procedures and updates paired-runtime names from the current naming +source candidate. Historical evidence remains in the original manual. +Candidate source commits, MSI signature/hash and exact installed +acceptance must be finalized separately; no current signing receipt or +installed-domain proof is implied by rendering this manual.

    +

    Workflow subject index

    + +

    Completed +recordings on YouTube and live CivicCast coverage

    +

    This source extension adds only completed-recording YouTube uploads +and a live Station-to-CivicCast feed. It is not in the published +Beta 1 installer. Existing component versions are retained. New +Station code is AGPL-3.0-only. The pinned CivicCast source and +third-party licenses remain unchanged. Standalone CivicCast is a +separate product; no installer, account, database, service or default in +it is changed by Station.

    +

    Staff workflow

    +

    For live coverage, choose a meeting, its chamber input and the +administrator’s CivicCast live feed option, then start +recording. Choose Recording only to capture privately +without a network feed. A disconnected receiver does not stop the +recording. Station sends the live MPEG-TS bytes as the recording grows; +it does not wait for the completed file. The feed is available only +during that capture. The CivicCast/PEG operator selects that source and +controls when it is broadcast on local cable. Station does not +automatically put the PEG channel on air. sending means +transport bytes were sent, not proof of cable carriage.

    +

    After Station shows complete, use Upload +completed recording to YouTube. Review the title, select +private/unlisted/public visibility (default private), +and enter the approval note. Click Upload to YouTube. +This is an explicit external upload to the Station-configured OAuth +account. No upload occurs just because recording stopped, a playout was +committed or a Records attachment was made. Station does not create a +YouTube livestream.

    +

    The upload receipt shows +queued/running/uploaded/failed/needs-reconciliation, the chosen +visibility and returned video link. uploaded is the YouTube +upload acknowledgement; YouTube may still be processing the video. The +canonical recording remains private and byte-identical for the existing +Records handoff. The YouTube visibility is separate from local +playback/disclosure approval.

    +

    Architecture

    +

    Station live feed to separate CivicCast and completed recording upload to YouTube

    +

    The sender has bounded, leaky buffers and follows the live edge after +congestion. Its network sink shares no pipeline with the recorder. A +late join or connection loss can leave a live coverage gap, while the +private recording continues. H.264/AAC and existing MPEG-TS captions are +forwarded without another encode. The MP4 upload remux reuses +vod_job.py; it does not generate transcripts or captions, +and does not upload a separate caption track. Upload queue work runs in +a separate process so a long upload never monopolizes the capture +worker.

    +

    Administrator setup

    +

    Use Station’s existing dedicated data root and PostgreSQL database. +Stop Station writers for a coordinated backup, retain that backup, and +run the explicit townlight-station migrate before starting +this source version. Schema 4 adds +station.youtube_uploads, keeping existing +recording/schedule/playout evidence. The data identity marker and +component versions are unchanged. Old services expect schema 3; use a +matched source/runtime and preserve the backup for rollback.

    +

    Create civiccast-feeds.json in the private Station data +directory:

    +
    [
    +  {
    +    "id": "peg",
    +    "label": "CivicCast council feed",
    +    "address": "192.0.2.10",
    +    "port": 10080,
    +    "secret_env": "TOWNLIGHT_STATION_SRT_PEG"
    +  }
    +]
    +

    The address is a numeric IPv4 local interface bind address on +Station, not the CivicCast computer. 192.0.2.10 is +a documentation placeholder. Use the actual Station interface, an unused +port (1024–65535), and appropriate network access between those two +systems. Clients select an administrator-defined ID, never an arbitrary +destination or media pipeline. Keep configuration files private.

    +

    Set TOWNLIGHT_STATION_SRT_PEG in the capture worker’s +process environment to a 10–79 character SRT passphrase. Configure a +separate CivicCast SRT live source with the caller URI +srt://<Station-address>:10080?mode=caller&latency=200 +and the same passphrase through CivicCast’s existing credential control. +Do not put the passphrase in the URI. Station’s +listener uses 128-bit SRT encryption. Keep the two accounts and +configuration stores separate; matching this specific transport +credential is the deliberate pairing. Site-specific camera, headend and +firewall commissioning remain deployment work.

    +

    For completed uploads, configure these Station-only +environment variables in the upload worker process. Obtain OAuth +authorization for the intended Station YouTube channel/account through +the existing deployment’s Google configuration; no OAuth onboarding +framework is added here. Do not use CivicCast’s credentials implicitly +or copy its profile.

    +
      +
    • TOWNLIGHT_STATION_YOUTUBE_CLIENT_ID
    • +
    • TOWNLIGHT_STATION_YOUTUBE_CLIENT_SECRET
    • +
    • TOWNLIGHT_STATION_YOUTUBE_REFRESH_TOKEN (authorized for +YouTube video uploads)
    • +
    +

    Run the existing serve and capture worker, +plus the separate upload consumer with the same Station settings and +dedicated database:

    +
    townlight-station migrate
    +townlight-station serve
    +# In separate managed processes with the same explicit Station configuration:
    +townlight-station worker
    +townlight-station uploads
    +

    These are deployment commands, not commands executed against +installed apps by this development task. Run only one capture +worker and one upload worker per database. Each holds a distinct +advisory lock; media children require the existing Windows job +containment. The recorder child gets no provider credentials; the SRT +child receives only its explicit transport passphrase plus the existing +runtime allowlist. The upload worker reads only the Station OAuth +variables. OAuth/upload HTTP is restricted to Google HTTPS hosts; +redirects are not followed. The pinned donor import is checked against +Station’s declared media source.

    +

    HTTP API and examples

    +

    All /v1 operations below require the existing current +Townlight staff session header (X-Townlight-Session) or the +existing same-origin operator session. Read roles can inspect receipts. +Starting live feed/upload/retry requires the existing Station +capture capability. No new login, role system or MCP server +is added.

    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Method and routePurpose
    GET /v1/civiccast-feedsCapture-authorized list of configured IDs and labels; no transport +credentials
    POST /v1/recordingsExisting capture contract plus optional +civiccast_feed_id, allowed only with +live_source_id
    POST /v1/recordings/{recording_id}/youtubeQueue one explicit completed-recording upload
    GET /v1/youtube-uploadsRead-authorized latest 100 durable upload receipts
    POST /v1/youtube-uploads/{upload_id}/retryCapture-authorized retry of a preparation failure +only
    +

    Station’s generated /openapi.json includes the new +routes and request schemas. Example bodies (use real canonical IDs from +the selected deployment):

    +
    {
    +  "meeting_id": "11111111-1111-4111-8111-111111111111",
    +  "agenda_ids": [],
    +  "live_source_id": "chamber",
    +  "civiccast_feed_id": "peg",
    +  "idempotency_key": "council-live-2026-10-30"
    +}
    +
    {
    +  "title": "City council meeting — 30 October 2026",
    +  "privacy": "private",
    +  "approval_note": "Reviewed completed recording for upload",
    +  "idempotency_key": "council-vod-2026-10-30"
    +}
    +

    Upload titles are 1–100 characters; control characters and angle +brackets are rejected. Visibility is private/unlisted/public; approval +note 3–500 characters; key 1–100 characters. Repeating the same key +returns the same intent, a changed request conflicts, and another key +cannot duplicate an existing recording upload. A +missing/uncompleted/tampered recording is rejected before upload +admission; the worker independently verifies the recording hash before +remuxing/sending. Retained receipts include approving actor, note/time, +recording hash, MP4 path/ hash/size, chosen title/privacy and provider +video ID/URL after acknowledgement. No OAuth token, passphrase or donor +credential pointer is stored in receipts.

    +

    Recovery and limits

    +

    A failed preparation (for example missing Station OAuth configuration +or failed remux) is failed; correct the cause and +explicitly call its retry route. The prior attempt files remain +retained. Once any external request begins, an error is conservatively +needs-reconciliation. A worker restart also moves +interrupted running uploads to that state. There is no +automatic retry that could create a duplicate YouTube video. Check +YouTube Studio and the retained job before a human chooses another +external action. This increment provides no automatic remote +reconciliation/delete/reupload control. A valid uploaded link is +retained even if the capture worker is restarted. The existing +recording/Records path does not depend on the external upload +succeeding.

    +

    Live sender state is in the recording’s +details.civiccast_delivery; its final byte count and +per-attempt status/log files stay with the private recording. On +capture-worker restart, an interrupted feed is marked interrupted rather +than left appearing to send. Stop/reap is bounded even if the network +child hangs. No feed is automatically re-aired after recovery.

    +

    Verification and release +status

    +

    tests/accept_deliveries.py exercises the real Station +API/store/media/remux, CivicCast’s pinned SRT source adapter and real +YouTube file-upload client using a disposable PostgreSQL cluster, +generated audio/video, synthetic staff authority and +httpx.MockTransport for Google. No city systems or external +publication are involved. tests/accept_delivery_ui.cjs +drives the actual compiled operator controls in headless Chromium with +synthetic API responses. Existing boundary/ operations checks and +TypeScript compilation also apply.

    +

    Example invocation from a development environment with existing +dependencies:

    +
    $env:PYTHONPATH = (Resolve-Path ./beta-1).Path
    +$env:STATION_TEST_PG_BIN = 'C:/test-tools/postgres/bin'
    +$env:STATION_TEST_MEDIA_RUNTIME = 'C:/test-tools/station-media-runtime'
    +python -B ./beta-1/tests/accept_deliveries.py C:/test-output/station-deliveries-new
    +

    Use a new output directory; the script starts/stops +only its owned disposable cluster and children. See the task’s retained +acceptance receipts for actual results. This evidence establishes the +new source wiring synthetically. It does not replace CivicCast’s already +established real YouTube delivery evidence, nor claim a new real YouTube +upload, physical cable broadcast, signed installer or Sandbox acceptance +of this extension. Published Beta 1 artifacts stay unchanged.

    +

    Delivery subject index

    +
      +
    • CivicCast +live feed
    • +
    • YouTube: explicit completed recording upload; visibility; receipt +and reconciliation.
    • +
    • Schema4: durable upload intent; existing evidence retained.
    • +
    +
    Townlight · AGPL-3.0-only · Candidate evidence applies only to its identified artifacts.
    \ No newline at end of file diff --git a/docs/beta-1/manuals/suite.html b/docs/beta-1/manuals/suite.html new file mode 100644 index 0000000..e51eec9 --- /dev/null +++ b/docs/beta-1/manuals/suite.html @@ -0,0 +1,1130 @@ + + +Townlight Suite Manual | Townlight candidate + +
    Townlight +
    +

    Naming, Access and Notice source candidate · 2 November 2026

    +

    Prepared documentation. Build, signing, installed acceptance and publication remain pending.

    + + +

    Townlight Suite Manual

    +
    +

    Naming, Access and Notice candidate — 2 November +2026. These instructions describe the prepared 1.7.0-1 source +candidate. Build, signing, Windows installed acceptance and publication +remain pending. The earlier Station delivery release and its original +receipts remain historical evidence for their exact artifacts.

    +
    +

    Using this manual

    +

    Townlight connects municipal workflows around retained sources, named +staff and explicit human decisions. This suite manual explains setup, +shared operating procedures and cross-product handoffs, including the +bounded Access and Notice workflows. Station is separately configured. +Standalone CivicCast remains a separate product.

    +

    Staff should start with First run and Connected workflows. +Administrators should read Architecture, Configuration, Security and +Recovery. Developers should use the API reference and per-product source +contracts. Each acceptance result applies only to the artifact +identified by its receipt.

    +

    Beta identity

    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    IdentityValue
    Public documentation identityTownlight Beta 1
    Intended installer version1.7.0.1; build and acceptance pending
    Native desktop source version1.7.0-1
    Candidate artifact identityNot yet built; use candidate-specific ACCEPTANCE.md and +SHA256SUMS.txt when issued
    Corresponding sourceCoordinated naming, Access and Notice source candidate
    Current owned software licenseAGPL-3.0-only
    Supported acceptance profileWindows x64 fresh install; inspections-preview; separate Station +configuration
    +

    The changed packages and native application advance their own +versions. This candidate requires a new signed installer and new +installed acceptance; earlier receipts do not certify it. Historical +tags, receipts and archived manuals retain their original identities. +Use a fresh profile and empty database. This candidate refuses legacy +initialization; it does not provide an in-place upgrade. The Windows +profile path remains %LOCALAPPDATA%\CivicSuite under +Scott’s explicit exception. Preserve existing profiles and backups.

    +

    Component versions

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ComponentDistributionCandidate version
    Coretownlight-core1.3.0.dev2
    Recordstownlight-records1.8.0.dev2
    Meetingstownlight-meetings1.0.5
    Codetownlight-code1.0.9
    Zoningtownlight-zoning0.2.3
    Planningtownlight-planning0.4.0.dev2
    Permittingtownlight-permitting0.3.0+dev.2
    Inspectionstownlight-inspections0.3.0+dev.2
    Stationtownlight-station0.3.0
    Accesstownlight-access0.5.0
    Noticetownlight-notice0.3.0
    Local runtimetownlight-runtime0.2.0
    +

    First run

    +
      +
    1. Obtain the identified naming/Access/Notice candidate MSI, matching +source/documentation and candidate-specific checksums after they are +issued. The prior Station delivery download is an earlier artifact.
    2. +
    3. Use a fresh Windows test installation and verify the candidate’s MSI +hash and publisher signature before installing. Preserve unrelated +profiles and recovery material. Windows installed acceptance for this +source candidate remains pending.
    4. +
    5. Launch Townlight under the intended named Windows account. Choose +the storage folders. Select Townlight Inspections +candidate (inspections-preview) for the bounded +desktop composition, including Access and Notice. A narrower selection +will not expose all workspaces.
    6. +
    7. Enter the city profile, time zone and contacts. Create the first +named local administrator, sign in and choose protected backup storage. +Continue without local AI is valid for the +deterministic workflows.
    8. +
    9. Run Health Check and wait for readiness. Open Townlight. In System +Health select Finish Records Migration to activate the +canonical Python/PostgreSQL runtime. Do not fabricate migration receipts +or seed accounts.
    10. +
    11. Create named staff through Settings. Import authorized sources using +each product’s source library. All examples in this package are +synthetic; they are not municipal authority.
    12. +
    13. Provision Station separately if it is part of the beta exercise. +Selecting the desktop composition does not start or configure Station. +Configure vision explicitly only if automatic photo drafting is +selected.
    14. +
    +

    Daily workflow

    +

    Sign in with your own named account. Confirm the selected workspace, +open a saved record and check its source/version before editing. Save +the work, record the intended review and inspect its audience. Use an +explicit export or cross-product selection when a copy is required. Sign +out when finished. Use the product manual for its field-level +procedure.

    +

    Use your own named account and save before leaving a screen. A saved +draft is durable; unsaved form text may not be. If a write has an +unknown result, reopen its record before repeating it.

    +

    Read source jurisdiction, dates, citation, version and visibility. A +copied source hash identifies exact bytes, not their legal +applicability. If a source changes or permission is removed, resolve the +source problem rather than substituting stale cached content.

    +

    Keep originals and derivatives separate. Review the intended audience +before export. A public summary excludes private fields only through the +applicable copy contract and your review. A renamed private packet is +still private content.

    +

    Drafting, review, approval, attachment, export, fulfillment and +publication are separate operations. A Townlight workpaper does not +itself adopt law, issue a permit, impose a fine or release a records +response. The responsible staff member records the applicable +decision.

    +

    Connected workflows

    +

    Meeting capture to a +Records response

    +
      +
    1. Meetings staff create the meeting and assign agenda items; save the +canonical records.
    2. +
    3. An authorized Station operator opens a one-use staff launch, chooses +that meeting and a configured live input or managed file, then starts +capture.
    4. +
    5. Stop and wait for completed validated media. Inspect the content and +provenance. Partial/failed attempts stay separate.
    6. +
    7. Records-authorized staff explicitly attach the completed recording +to an existing request. The receiver verifies bytes/hash and retains one +locked private original, including on an identical retry.
    8. +
    9. Records separately prepares any release copy, records +release/redact/exempt decisions, approves exact response text, exports +the response/package and fulfills the request. Capture and handoff do +not publish it.
    10. +
    +

    Legislation to cited staff +guidance

    +

    Code imports a retained source and creates a proposal connection to +actual Meetings evidence. Authorized staff record adoption, then a +separate codification decision. Zoning uses the cited Code context with +imported parcels and rules. Permitting and Inspections select permitted +cited authority for reviewed workpapers. An import, draft or meeting +motion does not replace the actual adoption/codification decisions.

    +

    Policy and land-use +evidence to Records

    +

    Planning imports adopted policy revisions, including neighborhood +applicability, and selects permitted Meetings/Zoning evidence. Staff +save and review the exact analysis, then create the audience-specific +snapshot. Planning initiatives/amendments retain their own history. +Permitting and Inspections independently review their saved cases and +prepare separate Records copies. Records rechecks the +source/version/hash and owns the response release. Private notes and +contact/property details must not be copied by relabeling a staff +packet.

    +

    Shared foundation and +recovery

    +

    Core provides shared contracts, named account/session support, +ingestion/task helpers and coherent recovery. Supporting Notice and +Access are included where selected. These relationships do not establish +all 56 directed product pairs, universal vendor integration or +unrestricted federation.

    +

    Product guide directory

    + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ProductPurposeManual
    CoreA shared foundation for accountable municipal work.Core
    RecordsFrom request intake to a deliberate release.Records
    MeetingsKeep the agenda, decisions and evidence connected.Meetings
    CodeTrace every section to its source and history.Code
    ZoningBring parcel context and cited rules into one review.Zoning
    PlanningConnect policy, analysis and municipal progress.Planning
    PermittingPrepare a complete, cited intake for staff review.Permitting
    InspectionsPreserve evidence and review every draft finding.Inspections
    StationCapture the meeting and preserve its evidence.Station
    +

    Architecture

    +

    Townlight Suite architecture and evidence flow

    +

    The drawing shows the principal staff/evidence path. Native commands +carry trusted identity to Python business services; PostgreSQL and +retained original files hold durable state. A downstream copy does not +silently transfer decision authority. Station has its own configured +authority/media boundary, database and mutable files. The +connected-workflow text supplies the drawing’s reading order and +accessibility alternative.

    +

    Existing product operating +guides

    +

    Use each product’s operating chapter for its actual controls, inputs, +readback and refusal states. The suite coordinates evidence and +authority; it does not replace those product decisions. Station requires +an explicitly configured paired runtime and its separate operating +procedure. The Code importer submits directly; Planning’s source library +has its own preview/confirmation flow.

    + +

    Technical specifications

    +

    Runtime and storage

    +

    The accepted package targets Windows x64 fresh +installation. Its native shell uses Rust 2021, Tauri 2 +and Microsoft WebView2; browser assets are JavaScript built +with Vite 8.1.6. This describes the native desktop +frontend; Station has a separate React operator, specified below or in +its product manual. Canonical business workflows use bundled +CPython 3.13.5, FastAPI, Pydantic, SQLAlchemy and +Alembic, with PostgreSQL 17 / PostGIS and +managed original files. The installed runtime tested here contains +FastAPI 0.162.0. Package minimum Python requirements can differ from the +bundled executable; the metadata reference preserves both. No stack +rewrite is implied by the beta label.

    +

    The native transport is fixed to loopback +127.0.0.1:15480; PostgreSQL uses the configured local +runtime port (default 15432). Optional local model service +defaults to 127.0.0.1:15434. Those are deployment defaults, +not internet endpoints. The runtime has health, module and readiness +endpoints; readiness is stronger than process existence. The task queue +is the existing local Core task infrastructure, not an assertion that a +separate Redis service is required for this desktop composition.

    +

    The default native profile is %LOCALAPPDATA%\CivicSuite; +the historical directory name remains part of compatibility. Do not +rename it to Townlight. A configured TOWNLIGHT_PROFILE_ROOT +must be absolute. Local configuration and secrets live under that +profile; protected managed files and database state must be backed up +coherently. Source/runtime identity is distinct from a product’s display +label.

    +

    Data and consistency

    +

    Each product retains the records described in its manual. The common +desktop uses one canonical PostgreSQL-backed domain with product-owned +tables/schemas and managed file storage. Station has a separate database +and media store.

    +

    Versioned saves use expected prior revision identifiers where +defined. Reopen and reconcile on conflict. Exact exports and handoffs +use source IDs, current visibility, revision and SHA256. Review belongs +to the saved revision and does not transfer silently to edited text. +Database changes use the owning product’s migrations; a request or +readiness check is not an authorization to mutate schema.

    +

    Capacity and platform +statements

    +

    This beta has synthetic single-profile workflow evidence. It does not +have a published benchmark for concurrent staff capacity, minimum +RAM/CPU, large-source limits or a field SLA. Do not turn a developer +machine’s specification into a supported minimum. The new installer size +remains pending its build; allow additional disk for extracted runtime, +database, originals, exports, media and backups. Select +equipment/storage after sizing those actual workloads.

    +

    The exact runtime +payload lock records pinned files, sizes and hashes. The component +metadata records shipped dependency declarations. These references +are more precise than a manually copied dependency list. Third-party and +historical license notices must accompany their matching payloads.

    +

    Station operator and +media components

    +

    The native desktop frontend above is distinct from Station’s browser +operator. The pinned operator package +townlight-station-operator is version +0.1.0, using React/react-dom 19.1.1, +TypeScript 5.9.2, Vite 7.3.7 and the +React Vite plugin 5.0.2. Station serves its built assets through its own +operator API. Its Python control/API package remains +townlight-station 0.3.0, while its retained storage +identity remains 0.1.0. These identities have different +purposes and are not renumbered.

    +

    The separate pinned CivicCast-derived media engine uses Python/native +GStreamer processing and bounded media children. It is not the +standalone CivicCast application. Station’s control database, data root, +service/configuration and update identity remain independent. This +describes the current mixed stack; no runtime rewrite or CivicCast +migration is implied.

    +

    Configuration and +administration

    +

    Native deployment +configuration

    +

    Use Setup, Settings and System Health for supported staff operation. +Administrators provision folders, backup storage, named accounts and the +city profile. Select inspections-preview for the bounded +desktop composition, including Access and Notice. Station remains a +separate service boundary. Do not use a standalone product’s demo server +as a substitute for the installed workspace.

    +

    Technical deployments use TOWNLIGHT_PRODUCT_PROFILE, +TOWNLIGHT_PROFILE_ROOT, DATABASE_URL, +TOWNLIGHT_RUNTIME_PORT, PORTAL_MODE and the +runtime-managed secret files. Treat database URLs and native session +proofs as secrets. The installed native domain runtime explicitly +refuses non-loopback binding. PORTAL_MODE=private is the +accepted posture; changing it does not by itself commission an internet +portal, authentication provider or reverse proxy.

    +

    The isolated documentation exporter sets a fictional profile and +unusable synthetic database origin only to read schemas; those values +are not deployment configuration. Keep deployment values in the intended +process/account scope. An already-running process does not automatically +inherit later environment edits.

    +

    API and integration examples

    +

    Native command example

    +

    The following JavaScript belongs in the existing trusted Townlight +frontend/development environment with invoke imported from +@tauri-apps/api/core. It is not a command for an arbitrary +web page or an instruction for nontechnical staff. IDs must come from +records created in an isolated synthetic exercise.

    +
    import { invoke } from '@tauri-apps/api/core';
    +const result = await invoke('meetings_domain_request', {request: {operation: 'get-proceedings', id: meetingId}});
    +console.log(result);
    +

    Trusted local HTTP example

    +

    An administrator/developer can inspect an already-configured isolated +runtime from a trusted local process. This PowerShell example reads the +signed-in synthetic profile’s existing proof into memory; it does not +create a user, seed a session, reveal the proof in output or bypass a +permission check. Do not use real city data in development examples. A +read response does not prove approval or publication.

    +
    $profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite'
    +$sessionPath = Join-Path $profilePath 'config\local-session.json'
    +$session = Get-Content -LiteralPath $sessionPath -Raw | ConvertFrom-Json
    +$headers = @{ 'X-Townlight-Session' = $session.session_hash }
    +Invoke-RestMethod -Uri 'http://127.0.0.1:15480/desktop/v1/meetings/station/catalog' -Headers $headers
    +Remove-Variable session, headers
    +

    A synthetic write +with subsequent readback

    +

    This example demonstrates the existing Meetings HTTP contract in an +isolated exercise. It is intentionally fictional. It does not start a +service. Its authentication setup is included so it can be run +independently under the signed-in synthetic account. If a write times +out, inspect current records before repeating it.

    +
    $profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite'
    +$sessionPath = Join-Path $profilePath 'config/local-session.json'
    +$session = Get-Content -LiteralPath $sessionPath -Raw | ConvertFrom-Json
    +$headers = @{ 'X-Townlight-Session' = $session.session_hash }
    +$body = @{
    +  title = 'Synthetic documentation exercise'
    +  scheduled_start = '2026-11-05T18:00:00-07:00'
    +  location = 'Synthetic room'
    +  meeting_type = 'regular'
    +} | ConvertTo-Json
    +$meeting = Invoke-RestMethod -Method Post `
    +  -Uri 'http://127.0.0.1:15480/desktop/v1/meetings/meetings' `
    +  -Headers $headers -ContentType 'application/json' -Body $body
    +Invoke-RestMethod `
    +  -Uri ('http://127.0.0.1:15480/desktop/v1/meetings/meetings/' + $meeting.id) `
    +  -Headers $headers
    +Remove-Variable session, headers
    +

    This write requires Meetings to be enabled and the signed-in staff +role to permit it. It is a cross-suite integration example; for this +product’s request models, use the complete technical reference +below.

    +

    Complete technical contract

    +

    Read the Suite +API reference for every documented operation, request field, +constraint, response declaration and source supplement. Download the OpenAPI +JSON for tools. For Station this is the suite-side schema only; its +separate service contract is documented in the API supplement. The reference +directory includes configuration/source inventories, dependency +declarations, native command contracts, MCP signatures and candidate +evidence.

    +

    MCP and automation boundary

    +

    No direct product MCP server is exposed by the accepted Townlight +desktop or Station boundary. Do not configure an invented +townlight mcp command or assume an AI client has staff +permissions. The integration surfaces for this beta are native IPC, the +documented HTTP APIs, source bundle imports, exact exports and the +existing Station CLI.

    +

    The bundled transcription code includes a TextFlowKit MCP +adapter as a separate source capability. It offers job-based +transcribe_media, get_transcript, +list_jobs, get_job_status and +export_transcript, and additional tools declared in that +adapter. It uses stdio first and optional Streamable HTTP, with the MCP +SDK as an optional extra. It is not automatically launched, +authenticated as Townlight staff or accepted as a Townlight product MCP +deployment. This documentation does not add such a service.

    +

    For a transcription client already provisioned separately, an +illustrative tool call is:

    +
    {"name":"get_job_status","arguments":{"job_id":"synthetic-existing-job-id"}}
    +

    Use a job ID returned by that transcription service. This example +does not create a Townlight record or bypass its review/Records handoff. +The exact optional adapter tool signatures are supplied in the MCP source +reference. Station meeting capture does not become live speech +recognition because this optional donor adapter exists.

    +

    Security and permissions

    +

    Use your own named account and save before leaving a screen. A saved +draft is durable; unsaved form text may not be. If a write has an +unknown result, reopen its record before repeating it.

    +

    Read source jurisdiction, dates, citation, version and visibility. A +copied source hash identifies exact bytes, not their legal +applicability. If a source changes or permission is removed, resolve the +source problem rather than substituting stale cached content.

    +

    Keep originals and derivatives separate. Review the intended audience +before export. A public summary excludes private fields only through the +applicable copy contract and your review. A renamed private packet is +still private content.

    +

    Drafting, review, approval, attachment, export, fulfillment and +publication are separate operations. A Townlight workpaper does not +itself adopt law, issue a permit, impose a fine or release a records +response. The responsible staff member records the applicable +decision.

    +

    The native session is validated and mapped to a persisted SQL +identity. An editable actor/reviewer label is not authentication. +Product/module permissions and source visibility apply at the server +boundary. Revoked/unavailable authority fails closed for new Station +operations; a previous permission result is not a perpetual +authorization.

    +

    Use protected local folders, account permissions and credential +storage. Never include the native session file, database passwords, +provider keys or unredacted support bundles in a public issue or +generated public documentation. A local public view is not automatically +a secured internet deployment. Keep network exposure and real equipment +acceptance specific to the chosen beta site.

    +

    Backup recovery and +maintenance

    +

    Save work and use Core’s canonical Backup Now before +maintenance. That operation stops writers. Preserve the coherent +profile/database/document backup and its receipt, then use +Start to resume. A source export is not a full +backup.

    +

    Use Restore Latest Backup through the supported +controls. If the result says Restore needs service +start, use Start, then Check, +and reopen a known record. Do not repeat restore merely because services +need to start. The fresh-profile acceptance verified that a fulfilled +request survived restore and a post-backup marker did not.

    +

    Keep Station’s dedicated database and media evidence together in its +own backup. Core’s native-profile backup must not be assumed to include +an external Station data directory. Stop writers during a coordinated +backup. Preserve failed media attempts and logs.

    +

    On failure, record the time, selected composition, +component/installer versions and exact message. Check System Health for +stopped, starting, ready or failed dependencies. Use the existing Retry +control after readiness; do not create duplicate business records to +refresh a stale view. Share only a redacted diagnostic bundle. Preserve +secrets, original evidence, recovery material and unrelated +installations.

    +

    Troubleshooting

    + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    SymptomLikely meaningNext action
    Workspace absentWrong product composition or unavailable canonical runtime.Check selected composition; activate through Finish Records +Migration; wait for readiness.
    Cannot sign in / 401Missing or expired named account session.Sign in normally; reopen a Station launch ticket if applicable.
    Permission denied / 403Account, module, source or browser-origin permission.Ask the authorized administrator to inspect the intended permission; +do not invent role headers.
    Save conflict / 409The saved revision, expected source hash or lifecycle changed.Keep edits, reopen current state and reconcile deliberately.
    Invalid input / 422Required field, format, geometry, source envelope or state is +invalid.Read the field detail and correct the input/source; preserve +originals.
    Service unavailable / 503Database, schema, connected source or configuration +unavailable.Inspect System Health and the named dependency. Preserve work; retry +only after readiness.
    Export refusedMissing exact review, approval, audience or source +authorization.Read the refusal and complete the owning product’s explicit +decision.
    Restore needs service startThe snapshot was restored but services have not resumed.Use Start, then Check and verify a saved record; do not blindly +repeat restore.
    +

    Verified workflows and +limits

    + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ProductRecorded resultPrecisely exercised
    CorePASSNormal empty-profile setup; canonical activation; UI-created staff +and sign-in; staff denied user administration; coherent backup, +mutation, restore, Start/Check and retained/absent record readback.
    RecordsPASSIntake, note, original attachment/readback, separate release copy, +explicit release decision, draft/approval, approved response and release +package exports, fulfillment/readback and native workspace.
    MeetingsPASSMeeting/agenda, packet assembly, motion/vote, supplied transcript, +reviewed/adopted minutes, restricted local archive and proceedings +readback; Code decision integration.
    CodePASSSynthetic official source import, exact citation/history/export; +proposal into Meetings, recorded adoption and separately codified +version; native connection readback.
    ZoningPASSGeoJSON/PostGIS import, cited dimensional rule, parcel answer, staff +review/history/snapshot and native workspace.
    PlanningPASSAdopted source import with neighborhood, saved/reviewed analysis and +snapshot, persisted initiative/history and draft amendment, public +explorer neighborhood readback and native workspace.
    PermittingPASSRetained requirement import, source-grounded +materials/pathway/timing, saved intake/review, separate hash-checked +Records copy and private handoff; contact exclusion; native +workspace.
    InspectionsPASSRetained original/hash, supplied observations and voice summary, +saved/reviewed case/readback, separate exact Records copy and private +handoff; address exclusion; native workspace.
    StationPASSActual native staff session and normally created meeting; headless +operator live start/stop, decoded generated audio/video, served hash, +private Records readback, idempotent locked original and logout.
    +

    The following baseline results come from the previously accepted +signed candidate’s fresh normal-profile Sandbox exercise: real native +IPC/HTTP/PostgreSQL and selected headless controls. All accounts, source +bundles and media were synthetic. The guest install/uninstall and +recovery passed, and the owned Sandbox stopped. No host installed +application or standalone CivicCast was changed. Those baseline receipts +are retained for unchanged workflows. The accompanying ACCEPTANCE.md +records the separate installed verification and exact identity of this +new Station delivery candidate.

    +

    The workflow +matrix identifies raw receipt filenames. The evidence +index retains their original hashes; raw receipts remain in the +private beta handoff rather than being silently republished with the +documentation site.

    +

    The limits remain: actual city field acceptance and equipment/network +commissioning; Station automatic provisioning/SCM commissioning; every +UI/role combination; field recognition accuracy; and historical in-place +upgrades are not certified. They are not five invented feature +requirements. Fresh-install controlled beta handoff remains the accepted +scope. This package makes no city-deployment, publication or +general-availability claim.

    +

    Terms of service and license

    +

    Scope and status

    +

    These terms describe the Townlight Beta 1 software and this +documentation package. This is a public beta software distribution. It +does not create a hosted-service subscription or a city deployment +agreement. No uptime commitment, support response time, indemnity, +data-processing agreement or paid service is created by these documents. +A separate signed agreement, if any, governs services it actually +provides.

    +

    Software license and rights

    +

    Current Townlight-owned distributions identified in this candidate +use AGPL-3.0-only. The full license is supplied with +this documentation and with the source companion. The license governs +rights to run, copy, modify and convey the covered software; these +operational terms do not add restrictions to those rights. Historical +grants and dependency licenses retain their own terms. CivicCast remains +a separate product and is not relicensed by this documentation work.

    +

    When conveying covered software, retain applicable notices and +provide the corresponding source and installation/build information +required by the license. For a modified version supporting remote +network interaction, follow section 13’s source-offer requirement. The +companion archive identifies the source for this candidate; a link to a +different public branch is not a substitute for the matching source. +Read the supplied license for the complete conditions. See the GNU license +reference and GNU licensing +FAQ.

    +

    Data ownership and access

    +

    Importing a document does not transfer its ownership or grant +permission to publish it. The operating organization controls its +accounts, access decisions, lawful source use, retention and +review/release policy. Keep resident information, credentials, private +notes and restricted evidence in their authorized locations. +Documentation examples contain fictional data. No real city account, +credential or record is required to exercise these examples in an +isolated test environment.

    +

    Local operation and +external processors

    +

    The accepted beta workflow is local and uses named staff accounts. +Station has separate storage and credentials. Configure backup +destinations and optional model/network providers deliberately. A +configured external provider may receive submitted prompts, images or +audio according to that configuration and provider’s terms; this +documentation does not promise that every optional configuration is +offline. An email outbox or local public view does not establish +external delivery or an internet deployment. This static documentation +site has no analytics, account collection or remote font dependency.

    +

    Staff decisions and +source applicability

    +

    Staff verify the jurisdiction, source currency, permissions, +citations and proposed audience. Model output and generated guidance +require review. No draft is automatically an official legal +interpretation, zoning determination, permit approval, fee assessment, +enforcement notice or records-release decision. Official permit fee +authority remains with the adopted source and responsible organization; +imported amounts do not become a new authoritative calculation.

    +

    Beta operation and recovery

    +

    Use the identified candidate in its supported fresh-install scope. +Preserve backups and original evidence. Test physical equipment and +chosen network/service configuration before relying on them. The +supplied acceptance describes selected synthetic workflows, not every +screen, vendor, field condition or upgrade. Operators decide whether a +particular deployment meets their own operational obligations.

    +

    Warranty and liability

    +

    The covered software’s warranty and liability conditions are those in +sections 15–17 of the supplied AGPL and any applicable separate written +undertaking. This documentation creates no additional warranty or +limitation beyond those terms. Third-party software is subject to its +retained license notices. Nothing here removes rights that applicable +law makes nonwaivable.

    +

    Support and incident +reporting

    +

    Use the project’s existing SUPPORT and SECURITY guidance for its +matching repository. Report reproducible behavior with the version, +operation and redacted logs. Do not put credentials, resident records or +unredacted evidence in a public issue. Coordinate sensitive reports +through the channel designated in SECURITY. No new support address or +service commitment is invented here.

    +

    Ending a beta +exercise and document changes

    +

    When an organization ends testing, it controls retention/export and +removes access according to its policy. Uninstall may retain data; back +up and inspect the selected removal options. Ending an exercise does not +revoke rights already granted by AGPL. Later software/documentation +versions must identify their changed candidate and scope; historical +receipts retain their original identities. These terms do not claim that +a city has accepted a contract merely by reading a manual.

    +

    Glossary

    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TermMeaning
    ApprovalAn explicit authorized decision on the saved text/artifact. It is +separate from saving or attachment.
    Canonical recordThe owning product’s retained identity and saved version, rather +than an editable copied label.
    CompositionThe selected set of desktop modules; inspections-preview exposes the +eight staff products.
    Corresponding sourceThe source/build material matching the delivered covered program, +subject to its license.
    Derivative / Records copyA separately prepared document with its own intended audience and +hash.
    Hash / SHA256A fingerprint of exact bytes. It detects change; it does not +establish legal authority.
    IdempotencyRepeating the same identified request has the same intended effect; +changing its payload can be refused.
    IPCThe native desktop command boundary between its browser interface +and Rust host.
    MCPModel Context Protocol; no direct Townlight product server is +enabled by this beta.
    OriginalRetained source bytes. A reviewed derivative does not replace +them.
    ProvenanceSource, version, date, actor and relationship information retained +with evidence.
    RevisionAn immutable saved version. Later edits do not inherit an earlier +review automatically.
    SnapshotA fixed audience-specific copy tied to a source/reviewed +revision.
    StationTownlight’s separate media boundary using a pinned CivicCast-derived +engine; standalone CivicCast remains separate.
    +

    Alphabetical subject index

    + + + +

    Source and document control

    +

    This edition is authored from the immutable corresponding-source +companion, the generated installed-domain schema and the retained +workflow receipts. Component version numbers are retained. The private +MSI has its own new hash and signing receipt. Historical release tags +and their artifacts remain unchanged.

    + +

    Station live and recorded +delivery

    +

    Station now offers two explicit delivery paths. During a live +recording, staff may select an administrator-configured encrypted SRT +feed to the separate CivicCast product. The PEG operator controls local +cable take-to-air. After completion, staff may approve an upload copy to +the Station-configured YouTube account, select its title and visibility, +and inspect the durable receipt. The private canonical recording and +existing Meetings → Station → Records handoff remain independent.

    +

    Station live delivery and completed video uploads

    +

    These paths reuse the pinned CivicCast media and YouTube client code. +A separate sender isolates network backpressure from capture, and a +separate upload worker prevents long uploads from blocking recording. +YouTube starts no live broadcast here. Standalone CivicCast has separate +installation, identity, storage and operator control.

    +

    Administrators run the explicit Station schema4 migration and +provision Station-only OAuth and SRT pairing credentials. Existing +component versions are retained. Preparation failures can be explicitly +retried; uncertain external uploads require manual reconciliation and +are never silently duplicated. No real credentials or external video +publication are used in synthetic development acceptance.

    +

    See the +Station manual delivery section for full staff steps, architecture, +configuration, API request examples, permissions and recovery. Existing +eight-product workflows are unchanged; their accepted evidence is +retained rather than presented as a new run.

    +

    Delivery subject index

    +
      +
    • CivicCast +live feed
    • +
    • YouTube: explicit completed recording upload; visibility; receipt +and reconciliation.
    • +
    • Schema4: durable upload intent; existing evidence retained.
    • +
    +
    Townlight · AGPL-3.0-only · Candidate evidence applies only to its identified artifacts.
    \ No newline at end of file diff --git a/docs/beta-1/manuals/zoning.html b/docs/beta-1/manuals/zoning.html new file mode 100644 index 0000000..9234293 --- /dev/null +++ b/docs/beta-1/manuals/zoning.html @@ -0,0 +1,1002 @@ + + +Townlight Zoning Manual | Townlight candidate + +
    Townlight +
    +

    Naming, Access and Notice source candidate · 2 November 2026

    +

    Prepared documentation. Build, signing, installed acceptance and publication remain pending.

    + + +

    Townlight Zoning Manual

    +

    Townlight Beta 1 · Naming candidate documentation +edition 2 November 2026

    +

    Contents

    + +

    Using this manual

    +

    Townlight Zoning helps planners, land-use staff and authorized +reviewers. Zoning combines local parcel geometry, cited zoning rules and +staff review. It retains questions, corrections and snapshots with +provenance so downstream staff can identify the precise evidence +used.

    +

    Staff should begin with First run and Daily workflow. Administrators +should also read Architecture, Technical specifications, Configuration, +Security and Recovery. Developers should use the exact API/data +dictionary and examples. The table of contents and alphabetical subject +index link to the relevant sections in the HTML edition; the PDF +preserves headings and searchable text. An editable Word edition is +included with the same documentation companion.

    +

    Beta identity

    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    IdentityValue
    DocumentationTownlight Beta 1 naming, Access and Notice candidate
    Intended installer version1.7.0.1; build and acceptance pending
    Product componenttownlight-zoning 0.2.3
    Principal import packagetownlight_zoning
    Native desktop source version1.7.0-1
    Candidate hashesPending candidate build, signing and installed acceptance
    Current owned software licenseAGPL-3.0-only
    Acceptance compositionFresh Windows x64 profile; inspections-preview; Station configured +separately
    +

    The naming change advances this package’s version and requires a new +signed installer and installed acceptance. Those steps and publication +remain pending. Historical tags, receipts and archived manuals keep +their original names and certify only their identified artifacts. Use an +empty database and fresh profile; no in-place legacy upgrade is +supported. The approved Windows profile path remains +%LOCALAPPDATA%\CivicSuite. Preserve existing profiles, data +and recovery material.

    +

    First run

    +
      +
    1. Obtain the identified signed private candidate and its +corresponding-source companion from the beta coordinator. The landing +pages in this documentation are not an installer download service.
    2. +
    3. On the intended fresh Windows test installation, verify the MSI hash +and publisher signature before installing. Preserve unrelated profiles +and recovery material. Installed acceptance for this source candidate +remains pending; no in-place legacy upgrade is supported.
    4. +
    5. Launch Townlight under the intended named Windows account. Choose +the storage folders. Select Townlight Inspections +candidate (inspections-preview) for the bounded +desktop composition, including Access and Notice. A narrower default +selection will not expose all workspaces.
    6. +
    7. Enter the city profile, time zone and contacts. Create the first +named local administrator, sign in and choose protected backup storage. +Continue without local AI is valid for the +deterministic workflows.
    8. +
    9. Run Health Check and wait for readiness. Open Townlight. In System +Health select Finish Records Migration to activate the +canonical Python/PostgreSQL runtime. Do not fabricate migration receipts +or seed accounts.
    10. +
    11. Create named staff through Settings. Import authorized sources using +each product’s source library. All examples in this package are +synthetic; they are not municipal authority.
    12. +
    13. Provision Station separately if it is part of the beta exercise. +Selecting the desktop composition does not start or configure Station. +Configure vision explicitly only if automatic photo drafting is +selected.
    14. +
    +

    Daily workflow

    +

    +

    1. Prepare parcel data

    +

    Use the complete supported bundle, including jurisdiction, dataset +metadata and original hashes. The coordinates must be EPSG:4326. A loose +geometry file is not the full source envelope.

    +

    +

    2. Import and inspect

    +

    Check the complete source envelope before selecting Import parcel +dataset. That control submits directly; inspect the saved +validation/provenance result afterward. Correct a refused source bundle +and preserve the evidence. Do not force acceptance by editing SQL.

    +

    +

    3. Register cited rules

    +

    Associate the zone, rule kind/key and value with the relevant public +Code section. Inspect overlays and effective context. Leave missing +authority visible for planner review.

    +

    +

    4. Ask a parcel question

    +

    Look up the intended parcel and ask the supported question. Read the +returned citation, applicability and disclaimer. Do not present an +uncertain answer as an official decision.

    +

    +

    5. Record review and context

    +

    Record a correction and its reason when needed. Select permitted +Meetings history explicitly. Preserve the question/review history and +distinguish staff-only precedent from public material.

    +

    +

    6. Create a snapshot

    +

    Review the audience and exact content before creating the immutable +snapshot. A public snapshot must satisfy its permitted-source contract; +choosing a public label does not sanitize private notes.

    +

    +

    7. Use it downstream

    +

    Select the exact snapshot for Records or the permitted provider path. +The receiving workflow rechecks visibility, source identity and hash +before retaining or exporting it.

    +

    Working safely

    +

    Use your own named account and save before leaving a screen. A saved +draft is durable; unsaved form text may not be. If a write has an +unknown result, reopen its record before repeating it.

    +

    Read source jurisdiction, dates, citation, version and visibility. A +copied source hash identifies exact bytes, not their legal +applicability. If a source changes or permission is removed, resolve the +source problem rather than substituting stale cached content.

    +

    Keep originals and derivatives separate. Review the intended audience +before export. A public summary excludes private fields only through the +applicable copy contract and your review. A renamed private packet is +still private content.

    +

    Drafting, review, approval, attachment, export, fulfillment and +publication are separate operations. A Townlight workpaper does not +itself adopt law, issue a permit, impose a fine or release a records +response. The responsible staff member records the applicable +decision.

    +

    Connected workflows

    +

    Consumes Code authority and permitted Meetings evidence. Supplies +permitted snapshots to Records and context to Planning and +Permitting.

    + ++++ + + + + + + + + + + + + + + + + +
    DirectionMaterial
    InputA supported EPSG:4326 GeoJSON envelope, jurisdiction and dataset +metadata, public Code authority and permitted meeting evidence.
    OutputSource-backed parcel context, informational answers, recorded human +corrections and reviewed snapshots with stable hashes.
    +

    Product boundary

    +

    The accepted path is local GeoJSON/PostGIS. It does not establish +every ArcGIS, assessor or CKAN connector. Answers and process +explanations are informational and do not issue an entitlement or an +official zoning determination.

    +

    Architecture

    +
    + + +
    +

    The drawing shows the principal staff/evidence path. Native commands +carry trusted identity to Python business services; PostgreSQL and +retained original files hold durable state. A downstream copy does not +silently transfer decision authority. Station has its own configured +authority/media boundary, database and mutable files. The +connected-workflow text supplies the drawing’s reading order and +accessibility alternative.

    +

    Discretionary +processes and staff review

    +

    Explain the cited process

    +

    In the existing Zoning workspace, complete Variance, +conditional use or nonconformity question. Supply the +applicable process Code section, zone +code, optional comma-separated standard to +cite, and optional observed condition, for +example front_setback=8 feet. Select Explain the +cited process. Choose actual imported public authority; the +synthetic values below require matching synthetic sources to return +supported guidance.

    +

    The mounted API is +POST /desktop/v1/zoning/standards/process-explanation under +the normal authenticated staff session. Its equivalent request body +is:

    +
    {"question":"Explain the synthetic variance process","process_section":"18.20.050","zone_code":"SYN-R","rule_types":["front_setback"],"observed":{"front_setback":"8 feet"}}
    +

    Read process citations and each cited standard independently. The +output can explain a verified process while reporting unavailable +standards or review flags. A difference between an observation and a +cited standard is an informational flag; it is not a variance finding, +approval, nonconformity determination or substitute for planner review. +If no relevant authority is available, obtain the source or leave the +item unavailable. Do not attach an unrelated citation to a proposed +requirement.

    +

    Keep +parcel import and inspection in the right order

    +

    Check the complete JSON envelope, original hashes and EPSG:4326 +geometry before submitting Import parcel dataset. That +control sends the import directly; it does not open a separate +preview/commit screen. Inspect the returned validation/provenance and +saved dataset. The browser refuses bundle files larger than 20 MiB; +valid geometry and metadata remain subject to server validation. Correct +the source bundle after a refusal and retain earlier evidence rather +than forcing SQL changes.

    +

    Use the existing +specialist review contracts

    +

    The standalone Zoning application’s review/analytics/report routes +are documented source capabilities, not extra native desktop screens. In +a deployment where its actual staff authentication is already +configured:

    +
      +
    • Create an ambiguity review with zone_code, +question and reason at +/api/v1/townlight_zoning/staff/ambiguity-reviews. Read its +returned ID and list state. Update that ID with status, +optional assigned_to and resolution; use +open, in_review, resolved or +closed. Resolving or closing requires a nonempty +resolution.
    • +
    • Retain a flagged answer at +/api/v1/townlight_zoning/staff/flagged-answers with the +original question/answer, zone, flag reason and source citations. Use +/{review_id}/improve with improved_answer and +improvement_notes. Preserve the original and improvement +attribution; a correction does not rewrite the imported Code +source.
    • +
    • Read /api/v1/townlight_zoning/staff/questions/analytics +with the desired high_volume_threshold to identify repeated +questions and uncertain answers. Analytics counts are review aids, not +jurisdictional conclusions.
    • +
    • Create /api/v1/townlight_zoning/staff/reports/outline +with a title and actual selected +question_ids/queue_item_ids. Review the +resulting outline and citations before incorporating it in a staff +report. It is not a filed report or a meeting decision.
    • +
    +

    A synthetic ambiguity request is:

    +
    {"zone_code":"SYN-R","question":"Which retained setback rule applies?","reason":"Synthetic overlay ambiguity requires planner review"}
    +

    Do not send invented staff-role headers or assume these standalone +paths exist at the installed desktop origin. The native workspace’s +supported review/history/snapshot controls continue to use its fixed +authenticated bridge. Use the technical supplement to distinguish the +two surfaces.

    +

    Source contracts: townlight_runtime/zoning_bridge.py, +townlight_zoning/main.py, the imported rule/source models +and desktop Zoning view.

    +

    Technical specifications

    +

    Runtime and storage

    +

    The accepted package targets Windows x64 fresh +installation. Its native shell uses Rust 2021, Tauri 2 +and Microsoft WebView2; browser assets are JavaScript built +with Vite 8.1.6. This describes the native desktop +frontend; Station has a separate React operator, specified below or in +its product manual. Canonical business workflows use bundled +CPython 3.13.5, FastAPI, Pydantic, SQLAlchemy and +Alembic, with PostgreSQL 17 / PostGIS and +managed original files. The installed runtime tested here contains +FastAPI 0.162.0. Package minimum Python requirements can differ from the +bundled executable; the metadata reference preserves both. No stack +rewrite is implied by the beta label.

    +

    The native transport is fixed to loopback +127.0.0.1:15480; PostgreSQL uses the configured local +runtime port (default 15432). Optional local model service +defaults to 127.0.0.1:15434. Those are deployment defaults, +not internet endpoints. The runtime has health, module and readiness +endpoints; readiness is stronger than process existence. The task queue +is the existing local Core task infrastructure, not an assertion that a +separate Redis service is required for this desktop composition.

    +

    The default native profile is %LOCALAPPDATA%\CivicSuite; +the historical directory name remains part of compatibility. Do not +rename it to Townlight. A configured TOWNLIGHT_PROFILE_ROOT +must be absolute. Local configuration and secrets live under that +profile; protected managed files and database state must be backed up +coherently. Source/runtime identity is distinct from a product’s display +label.

    +

    Data and consistency

    +

    GeoJSON import datasets; parcels and zone/overlay context; cited +rules; questions and answers; review events; selected Meetings history; +immutable snapshots.

    +

    Versioned saves use expected prior revision identifiers where +defined. Reopen and reconcile on conflict. Exact exports and handoffs +use source IDs, current visibility, revision and SHA256. Review belongs +to the saved revision and does not transfer silently to edited text. +Database changes use the owning product’s migrations; a request or +readiness check is not an authorization to mutate schema.

    +

    Capacity and platform +statements

    +

    This beta has synthetic single-profile workflow evidence. It does not +have a published benchmark for concurrent staff capacity, minimum +RAM/CPU, large-source limits or a field SLA. Do not turn a developer +machine’s specification into a supported minimum. The new installer size +remains pending its build; allow additional disk for extracted runtime, +database, originals, exports, media and backups. Select +equipment/storage after sizing those actual workloads.

    +

    The exact runtime payload +lock records pinned files, sizes and hashes. The component +metadata records shipped dependency declarations. These references +are more precise than a manually copied dependency list. Third-party and +historical license notices must accompany their matching payloads.

    +

    Configuration and +administration

    +

    Native deployment +configuration

    +

    Use Setup, Settings and System Health for supported staff operation. +Administrators provision folders, backup storage, named accounts and the +city profile. Select inspections-preview for the bounded +desktop composition, including Access and Notice. Station remains a +separate service boundary. Do not use a standalone product’s demo server +as a substitute for the installed workspace.

    +

    Technical deployments use TOWNLIGHT_PRODUCT_PROFILE, +TOWNLIGHT_PROFILE_ROOT, DATABASE_URL, +TOWNLIGHT_RUNTIME_PORT, PORTAL_MODE and the +runtime-managed secret files. Treat database URLs and native session +proofs as secrets. The installed native domain runtime explicitly +refuses non-loopback binding. PORTAL_MODE=private is the +accepted posture; changing it does not by itself commission an internet +portal, authentication provider or reverse proxy.

    +

    The isolated documentation exporter sets a fictional profile and +unusable synthetic database origin only to read schemas; those values +are not deployment configuration. Keep deployment values in the intended +process/account scope. An already-running process does not automatically +inherit later environment edits.

    +

    API and integration examples

    +

    Native command example

    +

    The following JavaScript belongs in the existing trusted Townlight +frontend/development environment with invoke imported from +@tauri-apps/api/core. It is not a command for an arbitrary +web page or an instruction for nontechnical staff. IDs must come from +records created in an isolated synthetic exercise.

    +
    import { invoke } from '@tauri-apps/api/core';
    +const result = await invoke('zoning_domain_request', {request: {operation: 'history', id: questionId}});
    +console.log(result);
    +

    Trusted local HTTP example

    +

    An administrator/developer can inspect an already-configured isolated +runtime from a trusted local process. This PowerShell example reads the +signed-in synthetic profile’s existing proof into memory; it does not +create a user, seed a session, reveal the proof in output or bypass a +permission check. Do not use real city data in development examples. A +read response does not prove approval or publication.

    +
    $profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite'
    +$sessionPath = Join-Path $profilePath 'config\local-session.json'
    +$session = Get-Content -LiteralPath $sessionPath -Raw | ConvertFrom-Json
    +$headers = @{ 'X-Townlight-Session' = $session.session_hash }
    +Invoke-RestMethod -Uri 'http://127.0.0.1:15480/desktop/v1/zoning/workspace' -Headers $headers
    +Remove-Variable session, headers
    +

    Complete synthetic source +bundle

    +

    The synthetic +Zoning bundle is the retained fixture used by the beta staff +exercise. It includes the complete supported source envelope rather than +a shortened pseudo-payload. Keep its fictional source labels. For +Planning, wrap it as +{"bundle": BUNDLE, "expected_previous_revision": null}; for +Permitting use +{"bundle": BUNDLE, "expected_revision": null}. Code and +Zoning take their own complete import envelopes. Replace null with the +current expected revision when revising an existing source, as the +applicable schema requires. These are import examples, not legal +authority or permission to load them into a live city profile.

    +

    A synthetic write +with subsequent readback

    +

    This example demonstrates the existing Meetings HTTP contract in an +isolated exercise. It is intentionally fictional. It does not start a +service. Its authentication setup is included so it can be run +independently under the signed-in synthetic account. If a write times +out, inspect current records before repeating it.

    +
    $profilePath = Join-Path $env:LOCALAPPDATA 'CivicSuite'
    +$sessionPath = Join-Path $profilePath 'config/local-session.json'
    +$session = Get-Content -LiteralPath $sessionPath -Raw | ConvertFrom-Json
    +$headers = @{ 'X-Townlight-Session' = $session.session_hash }
    +$body = @{
    +  title = 'Synthetic documentation exercise'
    +  scheduled_start = '2026-11-05T18:00:00-07:00'
    +  location = 'Synthetic room'
    +  meeting_type = 'regular'
    +} | ConvertTo-Json
    +$meeting = Invoke-RestMethod -Method Post `
    +  -Uri 'http://127.0.0.1:15480/desktop/v1/meetings/meetings' `
    +  -Headers $headers -ContentType 'application/json' -Body $body
    +Invoke-RestMethod `
    +  -Uri ('http://127.0.0.1:15480/desktop/v1/meetings/meetings/' + $meeting.id) `
    +  -Headers $headers
    +Remove-Variable session, headers
    +

    This write requires Meetings to be enabled and the signed-in staff +role to permit it. It is a cross-suite integration example; for this +product’s request models, use the complete technical reference +below.

    +

    Complete technical contract

    +

    Read the Zoning API +reference for every documented operation, request field, constraint, +response declaration and source supplement. Download the OpenAPI JSON for tools. +For Station this is the suite-side schema only; its separate service +contract is documented in the API supplement. The reference directory includes +configuration/source inventories, dependency declarations, native +command contracts, MCP signatures and candidate evidence.

    +

    MCP and automation boundary

    +

    No direct product MCP server is exposed by the accepted Townlight +desktop or Station boundary. Do not configure an invented +townlight mcp command or assume an AI client has staff +permissions. The integration surfaces for this beta are native IPC, the +documented HTTP APIs, source bundle imports, exact exports and the +existing Station CLI.

    +

    The bundled transcription code includes a TextFlowKit MCP +adapter as a separate source capability. It offers job-based +transcribe_media, get_transcript, +list_jobs, get_job_status and +export_transcript, and additional tools declared in that +adapter. It uses stdio first and optional Streamable HTTP, with the MCP +SDK as an optional extra. It is not automatically launched, +authenticated as Townlight staff or accepted as a Townlight product MCP +deployment. This documentation does not add such a service.

    +

    For a transcription client already provisioned separately, an +illustrative tool call is:

    +
    {"name":"get_job_status","arguments":{"job_id":"synthetic-existing-job-id"}}
    +

    Use a job ID returned by that transcription service. This example +does not create a Townlight record or bypass its review/Records handoff. +The exact optional adapter tool signatures are supplied in the MCP source reference. Station +meeting capture does not become live speech recognition because this +optional donor adapter exists.

    +

    Security and permissions

    +

    Use your own named account and save before leaving a screen. A saved +draft is durable; unsaved form text may not be. If a write has an +unknown result, reopen its record before repeating it.

    +

    Read source jurisdiction, dates, citation, version and visibility. A +copied source hash identifies exact bytes, not their legal +applicability. If a source changes or permission is removed, resolve the +source problem rather than substituting stale cached content.

    +

    Keep originals and derivatives separate. Review the intended audience +before export. A public summary excludes private fields only through the +applicable copy contract and your review. A renamed private packet is +still private content.

    +

    Drafting, review, approval, attachment, export, fulfillment and +publication are separate operations. A Townlight workpaper does not +itself adopt law, issue a permit, impose a fine or release a records +response. The responsible staff member records the applicable +decision.

    +

    The native session is validated and mapped to a persisted SQL +identity. An editable actor/reviewer label is not authentication. +Product/module permissions and source visibility apply at the server +boundary. Revoked/unavailable authority fails closed for new Station +operations; a previous permission result is not a perpetual +authorization.

    +

    Use protected local folders, account permissions and credential +storage. Never include the native session file, database passwords, +provider keys or unredacted support bundles in a public issue or +generated public documentation. A local public view is not automatically +a secured internet deployment. Keep network exposure and real equipment +acceptance specific to the chosen beta site.

    +

    Backup recovery and +maintenance

    +

    Save work and use Core’s canonical Backup Now before +maintenance. That operation stops writers. Preserve the coherent +profile/database/document backup and its receipt, then use +Start to resume. A source export is not a full +backup.

    +

    Use Restore Latest Backup through the supported +controls. If the result says Restore needs service +start, use Start, then Check, +and reopen a known record. Do not repeat restore merely because services +need to start. The fresh-profile acceptance verified that a fulfilled +request survived restore and a post-backup marker did not.

    +

    Keep Station’s dedicated database and media evidence together in its +own backup. Core’s native-profile backup must not be assumed to include +an external Station data directory. Stop writers during a coordinated +backup. Preserve failed media attempts and logs.

    +

    On failure, record the time, selected composition, +component/installer versions and exact message. Check System Health for +stopped, starting, ready or failed dependencies. Use the existing Retry +control after readiness; do not create duplicate business records to +refresh a stale view. Share only a redacted diagnostic bundle. Preserve +secrets, original evidence, recovery material and unrelated +installations.

    +

    Troubleshooting

    + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    SymptomLikely meaningNext action
    Workspace absentWrong product composition or unavailable canonical runtime.Check selected composition; activate through Finish Records +Migration; wait for readiness.
    Cannot sign in / 401Missing or expired named account session.Sign in normally; reopen a Station launch ticket if applicable.
    Permission denied / 403Account, module, source or browser-origin permission.Ask the authorized administrator to inspect the intended permission; +do not invent role headers.
    Save conflict / 409The saved revision, expected source hash or lifecycle changed.Keep edits, reopen current state and reconcile deliberately.
    Invalid input / 422Required field, format, geometry, source envelope or state is +invalid.Read the field detail and correct the input/source; preserve +originals.
    Service unavailable / 503Database, schema, connected source or configuration +unavailable.Inspect System Health and the named dependency. Preserve work; retry +only after readiness.
    Export refusedMissing exact review, approval, audience or source +authorization.Read the refusal and complete the owning product’s explicit +decision.
    Restore needs service startThe snapshot was restored but services have not resumed.Use Start, then Check and verify a saved record; do not blindly +repeat restore.
    +

    Verified workflows and +limits

    + +++++ + + + + + + + + + + + + + + +
    ProductRecorded resultPrecisely exercised
    ZoningPASSGeoJSON/PostGIS import, cited dimensional rule, parcel answer, staff +review/history/snapshot and native workspace.
    +

    These results come from the identified signed candidate’s fresh +normal-profile Sandbox exercise: real native IPC/HTTP/PostgreSQL and +selected headless controls. All accounts, source bundles and media were +synthetic. The guest install/uninstall and recovery passed, and the +owned Sandbox stopped. No host installed application or standalone +CivicCast was changed. This documentation task reuses those receipts; it +does not claim a new software acceptance run.

    +

    The workflow +matrix identifies raw receipt filenames. The evidence +index retains their original hashes; raw receipts remain in the +private beta handoff rather than being silently republished with the +documentation site.

    +

    The limits remain: actual city field acceptance and equipment/network +commissioning; Station automatic provisioning/SCM commissioning; every +UI/role combination; field recognition accuracy; and historical in-place +upgrades are not certified. They are not five invented feature +requirements. Fresh-install controlled beta handoff remains the accepted +scope. This package makes no city-deployment, publication or +general-availability claim.

    +

    Terms of service and license

    +

    Scope and status

    +

    These terms describe the Townlight Beta 1 software and this +documentation package. This is a locally prepared private beta, not a +hosted-service subscription, a city deployment agreement or a public +release. No uptime commitment, support response time, indemnity, +data-processing agreement or paid service is created by these documents. +A separate signed agreement, if any, governs services it actually +provides.

    +

    Software license and rights

    +

    Current Townlight-owned distributions identified in this candidate +use AGPL-3.0-only. The full license is supplied with +this documentation and with the source companion. The license governs +rights to run, copy, modify and convey the covered software; these +operational terms do not add restrictions to those rights. Historical +grants and dependency licenses retain their own terms. CivicCast remains +a separate product and is not relicensed by this documentation work.

    +

    When conveying covered software, retain applicable notices and +provide the corresponding source and installation/build information +required by the license. For a modified version supporting remote +network interaction, follow section 13’s source-offer requirement. The +companion archive identifies the source for this candidate; a link to a +different public branch is not a substitute for the matching source. +Read the supplied license for the complete conditions. See the GNU license +reference and GNU licensing +FAQ.

    +

    Data ownership and access

    +

    Importing a document does not transfer its ownership or grant +permission to publish it. The operating organization controls its +accounts, access decisions, lawful source use, retention and +review/release policy. Keep resident information, credentials, private +notes and restricted evidence in their authorized locations. +Documentation examples contain fictional data. No real city account, +credential or record is required to exercise these examples in an +isolated test environment.

    +

    Local operation and +external processors

    +

    The accepted beta workflow is local and uses named staff accounts. +Station has separate storage and credentials. Configure backup +destinations and optional model/network providers deliberately. A +configured external provider may receive submitted prompts, images or +audio according to that configuration and provider’s terms; this +documentation does not promise that every optional configuration is +offline. An email outbox or local public view does not establish +external delivery or an internet deployment. This static documentation +site has no analytics, account collection or remote font dependency.

    +

    Staff decisions and +source applicability

    +

    Staff verify the jurisdiction, source currency, permissions, +citations and proposed audience. Model output and generated guidance +require review. No draft is automatically an official legal +interpretation, zoning determination, permit approval, fee assessment, +enforcement notice or records-release decision. Official permit fee +authority remains with the adopted source and responsible organization; +imported amounts do not become a new authoritative calculation.

    +

    Beta operation and recovery

    +

    Use the identified candidate in its supported fresh-install scope. +Preserve backups and original evidence. Test physical equipment and +chosen network/service configuration before relying on them. The +supplied acceptance describes selected synthetic workflows, not every +screen, vendor, field condition or upgrade. Operators decide whether a +particular deployment meets their own operational obligations.

    +

    Warranty and liability

    +

    The covered software’s warranty and liability conditions are those in +sections 15–17 of the supplied AGPL and any applicable separate written +undertaking. This documentation creates no additional warranty or +limitation beyond those terms. Third-party software is subject to its +retained license notices. Nothing here removes rights that applicable +law makes nonwaivable.

    +

    Support and incident +reporting

    +

    Use the project’s existing SUPPORT and SECURITY guidance for its +matching repository. Report reproducible behavior with the version, +operation and redacted logs. Do not put credentials, resident records or +unredacted evidence in a public issue. Coordinate sensitive reports +through the channel designated in SECURITY. No new support address or +service commitment is invented here.

    +

    Ending a beta +exercise and document changes

    +

    When an organization ends testing, it controls retention/export and +removes access according to its policy. Uninstall may retain data; back +up and inspect the selected removal options. Ending an exercise does not +revoke rights already granted by AGPL. Later software/documentation +versions must identify their changed candidate and scope; historical +receipts retain their original identities. These terms do not claim that +a city has accepted a contract merely by reading a manual.

    +

    Glossary

    + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TermMeaning
    ApprovalAn explicit authorized decision on the saved text/artifact. It is +separate from saving or attachment.
    Canonical recordThe owning product’s retained identity and saved version, rather +than an editable copied label.
    CompositionThe selected set of desktop modules; inspections-preview exposes the +eight staff products.
    Corresponding sourceThe source/build material matching the delivered covered program, +subject to its license.
    Derivative / Records copyA separately prepared document with its own intended audience and +hash.
    Hash / SHA256A fingerprint of exact bytes. It detects change; it does not +establish legal authority.
    IdempotencyRepeating the same identified request has the same intended effect; +changing its payload can be refused.
    IPCThe native desktop command boundary between its browser interface +and Rust host.
    MCPModel Context Protocol; no direct Townlight product server is +enabled by this beta.
    OriginalRetained source bytes. A reviewed derivative does not replace +them.
    ProvenanceSource, version, date, actor and relationship information retained +with evidence.
    RevisionAn immutable saved version. Later edits do not inherit an earlier +review automatically.
    SnapshotA fixed audience-specific copy tied to a source/reviewed +revision.
    StationTownlight’s separate media boundary using a pinned CivicCast-derived +engine; standalone CivicCast remains separate.
    +

    Alphabetical subject index

    + + + +

    Source and document control

    +

    This edition is authored from the immutable corresponding-source +companion, the generated installed-domain schema and the retained +workflow receipts. The current software versions and signed artifacts +are unchanged. Public historical pages are not synchronized or published +by this local documentation task.

    +

    Workflow subject index

    + +
    Townlight · AGPL-3.0-only · Candidate evidence applies only to its identified artifacts.
    \ No newline at end of file diff --git a/docs/beta-1/pdf/Townlight-Access-Manual-Beta-1.pdf b/docs/beta-1/pdf/Townlight-Access-Manual-Beta-1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..33bcd16fb3450c6fc5241e976dc97040436cb468 GIT binary patch literal 213724 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%0A{ft+?Ak^66bXQ{AXr8^5jf+m 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